Cyr-To-Lat - Version 5.0.0

Version Description

(18.03.2021) = * Introduce tabs on options page * Add options to select post types and statuses for background conversion * Make colors compatible to WP official palette * Fix bug with Polylang when locale is not equal to language slug

Download this release

Release Info

Developer mihdan
Plugin Icon 128x128 Cyr-To-Lat
Version 5.0.0
Comparing to
See all releases

Code changes from version 4.6.4 to 5.0.0

Files changed (37) hide show
  1. assets/css/converter.css +74 -0
  2. assets/css/settings-base.css +25 -0
  3. css/cyr-to-lat-admin.css → assets/css/tables.css +11 -26
  4. {js → assets/js}/acf-field-group.js +0 -0
  5. assets/js/converter/app.js +2 -0
  6. assets/js/tables/app.js +2 -0
  7. classes/class-settings.php +0 -785
  8. cyr-to-lat.php +19 -22
  9. dist/js/settings/app.js +0 -2
  10. languages/cyr2lat-ru_RU.mo +0 -0
  11. languages/cyr2lat-ru_RU.po +158 -176
  12. languages/cyr2lat-sv.po +7 -7
  13. languages/cyr2lat-uk.po +7 -7
  14. readme.txt +13 -3
  15. src/php/Settings/Abstracts/SettingsBase.php +956 -0
  16. src/php/Settings/Abstracts/SettingsInterface.php +23 -0
  17. src/php/Settings/Converter.php +295 -0
  18. src/php/Settings/PluginSettingsBase.php +72 -0
  19. src/php/Settings/Settings.php +165 -0
  20. src/php/Settings/Tables.php +286 -0
  21. {classes → src/php}/background-processes/class-conversion-process.php +0 -0
  22. {classes → src/php}/background-processes/class-post-conversion-process.php +0 -0
  23. {classes → src/php}/background-processes/class-term-conversion-process.php +0 -0
  24. {classes → src/php}/class-acf.php +3 -1
  25. {classes → src/php}/class-admin-notices.php +6 -7
  26. {classes → src/php}/class-conversion-tables.php +0 -0
  27. {classes → src/php}/class-converter.php +21 -19
  28. {classes → src/php}/class-main.php +17 -8
  29. {classes → src/php}/class-requirements.php +18 -13
  30. {classes → src/php}/class-wp-cli.php +0 -0
  31. vendor/autoload.php +1 -1
  32. vendor/composer/ClassLoader.php +4 -2
  33. vendor/composer/InstalledVersions.php +6 -7
  34. vendor/composer/autoload_classmap.php +16 -11
  35. vendor/composer/autoload_real.php +7 -7
  36. vendor/composer/autoload_static.php +20 -15
  37. vendor/composer/installed.php +6 -6
assets/css/converter.css ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #ctl-confirm-popup {
2
+ display: none;
3
+ position: fixed;
4
+ left: 0;
5
+ right: 0;
6
+ top: 0;
7
+ bottom: 0;
8
+ background: rgba(241,241,241,0.8);
9
+ z-index: 9999;
10
+ }
11
+
12
+ #ctl-confirm-content {
13
+ display: block;
14
+ position: fixed;
15
+ left: 50%;
16
+ top: 50%;
17
+ transform: translate(-50%, -50%);
18
+ background: #fff;
19
+ padding: 20px;
20
+ }
21
+
22
+ .helper {
23
+ position: relative;
24
+ float: left;
25
+ left: -1.7em;
26
+ top: 0.4em;
27
+ }
28
+
29
+ .helper-content {
30
+ position: absolute;
31
+ display: none;
32
+ line-height: 1.5em;
33
+ top: 50%;
34
+ left: 50%;
35
+ transform: translate(calc(-50% + 5px), 26px);
36
+ color: #fff;
37
+ font-size: .8em;
38
+ width: 150px;
39
+ background: #333;
40
+ text-align: center;
41
+ border-radius: 3px;
42
+ padding: .618em 1em;
43
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
44
+ }
45
+
46
+ .helper::after {
47
+ font-family: Dashicons;
48
+ font-size: 1.3em;
49
+ speak: none;
50
+ font-weight: 400;
51
+ text-transform: none;
52
+ line-height: 1;
53
+ -webkit-font-smoothing: antialiased;
54
+ text-indent: 0;
55
+ position: absolute;
56
+ top: 0;
57
+ left: 0;
58
+ width: 100%;
59
+ height: 100%;
60
+ text-align: center;
61
+ content: "";
62
+ cursor: help;
63
+ font-variant: normal;
64
+ margin: 0;
65
+ }
66
+
67
+ .helper:hover .helper-content {
68
+ display: block;
69
+ }
70
+
71
+ #ctl-convert-button {
72
+ color: #d63638;
73
+ border-color: #d63638;
74
+ }
assets/css/settings-base.css ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .ctl-settings-tabs {
2
+ line-height: 4.5em;
3
+ background: #fff;
4
+ margin: 10px -20px 0 -20px;
5
+ padding: 0 20px;
6
+ }
7
+
8
+ .ctl-settings-tab {
9
+ display: inline-block;
10
+ font-size: 1.1em;
11
+ text-decoration: none;
12
+ margin-right: 30px;
13
+ color: #646970;
14
+ border-bottom: 2px solid transparent;
15
+ }
16
+
17
+ .ctl-settings-tab:hover {
18
+ color: #666;
19
+ border-color: #646970;
20
+ border-bottom: 2px solid;
21
+ }
22
+
23
+ .ctl-settings-tab.active {
24
+ border-bottom: 2px solid #4f94d4;
25
+ }
css/cyr-to-lat-admin.css → assets/css/tables.css RENAMED
@@ -27,6 +27,7 @@
27
  max-height: 34px;
28
  height: 14px;
29
  line-height: 14px;
 
30
  }
31
 
32
  #ctl-options .nav-tab-wrapper {
@@ -49,7 +50,7 @@ body.js #ctl-options .ctl-table {
49
  clear: both;
50
  width: 100%;
51
  box-sizing: border-box;
52
- border: 1px solid #ccc;
53
  }
54
 
55
  #ctl-options .submit, #ctl-convert-existing-slugs {
@@ -64,12 +65,16 @@ body.js #ctl-options .ctl-table {
64
  }
65
 
66
  #ctl-options .nav-tab-active {
67
- background: #fff;
68
- border-bottom: 1px solid #ccc;
 
69
  }
70
 
71
- .nav-tab-current {
72
- box-shadow: 0 0 5px 5px #fff;
 
 
 
73
  }
74
 
75
  .ctl-table.active {
@@ -134,27 +139,7 @@ body.js #ctl-options .ctl-table {
134
 
135
  #appreciation {
136
  clear: both;
137
- }
138
-
139
- #ctl-confirm-popup {
140
- display: none;
141
- position: fixed;
142
- left: 0;
143
- right: 0;
144
- top: 0;
145
- bottom: 0;
146
- background: rgba(241,241,241,0.8);
147
- z-index: 9999;
148
- }
149
-
150
- #ctl-confirm-content {
151
- display: block;
152
- position: fixed;
153
- left: 50%;
154
- top: 50%;
155
- transform: translate(-50%, -50%);
156
- background: #fff;
157
- padding: 20px;
158
  }
159
 
160
  @media screen and (max-width: 767px) {
27
  max-height: 34px;
28
  height: 14px;
29
  line-height: 14px;
30
+ margin-top: 15px;
31
  }
32
 
33
  #ctl-options .nav-tab-wrapper {
50
  clear: both;
51
  width: 100%;
52
  box-sizing: border-box;
53
+ border: 1px solid #c3c4c7;
54
  }
55
 
56
  #ctl-options .submit, #ctl-convert-existing-slugs {
65
  }
66
 
67
  #ctl-options .nav-tab-active {
68
+ background: #4f94d4;
69
+ color: #fff;
70
+ border-color: #2271b1;
71
  }
72
 
73
+ #ctl-options .nav-tab-current.nav-tab-active {
74
+ /*box-shadow: 0 0 5px 5px #2271b1;*/
75
+ background: #2271b1;
76
+ color: #fff;
77
+ border-color: #0a4b78;
78
  }
79
 
80
  .ctl-table.active {
139
 
140
  #appreciation {
141
  clear: both;
142
+ padding-top: 10px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  }
144
 
145
  @media screen and (max-width: 767px) {
{js → assets/js}/acf-field-group.js RENAMED
File without changes
assets/js/converter/app.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ !function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,r){r(1),t.exports=r(2)},function(t,e){var r="undefined"!=typeof self?self:this,n=function(){function t(){this.fetch=!1,this.DOMException=r.DOMException}return t.prototype=r,new t}();!function(t){!function(e){var r="URLSearchParams"in t,n="Symbol"in t&&"iterator"in Symbol,o="FileReader"in t&&"Blob"in t&&function(){try{return new Blob,!0}catch(t){return!1}}(),i="FormData"in t,s="ArrayBuffer"in t;if(s)var a=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],u=ArrayBuffer.isView||function(t){return t&&a.indexOf(Object.prototype.toString.call(t))>-1};function c(t){if("string"!=typeof t&&(t=String(t)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(t))throw new TypeError("Invalid character in header field name");return t.toLowerCase()}function f(t){return"string"!=typeof t&&(t=String(t)),t}function h(t){var e={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return n&&(e[Symbol.iterator]=function(){return e}),e}function d(t){this.map={},t instanceof d?t.forEach((function(t,e){this.append(e,t)}),this):Array.isArray(t)?t.forEach((function(t){this.append(t[0],t[1])}),this):t&&Object.getOwnPropertyNames(t).forEach((function(e){this.append(e,t[e])}),this)}function l(t){if(t.bodyUsed)return Promise.reject(new TypeError("Already read"));t.bodyUsed=!0}function p(t){return new Promise((function(e,r){t.onload=function(){e(t.result)},t.onerror=function(){r(t.error)}}))}function y(t){var e=new FileReader,r=p(e);return e.readAsArrayBuffer(t),r}function b(t){if(t.slice)return t.slice(0);var e=new Uint8Array(t.byteLength);return e.set(new Uint8Array(t)),e.buffer}function m(){return this.bodyUsed=!1,this._initBody=function(t){var e;this._bodyInit=t,t?"string"==typeof t?this._bodyText=t:o&&Blob.prototype.isPrototypeOf(t)?this._bodyBlob=t:i&&FormData.prototype.isPrototypeOf(t)?this._bodyFormData=t:r&&URLSearchParams.prototype.isPrototypeOf(t)?this._bodyText=t.toString():s&&o&&((e=t)&&DataView.prototype.isPrototypeOf(e))?(this._bodyArrayBuffer=b(t.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):s&&(ArrayBuffer.prototype.isPrototypeOf(t)||u(t))?this._bodyArrayBuffer=b(t):this._bodyText=t=Object.prototype.toString.call(t):this._bodyText="",this.headers.get("content-type")||("string"==typeof t?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):r&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},o&&(this.blob=function(){var t=l(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?l(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(y)}),this.text=function(){var t,e,r,n=l(this);if(n)return n;if(this._bodyBlob)return t=this._bodyBlob,e=new FileReader,r=p(e),e.readAsText(t),r;if(this._bodyArrayBuffer)return Promise.resolve(function(t){for(var e=new Uint8Array(t),r=new Array(e.length),n=0;n<e.length;n++)r[n]=String.fromCharCode(e[n]);return r.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},i&&(this.formData=function(){return this.text().then(O)}),this.json=function(){return this.text().then(JSON.parse)},this}d.prototype.append=function(t,e){t=c(t),e=f(e);var r=this.map[t];this.map[t]=r?r+", "+e:e},d.prototype.delete=function(t){delete this.map[c(t)]},d.prototype.get=function(t){return t=c(t),this.has(t)?this.map[t]:null},d.prototype.has=function(t){return this.map.hasOwnProperty(c(t))},d.prototype.set=function(t,e){this.map[c(t)]=f(e)},d.prototype.forEach=function(t,e){for(var r in this.map)this.map.hasOwnProperty(r)&&t.call(e,this.map[r],r,this)},d.prototype.keys=function(){var t=[];return this.forEach((function(e,r){t.push(r)})),h(t)},d.prototype.values=function(){var t=[];return this.forEach((function(e){t.push(e)})),h(t)},d.prototype.entries=function(){var t=[];return this.forEach((function(e,r){t.push([r,e])})),h(t)},n&&(d.prototype[Symbol.iterator]=d.prototype.entries);var E=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];function v(t,e){var r,n,o=(e=e||{}).body;if(t instanceof v){if(t.bodyUsed)throw new TypeError("Already read");this.url=t.url,this.credentials=t.credentials,e.headers||(this.headers=new d(t.headers)),this.method=t.method,this.mode=t.mode,this.signal=t.signal,o||null==t._bodyInit||(o=t._bodyInit,t.bodyUsed=!0)}else this.url=String(t);if(this.credentials=e.credentials||this.credentials||"same-origin",!e.headers&&this.headers||(this.headers=new d(e.headers)),this.method=(r=e.method||this.method||"GET",n=r.toUpperCase(),E.indexOf(n)>-1?n:r),this.mode=e.mode||this.mode||null,this.signal=e.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&o)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(o)}function O(t){var e=new FormData;return t.trim().split("&").forEach((function(t){if(t){var r=t.split("="),n=r.shift().replace(/\+/g," "),o=r.join("=").replace(/\+/g," ");e.append(decodeURIComponent(n),decodeURIComponent(o))}})),e}function _(t,e){e||(e={}),this.type="default",this.status=void 0===e.status?200:e.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in e?e.statusText:"OK",this.headers=new d(e.headers),this.url=e.url||"",this._initBody(t)}v.prototype.clone=function(){return new v(this,{body:this._bodyInit})},m.call(v.prototype),m.call(_.prototype),_.prototype.clone=function(){return new _(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new d(this.headers),url:this.url})},_.error=function(){var t=new _(null,{status:0,statusText:""});return t.type="error",t};var w=[301,302,303,307,308];_.redirect=function(t,e){if(-1===w.indexOf(e))throw new RangeError("Invalid status code");return new _(null,{status:e,headers:{location:t}})},e.DOMException=t.DOMException;try{new e.DOMException}catch(t){e.DOMException=function(t,e){this.message=t,this.name=e;var r=Error(t);this.stack=r.stack},e.DOMException.prototype=Object.create(Error.prototype),e.DOMException.prototype.constructor=e.DOMException}function T(t,r){return new Promise((function(n,i){var s=new v(t,r);if(s.signal&&s.signal.aborted)return i(new e.DOMException("Aborted","AbortError"));var a=new XMLHttpRequest;function u(){a.abort()}a.onload=function(){var t,e,r={status:a.status,statusText:a.statusText,headers:(t=a.getAllResponseHeaders()||"",e=new d,t.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach((function(t){var r=t.split(":"),n=r.shift().trim();if(n){var o=r.join(":").trim();e.append(n,o)}})),e)};r.url="responseURL"in a?a.responseURL:r.headers.get("X-Request-URL");var o="response"in a?a.response:a.responseText;n(new _(o,r))},a.onerror=function(){i(new TypeError("Network request failed"))},a.ontimeout=function(){i(new TypeError("Network request failed"))},a.onabort=function(){i(new e.DOMException("Aborted","AbortError"))},a.open(s.method,s.url,!0),"include"===s.credentials?a.withCredentials=!0:"omit"===s.credentials&&(a.withCredentials=!1),"responseType"in a&&o&&(a.responseType="blob"),s.headers.forEach((function(t,e){a.setRequestHeader(e,t)})),s.signal&&(s.signal.addEventListener("abort",u),a.onreadystatechange=function(){4===a.readyState&&s.signal.removeEventListener("abort",u)}),a.send(void 0===s._bodyInit?null:s._bodyInit)}))}T.polyfill=!0,t.fetch||(t.fetch=T,t.Headers=d,t.Request=v,t.Response=_),e.Headers=d,e.Request=v,e.Response=_,e.fetch=T,Object.defineProperty(e,"__esModule",{value:!0})}({})}(n),n.fetch.ponyfill=!0,delete n.fetch.polyfill;var o=n;(e=o.fetch).default=o.fetch,e.fetch=o.fetch,e.Headers=o.Headers,e.Request=o.Request,e.Response=o.Response,t.exports=e},function(t,e,r){"use strict";var n,o=r(3),i=(n=o)&&n.__esModule?n:{default:n};document.addEventListener("DOMContentLoaded",(function(){new i.default}))},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}();var o=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.CONVERT_FORM_SELECTOR="#ctl-convert-existing-slugs",this.CONVERT_BUTTON_SELECTOR="#ctl-convert-button",this.CONFIRM_POPUP_SELECTOR="#ctl-confirm-popup",this.CONFIRM_OK_SELECTOR="#ctl-confirm-ok",this.CONFIRM_CANCEL_SELECTOR="#ctl-confirm-cancel",this.confirmPopup=document.querySelector(this.CONFIRM_POPUP_SELECTOR),this.bindEvents()}return n(t,[{key:"bindEvents",value:function(){var t=this;document.querySelector(this.CONVERT_BUTTON_SELECTOR).onclick=function(e){return e.preventDefault(),t.confirmPopup.style.display="block",!1},this.confirmPopup.onclick=function(){t.hideConfirmPopup()},document.querySelector(this.CONFIRM_OK_SELECTOR).onclick=function(e){e.stopPropagation(),t.hideConfirmPopup(),document.querySelector(t.CONVERT_FORM_SELECTOR).submit()},document.querySelector(this.CONFIRM_CANCEL_SELECTOR).onclick=function(e){e.stopPropagation(),t.hideConfirmPopup()}}},{key:"hideConfirmPopup",value:function(){this.confirmPopup.style.display="none"}}]),t}();e.default=o}]);
2
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2Nyb3NzLWZldGNoL2Rpc3QvYnJvd3Nlci1wb255ZmlsbC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvanMvY29udmVydGVyL2FwcC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvanMvY29udmVydGVyL2NvbnZlcnRlci5qcyJdLCJuYW1lcyI6WyJpbnN0YWxsZWRNb2R1bGVzIiwiX193ZWJwYWNrX3JlcXVpcmVfXyIsIm1vZHVsZUlkIiwiZXhwb3J0cyIsIm1vZHVsZSIsImkiLCJsIiwibW9kdWxlcyIsImNhbGwiLCJtIiwiYyIsImQiLCJuYW1lIiwiZ2V0dGVyIiwibyIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZW51bWVyYWJsZSIsImdldCIsInIiLCJTeW1ib2wiLCJ0b1N0cmluZ1RhZyIsInZhbHVlIiwidCIsIm1vZGUiLCJfX2VzTW9kdWxlIiwibnMiLCJjcmVhdGUiLCJrZXkiLCJiaW5kIiwibiIsIm9iamVjdCIsInByb3BlcnR5IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJwIiwicyIsImdsb2JhbCIsInNlbGYiLCJ0aGlzIiwiX19zZWxmX18iLCJGIiwiZmV0Y2giLCJET01FeGNlcHRpb24iLCJzdXBwb3J0IiwiQmxvYiIsImUiLCJ2aWV3Q2xhc3NlcyIsImlzQXJyYXlCdWZmZXJWaWV3IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJvYmoiLCJpbmRleE9mIiwidG9TdHJpbmciLCJub3JtYWxpemVOYW1lIiwiU3RyaW5nIiwidGVzdCIsIlR5cGVFcnJvciIsInRvTG93ZXJDYXNlIiwibm9ybWFsaXplVmFsdWUiLCJpdGVyYXRvckZvciIsIml0ZW1zIiwiaXRlcmF0b3IiLCJuZXh0Iiwic2hpZnQiLCJkb25lIiwidW5kZWZpbmVkIiwiSGVhZGVycyIsImhlYWRlcnMiLCJtYXAiLCJmb3JFYWNoIiwiYXBwZW5kIiwiQXJyYXkiLCJpc0FycmF5IiwiaGVhZGVyIiwiZ2V0T3duUHJvcGVydHlOYW1lcyIsImNvbnN1bWVkIiwiYm9keSIsImJvZHlVc2VkIiwiUHJvbWlzZSIsInJlamVjdCIsImZpbGVSZWFkZXJSZWFkeSIsInJlYWRlciIsInJlc29sdmUiLCJvbmxvYWQiLCJyZXN1bHQiLCJvbmVycm9yIiwiZXJyb3IiLCJyZWFkQmxvYkFzQXJyYXlCdWZmZXIiLCJibG9iIiwiRmlsZVJlYWRlciIsInByb21pc2UiLCJyZWFkQXNBcnJheUJ1ZmZlciIsImJ1ZmZlckNsb25lIiwiYnVmIiwic2xpY2UiLCJ2aWV3IiwiVWludDhBcnJheSIsImJ5dGVMZW5ndGgiLCJzZXQiLCJidWZmZXIiLCJCb2R5IiwiX2luaXRCb2R5IiwiX2JvZHlJbml0IiwiX2JvZHlUZXh0IiwiaXNQcm90b3R5cGVPZiIsIl9ib2R5QmxvYiIsIkZvcm1EYXRhIiwiX2JvZHlGb3JtRGF0YSIsIlVSTFNlYXJjaFBhcmFtcyIsIkRhdGFWaWV3IiwiX2JvZHlBcnJheUJ1ZmZlciIsInR5cGUiLCJyZWplY3RlZCIsIkVycm9yIiwiYXJyYXlCdWZmZXIiLCJ0aGVuIiwidGV4dCIsInJlYWRBc1RleHQiLCJjaGFycyIsImxlbmd0aCIsImZyb21DaGFyQ29kZSIsImpvaW4iLCJyZWFkQXJyYXlCdWZmZXJBc1RleHQiLCJmb3JtRGF0YSIsImRlY29kZSIsImpzb24iLCJKU09OIiwicGFyc2UiLCJvbGRWYWx1ZSIsImhhcyIsImNhbGxiYWNrIiwidGhpc0FyZyIsImtleXMiLCJwdXNoIiwidmFsdWVzIiwiZW50cmllcyIsIm1ldGhvZHMiLCJSZXF1ZXN0IiwiaW5wdXQiLCJvcHRpb25zIiwibWV0aG9kIiwidXBjYXNlZCIsInVybCIsImNyZWRlbnRpYWxzIiwic2lnbmFsIiwidG9VcHBlckNhc2UiLCJyZWZlcnJlciIsImZvcm0iLCJ0cmltIiwic3BsaXQiLCJieXRlcyIsInJlcGxhY2UiLCJkZWNvZGVVUklDb21wb25lbnQiLCJSZXNwb25zZSIsImJvZHlJbml0Iiwic3RhdHVzIiwib2siLCJzdGF0dXNUZXh0IiwiY2xvbmUiLCJyZXNwb25zZSIsInJlZGlyZWN0U3RhdHVzZXMiLCJyZWRpcmVjdCIsIlJhbmdlRXJyb3IiLCJsb2NhdGlvbiIsImVyciIsIm1lc3NhZ2UiLCJzdGFjayIsImNvbnN0cnVjdG9yIiwiaW5pdCIsInJlcXVlc3QiLCJhYm9ydGVkIiwieGhyIiwiWE1MSHR0cFJlcXVlc3QiLCJhYm9ydFhociIsImFib3J0IiwicmF3SGVhZGVycyIsImdldEFsbFJlc3BvbnNlSGVhZGVycyIsImxpbmUiLCJwYXJ0cyIsInJlc3BvbnNlVVJMIiwicmVzcG9uc2VUZXh0Iiwib250aW1lb3V0Iiwib25hYm9ydCIsIm9wZW4iLCJ3aXRoQ3JlZGVudGlhbHMiLCJyZXNwb25zZVR5cGUiLCJzZXRSZXF1ZXN0SGVhZGVyIiwiYWRkRXZlbnRMaXN0ZW5lciIsIm9ucmVhZHlzdGF0ZWNoYW5nZSIsInJlYWR5U3RhdGUiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwic2VuZCIsInBvbHlmaWxsIiwicG9ueWZpbGwiLCJjdHgiLCJkZWZhdWx0IiwiZG9jdW1lbnQiLCJDb252ZXJ0ZXIiLCJDT05WRVJUX0ZPUk1fU0VMRUNUT1IiLCJDT05WRVJUX0JVVFRPTl9TRUxFQ1RPUiIsIkNPTkZJUk1fUE9QVVBfU0VMRUNUT1IiLCJDT05GSVJNX09LX1NFTEVDVE9SIiwiQ09ORklSTV9DQU5DRUxfU0VMRUNUT1IiLCJjb25maXJtUG9wdXAiLCJxdWVyeVNlbGVjdG9yIiwiYmluZEV2ZW50cyIsIm9uY2xpY2siLCJldmVudCIsInByZXZlbnREZWZhdWx0Iiwic3R5bGUiLCJkaXNwbGF5IiwiaGlkZUNvbmZpcm1Qb3B1cCIsInN0b3BQcm9wYWdhdGlvbiIsInN1Ym1pdCJdLCJtYXBwaW5ncyI6ImFBQ0UsSUFBSUEsRUFBbUIsR0FHdkIsU0FBU0MsRUFBb0JDLEdBRzVCLEdBQUdGLEVBQWlCRSxHQUNuQixPQUFPRixFQUFpQkUsR0FBVUMsUUFHbkMsSUFBSUMsRUFBU0osRUFBaUJFLEdBQVksQ0FDekNHLEVB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QyxJQUFJVSxjLDJVQ0ZDQSxFLFdBSUwsYyw0RkFBYyxTQUNiL0osS0FBS2dLLHNCQUF3Qiw4QkFDN0JoSyxLQUFLaUssd0JBQTBCLHNCQUMvQmpLLEtBQUtrSyx1QkFBeUIscUJBQzlCbEssS0FBS21LLG9CQUFzQixrQkFDM0JuSyxLQUFLb0ssd0JBQTBCLHNCQUUvQnBLLEtBQUtxSyxhQUFlUCxTQUFTUSxjQUM1QnRLLEtBQUtrSyx3QkFHTmxLLEtBQUt1SyxhLCtDQU1PLFdBQ1pULFNBQVNRLGNBQWV0SyxLQUFLaUsseUJBQTBCTyxRQUFVLFNBQ2hFQyxHQUlBLE9BRkFBLEVBQU1DLGlCQUNOLEVBQUtMLGFBQWFNLE1BQU1DLFFBQVUsU0FDM0IsR0FHUjVLLEtBQUtxSyxhQUFhRyxRQUFVLFdBQzNCLEVBQUtLLG9CQUdOZixTQUFTUSxjQUFldEssS0FBS21LLHFCQUFzQkssUUFBVSxTQUM1REMsR0FFQUEsRUFBTUssa0JBQ04sRUFBS0QsbUJBQ0xmLFNBQVNRLGNBQWUsRUFBS04sdUJBQXdCZSxVQUd0RGpCLFNBQVNRLGNBQWV0SyxLQUFLb0sseUJBQTBCSSxRQUFVLFNBQ2hFQyxHQUVBQSxFQUFNSyxrQkFDTixFQUFLRCxzQix5Q0FRTjdLLEtBQUtxSyxhQUFhTSxNQUFNQyxRQUFVLFcsZUFJckJiIiwiZmlsZSI6ImNvbnZlcnRlci9hcHAuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG4iLCJ2YXIgZ2xvYmFsID0gdHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnID8gc2VsZiA6IHRoaXM7XG52YXIgX19zZWxmX18gPSAoZnVuY3Rpb24gKCkge1xuZnVuY3Rpb24gRigpIHtcbnRoaXMuZmV0Y2ggPSBmYWxzZTtcbnRoaXMuRE9NRXhjZXB0aW9uID0gZ2xvYmFsLkRPTUV4Y2VwdGlvblxufVxuRi5wcm90b3R5cGUgPSBnbG9iYWw7XG5yZXR1cm4gbmV3IEYoKTtcbn0pKCk7XG4oZnVuY3Rpb24oc2VsZikge1xuXG52YXIgaXJyZWxldmFudCA9IChmdW5jdGlvbiAoZXhwb3J0cykge1xuXG4gIHZhciBzdXBwb3J0ID0ge1xuICAgIHNlYXJjaFBhcmFtczogJ1VSTFNlYXJjaFBhcmFtcycgaW4gc2VsZixcbiAgICBpdGVyYWJsZTogJ1N5bWJvbCcgaW4gc2VsZiAmJiAnaXRlcmF0b3InIGluIFN5bWJvbCxcbiAgICBibG9iOlxuICAgICAgJ0ZpbGVSZWFkZXInIGluIHNlbGYgJiZcbiAgICAgICdCbG9iJyBpbiBzZWxmICYmXG4gICAgICAoZnVuY3Rpb24oKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbmV3IEJsb2IoKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH0pKCksXG4gICAgZm9ybURhdGE6ICdGb3JtRGF0YScgaW4gc2VsZixcbiAgICBhcnJheUJ1ZmZlcjogJ0FycmF5QnVmZmVyJyBpbiBzZWxmXG4gIH07XG5cbiAgZnVuY3Rpb24gaXNEYXRhVmlldyhvYmopIHtcbiAgICByZXR1cm4gb2JqICYmIERhdGFWaWV3LnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKG9iailcbiAgfVxuXG4gIGlmIChzdXBwb3J0LmFycmF5QnVmZmVyKSB7XG4gICAgdmFyIHZpZXdDbGFzc2VzID0gW1xuICAgICAgJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgICAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgICAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICAgICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICAgICdbb2JqZWN0IFVpbnQzMkFycmF5XScsXG4gICAgICAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICAgICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nXG4gICAgXTtcblxuICAgIHZhciBpc0FycmF5QnVmZmVyVmlldyA9XG4gICAgICBBcnJheUJ1ZmZlci5pc1ZpZXcgfHxcbiAgICAgIGZ1bmN0aW9uKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqICYmIHZpZXdDbGFzc2VzLmluZGV4T2YoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikpID4gLTFcbiAgICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBub3JtYWxpemVOYW1lKG5hbWUpIHtcbiAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICBuYW1lID0gU3RyaW5nKG5hbWUpO1xuICAgIH1cbiAgICBpZiAoL1teYS16MC05XFwtIyQlJicqKy5eX2B8fl0vaS50ZXN0KG5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGNoYXJhY3RlciBpbiBoZWFkZXIgZmllbGQgbmFtZScpXG4gICAgfVxuICAgIHJldHVybiBuYW1lLnRvTG93ZXJDYXNlKClcbiAgfVxuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZVZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gU3RyaW5nKHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICAvLyBCdWlsZCBhIGRlc3RydWN0aXZlIGl0ZXJhdG9yIGZvciB0aGUgdmFsdWUgbGlzdFxuICBmdW5jdGlvbiBpdGVyYXRvckZvcihpdGVtcykge1xuICAgIHZhciBpdGVyYXRvciA9IHtcbiAgICAgIG5leHQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBpdGVtcy5zaGlmdCgpO1xuICAgICAgICByZXR1cm4ge2RvbmU6IHZhbHVlID09PSB1bmRlZmluZWQsIHZhbHVlOiB2YWx1ZX1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHN1cHBvcnQuaXRlcmFibGUpIHtcbiAgICAgIGl0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBpdGVyYXRvclxuICB9XG5cbiAgZnVuY3Rpb24gSGVhZGVycyhoZWFkZXJzKSB7XG4gICAgdGhpcy5tYXAgPSB7fTtcblxuICAgIGlmIChoZWFkZXJzIGluc3RhbmNlb2YgSGVhZGVycykge1xuICAgICAgaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kKG5hbWUsIHZhbHVlKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShoZWFkZXJzKSkge1xuICAgICAgaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKGhlYWRlcikge1xuICAgICAgICB0aGlzLmFwcGVuZChoZWFkZXJbMF0sIGhlYWRlclsxXSk7XG4gICAgICB9LCB0aGlzKTtcbiAgICB9IGVsc2UgaWYgKGhlYWRlcnMpIHtcbiAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGhlYWRlcnMpLmZvckVhY2goZnVuY3Rpb24obmFtZSkge1xuICAgICAgICB0aGlzLmFwcGVuZChuYW1lLCBoZWFkZXJzW25hbWVdKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIEhlYWRlcnMucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgbmFtZSA9IG5vcm1hbGl6ZU5hbWUobmFtZSk7XG4gICAgdmFsdWUgPSBub3JtYWxpemVWYWx1ZSh2YWx1ZSk7XG4gICAgdmFyIG9sZFZhbHVlID0gdGhpcy5tYXBbbmFtZV07XG4gICAgdGhpcy5tYXBbbmFtZV0gPSBvbGRWYWx1ZSA/IG9sZFZhbHVlICsgJywgJyArIHZhbHVlIDogdmFsdWU7XG4gIH07XG5cbiAgSGVhZGVycy5wcm90b3R5cGVbJ2RlbGV0ZSddID0gZnVuY3Rpb24obmFtZSkge1xuICAgIGRlbGV0ZSB0aGlzLm1hcFtub3JtYWxpemVOYW1lKG5hbWUpXTtcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgbmFtZSA9IG5vcm1hbGl6ZU5hbWUobmFtZSk7XG4gICAgcmV0dXJuIHRoaXMuaGFzKG5hbWUpID8gdGhpcy5tYXBbbmFtZV0gOiBudWxsXG4gIH07XG5cbiAgSGVhZGVycy5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24obmFtZSkge1xuICAgIHJldHVybiB0aGlzLm1hcC5oYXNPd25Qcm9wZXJ0eShub3JtYWxpemVOYW1lKG5hbWUpKVxuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgdGhpcy5tYXBbbm9ybWFsaXplTmFtZShuYW1lKV0gPSBub3JtYWxpemVWYWx1ZSh2YWx1ZSk7XG4gIH07XG5cbiAgSGVhZGVycy5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrLCB0aGlzQXJnKSB7XG4gICAgZm9yICh2YXIgbmFtZSBpbiB0aGlzLm1hcCkge1xuICAgICAgaWYgKHRoaXMubWFwLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdGhpcy5tYXBbbmFtZV0sIG5hbWUsIHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZS5rZXlzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGl0ZW1zID0gW107XG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICBpdGVtcy5wdXNoKG5hbWUpO1xuICAgIH0pO1xuICAgIHJldHVybiBpdGVyYXRvckZvcihpdGVtcylcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZS52YWx1ZXMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGl0ZW1zLnB1c2godmFsdWUpO1xuICAgIH0pO1xuICAgIHJldHVybiBpdGVyYXRvckZvcihpdGVtcylcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZS5lbnRyaWVzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGl0ZW1zID0gW107XG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICBpdGVtcy5wdXNoKFtuYW1lLCB2YWx1ZV0pO1xuICAgIH0pO1xuICAgIHJldHVybiBpdGVyYXRvckZvcihpdGVtcylcbiAgfTtcblxuICBpZiAoc3VwcG9ydC5pdGVyYWJsZSkge1xuICAgIEhlYWRlcnMucHJvdG90eXBlW1N5bWJvbC5pdGVyYXRvcl0gPSBIZWFkZXJzLnByb3RvdHlwZS5lbnRyaWVzO1xuICB9XG5cbiAgZnVuY3Rpb24gY29uc3VtZWQoYm9keSkge1xuICAgIGlmIChib2R5LmJvZHlVc2VkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFR5cGVFcnJvcignQWxyZWFkeSByZWFkJykpXG4gICAgfVxuICAgIGJvZHkuYm9keVVzZWQgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gZmlsZVJlYWRlclJlYWR5KHJlYWRlcikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmVzb2x2ZShyZWFkZXIucmVzdWx0KTtcbiAgICAgIH07XG4gICAgICByZWFkZXIub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZWplY3QocmVhZGVyLmVycm9yKTtcbiAgICAgIH07XG4gICAgfSlcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWRCbG9iQXNBcnJheUJ1ZmZlcihibG9iKSB7XG4gICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgdmFyIHByb21pc2UgPSBmaWxlUmVhZGVyUmVhZHkocmVhZGVyKTtcbiAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoYmxvYik7XG4gICAgcmV0dXJuIHByb21pc2VcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWRCbG9iQXNUZXh0KGJsb2IpIHtcbiAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICB2YXIgcHJvbWlzZSA9IGZpbGVSZWFkZXJSZWFkeShyZWFkZXIpO1xuICAgIHJlYWRlci5yZWFkQXNUZXh0KGJsb2IpO1xuICAgIHJldHVybiBwcm9taXNlXG4gIH1cblxuICBmdW5jdGlvbiByZWFkQXJyYXlCdWZmZXJBc1RleHQoYnVmKSB7XG4gICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShidWYpO1xuICAgIHZhciBjaGFycyA9IG5ldyBBcnJheSh2aWV3Lmxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXcubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoYXJzW2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZSh2aWV3W2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIGNoYXJzLmpvaW4oJycpXG4gIH1cblxuICBmdW5jdGlvbiBidWZmZXJDbG9uZShidWYpIHtcbiAgICBpZiAoYnVmLnNsaWNlKSB7XG4gICAgICByZXR1cm4gYnVmLnNsaWNlKDApXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoYnVmLmJ5dGVMZW5ndGgpO1xuICAgICAgdmlldy5zZXQobmV3IFVpbnQ4QXJyYXkoYnVmKSk7XG4gICAgICByZXR1cm4gdmlldy5idWZmZXJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBCb2R5KCkge1xuICAgIHRoaXMuYm9keVVzZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuX2luaXRCb2R5ID0gZnVuY3Rpb24oYm9keSkge1xuICAgICAgdGhpcy5fYm9keUluaXQgPSBib2R5O1xuICAgICAgaWYgKCFib2R5KSB7XG4gICAgICAgIHRoaXMuX2JvZHlUZXh0ID0gJyc7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLl9ib2R5VGV4dCA9IGJvZHk7XG4gICAgICB9IGVsc2UgaWYgKHN1cHBvcnQuYmxvYiAmJiBCbG9iLnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKGJvZHkpKSB7XG4gICAgICAgIHRoaXMuX2JvZHlCbG9iID0gYm9keTtcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5mb3JtRGF0YSAmJiBGb3JtRGF0YS5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihib2R5KSkge1xuICAgICAgICB0aGlzLl9ib2R5Rm9ybURhdGEgPSBib2R5O1xuICAgICAgfSBlbHNlIGlmIChzdXBwb3J0LnNlYXJjaFBhcmFtcyAmJiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkpIHtcbiAgICAgICAgdGhpcy5fYm9keVRleHQgPSBib2R5LnRvU3RyaW5nKCk7XG4gICAgICB9IGVsc2UgaWYgKHN1cHBvcnQuYXJyYXlCdWZmZXIgJiYgc3VwcG9ydC5ibG9iICYmIGlzRGF0YVZpZXcoYm9keSkpIHtcbiAgICAgICAgdGhpcy5fYm9keUFycmF5QnVmZmVyID0gYnVmZmVyQ2xvbmUoYm9keS5idWZmZXIpO1xuICAgICAgICAvLyBJRSAxMC0xMSBjYW4ndCBoYW5kbGUgYSBEYXRhVmlldyBib2R5LlxuICAgICAgICB0aGlzLl9ib2R5SW5pdCA9IG5ldyBCbG9iKFt0aGlzLl9ib2R5QXJyYXlCdWZmZXJdKTtcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5hcnJheUJ1ZmZlciAmJiAoQXJyYXlCdWZmZXIucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkgfHwgaXNBcnJheUJ1ZmZlclZpZXcoYm9keSkpKSB7XG4gICAgICAgIHRoaXMuX2JvZHlBcnJheUJ1ZmZlciA9IGJ1ZmZlckNsb25lKGJvZHkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fYm9keVRleHQgPSBib2R5ID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGJvZHkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aGlzLmhlYWRlcnMuc2V0KCdjb250ZW50LXR5cGUnLCAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYm9keUJsb2IgJiYgdGhpcy5fYm9keUJsb2IudHlwZSkge1xuICAgICAgICAgIHRoaXMuaGVhZGVycy5zZXQoJ2NvbnRlbnQtdHlwZScsIHRoaXMuX2JvZHlCbG9iLnR5cGUpO1xuICAgICAgICB9IGVsc2UgaWYgKHN1cHBvcnQuc2VhcmNoUGFyYW1zICYmIFVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihib2R5KSkge1xuICAgICAgICAgIHRoaXMuaGVhZGVycy5zZXQoJ2NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7Y2hhcnNldD1VVEYtOCcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChzdXBwb3J0LmJsb2IpIHtcbiAgICAgIHRoaXMuYmxvYiA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgcmVqZWN0ZWQgPSBjb25zdW1lZCh0aGlzKTtcbiAgICAgICAgaWYgKHJlamVjdGVkKSB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdGVkXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fYm9keUJsb2IpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX2JvZHlCbG9iKVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2JvZHlBcnJheUJ1ZmZlcikge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEJsb2IoW3RoaXMuX2JvZHlBcnJheUJ1ZmZlcl0pKVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2JvZHlGb3JtRGF0YSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY291bGQgbm90IHJlYWQgRm9ybURhdGEgYm9keSBhcyBibG9iJylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBCbG9iKFt0aGlzLl9ib2R5VGV4dF0pKVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICB0aGlzLmFycmF5QnVmZmVyID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9ib2R5QXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICByZXR1cm4gY29uc3VtZWQodGhpcykgfHwgUHJvbWlzZS5yZXNvbHZlKHRoaXMuX2JvZHlBcnJheUJ1ZmZlcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iKCkudGhlbihyZWFkQmxvYkFzQXJyYXlCdWZmZXIpXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy50ZXh0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVqZWN0ZWQgPSBjb25zdW1lZCh0aGlzKTtcbiAgICAgIGlmIChyZWplY3RlZCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0ZWRcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX2JvZHlCbG9iKSB7XG4gICAgICAgIHJldHVybiByZWFkQmxvYkFzVGV4dCh0aGlzLl9ib2R5QmxvYilcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fYm9keUFycmF5QnVmZmVyKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVhZEFycmF5QnVmZmVyQXNUZXh0KHRoaXMuX2JvZHlBcnJheUJ1ZmZlcikpXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX2JvZHlGb3JtRGF0YSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCByZWFkIEZvcm1EYXRhIGJvZHkgYXMgdGV4dCcpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX2JvZHlUZXh0KVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoc3VwcG9ydC5mb3JtRGF0YSkge1xuICAgICAgdGhpcy5mb3JtRGF0YSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXh0KCkudGhlbihkZWNvZGUpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuanNvbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudGV4dCgpLnRoZW4oSlNPTi5wYXJzZSlcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8vIEhUVFAgbWV0aG9kcyB3aG9zZSBjYXBpdGFsaXphdGlvbiBzaG91bGQgYmUgbm9ybWFsaXplZFxuICB2YXIgbWV0aG9kcyA9IFsnREVMRVRFJywgJ0dFVCcsICdIRUFEJywgJ09QVElPTlMnLCAnUE9TVCcsICdQVVQnXTtcblxuICBmdW5jdGlvbiBub3JtYWxpemVNZXRob2QobWV0aG9kKSB7XG4gICAgdmFyIHVwY2FzZWQgPSBtZXRob2QudG9VcHBlckNhc2UoKTtcbiAgICByZXR1cm4gbWV0aG9kcy5pbmRleE9mKHVwY2FzZWQpID4gLTEgPyB1cGNhc2VkIDogbWV0aG9kXG4gIH1cblxuICBmdW5jdGlvbiBSZXF1ZXN0KGlucHV0LCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgdmFyIGJvZHkgPSBvcHRpb25zLmJvZHk7XG5cbiAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBSZXF1ZXN0KSB7XG4gICAgICBpZiAoaW5wdXQuYm9keVVzZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQWxyZWFkeSByZWFkJylcbiAgICAgIH1cbiAgICAgIHRoaXMudXJsID0gaW5wdXQudXJsO1xuICAgICAgdGhpcy5jcmVkZW50aWFscyA9IGlucHV0LmNyZWRlbnRpYWxzO1xuICAgICAgaWYgKCFvcHRpb25zLmhlYWRlcnMpIHtcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IEhlYWRlcnMoaW5wdXQuaGVhZGVycyk7XG4gICAgICB9XG4gICAgICB0aGlzLm1ldGhvZCA9IGlucHV0Lm1ldGhvZDtcbiAgICAgIHRoaXMubW9kZSA9IGlucHV0Lm1vZGU7XG4gICAgICB0aGlzLnNpZ25hbCA9IGlucHV0LnNpZ25hbDtcbiAgICAgIGlmICghYm9keSAmJiBpbnB1dC5fYm9keUluaXQgIT0gbnVsbCkge1xuICAgICAgICBib2R5ID0gaW5wdXQuX2JvZHlJbml0O1xuICAgICAgICBpbnB1dC5ib2R5VXNlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXJsID0gU3RyaW5nKGlucHV0KTtcbiAgICB9XG5cbiAgICB0aGlzLmNyZWRlbnRpYWxzID0gb3B0aW9ucy5jcmVkZW50aWFscyB8fCB0aGlzLmNyZWRlbnRpYWxzIHx8ICdzYW1lLW9yaWdpbic7XG4gICAgaWYgKG9wdGlvbnMuaGVhZGVycyB8fCAhdGhpcy5oZWFkZXJzKSB7XG4gICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgSGVhZGVycyhvcHRpb25zLmhlYWRlcnMpO1xuICAgIH1cbiAgICB0aGlzLm1ldGhvZCA9IG5vcm1hbGl6ZU1ldGhvZChvcHRpb25zLm1ldGhvZCB8fCB0aGlzLm1ldGhvZCB8fCAnR0VUJyk7XG4gICAgdGhpcy5tb2RlID0gb3B0aW9ucy5tb2RlIHx8IHRoaXMubW9kZSB8fCBudWxsO1xuICAgIHRoaXMuc2lnbmFsID0gb3B0aW9ucy5zaWduYWwgfHwgdGhpcy5zaWduYWw7XG4gICAgdGhpcy5yZWZlcnJlciA9IG51bGw7XG5cbiAgICBpZiAoKHRoaXMubWV0aG9kID09PSAnR0VUJyB8fCB0aGlzLm1ldGhvZCA9PT0gJ0hFQUQnKSAmJiBib2R5KSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCb2R5IG5vdCBhbGxvd2VkIGZvciBHRVQgb3IgSEVBRCByZXF1ZXN0cycpXG4gICAgfVxuICAgIHRoaXMuX2luaXRCb2R5KGJvZHkpO1xuICB9XG5cbiAgUmVxdWVzdC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbmV3IFJlcXVlc3QodGhpcywge2JvZHk6IHRoaXMuX2JvZHlJbml0fSlcbiAgfTtcblxuICBmdW5jdGlvbiBkZWNvZGUoYm9keSkge1xuICAgIHZhciBmb3JtID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgYm9keVxuICAgICAgLnRyaW0oKVxuICAgICAgLnNwbGl0KCcmJylcbiAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICAgIGlmIChieXRlcykge1xuICAgICAgICAgIHZhciBzcGxpdCA9IGJ5dGVzLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgdmFyIG5hbWUgPSBzcGxpdC5zaGlmdCgpLnJlcGxhY2UoL1xcKy9nLCAnICcpO1xuICAgICAgICAgIHZhciB2YWx1ZSA9IHNwbGl0LmpvaW4oJz0nKS5yZXBsYWNlKC9cXCsvZywgJyAnKTtcbiAgICAgICAgICBmb3JtLmFwcGVuZChkZWNvZGVVUklDb21wb25lbnQobmFtZSksIGRlY29kZVVSSUNvbXBvbmVudCh2YWx1ZSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICByZXR1cm4gZm9ybVxuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VIZWFkZXJzKHJhd0hlYWRlcnMpIHtcbiAgICB2YXIgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgLy8gUmVwbGFjZSBpbnN0YW5jZXMgb2YgXFxyXFxuIGFuZCBcXG4gZm9sbG93ZWQgYnkgYXQgbGVhc3Qgb25lIHNwYWNlIG9yIGhvcml6b250YWwgdGFiIHdpdGggYSBzcGFjZVxuICAgIC8vIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM3MjMwI3NlY3Rpb24tMy4yXG4gICAgdmFyIHByZVByb2Nlc3NlZEhlYWRlcnMgPSByYXdIZWFkZXJzLnJlcGxhY2UoL1xccj9cXG5bXFx0IF0rL2csICcgJyk7XG4gICAgcHJlUHJvY2Vzc2VkSGVhZGVycy5zcGxpdCgvXFxyP1xcbi8pLmZvckVhY2goZnVuY3Rpb24obGluZSkge1xuICAgICAgdmFyIHBhcnRzID0gbGluZS5zcGxpdCgnOicpO1xuICAgICAgdmFyIGtleSA9IHBhcnRzLnNoaWZ0KCkudHJpbSgpO1xuICAgICAgaWYgKGtleSkge1xuICAgICAgICB2YXIgdmFsdWUgPSBwYXJ0cy5qb2luKCc6JykudHJpbSgpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaGVhZGVyc1xuICB9XG5cbiAgQm9keS5jYWxsKFJlcXVlc3QucHJvdG90eXBlKTtcblxuICBmdW5jdGlvbiBSZXNwb25zZShib2R5SW5pdCwgb3B0aW9ucykge1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIHRoaXMudHlwZSA9ICdkZWZhdWx0JztcbiAgICB0aGlzLnN0YXR1cyA9IG9wdGlvbnMuc3RhdHVzID09PSB1bmRlZmluZWQgPyAyMDAgOiBvcHRpb25zLnN0YXR1cztcbiAgICB0aGlzLm9rID0gdGhpcy5zdGF0dXMgPj0gMjAwICYmIHRoaXMuc3RhdHVzIDwgMzAwO1xuICAgIHRoaXMuc3RhdHVzVGV4dCA9ICdzdGF0dXNUZXh0JyBpbiBvcHRpb25zID8gb3B0aW9ucy5zdGF0dXNUZXh0IDogJ09LJztcbiAgICB0aGlzLmhlYWRlcnMgPSBuZXcgSGVhZGVycyhvcHRpb25zLmhlYWRlcnMpO1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmwgfHwgJyc7XG4gICAgdGhpcy5faW5pdEJvZHkoYm9keUluaXQpO1xuICB9XG5cbiAgQm9keS5jYWxsKFJlc3BvbnNlLnByb3RvdHlwZSk7XG5cbiAgUmVzcG9uc2UucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZSh0aGlzLl9ib2R5SW5pdCwge1xuICAgICAgc3RhdHVzOiB0aGlzLnN0YXR1cyxcbiAgICAgIHN0YXR1c1RleHQ6IHRoaXMuc3RhdHVzVGV4dCxcbiAgICAgIGhlYWRlcnM6IG5ldyBIZWFkZXJzKHRoaXMuaGVhZGVycyksXG4gICAgICB1cmw6IHRoaXMudXJsXG4gICAgfSlcbiAgfTtcblxuICBSZXNwb25zZS5lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciByZXNwb25zZSA9IG5ldyBSZXNwb25zZShudWxsLCB7c3RhdHVzOiAwLCBzdGF0dXNUZXh0OiAnJ30pO1xuICAgIHJlc3BvbnNlLnR5cGUgPSAnZXJyb3InO1xuICAgIHJldHVybiByZXNwb25zZVxuICB9O1xuXG4gIHZhciByZWRpcmVjdFN0YXR1c2VzID0gWzMwMSwgMzAyLCAzMDMsIDMwNywgMzA4XTtcblxuICBSZXNwb25zZS5yZWRpcmVjdCA9IGZ1bmN0aW9uKHVybCwgc3RhdHVzKSB7XG4gICAgaWYgKHJlZGlyZWN0U3RhdHVzZXMuaW5kZXhPZihzdGF0dXMpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgc3RhdHVzIGNvZGUnKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgUmVzcG9uc2UobnVsbCwge3N0YXR1czogc3RhdHVzLCBoZWFkZXJzOiB7bG9jYXRpb246IHVybH19KVxuICB9O1xuXG4gIGV4cG9ydHMuRE9NRXhjZXB0aW9uID0gc2VsZi5ET01FeGNlcHRpb247XG4gIHRyeSB7XG4gICAgbmV3IGV4cG9ydHMuRE9NRXhjZXB0aW9uKCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGV4cG9ydHMuRE9NRXhjZXB0aW9uID0gZnVuY3Rpb24obWVzc2FnZSwgbmFtZSkge1xuICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICB2YXIgZXJyb3IgPSBFcnJvcihtZXNzYWdlKTtcbiAgICAgIHRoaXMuc3RhY2sgPSBlcnJvci5zdGFjaztcbiAgICB9O1xuICAgIGV4cG9ydHMuRE9NRXhjZXB0aW9uLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcbiAgICBleHBvcnRzLkRPTUV4Y2VwdGlvbi5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBleHBvcnRzLkRPTUV4Y2VwdGlvbjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZldGNoKGlucHV0LCBpbml0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIHJlcXVlc3QgPSBuZXcgUmVxdWVzdChpbnB1dCwgaW5pdCk7XG5cbiAgICAgIGlmIChyZXF1ZXN0LnNpZ25hbCAmJiByZXF1ZXN0LnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICAgIHJldHVybiByZWplY3QobmV3IGV4cG9ydHMuRE9NRXhjZXB0aW9uKCdBYm9ydGVkJywgJ0Fib3J0RXJyb3InKSlcbiAgICAgIH1cblxuICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXG4gICAgICBmdW5jdGlvbiBhYm9ydFhocigpIHtcbiAgICAgICAgeGhyLmFib3J0KCk7XG4gICAgICB9XG5cbiAgICAgIHhoci5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB7XG4gICAgICAgICAgc3RhdHVzOiB4aHIuc3RhdHVzLFxuICAgICAgICAgIHN0YXR1c1RleHQ6IHhoci5zdGF0dXNUZXh0LFxuICAgICAgICAgIGhlYWRlcnM6IHBhcnNlSGVhZGVycyh4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkgfHwgJycpXG4gICAgICAgIH07XG4gICAgICAgIG9wdGlvbnMudXJsID0gJ3Jlc3BvbnNlVVJMJyBpbiB4aHIgPyB4aHIucmVzcG9uc2VVUkwgOiBvcHRpb25zLmhlYWRlcnMuZ2V0KCdYLVJlcXVlc3QtVVJMJyk7XG4gICAgICAgIHZhciBib2R5ID0gJ3Jlc3BvbnNlJyBpbiB4aHIgPyB4aHIucmVzcG9uc2UgOiB4aHIucmVzcG9uc2VUZXh0O1xuICAgICAgICByZXNvbHZlKG5ldyBSZXNwb25zZShib2R5LCBvcHRpb25zKSk7XG4gICAgICB9O1xuXG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZWplY3QobmV3IFR5cGVFcnJvcignTmV0d29yayByZXF1ZXN0IGZhaWxlZCcpKTtcbiAgICAgIH07XG5cbiAgICAgIHhoci5vbnRpbWVvdXQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmVqZWN0KG5ldyBUeXBlRXJyb3IoJ05ldHdvcmsgcmVxdWVzdCBmYWlsZWQnKSk7XG4gICAgICB9O1xuXG4gICAgICB4aHIub25hYm9ydCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZWplY3QobmV3IGV4cG9ydHMuRE9NRXhjZXB0aW9uKCdBYm9ydGVkJywgJ0Fib3J0RXJyb3InKSk7XG4gICAgICB9O1xuXG4gICAgICB4aHIub3BlbihyZXF1ZXN0Lm1ldGhvZCwgcmVxdWVzdC51cmwsIHRydWUpO1xuXG4gICAgICBpZiAocmVxdWVzdC5jcmVkZW50aWFscyA9PT0gJ2luY2x1ZGUnKSB7XG4gICAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LmNyZWRlbnRpYWxzID09PSAnb21pdCcpIHtcbiAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoJ3Jlc3BvbnNlVHlwZScgaW4geGhyICYmIHN1cHBvcnQuYmxvYikge1xuICAgICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2Jsb2InO1xuICAgICAgfVxuXG4gICAgICByZXF1ZXN0LmhlYWRlcnMuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSwgbmFtZSkge1xuICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihuYW1lLCB2YWx1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKHJlcXVlc3Quc2lnbmFsKSB7XG4gICAgICAgIHJlcXVlc3Quc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnRYaHIpO1xuXG4gICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAvLyBET05FIChzdWNjZXNzIG9yIGZhaWx1cmUpXG4gICAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICByZXF1ZXN0LnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0WGhyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHhoci5zZW5kKHR5cGVvZiByZXF1ZXN0Ll9ib2R5SW5pdCA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogcmVxdWVzdC5fYm9keUluaXQpO1xuICAgIH0pXG4gIH1cblxuICBmZXRjaC5wb2x5ZmlsbCA9IHRydWU7XG5cbiAgaWYgKCFzZWxmLmZldGNoKSB7XG4gICAgc2VsZi5mZXRjaCA9IGZldGNoO1xuICAgIHNlbGYuSGVhZGVycyA9IEhlYWRlcnM7XG4gICAgc2VsZi5SZXF1ZXN0ID0gUmVxdWVzdDtcbiAgICBzZWxmLlJlc3BvbnNlID0gUmVzcG9uc2U7XG4gIH1cblxuICBleHBvcnRzLkhlYWRlcnMgPSBIZWFkZXJzO1xuICBleHBvcnRzLlJlcXVlc3QgPSBSZXF1ZXN0O1xuICBleHBvcnRzLlJlc3BvbnNlID0gUmVzcG9uc2U7XG4gIGV4cG9ydHMuZmV0Y2ggPSBmZXRjaDtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4gIHJldHVybiBleHBvcnRzO1xuXG59KHt9KSk7XG59KShfX3NlbGZfXyk7XG5fX3NlbGZfXy5mZXRjaC5wb255ZmlsbCA9IHRydWU7XG4vLyBSZW1vdmUgXCJwb2x5ZmlsbFwiIHByb3BlcnR5IGFkZGVkIGJ5IHdoYXR3Zy1mZXRjaFxuZGVsZXRlIF9fc2VsZl9fLmZldGNoLnBvbHlmaWxsO1xuLy8gQ2hvb3NlIGJldHdlZW4gbmF0aXZlIGltcGxlbWVudGF0aW9uIChnbG9iYWwpIG9yIGN1c3RvbSBpbXBsZW1lbnRhdGlvbiAoX19zZWxmX18pXG4vLyB2YXIgY3R4ID0gZ2xvYmFsLmZldGNoID8gZ2xvYmFsIDogX19zZWxmX187XG52YXIgY3R4ID0gX19zZWxmX187IC8vIHRoaXMgbGluZSBkaXNhYmxlIHNlcnZpY2Ugd29ya2VyIHN1cHBvcnQgdGVtcG9yYXJpbHlcbmV4cG9ydHMgPSBjdHguZmV0Y2ggLy8gVG8gZW5hYmxlOiBpbXBvcnQgZmV0Y2ggZnJvbSAnY3Jvc3MtZmV0Y2gnXG5leHBvcnRzLmRlZmF1bHQgPSBjdHguZmV0Y2ggLy8gRm9yIFR5cGVTY3JpcHQgY29uc3VtZXJzIHdpdGhvdXQgZXNNb2R1bGVJbnRlcm9wLlxuZXhwb3J0cy5mZXRjaCA9IGN0eC5mZXRjaCAvLyBUbyBlbmFibGU6IGltcG9ydCB7ZmV0Y2h9IGZyb20gJ2Nyb3NzLWZldGNoJ1xuZXhwb3J0cy5IZWFkZXJzID0gY3R4LkhlYWRlcnNcbmV4cG9ydHMuUmVxdWVzdCA9IGN0eC5SZXF1ZXN0XG5leHBvcnRzLlJlc3BvbnNlID0gY3R4LlJlc3BvbnNlXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNcbiIsIi8qKlxuICogQGZpbGUgQ29udmVydGVyIEFwcGxpY2F0aW9uLlxuICovXG5pbXBvcnQgQ29udmVydGVyIGZyb20gJy4vY29udmVydGVyJztcblxuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggJ0RPTUNvbnRlbnRMb2FkZWQnLCAoKSA9PiB7XG5cdG5ldyBDb252ZXJ0ZXIoKTtcbn0gKTtcbiIsIi8qKlxuICogQGZpbGUgY2xhc3MgQ29udmVydGVyLlxuICovXG5cbmNsYXNzIENvbnZlcnRlciB7XG5cdC8qKlxuXHQgKiBDbGFzcyBjb25zdHJ1Y3Rvci5cblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHRoaXMuQ09OVkVSVF9GT1JNX1NFTEVDVE9SID0gJyNjdGwtY29udmVydC1leGlzdGluZy1zbHVncyc7XG5cdFx0dGhpcy5DT05WRVJUX0JVVFRPTl9TRUxFQ1RPUiA9ICcjY3RsLWNvbnZlcnQtYnV0dG9uJztcblx0XHR0aGlzLkNPTkZJUk1fUE9QVVBfU0VMRUNUT1IgPSAnI2N0bC1jb25maXJtLXBvcHVwJztcblx0XHR0aGlzLkNPTkZJUk1fT0tfU0VMRUNUT1IgPSAnI2N0bC1jb25maXJtLW9rJztcblx0XHR0aGlzLkNPTkZJUk1fQ0FOQ0VMX1NFTEVDVE9SID0gJyNjdGwtY29uZmlybS1jYW5jZWwnO1xuXG5cdFx0dGhpcy5jb25maXJtUG9wdXAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuXHRcdFx0dGhpcy5DT05GSVJNX1BPUFVQX1NFTEVDVE9SXG5cdFx0KTtcblxuXHRcdHRoaXMuYmluZEV2ZW50cygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEJpbmQgZXZlbnRzIHRvIG1ldGhvZHMuXG5cdCAqL1xuXHRiaW5kRXZlbnRzKCkge1xuXHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIHRoaXMuQ09OVkVSVF9CVVRUT05fU0VMRUNUT1IgKS5vbmNsaWNrID0gKFxuXHRcdFx0ZXZlbnRcblx0XHQpID0+IHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHR0aGlzLmNvbmZpcm1Qb3B1cC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5jb25maXJtUG9wdXAub25jbGljayA9ICgpID0+IHtcblx0XHRcdHRoaXMuaGlkZUNvbmZpcm1Qb3B1cCgpO1xuXHRcdH07XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCB0aGlzLkNPTkZJUk1fT0tfU0VMRUNUT1IgKS5vbmNsaWNrID0gKFxuXHRcdFx0ZXZlbnRcblx0XHQpID0+IHtcblx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0dGhpcy5oaWRlQ29uZmlybVBvcHVwKCk7XG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCB0aGlzLkNPTlZFUlRfRk9STV9TRUxFQ1RPUiApLnN1Ym1pdCgpO1xuXHRcdH07XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCB0aGlzLkNPTkZJUk1fQ0FOQ0VMX1NFTEVDVE9SICkub25jbGljayA9IChcblx0XHRcdGV2ZW50XG5cdFx0KSA9PiB7XG5cdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdHRoaXMuaGlkZUNvbmZpcm1Qb3B1cCgpO1xuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogSGlkZSBjb25maXJtYXRpb24gcG9wdXAuXG5cdCAqL1xuXHRoaWRlQ29uZmlybVBvcHVwKCkge1xuXHRcdHRoaXMuY29uZmlybVBvcHVwLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29udmVydGVyO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==
assets/js/tables/app.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ !function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){n(1),e.exports=n(2)},function(e,t){var n="undefined"!=typeof self?self:this,r=function(){function e(){this.fetch=!1,this.DOMException=n.DOMException}return e.prototype=n,new e}();!function(e){!function(t){var n="URLSearchParams"in e,r="Symbol"in e&&"iterator"in Symbol,i="FileReader"in e&&"Blob"in e&&function(){try{return new Blob,!0}catch(e){return!1}}(),s="FormData"in e,o="ArrayBuffer"in e;if(o)var a=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],u=ArrayBuffer.isView||function(e){return e&&a.indexOf(Object.prototype.toString.call(e))>-1};function l(e){if("string"!=typeof e&&(e=String(e)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(e))throw new TypeError("Invalid character in header field name");return e.toLowerCase()}function c(e){return"string"!=typeof e&&(e=String(e)),e}function h(e){var t={next:function(){var t=e.shift();return{done:void 0===t,value:t}}};return r&&(t[Symbol.iterator]=function(){return t}),t}function d(e){this.map={},e instanceof d?e.forEach((function(e,t){this.append(t,e)}),this):Array.isArray(e)?e.forEach((function(e){this.append(e[0],e[1])}),this):e&&Object.getOwnPropertyNames(e).forEach((function(t){this.append(t,e[t])}),this)}function p(e){if(e.bodyUsed)return Promise.reject(new TypeError("Already read"));e.bodyUsed=!0}function f(e){return new Promise((function(t,n){e.onload=function(){t(e.result)},e.onerror=function(){n(e.error)}}))}function y(e){var t=new FileReader,n=f(t);return t.readAsArrayBuffer(e),n}function b(e){if(e.slice)return e.slice(0);var t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e)),t.buffer}function v(){return this.bodyUsed=!1,this._initBody=function(e){var t;this._bodyInit=e,e?"string"==typeof e?this._bodyText=e:i&&Blob.prototype.isPrototypeOf(e)?this._bodyBlob=e:s&&FormData.prototype.isPrototypeOf(e)?this._bodyFormData=e:n&&URLSearchParams.prototype.isPrototypeOf(e)?this._bodyText=e.toString():o&&i&&((t=e)&&DataView.prototype.isPrototypeOf(t))?(this._bodyArrayBuffer=b(e.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):o&&(ArrayBuffer.prototype.isPrototypeOf(e)||u(e))?this._bodyArrayBuffer=b(e):this._bodyText=e=Object.prototype.toString.call(e):this._bodyText="",this.headers.get("content-type")||("string"==typeof e?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):n&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},i&&(this.blob=function(){var e=p(this);if(e)return e;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?p(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(y)}),this.text=function(){var e,t,n,r=p(this);if(r)return r;if(this._bodyBlob)return e=this._bodyBlob,t=new FileReader,n=f(t),t.readAsText(e),n;if(this._bodyArrayBuffer)return Promise.resolve(function(e){for(var t=new Uint8Array(e),n=new Array(t.length),r=0;r<t.length;r++)n[r]=String.fromCharCode(t[r]);return n.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},s&&(this.formData=function(){return this.text().then(L)}),this.json=function(){return this.text().then(JSON.parse)},this}d.prototype.append=function(e,t){e=l(e),t=c(t);var n=this.map[e];this.map[e]=n?n+", "+t:t},d.prototype.delete=function(e){delete this.map[l(e)]},d.prototype.get=function(e){return e=l(e),this.has(e)?this.map[e]:null},d.prototype.has=function(e){return this.map.hasOwnProperty(l(e))},d.prototype.set=function(e,t){this.map[l(e)]=c(t)},d.prototype.forEach=function(e,t){for(var n in this.map)this.map.hasOwnProperty(n)&&e.call(t,this.map[n],n,this)},d.prototype.keys=function(){var e=[];return this.forEach((function(t,n){e.push(n)})),h(e)},d.prototype.values=function(){var e=[];return this.forEach((function(t){e.push(t)})),h(e)},d.prototype.entries=function(){var e=[];return this.forEach((function(t,n){e.push([n,t])})),h(e)},r&&(d.prototype[Symbol.iterator]=d.prototype.entries);var m=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];function E(e,t){var n,r,i=(t=t||{}).body;if(e instanceof E){if(e.bodyUsed)throw new TypeError("Already read");this.url=e.url,this.credentials=e.credentials,t.headers||(this.headers=new d(e.headers)),this.method=e.method,this.mode=e.mode,this.signal=e.signal,i||null==e._bodyInit||(i=e._bodyInit,e.bodyUsed=!0)}else this.url=String(e);if(this.credentials=t.credentials||this.credentials||"same-origin",!t.headers&&this.headers||(this.headers=new d(t.headers)),this.method=(n=t.method||this.method||"GET",r=n.toUpperCase(),m.indexOf(r)>-1?r:n),this.mode=t.mode||this.mode||null,this.signal=t.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&i)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(i)}function L(e){var t=new FormData;return e.trim().split("&").forEach((function(e){if(e){var n=e.split("="),r=n.shift().replace(/\+/g," "),i=n.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(i))}})),t}function S(e,t){t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in t?t.statusText:"OK",this.headers=new d(t.headers),this.url=t.url||"",this._initBody(e)}E.prototype.clone=function(){return new E(this,{body:this._bodyInit})},v.call(E.prototype),v.call(S.prototype),S.prototype.clone=function(){return new S(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new d(this.headers),url:this.url})},S.error=function(){var e=new S(null,{status:0,statusText:""});return e.type="error",e};var T=[301,302,303,307,308];S.redirect=function(e,t){if(-1===T.indexOf(t))throw new RangeError("Invalid status code");return new S(null,{status:t,headers:{location:e}})},t.DOMException=e.DOMException;try{new t.DOMException}catch(e){t.DOMException=function(e,t){this.message=e,this.name=t;var n=Error(e);this.stack=n.stack},t.DOMException.prototype=Object.create(Error.prototype),t.DOMException.prototype.constructor=t.DOMException}function _(e,n){return new Promise((function(r,s){var o=new E(e,n);if(o.signal&&o.signal.aborted)return s(new t.DOMException("Aborted","AbortError"));var a=new XMLHttpRequest;function u(){a.abort()}a.onload=function(){var e,t,n={status:a.status,statusText:a.statusText,headers:(e=a.getAllResponseHeaders()||"",t=new d,e.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach((function(e){var n=e.split(":"),r=n.shift().trim();if(r){var i=n.join(":").trim();t.append(r,i)}})),t)};n.url="responseURL"in a?a.responseURL:n.headers.get("X-Request-URL");var i="response"in a?a.response:a.responseText;r(new S(i,n))},a.onerror=function(){s(new TypeError("Network request failed"))},a.ontimeout=function(){s(new TypeError("Network request failed"))},a.onabort=function(){s(new t.DOMException("Aborted","AbortError"))},a.open(o.method,o.url,!0),"include"===o.credentials?a.withCredentials=!0:"omit"===o.credentials&&(a.withCredentials=!1),"responseType"in a&&i&&(a.responseType="blob"),o.headers.forEach((function(e,t){a.setRequestHeader(t,e)})),o.signal&&(o.signal.addEventListener("abort",u),a.onreadystatechange=function(){4===a.readyState&&o.signal.removeEventListener("abort",u)}),a.send(void 0===o._bodyInit?null:o._bodyInit)}))}_.polyfill=!0,e.fetch||(e.fetch=_,e.Headers=d,e.Request=E,e.Response=S),t.Headers=d,t.Request=E,t.Response=S,t.fetch=_,Object.defineProperty(t,"__esModule",{value:!0})}({})}(r),r.fetch.ponyfill=!0,delete r.fetch.polyfill;var i=r;(t=i.fetch).default=i.fetch,t.fetch=i.fetch,t.Headers=i.Headers,t.Request=i.Request,t.Response=i.Response,e.exports=t},function(e,t,n){"use strict";var r,i=n(3),s=(r=i)&&r.__esModule?r:{default:r};document.addEventListener("DOMContentLoaded",(function(){new s.default}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();function i(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var s=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.OPTIONS_FORM_SELECTOR="#ctl-options",this.HEADER_SELECTOR=this.OPTIONS_FORM_SELECTOR+" h2",this.TABLE_SELECTOR=this.OPTIONS_FORM_SELECTOR+" table",this.SUBMIT_SELECTOR=this.OPTIONS_FORM_SELECTOR+" #submit",this.CURRENT_STUB_ID="ctl-current",this.CURRENT_NAV_TAB_CLASS="nav-tab-current",this.ACTIVE_NAV_TAB_CLASS="nav-tab-active",this.ACTIVE_TABLE_CLASS="active",this.EDIT_LABEL_ID="ctl-edit-label",this.EDIT_LABEL_ERROR_CLASS="ctl-edit-label-error",this.plusButton='<button type="button" aria-haspopup="true" aria-expanded="false" class="components-button block-editor-inserter__toggle has-icon" aria-label="Добавить блок"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" role="img" aria-hidden="true" focusable="false"><path d="M10 1c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 16c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7zm1-11H9v3H6v2h3v3h2v-3h3V9h-3V6zM10 1c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 16c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7zm1-11H9v3H6v2h3v3h2v-3h3V9h-3V6z"></path></svg></button>',this.PLUS_CLASS="ctl-plus",this.optionsForm=document.querySelector(this.OPTIONS_FORM_SELECTOR),this.tablesData=this.getTablesData(),this.submitButton=document.querySelector(this.SUBMIT_SELECTOR),this.optionsSaveSuccessMessage=Cyr2LatTablesObject.optionsSaveSuccessMessage,this.optionsSaveErrorMessage=Cyr2LatTablesObject.optionsSaveErrorMessage,this.addWrapper(),this.addMessageLines(),this.moveTabs(),this.addEditLabelInput(),this.hideTables(),this.bindEvents(),this.setSubmitStatus()}return r(e,[{key:"getHeaders",value:function(){return[].concat(i(document.querySelectorAll(this.HEADER_SELECTOR)))}},{key:"getActiveHeader",value:function(){return document.querySelector(this.HEADER_SELECTOR+"."+this.ACTIVE_NAV_TAB_CLASS)}},{key:"getActiveIndex",value:function(){return this.getActiveHeader().dataset.index}},{key:"getTables",value:function(){return[].concat(i(document.querySelectorAll(this.TABLE_SELECTOR)))}},{key:"getActiveTable",value:function(){return document.querySelector(this.TABLE_SELECTOR+"."+this.ACTIVE_TABLE_CLASS)}},{key:"getInputs",value:function(){return[].concat(i(document.querySelectorAll(this.OPTIONS_FORM_SELECTOR+" input")))}},{key:"getLabels",value:function(){return[].concat(i(document.querySelectorAll(this.OPTIONS_FORM_SELECTOR+" label")))}},{key:"getPlusButtons",value:function(){return[].concat(i(document.querySelectorAll(this.OPTIONS_FORM_SELECTOR+" ."+this.PLUS_CLASS)))}},{key:"isActiveTableChanged",value:function(){var e=this.getActiveIndex();return JSON.stringify(this.getActiveTableData())!==JSON.stringify(this.tablesData[e])}},{key:"setSubmitStatus",value:function(){this.submitButton.disabled=!this.isActiveTableChanged()}},{key:"saveActiveTable",value:function(){var e=this;if(this.isActiveTableChanged()){var t=this.getActiveTable(),n=document.createElement("form");return n.action=this.optionsForm.getAttribute("action"),n.method=this.optionsForm.method,n.appendChild(t.cloneNode(!0)),[].concat(i(t.querySelectorAll("input"))).map((function(e){return n.querySelector("#"+e.id).value=e.value})),[].concat(i(this.optionsForm.querySelectorAll('input[type="hidden"]'))).map((function(e){return n.appendChild(e.cloneNode(!0))})),document.body.appendChild(n),fetch(this.optionsForm.getAttribute("action"),{method:n.method,body:new URLSearchParams([].concat(i(new FormData(n))))}).then((function(t){return t.ok?(e.showMessage(e.successMessage,e.optionsSaveSuccessMessage),e.tablesData=e.getTablesData()):e.showMessage(e.errorMessage,e.optionsSaveErrorMessage),t.json()})).finally((function(){n.parentNode.removeChild(n),e.setSubmitStatus()}))}}},{key:"getTableData",value:function(e){var t=this,n=[].concat(i(e.querySelectorAll("input"))),r={};return n.forEach((function(e){var n=document.querySelector(t.OPTIONS_FORM_SELECTOR+' label[for="'+e.id+'"]');r[n.innerHTML]=e.value})),r}},{key:"getTablesData",value:function(){var e=this;return this.getTables().map((function(t){return e.getTableData(t)}))}},{key:"getActiveTableData",value:function(){return this.getTableData(this.getActiveTable())}},{key:"addWrapper",value:function(){this.wrapper=document.createElement("ul"),this.wrapper.classList.add("nav-tab-wrapper"),this.optionsForm.insertBefore(this.wrapper,this.optionsForm.firstChild)}},{key:"addMessageLine",value:function(e){var t=document.createElement("div");return t.id=e,this.optionsForm.insertBefore(t,this.optionsForm.firstChild),t}},{key:"addMessageLines",value:function(){this.successMessage=this.addMessageLine("ctl-success"),this.errorMessage=this.addMessageLine("ctl-error")}},{key:"moveTabs",value:function(){var e=document.querySelector(".ctl-settings-tabs");e&&this.optionsForm.insertBefore(e,this.optionsForm.firstChild)}},{key:"addEditLabelInput",value:function(){this.editLabelInput=document.createElement("input"),this.editLabelInput.id=this.EDIT_LABEL_ID,this.editLabelInput.style.display="none",document.body.appendChild(this.editLabelInput)}},{key:"hideEditLabelInput",value:function(){this.editLabelInput.style.display="none",this.editLabelInput.classList.remove(this.EDIT_LABEL_ERROR_CLASS),document.body.appendChild(this.editLabelInput)}},{key:"getLastCell",value:function(){return document.querySelector(this.OPTIONS_FORM_SELECTOR+" ."+this.ACTIVE_TABLE_CLASS+" ."+this.PLUS_CLASS).previousElementSibling}},{key:"addCell",value:function(){var e=this.getLastCell();e.parentElement.insertBefore(e.cloneNode(!0),e.nextElementSibling);var t=(e=this.getLastCell()).querySelector("label"),n=e.querySelector("input"),r=n.id.split("-"),i=r[0]+"-"+(parseInt(r[1])+1);t.htmlFor=i,t.innerHTML="",n.id=i,n.value="",n.setAttribute("value",""),this.replaceName(n,""),this.bindEvents(),this.editLabel(t)}},{key:"hideTables",value:function(){var e=this,t=0;this.getTables().map((function(n,r){n.classList.add("ctl-table"),e.CURRENT_STUB_ID===n.previousElementSibling.id&&(t=r,n.classList.add(e.ACTIVE_TABLE_CLASS));var i=document.createElement("div");return i.classList.add(e.PLUS_CLASS),i.innerHTML=e.plusButton,n.querySelector("td").appendChild(i),null})),this.getHeaders().map((function(n,r){return n.classList.add("nav-tab"),n.dataset.index=r,e.wrapper.appendChild(n),r===t&&(n.classList.add(e.CURRENT_NAV_TAB_CLASS),n.classList.add(e.ACTIVE_NAV_TAB_CLASS)),null}))}},{key:"bindEvents",value:function(){var e=this;this.getHeaders().map((function(t,n,r){return t.onclick=function(t){t.preventDefault();var n=t.target.dataset.index;if(n===e.getActiveIndex())return!1;e.saveActiveTable(),r.map((function(t){return t.classList.remove(e.ACTIVE_NAV_TAB_CLASS)})),r[n].classList.add(e.ACTIVE_NAV_TAB_CLASS);var i=e.getTables();return i.map((function(t){return t.classList.remove(e.ACTIVE_TABLE_CLASS)})),i[n].classList.add(e.ACTIVE_TABLE_CLASS),e.setSubmitStatus(),!1},null})),this.getInputs().map((function(t){return t.oninput=function(){e.setSubmitStatus()},null})),this.getLabels().map((function(t){return t.onclick=function(t){return t.preventDefault(),e.editLabel(t.target),!1},null})),this.editLabelInput.onblur=function(){e.saveLabel()},this.editLabelInput.onkeyup=function(t){"Escape"===t.key&&e.saveLabel(!0),"Enter"===t.key&&e.saveLabel()},this.getPlusButtons().map((function(t){return t.onclick=function(t){return t.preventDefault(),e.addCell(t.target),!1},null})),this.submitButton.onclick=function(t){return t.preventDefault(),e.saveActiveTable(),!1}}},{key:"editLabel",value:function(e){e.parentNode.appendChild(this.editLabelInput),this.editLabelInput.value=e.innerHTML,this.editLabelInput.classList.remove(this.EDIT_LABEL_ERROR_CLASS),this.editLabelInput.style.display="block",this.editLabelInput.focus()}},{key:"isUniqueLabel",value:function(e){return[].concat(i(this.getActiveTable().querySelectorAll("label"))).reduce((function(t,n){return t&&n.innerHTML!==e}),!0)}},{key:"saveLabel",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if("none"!==this.editLabelInput.style.display){var t=this.editLabelInput.value.trim();if(""===t){var n=document.getElementById(this.EDIT_LABEL_ID).parentElement;return this.hideEditLabelInput(),n.parentNode.removeChild(n),void this.setSubmitStatus()}var r=this.editLabelInput.parentNode.querySelector("label");if(e||t===r.innerHTML)this.hideEditLabelInput();else if(this.isUniqueLabel(t)){var i=this.editLabelInput.parentNode.querySelector("input");this.hideEditLabelInput(),r.innerHTML=t,this.replaceName(i,t),this.setSubmitStatus()}else this.editLabelInput.classList.add(this.EDIT_LABEL_ERROR_CLASS)}}},{key:"replaceName",value:function(e,t){e.name=e.name.replace(/(.+\[.+])\[.*]/g,"$1["+t+"]")}},{key:"clearMessage",value:function(e){e.innerHTML="",e.classList.remove("active")}},{key:"clearMessages",value:function(){this.clearMessage(this.successMessage),this.clearMessage(this.errorMessage),clearTimeout(this.msgTimer)}},{key:"showMessage",value:function(e,t){var n=this;e.innerHTML=t,e.classList.add("active"),this.msgTimer=setTimeout((function(){n.clearMessages()}),5e3)}}]),e}();t.default=s}]);
2
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2Nyb3NzLWZldGNoL2Rpc3QvYnJvd3Nlci1wb255ZmlsbC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvanMvdGFibGVzL2FwcC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvanMvdGFibGVzL3RhYmxlcy5qcyJdLCJuYW1lcyI6WyJpbnN0YWxsZWRNb2R1bGVzIiwiX193ZWJwYWNrX3JlcXVpcmVfXyIsIm1vZHVsZUlkIiwiZXhwb3J0cyIsIm1vZHVsZSIsImkiLCJsIiwibW9kdWxlcyIsImNhbGwiLCJtIiwiYyIsImQiLCJuYW1lIiwiZ2V0dGVyIiwibyIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZW51bWVyYWJsZSIsImdldCIsInIiLCJTeW1ib2wiLCJ0b1N0cmluZ1RhZyIsInZhbHVlIiwidCIsIm1vZGUiLCJfX2VzTW9kdWxlIiwibnMiLCJjcmVhdGUiLCJrZXkiLCJiaW5kIiwibiIsIm9iamVjdCIsInByb3BlcnR5IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJwIiwicyIsImdsb2JhbCIsInNlbGYiLCJ0aGlzIiwiX19zZWxmX18iLCJGIiwiZmV0Y2giLCJET01FeGNlcHRpb24iLCJzdXBwb3J0IiwiQmxvYiIsImUiLCJ2aWV3Q2xhc3NlcyIsImlzQXJyYXlCdWZmZXJWaWV3IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJvYmoiLCJpbmRleE9mIiwidG9TdHJpbmciLCJub3JtYWxpemVOYW1lIiwiU3RyaW5nIiwidGVzdCIsIlR5cGVFcnJvciIsInRvTG93ZXJDYXNlIiwibm9ybWFsaXplVmFsdWUiLCJpdGVyYXRvckZvciIsIml0ZW1zIiwiaXRlcmF0b3IiLCJuZXh0Iiwic2hpZnQiLCJkb25lIiwidW5kZWZpbmVkIiwiSGVhZGVycyIsImhlYWRlcnMiLCJtYXAiLCJmb3JFYWNoIiwiYXBwZW5kIiwiQXJyYXkiLCJpc0FycmF5IiwiaGVhZGVyIiwiZ2V0T3duUHJvcGVydHlOYW1lcyIsImNvbnN1bWVkIiwiYm9keSIsImJvZHlVc2VkIiwiUHJvbWlzZSIsInJlamVjdCIsImZpbGVSZWFkZXJSZWFkeSIsInJlYWRlciIsInJlc29sdmUiLCJvbmxvYWQiLCJyZXN1bHQiLCJvbmVycm9yIiwiZXJyb3IiLCJyZWFkQmxvYkFzQXJyYXlCdWZmZXIiLCJibG9iIiwiRmlsZVJlYWRlciIsInByb21pc2UiLCJyZWFkQXNBcnJheUJ1ZmZlciIsImJ1ZmZlckNsb25lIiwiYnVmIiwic2xpY2UiLCJ2aWV3IiwiVWludDhBcnJheSIsImJ5dGVMZW5ndGgiLCJzZXQiLCJidWZmZXIiLCJCb2R5IiwiX2luaXRCb2R5IiwiX2JvZHlJbml0IiwiX2JvZHlUZXh0IiwiaXNQcm90b3R5cGVPZiIsIl9ib2R5QmxvYiIsIkZvcm1EYXRhIiwiX2JvZHlGb3JtRGF0YSIsIlVSTFNlYXJjaFBhcmFtcyIsIkRhdGFWaWV3IiwiX2JvZHlBcnJheUJ1ZmZlciIsInR5cGUiLCJyZWplY3RlZCIsIkVycm9yIiwiYXJyYXlCdWZmZXIiLCJ0aGVuIiwidGV4dCIsInJlYWRBc1RleHQiLCJjaGFycyIsImxlbmd0aCIsImZyb21DaGFyQ29kZSIsImpvaW4iLCJyZWFkQXJyYXlCdWZmZXJBc1RleHQiLCJmb3JtRGF0YSIsImRlY29kZSIsImpzb24iLCJKU09OIiwicGFyc2UiLCJvbGRWYWx1ZSIsImhhcyIsImNhbGxiYWNrIiwidGhpc0FyZyIsImtleXMiLCJwdXNoIiwidmFsdWVzIiwiZW50cmllcyIsIm1ldGhvZHMiLCJSZXF1ZXN0IiwiaW5wdXQiLCJvcHRpb25zIiwibWV0aG9kIiwidXBjYXNlZCIsInVybCIsImNyZWRlbnRpYWxzIiwic2lnbmFsIiwidG9VcHBlckNhc2UiLCJyZWZlcnJlciIsImZvcm0iLCJ0cmltIiwic3BsaXQiLCJieXRlcyIsInJlcGxhY2UiLCJkZWNvZGVVUklDb21wb25lbnQiLCJSZXNwb25zZSIsImJvZHlJbml0Iiwic3RhdHVzIiwib2siLCJzdGF0dXNUZXh0IiwiY2xvbmUiLCJyZXNwb25zZSIsInJlZGlyZWN0U3RhdHVzZXMiLCJyZWRpcmVjdCIsIlJhbmdlRXJyb3IiLCJsb2NhdGlvbiIsImVyciIsIm1lc3NhZ2UiLCJzdGFjayIsImNvbnN0cnVjdG9yIiwiaW5pdCIsInJlcXVlc3QiLCJhYm9ydGVkIiwieGhyIiwiWE1MSHR0cFJlcXVlc3QiLCJhYm9ydFhociIsImFib3J0IiwicmF3SGVhZGVycyIsImdldEFsbFJlc3BvbnNlSGVhZGVycyIsImxpbmUiLCJwYXJ0cyIsInJlc3BvbnNlVVJMIiwicmVzcG9uc2VUZXh0Iiwib250aW1lb3V0Iiwib25hYm9ydCIsIm9wZW4iLCJ3aXRoQ3JlZGVudGlhbHMiLCJyZXNwb25zZVR5cGUiLCJzZXRSZXF1ZXN0SGVhZGVyIiwiYWRkRXZlbnRMaXN0ZW5lciIsIm9ucmVhZHlzdGF0ZWNoYW5nZSIsInJlYWR5U3RhdGUiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwic2VuZCIsInBvbHlmaWxsIiwicG9ueWZpbGwiLCJjdHgiLCJkZWZhdWx0IiwiZG9jdW1lbnQiLCJUYWJsZXMiLCJPUFRJT05TX0ZPUk1fU0VMRUNUT1IiLCJIRUFERVJfU0VMRUNUT1IiLCJUQUJMRV9TRUxFQ1RPUiIsIlNVQk1JVF9TRUxFQ1RPUiIsIkNVUlJFTlRfU1RVQl9JRCIsIkNVUlJFTlRfTkFWX1RBQl9DTEFTUyIsIkFDVElWRV9OQVZfVEFCX0NMQVNTIiwiQUNUSVZFX1RBQkxFX0NMQVNTIiwiRURJVF9MQUJFTF9JRCIsIkVESVRfTEFCRUxfRVJST1JfQ0xBU1MiLCJwbHVzQnV0dG9uIiwiUExVU19DTEFTUyIsIm9wdGlvbnNGb3JtIiwicXVlcnlTZWxlY3RvciIsInRhYmxlc0RhdGEiLCJnZXRUYWJsZXNEYXRhIiwic3VibWl0QnV0dG9uIiwib3B0aW9uc1NhdmVTdWNjZXNzTWVzc2FnZSIsIkN5cjJMYXRUYWJsZXNPYmplY3QiLCJvcHRpb25zU2F2ZUVycm9yTWVzc2FnZSIsImFkZFdyYXBwZXIiLCJhZGRNZXNzYWdlTGluZXMiLCJtb3ZlVGFicyIsImFkZEVkaXRMYWJlbElucHV0IiwiaGlkZVRhYmxlcyIsImJpbmRFdmVudHMiLCJzZXRTdWJtaXRTdGF0dXMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZ2V0QWN0aXZlSGVhZGVyIiwiZGF0YXNldCIsImluZGV4IiwiYWN0aXZlSW5kZXgiLCJnZXRBY3RpdmVJbmRleCIsInN0cmluZ2lmeSIsImdldEFjdGl2ZVRhYmxlRGF0YSIsImRpc2FibGVkIiwiaXNBY3RpdmVUYWJsZUNoYW5nZWQiLCJhY3RpdmVUYWJsZSIsImdldEFjdGl2ZVRhYmxlIiwiYWN0aXZlRm9ybSIsImNyZWF0ZUVsZW1lbnQiLCJhY3Rpb24iLCJnZXRBdHRyaWJ1dGUiLCJhcHBlbmRDaGlsZCIsImNsb25lTm9kZSIsImFjdGl2ZUlucHV0cyIsImlkIiwiaGlkZGVuSW5wdXRzIiwic2hvd01lc3NhZ2UiLCJzdWNjZXNzTWVzc2FnZSIsImVycm9yTWVzc2FnZSIsImZpbmFsbHkiLCJwYXJlbnROb2RlIiwicmVtb3ZlQ2hpbGQiLCJ0YWJsZSIsImlucHV0cyIsImRhdGEiLCJsYWJlbCIsImlubmVySFRNTCIsImdldFRhYmxlcyIsImdldFRhYmxlRGF0YSIsIndyYXBwZXIiLCJjbGFzc0xpc3QiLCJhZGQiLCJpbnNlcnRCZWZvcmUiLCJmaXJzdENoaWxkIiwiYWRkTWVzc2FnZUxpbmUiLCJ0YWJzIiwiZWRpdExhYmVsSW5wdXQiLCJzdHlsZSIsImRpc3BsYXkiLCJyZW1vdmUiLCJwcmV2aW91c0VsZW1lbnRTaWJsaW5nIiwibGFzdENlbGwiLCJnZXRMYXN0Q2VsbCIsInBhcmVudEVsZW1lbnQiLCJuZXh0RWxlbWVudFNpYmxpbmciLCJpZEFyciIsIm5ld0lkIiwicGFyc2VJbnQiLCJodG1sRm9yIiwic2V0QXR0cmlidXRlIiwicmVwbGFjZU5hbWUiLCJlZGl0TGFiZWwiLCJjdXJyZW50SW5kZXgiLCJwbHVzIiwiZ2V0SGVhZGVycyIsIm9uY2xpY2siLCJldmVudCIsInByZXZlbnREZWZhdWx0IiwidGFyZ2V0Iiwic2F2ZUFjdGl2ZVRhYmxlIiwiYUhlYWRlciIsInRhYmxlcyIsImdldElucHV0cyIsIm9uaW5wdXQiLCJnZXRMYWJlbHMiLCJvbmJsdXIiLCJzYXZlTGFiZWwiLCJvbmtleXVwIiwiZ2V0UGx1c0J1dHRvbnMiLCJhZGRDZWxsIiwiZm9jdXMiLCJuZXdWYWx1ZSIsInJlZHVjZSIsImFjYyIsImNhbmNlbCIsImVkaXRlZENlbGwiLCJnZXRFbGVtZW50QnlJZCIsImhpZGVFZGl0TGFiZWxJbnB1dCIsImlzVW5pcXVlTGFiZWwiLCJjbGVhck1lc3NhZ2UiLCJjbGVhclRpbWVvdXQiLCJtc2dUaW1lciIsImVsIiwic2V0VGltZW91dCIsImNsZWFyTWVzc2FnZXMiXSwibWFwcGluZ3MiOiJhQUNFLElBQUlBLEVBQW1CLEdBR3ZCLFNBQVNDLEVBQW9CQyxHQUc1QixHQUFHRixFQUFpQkUsR0FDbkIsT0FBT0YsRUFBaUJFLEdBQVVDLFFBR25DLElBQUlDLEVBQVNKLEVBQWlCRSxHQUFZLENBQ3pDRyxFQUFHSCxFQUNISSxHQUFHLEVBQ0hILFFBQVMsSUFVVixPQU5BSSxFQUFRTCxHQUFVTSxLQUFLSixFQUFPRCxRQUFTQyxFQUFRQSxFQUFPRCxRQUFTRixHQUcvREcsRUFBT0UsR0FBSSxFQUdKRixFQUFPRCxRQUtmRixFQUFvQlEsRUFBSUYsRUFHeEJOLEVBQW9CUyxFQUFJVixFQUd4QkMsRUFBb0JVLEVBQUksU0FBU1IsRUFBU1MsRUFBTUMsR0FDM0NaLEVBQW9CYSxFQUFFWCxFQUFTUyxJQUNsQ0csT0FBT0MsZUFBZWIsRUFBU1MsRUFBTSxDQUFFSyxZQUFZLEVBQU1DLElBQUtMLEtBS2hFWixFQUFvQmtCLEVBQUksU0FBU2hCLEdBQ1gsb0JBQVhpQixRQUEwQkEsT0FBT0MsYUFDMUNOLE9BQU9DLGVBQWViLEVBQVNpQixPQUFPQyxZQUFhLENBQUVDLE1BQU8sV0FFN0RQLE9BQU9DLGVBQWViLEVBQVMsYUFBYyxDQUFFbUIsT0FBTyxLQVF2RHJCLEVBQW9Cc0IsRUFBSSxTQUFTRCxFQUFPRSxHQUV2QyxHQURVLEVB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LEtBQUtpUixZLGtDQVNQQyxFQUFJbkosR0FBVSxXQUMxQm1KLEVBQUd4RCxVQUFZM0YsRUFDZm1KLEVBQUdwRCxVQUFVQyxJQUFLLFVBRWxCL04sS0FBS2lSLFNBQVdFLFlBQVksV0FDM0IsRUFBS0Msa0JBQ0gsUyxlQUlVckgiLCJmaWxlIjoidGFibGVzL2FwcC5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGdldHRlciB9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuIFx0XHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcbiBcdFx0fVxuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuIFx0fTtcblxuIFx0Ly8gY3JlYXRlIGEgZmFrZSBuYW1lc3BhY2Ugb2JqZWN0XG4gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcbiBcdC8vIG1vZGUgJiAyOiBtZXJnZSBhbGwgcHJvcGVydGllcyBvZiB2YWx1ZSBpbnRvIHRoZSBuc1xuIFx0Ly8gbW9kZSAmIDQ6IHJldHVybiB2YWx1ZSB3aGVuIGFscmVhZHkgbnMgb2JqZWN0XG4gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnQgPSBmdW5jdGlvbih2YWx1ZSwgbW9kZSkge1xuIFx0XHRpZihtb2RlICYgMSkgdmFsdWUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKHZhbHVlKTtcbiBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcbiBcdFx0aWYoKG1vZGUgJiA0KSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcbiBcdFx0dmFyIG5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG5zLCAnZGVmYXVsdCcsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuIFx0XHRpZihtb2RlICYgMiAmJiB0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIGZvcih2YXIga2V5IGluIHZhbHVlKSBfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGtleSwgZnVuY3Rpb24oa2V5KSB7IHJldHVybiB2YWx1ZVtrZXldOyB9LmJpbmQobnVsbCwga2V5KSk7XG4gXHRcdHJldHVybiBucztcbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSAwKTtcbiIsInZhciBnbG9iYWwgPSB0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDogdGhpcztcbnZhciBfX3NlbGZfXyA9IChmdW5jdGlvbiAoKSB7XG5mdW5jdGlvbiBGKCkge1xudGhpcy5mZXRjaCA9IGZhbHNlO1xudGhpcy5ET01FeGNlcHRpb24gPSBnbG9iYWwuRE9NRXhjZXB0aW9uXG59XG5GLnByb3RvdHlwZSA9IGdsb2JhbDtcbnJldHVybiBuZXcgRigpO1xufSkoKTtcbihmdW5jdGlvbihzZWxmKSB7XG5cbnZhciBpcnJlbGV2YW50ID0gKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cbiAgdmFyIHN1cHBvcnQgPSB7XG4gICAgc2VhcmNoUGFyYW1zOiAnVVJMU2VhcmNoUGFyYW1zJyBpbiBzZWxmLFxuICAgIGl0ZXJhYmxlOiAnU3ltYm9sJyBpbiBzZWxmICYmICdpdGVyYXRvcicgaW4gU3ltYm9sLFxuICAgIGJsb2I6XG4gICAgICAnRmlsZVJlYWRlcicgaW4gc2VsZiAmJlxuICAgICAgJ0Jsb2InIGluIHNlbGYgJiZcbiAgICAgIChmdW5jdGlvbigpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBuZXcgQmxvYigpO1xuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICBmb3JtRGF0YTogJ0Zvcm1EYXRhJyBpbiBzZWxmLFxuICAgIGFycmF5QnVmZmVyOiAnQXJyYXlCdWZmZXInIGluIHNlbGZcbiAgfTtcblxuICBmdW5jdGlvbiBpc0RhdGFWaWV3KG9iaikge1xuICAgIHJldHVybiBvYmogJiYgRGF0YVZpZXcucHJvdG90eXBlLmlzUHJvdG90eXBlT2Yob2JqKVxuICB9XG5cbiAgaWYgKHN1cHBvcnQuYXJyYXlCdWZmZXIpIHtcbiAgICB2YXIgdmlld0NsYXNzZXMgPSBbXG4gICAgICAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICAgICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICAgICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgICAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgICAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgVWludDMyQXJyYXldJyxcbiAgICAgICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgRmxvYXQ2NEFycmF5XSdcbiAgICBdO1xuXG4gICAgdmFyIGlzQXJyYXlCdWZmZXJWaWV3ID1cbiAgICAgIEFycmF5QnVmZmVyLmlzVmlldyB8fFxuICAgICAgZnVuY3Rpb24ob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogJiYgdmlld0NsYXNzZXMuaW5kZXhPZihPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSkgPiAtMVxuICAgICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZU5hbWUobmFtZSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIG5hbWUgPSBTdHJpbmcobmFtZSk7XG4gICAgfVxuICAgIGlmICgvW15hLXowLTlcXC0jJCUmJyorLl5fYHx+XS9pLnRlc3QobmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgY2hhcmFjdGVyIGluIGhlYWRlciBmaWVsZCBuYW1lJylcbiAgICB9XG4gICAgcmV0dXJuIG5hbWUudG9Mb3dlckNhc2UoKVxuICB9XG5cbiAgZnVuY3Rpb24gbm9ybWFsaXplVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIC8vIEJ1aWxkIGEgZGVzdHJ1Y3RpdmUgaXRlcmF0b3IgZm9yIHRoZSB2YWx1ZSBsaXN0XG4gIGZ1bmN0aW9uIGl0ZXJhdG9yRm9yKGl0ZW1zKSB7XG4gICAgdmFyIGl0ZXJhdG9yID0ge1xuICAgICAgbmV4dDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGl0ZW1zLnNoaWZ0KCk7XG4gICAgICAgIHJldHVybiB7ZG9uZTogdmFsdWUgPT09IHVuZGVmaW5lZCwgdmFsdWU6IHZhbHVlfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoc3VwcG9ydC5pdGVyYWJsZSkge1xuICAgICAgaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGl0ZXJhdG9yXG4gIH1cblxuICBmdW5jdGlvbiBIZWFkZXJzKGhlYWRlcnMpIHtcbiAgICB0aGlzLm1hcCA9IHt9O1xuXG4gICAgaWYgKGhlYWRlcnMgaW5zdGFuY2VvZiBIZWFkZXJzKSB7XG4gICAgICBoZWFkZXJzLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICAgICAgdGhpcy5hcHBlbmQobmFtZSwgdmFsdWUpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGhlYWRlcnMpKSB7XG4gICAgICBoZWFkZXJzLmZvckVhY2goZnVuY3Rpb24oaGVhZGVyKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kKGhlYWRlclswXSwgaGVhZGVyWzFdKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoaGVhZGVycykge1xuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoaGVhZGVycykuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kKG5hbWUsIGhlYWRlcnNbbmFtZV0pO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfVxuICB9XG5cbiAgSGVhZGVycy5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICBuYW1lID0gbm9ybWFsaXplTmFtZShuYW1lKTtcbiAgICB2YWx1ZSA9IG5vcm1hbGl6ZVZhbHVlKHZhbHVlKTtcbiAgICB2YXIgb2xkVmFsdWUgPSB0aGlzLm1hcFtuYW1lXTtcbiAgICB0aGlzLm1hcFtuYW1lXSA9IG9sZFZhbHVlID8gb2xkVmFsdWUgKyAnLCAnICsgdmFsdWUgOiB2YWx1ZTtcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgZGVsZXRlIHRoaXMubWFwW25vcm1hbGl6ZU5hbWUobmFtZSldO1xuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBuYW1lID0gbm9ybWFsaXplTmFtZShuYW1lKTtcbiAgICByZXR1cm4gdGhpcy5oYXMobmFtZSkgPyB0aGlzLm1hcFtuYW1lXSA6IG51bGxcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwLmhhc093blByb3BlcnR5KG5vcm1hbGl6ZU5hbWUobmFtZSkpXG4gIH07XG5cbiAgSGVhZGVycy5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICB0aGlzLm1hcFtub3JtYWxpemVOYW1lKG5hbWUpXSA9IG5vcm1hbGl6ZVZhbHVlKHZhbHVlKTtcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24oY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMubWFwKSB7XG4gICAgICBpZiAodGhpcy5tYXAuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB0aGlzLm1hcFtuYW1lXSwgbmFtZSwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLmtleXMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICAgIGl0ZW1zLnB1c2gobmFtZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yRm9yKGl0ZW1zKVxuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLnZhbHVlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBpdGVtcyA9IFtdO1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaXRlbXMucHVzaCh2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yRm9yKGl0ZW1zKVxuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLmVudHJpZXMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICAgIGl0ZW1zLnB1c2goW25hbWUsIHZhbHVlXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yRm9yKGl0ZW1zKVxuICB9O1xuXG4gIGlmIChzdXBwb3J0Lml0ZXJhYmxlKSB7XG4gICAgSGVhZGVycy5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9IEhlYWRlcnMucHJvdG90eXBlLmVudHJpZXM7XG4gIH1cblxuICBmdW5jdGlvbiBjb25zdW1lZChib2R5KSB7XG4gICAgaWYgKGJvZHkuYm9keVVzZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgVHlwZUVycm9yKCdBbHJlYWR5IHJlYWQnKSlcbiAgICB9XG4gICAgYm9keS5ib2R5VXNlZCA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiBmaWxlUmVhZGVyUmVhZHkocmVhZGVyKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXNvbHZlKHJlYWRlci5yZXN1bHQpO1xuICAgICAgfTtcbiAgICAgIHJlYWRlci5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJlamVjdChyZWFkZXIuZXJyb3IpO1xuICAgICAgfTtcbiAgICB9KVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZEJsb2JBc0FycmF5QnVmZmVyKGJsb2IpIHtcbiAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICB2YXIgcHJvbWlzZSA9IGZpbGVSZWFkZXJSZWFkeShyZWFkZXIpO1xuICAgIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihibG9iKTtcbiAgICByZXR1cm4gcHJvbWlzZVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZEJsb2JBc1RleHQoYmxvYikge1xuICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgIHZhciBwcm9taXNlID0gZmlsZVJlYWRlclJlYWR5KHJlYWRlcik7XG4gICAgcmVhZGVyLnJlYWRBc1RleHQoYmxvYik7XG4gICAgcmV0dXJuIHByb21pc2VcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWRBcnJheUJ1ZmZlckFzVGV4dChidWYpIHtcbiAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1Zik7XG4gICAgdmFyIGNoYXJzID0gbmV3IEFycmF5KHZpZXcubGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgY2hhcnNbaV0gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHZpZXdbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gY2hhcnMuam9pbignJylcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1ZmZlckNsb25lKGJ1Zikge1xuICAgIGlmIChidWYuc2xpY2UpIHtcbiAgICAgIHJldHVybiBidWYuc2xpY2UoMClcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShidWYuYnl0ZUxlbmd0aCk7XG4gICAgICB2aWV3LnNldChuZXcgVWludDhBcnJheShidWYpKTtcbiAgICAgIHJldHVybiB2aWV3LmJ1ZmZlclxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIEJvZHkoKSB7XG4gICAgdGhpcy5ib2R5VXNlZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5faW5pdEJvZHkgPSBmdW5jdGlvbihib2R5KSB7XG4gICAgICB0aGlzLl9ib2R5SW5pdCA9IGJvZHk7XG4gICAgICBpZiAoIWJvZHkpIHtcbiAgICAgICAgdGhpcy5fYm9keVRleHQgPSAnJztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGJvZHkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMuX2JvZHlUZXh0ID0gYm9keTtcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5ibG9iICYmIEJsb2IucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkpIHtcbiAgICAgICAgdGhpcy5fYm9keUJsb2IgPSBib2R5O1xuICAgICAgfSBlbHNlIGlmIChzdXBwb3J0LmZvcm1EYXRhICYmIEZvcm1EYXRhLnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKGJvZHkpKSB7XG4gICAgICAgIHRoaXMuX2JvZHlGb3JtRGF0YSA9IGJvZHk7XG4gICAgICB9IGVsc2UgaWYgKHN1cHBvcnQuc2VhcmNoUGFyYW1zICYmIFVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihib2R5KSkge1xuICAgICAgICB0aGlzLl9ib2R5VGV4dCA9IGJvZHkudG9TdHJpbmcoKTtcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5hcnJheUJ1ZmZlciAmJiBzdXBwb3J0LmJsb2IgJiYgaXNEYXRhVmlldyhib2R5KSkge1xuICAgICAgICB0aGlzLl9ib2R5QXJyYXlCdWZmZXIgPSBidWZmZXJDbG9uZShib2R5LmJ1ZmZlcik7XG4gICAgICAgIC8vIElFIDEwLTExIGNhbid0IGhhbmRsZSBhIERhdGFWaWV3IGJvZHkuXG4gICAgICAgIHRoaXMuX2JvZHlJbml0ID0gbmV3IEJsb2IoW3RoaXMuX2JvZHlBcnJheUJ1ZmZlcl0pO1xuICAgICAgfSBlbHNlIGlmIChzdXBwb3J0LmFycmF5QnVmZmVyICYmIChBcnJheUJ1ZmZlci5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihib2R5KSB8fCBpc0FycmF5QnVmZmVyVmlldyhib2R5KSkpIHtcbiAgICAgICAgdGhpcy5fYm9keUFycmF5QnVmZmVyID0gYnVmZmVyQ2xvbmUoYm9keSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9ib2R5VGV4dCA9IGJvZHkgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYm9keSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5oZWFkZXJzLmdldCgnY29udGVudC10eXBlJykpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRoaXMuaGVhZGVycy5zZXQoJ2NvbnRlbnQtdHlwZScsICd0ZXh0L3BsYWluO2NoYXJzZXQ9VVRGLTgnKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9ib2R5QmxvYiAmJiB0aGlzLl9ib2R5QmxvYi50eXBlKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXJzLnNldCgnY29udGVudC10eXBlJywgdGhpcy5fYm9keUJsb2IudHlwZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5zZWFyY2hQYXJhbXMgJiYgVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKGJvZHkpKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXJzLnNldCgnY29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDtjaGFyc2V0PVVURi04Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHN1cHBvcnQuYmxvYikge1xuICAgICAgdGhpcy5ibG9iID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciByZWplY3RlZCA9IGNvbnN1bWVkKHRoaXMpO1xuICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0ZWRcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9ib2R5QmxvYikge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keUJsb2IpXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYm9keUFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgQmxvYihbdGhpcy5fYm9keUFycmF5QnVmZmVyXSkpXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYm9keUZvcm1EYXRhKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgcmVhZCBGb3JtRGF0YSBib2R5IGFzIGJsb2InKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEJsb2IoW3RoaXMuX2JvZHlUZXh0XSkpXG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHRoaXMuYXJyYXlCdWZmZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2JvZHlBcnJheUJ1ZmZlcikge1xuICAgICAgICAgIHJldHVybiBjb25zdW1lZCh0aGlzKSB8fCBQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keUFycmF5QnVmZmVyKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmJsb2IoKS50aGVuKHJlYWRCbG9iQXNBcnJheUJ1ZmZlcilcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLnRleHQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWplY3RlZCA9IGNvbnN1bWVkKHRoaXMpO1xuICAgICAgaWYgKHJlamVjdGVkKSB7XG4gICAgICAgIHJldHVybiByZWplY3RlZFxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fYm9keUJsb2IpIHtcbiAgICAgICAgcmV0dXJuIHJlYWRCbG9iQXNUZXh0KHRoaXMuX2JvZHlCbG9iKVxuICAgICAgfSBlbHNlIGlmICh0aGlzLl9ib2R5QXJyYXlCdWZmZXIpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZWFkQXJyYXlCdWZmZXJBc1RleHQodGhpcy5fYm9keUFycmF5QnVmZmVyKSlcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fYm9keUZvcm1EYXRhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY291bGQgbm90IHJlYWQgRm9ybURhdGEgYm9keSBhcyB0ZXh0JylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keVRleHQpXG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChzdXBwb3J0LmZvcm1EYXRhKSB7XG4gICAgICB0aGlzLmZvcm1EYXRhID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRleHQoKS50aGVuKGRlY29kZSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5qc29uID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50ZXh0KCkudGhlbihKU09OLnBhcnNlKVxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLy8gSFRUUCBtZXRob2RzIHdob3NlIGNhcGl0YWxpemF0aW9uIHNob3VsZCBiZSBub3JtYWxpemVkXG4gIHZhciBtZXRob2RzID0gWydERUxFVEUnLCAnR0VUJywgJ0hFQUQnLCAnT1BUSU9OUycsICdQT1NUJywgJ1BVVCddO1xuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZU1ldGhvZChtZXRob2QpIHtcbiAgICB2YXIgdXBjYXNlZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgIHJldHVybiBtZXRob2RzLmluZGV4T2YodXBjYXNlZCkgPiAtMSA/IHVwY2FzZWQgOiBtZXRob2RcbiAgfVxuXG4gIGZ1bmN0aW9uIFJlcXVlc3QoaW5wdXQsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgYm9keSA9IG9wdGlvbnMuYm9keTtcblxuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIFJlcXVlc3QpIHtcbiAgICAgIGlmIChpbnB1dC5ib2R5VXNlZCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBbHJlYWR5IHJlYWQnKVxuICAgICAgfVxuICAgICAgdGhpcy51cmwgPSBpbnB1dC51cmw7XG4gICAgICB0aGlzLmNyZWRlbnRpYWxzID0gaW5wdXQuY3JlZGVudGlhbHM7XG4gICAgICBpZiAoIW9wdGlvbnMuaGVhZGVycykge1xuICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgSGVhZGVycyhpbnB1dC5oZWFkZXJzKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWV0aG9kID0gaW5wdXQubWV0aG9kO1xuICAgICAgdGhpcy5tb2RlID0gaW5wdXQubW9kZTtcbiAgICAgIHRoaXMuc2lnbmFsID0gaW5wdXQuc2lnbmFsO1xuICAgICAgaWYgKCFib2R5ICYmIGlucHV0Ll9ib2R5SW5pdCAhPSBudWxsKSB7XG4gICAgICAgIGJvZHkgPSBpbnB1dC5fYm9keUluaXQ7XG4gICAgICAgIGlucHV0LmJvZHlVc2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cmwgPSBTdHJpbmcoaW5wdXQpO1xuICAgIH1cblxuICAgIHRoaXMuY3JlZGVudGlhbHMgPSBvcHRpb25zLmNyZWRlbnRpYWxzIHx8IHRoaXMuY3JlZGVudGlhbHMgfHwgJ3NhbWUtb3JpZ2luJztcbiAgICBpZiAob3B0aW9ucy5oZWFkZXJzIHx8ICF0aGlzLmhlYWRlcnMpIHtcbiAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyBIZWFkZXJzKG9wdGlvbnMuaGVhZGVycyk7XG4gICAgfVxuICAgIHRoaXMubWV0aG9kID0gbm9ybWFsaXplTWV0aG9kKG9wdGlvbnMubWV0aG9kIHx8IHRoaXMubWV0aG9kIHx8ICdHRVQnKTtcbiAgICB0aGlzLm1vZGUgPSBvcHRpb25zLm1vZGUgfHwgdGhpcy5tb2RlIHx8IG51bGw7XG4gICAgdGhpcy5zaWduYWwgPSBvcHRpb25zLnNpZ25hbCB8fCB0aGlzLnNpZ25hbDtcbiAgICB0aGlzLnJlZmVycmVyID0gbnVsbDtcblxuICAgIGlmICgodGhpcy5tZXRob2QgPT09ICdHRVQnIHx8IHRoaXMubWV0aG9kID09PSAnSEVBRCcpICYmIGJvZHkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0JvZHkgbm90IGFsbG93ZWQgZm9yIEdFVCBvciBIRUFEIHJlcXVlc3RzJylcbiAgICB9XG4gICAgdGhpcy5faW5pdEJvZHkoYm9keSk7XG4gIH1cblxuICBSZXF1ZXN0LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdCh0aGlzLCB7Ym9keTogdGhpcy5fYm9keUluaXR9KVxuICB9O1xuXG4gIGZ1bmN0aW9uIGRlY29kZShib2R5KSB7XG4gICAgdmFyIGZvcm0gPSBuZXcgRm9ybURhdGEoKTtcbiAgICBib2R5XG4gICAgICAudHJpbSgpXG4gICAgICAuc3BsaXQoJyYnKVxuICAgICAgLmZvckVhY2goZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAgICAgaWYgKGJ5dGVzKSB7XG4gICAgICAgICAgdmFyIHNwbGl0ID0gYnl0ZXMuc3BsaXQoJz0nKTtcbiAgICAgICAgICB2YXIgbmFtZSA9IHNwbGl0LnNoaWZ0KCkucmVwbGFjZSgvXFwrL2csICcgJyk7XG4gICAgICAgICAgdmFyIHZhbHVlID0gc3BsaXQuam9pbignPScpLnJlcGxhY2UoL1xcKy9nLCAnICcpO1xuICAgICAgICAgIGZvcm0uYXBwZW5kKGRlY29kZVVSSUNvbXBvbmVudChuYW1lKSwgZGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIHJldHVybiBmb3JtXG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZUhlYWRlcnMocmF3SGVhZGVycykge1xuICAgIHZhciBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAvLyBSZXBsYWNlIGluc3RhbmNlcyBvZiBcXHJcXG4gYW5kIFxcbiBmb2xsb3dlZCBieSBhdCBsZWFzdCBvbmUgc3BhY2Ugb3IgaG9yaXpvbnRhbCB0YWIgd2l0aCBhIHNwYWNlXG4gICAgLy8gaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzcyMzAjc2VjdGlvbi0zLjJcbiAgICB2YXIgcHJlUHJvY2Vzc2VkSGVhZGVycyA9IHJhd0hlYWRlcnMucmVwbGFjZSgvXFxyP1xcbltcXHQgXSsvZywgJyAnKTtcbiAgICBwcmVQcm9jZXNzZWRIZWFkZXJzLnNwbGl0KC9cXHI/XFxuLykuZm9yRWFjaChmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgcGFydHMgPSBsaW5lLnNwbGl0KCc6Jyk7XG4gICAgICB2YXIga2V5ID0gcGFydHMuc2hpZnQoKS50cmltKCk7XG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHBhcnRzLmpvaW4oJzonKS50cmltKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBoZWFkZXJzXG4gIH1cblxuICBCb2R5LmNhbGwoUmVxdWVzdC5wcm90b3R5cGUpO1xuXG4gIGZ1bmN0aW9uIFJlc3BvbnNlKGJvZHlJbml0LCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICBvcHRpb25zID0ge307XG4gICAgfVxuXG4gICAgdGhpcy50eXBlID0gJ2RlZmF1bHQnO1xuICAgIHRoaXMuc3RhdHVzID0gb3B0aW9ucy5zdGF0dXMgPT09IHVuZGVmaW5lZCA/IDIwMCA6IG9wdGlvbnMuc3RhdHVzO1xuICAgIHRoaXMub2sgPSB0aGlzLnN0YXR1cyA+PSAyMDAgJiYgdGhpcy5zdGF0dXMgPCAzMDA7XG4gICAgdGhpcy5zdGF0dXNUZXh0ID0gJ3N0YXR1c1RleHQnIGluIG9wdGlvbnMgPyBvcHRpb25zLnN0YXR1c1RleHQgOiAnT0snO1xuICAgIHRoaXMuaGVhZGVycyA9IG5ldyBIZWFkZXJzKG9wdGlvbnMuaGVhZGVycyk7XG4gICAgdGhpcy51cmwgPSBvcHRpb25zLnVybCB8fCAnJztcbiAgICB0aGlzLl9pbml0Qm9keShib2R5SW5pdCk7XG4gIH1cblxuICBCb2R5LmNhbGwoUmVzcG9uc2UucHJvdG90eXBlKTtcblxuICBSZXNwb25zZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKHRoaXMuX2JvZHlJbml0LCB7XG4gICAgICBzdGF0dXM6IHRoaXMuc3RhdHVzLFxuICAgICAgc3RhdHVzVGV4dDogdGhpcy5zdGF0dXNUZXh0LFxuICAgICAgaGVhZGVyczogbmV3IEhlYWRlcnModGhpcy5oZWFkZXJzKSxcbiAgICAgIHVybDogdGhpcy51cmxcbiAgICB9KVxuICB9O1xuXG4gIFJlc3BvbnNlLmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKG51bGwsIHtzdGF0dXM6IDAsIHN0YXR1c1RleHQ6ICcnfSk7XG4gICAgcmVzcG9uc2UudHlwZSA9ICdlcnJvcic7XG4gICAgcmV0dXJuIHJlc3BvbnNlXG4gIH07XG5cbiAgdmFyIHJlZGlyZWN0U3RhdHVzZXMgPSBbMzAxLCAzMDIsIDMwMywgMzA3LCAzMDhdO1xuXG4gIFJlc3BvbnNlLnJlZGlyZWN0ID0gZnVuY3Rpb24odXJsLCBzdGF0dXMpIHtcbiAgICBpZiAocmVkaXJlY3RTdGF0dXNlcy5pbmRleE9mKHN0YXR1cykgPT09IC0xKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCBzdGF0dXMgY29kZScpXG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZShudWxsLCB7c3RhdHVzOiBzdGF0dXMsIGhlYWRlcnM6IHtsb2NhdGlvbjogdXJsfX0pXG4gIH07XG5cbiAgZXhwb3J0cy5ET01FeGNlcHRpb24gPSBzZWxmLkRPTUV4Y2VwdGlvbjtcbiAgdHJ5IHtcbiAgICBuZXcgZXhwb3J0cy5ET01FeGNlcHRpb24oKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXhwb3J0cy5ET01FeGNlcHRpb24gPSBmdW5jdGlvbihtZXNzYWdlLCBuYW1lKSB7XG4gICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgIHZhciBlcnJvciA9IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgdGhpcy5zdGFjayA9IGVycm9yLnN0YWNrO1xuICAgIH07XG4gICAgZXhwb3J0cy5ET01FeGNlcHRpb24ucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUpO1xuICAgIGV4cG9ydHMuRE9NRXhjZXB0aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGV4cG9ydHMuRE9NRXhjZXB0aW9uO1xuICB9XG5cbiAgZnVuY3Rpb24gZmV0Y2goaW5wdXQsIGluaXQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KGlucHV0LCBpbml0KTtcblxuICAgICAgaWYgKHJlcXVlc3Quc2lnbmFsICYmIHJlcXVlc3Quc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgZXhwb3J0cy5ET01FeGNlcHRpb24oJ0Fib3J0ZWQnLCAnQWJvcnRFcnJvcicpKVxuICAgICAgfVxuXG4gICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cbiAgICAgIGZ1bmN0aW9uIGFib3J0WGhyKCkge1xuICAgICAgICB4aHIuYWJvcnQoKTtcbiAgICAgIH1cblxuICAgICAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgICBzdGF0dXM6IHhoci5zdGF0dXMsXG4gICAgICAgICAgc3RhdHVzVGV4dDogeGhyLnN0YXR1c1RleHQsXG4gICAgICAgICAgaGVhZGVyczogcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSB8fCAnJylcbiAgICAgICAgfTtcbiAgICAgICAgb3B0aW9ucy51cmwgPSAncmVzcG9uc2VVUkwnIGluIHhociA/IHhoci5yZXNwb25zZVVSTCA6IG9wdGlvbnMuaGVhZGVycy5nZXQoJ1gtUmVxdWVzdC1VUkwnKTtcbiAgICAgICAgdmFyIGJvZHkgPSAncmVzcG9uc2UnIGluIHhociA/IHhoci5yZXNwb25zZSA6IHhoci5yZXNwb25zZVRleHQ7XG4gICAgICAgIHJlc29sdmUobmV3IFJlc3BvbnNlKGJvZHksIG9wdGlvbnMpKTtcbiAgICAgIH07XG5cbiAgICAgIHhoci5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJlamVjdChuZXcgVHlwZUVycm9yKCdOZXR3b3JrIHJlcXVlc3QgZmFpbGVkJykpO1xuICAgICAgfTtcblxuICAgICAgeGhyLm9udGltZW91dCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZWplY3QobmV3IFR5cGVFcnJvcignTmV0d29yayByZXF1ZXN0IGZhaWxlZCcpKTtcbiAgICAgIH07XG5cbiAgICAgIHhoci5vbmFib3J0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJlamVjdChuZXcgZXhwb3J0cy5ET01FeGNlcHRpb24oJ0Fib3J0ZWQnLCAnQWJvcnRFcnJvcicpKTtcbiAgICAgIH07XG5cbiAgICAgIHhoci5vcGVuKHJlcXVlc3QubWV0aG9kLCByZXF1ZXN0LnVybCwgdHJ1ZSk7XG5cbiAgICAgIGlmIChyZXF1ZXN0LmNyZWRlbnRpYWxzID09PSAnaW5jbHVkZScpIHtcbiAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKHJlcXVlc3QuY3JlZGVudGlhbHMgPT09ICdvbWl0Jykge1xuICAgICAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICgncmVzcG9uc2VUeXBlJyBpbiB4aHIgJiYgc3VwcG9ydC5ibG9iKSB7XG4gICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAnYmxvYic7XG4gICAgICB9XG5cbiAgICAgIHJlcXVlc3QuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKG5hbWUsIHZhbHVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocmVxdWVzdC5zaWduYWwpIHtcbiAgICAgICAgcmVxdWVzdC5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydFhocik7XG5cbiAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIC8vIERPTkUgKHN1Y2Nlc3Mgb3IgZmFpbHVyZSlcbiAgICAgICAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgIHJlcXVlc3Quc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnRYaHIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgeGhyLnNlbmQodHlwZW9mIHJlcXVlc3QuX2JvZHlJbml0ID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiByZXF1ZXN0Ll9ib2R5SW5pdCk7XG4gICAgfSlcbiAgfVxuXG4gIGZldGNoLnBvbHlmaWxsID0gdHJ1ZTtcblxuICBpZiAoIXNlbGYuZmV0Y2gpIHtcbiAgICBzZWxmLmZldGNoID0gZmV0Y2g7XG4gICAgc2VsZi5IZWFkZXJzID0gSGVhZGVycztcbiAgICBzZWxmLlJlcXVlc3QgPSBSZXF1ZXN0O1xuICAgIHNlbGYuUmVzcG9uc2UgPSBSZXNwb25zZTtcbiAgfVxuXG4gIGV4cG9ydHMuSGVhZGVycyA9IEhlYWRlcnM7XG4gIGV4cG9ydHMuUmVxdWVzdCA9IFJlcXVlc3Q7XG4gIGV4cG9ydHMuUmVzcG9uc2UgPSBSZXNwb25zZTtcbiAgZXhwb3J0cy5mZXRjaCA9IGZldGNoO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbiAgcmV0dXJuIGV4cG9ydHM7XG5cbn0oe30pKTtcbn0pKF9fc2VsZl9fKTtcbl9fc2VsZl9fLmZldGNoLnBvbnlmaWxsID0gdHJ1ZTtcbi8vIFJlbW92ZSBcInBvbHlmaWxsXCIgcHJvcGVydHkgYWRkZWQgYnkgd2hhdHdnLWZldGNoXG5kZWxldGUgX19zZWxmX18uZmV0Y2gucG9seWZpbGw7XG4vLyBDaG9vc2UgYmV0d2VlbiBuYXRpdmUgaW1wbGVtZW50YXRpb24gKGdsb2JhbCkgb3IgY3VzdG9tIGltcGxlbWVudGF0aW9uIChfX3NlbGZfXylcbi8vIHZhciBjdHggPSBnbG9iYWwuZmV0Y2ggPyBnbG9iYWwgOiBfX3NlbGZfXztcbnZhciBjdHggPSBfX3NlbGZfXzsgLy8gdGhpcyBsaW5lIGRpc2FibGUgc2VydmljZSB3b3JrZXIgc3VwcG9ydCB0ZW1wb3JhcmlseVxuZXhwb3J0cyA9IGN0eC5mZXRjaCAvLyBUbyBlbmFibGU6IGltcG9ydCBmZXRjaCBmcm9tICdjcm9zcy1mZXRjaCdcbmV4cG9ydHMuZGVmYXVsdCA9IGN0eC5mZXRjaCAvLyBGb3IgVHlwZVNjcmlwdCBjb25zdW1lcnMgd2l0aG91dCBlc01vZHVsZUludGVyb3AuXG5leHBvcnRzLmZldGNoID0gY3R4LmZldGNoIC8vIFRvIGVuYWJsZTogaW1wb3J0IHtmZXRjaH0gZnJvbSAnY3Jvc3MtZmV0Y2gnXG5leHBvcnRzLkhlYWRlcnMgPSBjdHguSGVhZGVyc1xuZXhwb3J0cy5SZXF1ZXN0ID0gY3R4LlJlcXVlc3RcbmV4cG9ydHMuUmVzcG9uc2UgPSBjdHguUmVzcG9uc2Vcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1xuIiwiLyoqXG4gKiBAZmlsZSBUYWJsZXMgQXBwbGljYXRpb24uXG4gKi9cbmltcG9ydCBUYWJsZXMgZnJvbSAnLi90YWJsZXMnO1xuXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCAnRE9NQ29udGVudExvYWRlZCcsICgpID0+IHtcblx0bmV3IFRhYmxlcygpO1xufSApO1xuIiwiLyoqXG4gKiBAZmlsZSBjbGFzcyBUYWJsZXMuXG4gKi9cblxuLyogZ2xvYmFsIEN5cjJMYXRUYWJsZXNPYmplY3QgKi9cblxuY2xhc3MgVGFibGVzIHtcblx0LyoqXG5cdCAqIENsYXNzIGNvbnN0cnVjdG9yLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy5PUFRJT05TX0ZPUk1fU0VMRUNUT1IgPSAnI2N0bC1vcHRpb25zJztcblx0XHR0aGlzLkhFQURFUl9TRUxFQ1RPUiA9IHRoaXMuT1BUSU9OU19GT1JNX1NFTEVDVE9SICsgJyBoMic7XG5cdFx0dGhpcy5UQUJMRV9TRUxFQ1RPUiA9IHRoaXMuT1BUSU9OU19GT1JNX1NFTEVDVE9SICsgJyB0YWJsZSc7XG5cdFx0dGhpcy5TVUJNSVRfU0VMRUNUT1IgPSB0aGlzLk9QVElPTlNfRk9STV9TRUxFQ1RPUiArICcgI3N1Ym1pdCc7XG5cdFx0dGhpcy5DVVJSRU5UX1NUVUJfSUQgPSAnY3RsLWN1cnJlbnQnO1xuXHRcdHRoaXMuQ1VSUkVOVF9OQVZfVEFCX0NMQVNTID0gJ25hdi10YWItY3VycmVudCc7XG5cdFx0dGhpcy5BQ1RJVkVfTkFWX1RBQl9DTEFTUyA9ICduYXYtdGFiLWFjdGl2ZSc7XG5cdFx0dGhpcy5BQ1RJVkVfVEFCTEVfQ0xBU1MgPSAnYWN0aXZlJztcblx0XHR0aGlzLkVESVRfTEFCRUxfSUQgPSAnY3RsLWVkaXQtbGFiZWwnO1xuXHRcdHRoaXMuRURJVF9MQUJFTF9FUlJPUl9DTEFTUyA9ICdjdGwtZWRpdC1sYWJlbC1lcnJvcic7XG5cdFx0dGhpcy5wbHVzQnV0dG9uID1cblx0XHRcdCc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBhcmlhLWhhc3BvcHVwPVwidHJ1ZVwiIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiIGNsYXNzPVwiY29tcG9uZW50cy1idXR0b24gYmxvY2stZWRpdG9yLWluc2VydGVyX190b2dnbGUgaGFzLWljb25cIiBhcmlhLWxhYmVsPVwi0JTQvtCx0LDQstC40YLRjCDQsdC70L7QulwiPicgK1xuXHRcdFx0Jzxzdmcgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCItMiAtMiAyNCAyNFwiIHJvbGU9XCJpbWdcIiBhcmlhLWhpZGRlbj1cInRydWVcIiBmb2N1c2FibGU9XCJmYWxzZVwiPicgK1xuXHRcdFx0JzxwYXRoIGQ9XCJNMTAgMWMtNSAwLTkgNC05IDlzNCA5IDkgOSA5LTQgOS05LTQtOS05LTl6bTAgMTZjLTMuOSAwLTctMy4xLTctN3MzLjEtNyA3LTcgNyAzLjEgNyA3LTMuMSA3LTcgN3ptMS0xMUg5djNINnYyaDN2M2gydi0zaDNWOWgtM1Y2ek0xMCAxYy01IDAtOSA0LTkgOXM0IDkgOSA5IDktNCA5LTktNC05LTktOXptMCAxNmMtMy45IDAtNy0zLjEtNy03czMuMS03IDctNyA3IDMuMSA3IDctMy4xIDctNyA3em0xLTExSDl2M0g2djJoM3YzaDJ2LTNoM1Y5aC0zVjZ6XCI+JyArXG5cdFx0XHQnPC9wYXRoPicgK1xuXHRcdFx0Jzwvc3ZnPicgK1xuXHRcdFx0JzwvYnV0dG9uPic7XG5cdFx0dGhpcy5QTFVTX0NMQVNTID0gJ2N0bC1wbHVzJztcblxuXHRcdHRoaXMub3B0aW9uc0Zvcm0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCB0aGlzLk9QVElPTlNfRk9STV9TRUxFQ1RPUiApO1xuXHRcdHRoaXMudGFibGVzRGF0YSA9IHRoaXMuZ2V0VGFibGVzRGF0YSgpO1xuXHRcdHRoaXMuc3VibWl0QnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvciggdGhpcy5TVUJNSVRfU0VMRUNUT1IgKTtcblxuXHRcdC8vIENvcHkgdG8gY2xhc3MgcHJvcGVydGllcywgb3RoZXJ3aXNlIGVzbGludCBtYXJrcyBzb21lIHByb3BlcnRpZXMgb2YgZ2xvYmFsIG9iamVjdCBhcyB1bnJlc29sdmVkLlxuXHRcdHRoaXMub3B0aW9uc1NhdmVTdWNjZXNzTWVzc2FnZSA9XG5cdFx0XHRDeXIyTGF0VGFibGVzT2JqZWN0Lm9wdGlvbnNTYXZlU3VjY2Vzc01lc3NhZ2U7XG5cdFx0dGhpcy5vcHRpb25zU2F2ZUVycm9yTWVzc2FnZSA9XG5cdFx0XHRDeXIyTGF0VGFibGVzT2JqZWN0Lm9wdGlvbnNTYXZlRXJyb3JNZXNzYWdlO1xuXG5cdFx0dGhpcy5hZGRXcmFwcGVyKCk7XG5cdFx0dGhpcy5hZGRNZXNzYWdlTGluZXMoKTtcblx0XHR0aGlzLm1vdmVUYWJzKCk7XG5cdFx0dGhpcy5hZGRFZGl0TGFiZWxJbnB1dCgpO1xuXHRcdHRoaXMuaGlkZVRhYmxlcygpO1xuXHRcdHRoaXMuYmluZEV2ZW50cygpO1xuXHRcdHRoaXMuc2V0U3VibWl0U3RhdHVzKCk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0IGhlYWRlcnMuXG5cdCAqXG5cdCAqIEByZXR1cm4geypbXX0gSGVhZGVycy5cblx0ICovXG5cdGdldEhlYWRlcnMoKSB7XG5cdFx0cmV0dXJuIFsgLi4uZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCggdGhpcy5IRUFERVJfU0VMRUNUT1IgKSBdO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBhY3RpdmUgaGVhZGVyLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBBY3RpdmUgaGVhZGVyLlxuXHQgKi9cblx0Z2V0QWN0aXZlSGVhZGVyKCkge1xuXHRcdHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuXHRcdFx0dGhpcy5IRUFERVJfU0VMRUNUT1IgKyAnLicgKyB0aGlzLkFDVElWRV9OQVZfVEFCX0NMQVNTXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgYWN0aXZlIGluZGV4LlxuXHQgKlxuXHQgKiBAcmV0dXJuIHsqfSBBY3RpdmUgaW5kZXguXG5cdCAqL1xuXHRnZXRBY3RpdmVJbmRleCgpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRBY3RpdmVIZWFkZXIoKS5kYXRhc2V0LmluZGV4O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCB0YWJsZXMuXG5cdCAqXG5cdCAqIEByZXR1cm4geypbXX0gVGFibGVzLlxuXHQgKi9cblx0Z2V0VGFibGVzKCkge1xuXHRcdHJldHVybiBbIC4uLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIHRoaXMuVEFCTEVfU0VMRUNUT1IgKSBdO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBhY3RpdmUgdGFibGUuXG5cdCAqXG5cdCAqIEByZXR1cm4ge0VsZW1lbnR9IEFjdGl2ZSB0YWJsZS5cblx0ICovXG5cdGdldEFjdGl2ZVRhYmxlKCkge1xuXHRcdHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuXHRcdFx0dGhpcy5UQUJMRV9TRUxFQ1RPUiArICcuJyArIHRoaXMuQUNUSVZFX1RBQkxFX0NMQVNTXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgaW5wdXRzLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHsqW119IElucHV0cy5cblx0ICovXG5cdGdldElucHV0cygpIHtcblx0XHRyZXR1cm4gW1xuXHRcdFx0Li4uZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcblx0XHRcdFx0dGhpcy5PUFRJT05TX0ZPUk1fU0VMRUNUT1IgKyAnIGlucHV0J1xuXHRcdFx0KSxcblx0XHRdO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBsYWJlbHMuXG5cdCAqXG5cdCAqIEByZXR1cm4geypbXX0gTGFiZWxzLlxuXHQgKi9cblx0Z2V0TGFiZWxzKCkge1xuXHRcdHJldHVybiBbXG5cdFx0XHQuLi5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuXHRcdFx0XHR0aGlzLk9QVElPTlNfRk9STV9TRUxFQ1RPUiArICcgbGFiZWwnXG5cdFx0XHQpLFxuXHRcdF07XG5cdH1cblxuXHQvKipcblx0ICogR2V0IHBsdXMgYnV0dG9ucy5cblx0ICpcblx0ICogQHJldHVybiB7KltdfSBQbHVzIGJ1dHRvbnMuXG5cdCAqL1xuXHRnZXRQbHVzQnV0dG9ucygpIHtcblx0XHRyZXR1cm4gW1xuXHRcdFx0Li4uZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcblx0XHRcdFx0dGhpcy5PUFRJT05TX0ZPUk1fU0VMRUNUT1IgKyAnIC4nICsgdGhpcy5QTFVTX0NMQVNTXG5cdFx0XHQpLFxuXHRcdF07XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2sgb2YgYWN0aXZlIHRhYmxlIHdhcyBjaGFuZ2VkLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBJZiBhY3RpdmUgdGFibGUgd2FzIGNoYW5nZWQuXG5cdCAqL1xuXHRpc0FjdGl2ZVRhYmxlQ2hhbmdlZCgpIHtcblx0XHRjb25zdCBhY3RpdmVJbmRleCA9IHRoaXMuZ2V0QWN0aXZlSW5kZXgoKTtcblxuXHRcdHJldHVybiAoXG5cdFx0XHRKU09OLnN0cmluZ2lmeSggdGhpcy5nZXRBY3RpdmVUYWJsZURhdGEoKSApICE9PVxuXHRcdFx0SlNPTi5zdHJpbmdpZnkoIHRoaXMudGFibGVzRGF0YVsgYWN0aXZlSW5kZXggXSApXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgc3RhdHVzIG9mIHN1Ym1pdCBidXR0b24uXG5cdCAqL1xuXHRzZXRTdWJtaXRTdGF0dXMoKSB7XG5cdFx0dGhpcy5zdWJtaXRCdXR0b24uZGlzYWJsZWQgPSAhIHRoaXMuaXNBY3RpdmVUYWJsZUNoYW5nZWQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTYXZlIGFjdGl2ZSB0YWJsZS5cblx0ICovXG5cdHNhdmVBY3RpdmVUYWJsZSgpIHtcblx0XHRpZiAoICEgdGhpcy5pc0FjdGl2ZVRhYmxlQ2hhbmdlZCgpICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGFjdGl2ZVRhYmxlID0gdGhpcy5nZXRBY3RpdmVUYWJsZSgpO1xuXG5cdFx0Y29uc3QgYWN0aXZlRm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdmb3JtJyApO1xuXHRcdGFjdGl2ZUZvcm0uYWN0aW9uID0gdGhpcy5vcHRpb25zRm9ybS5nZXRBdHRyaWJ1dGUoICdhY3Rpb24nICk7XG5cdFx0YWN0aXZlRm9ybS5tZXRob2QgPSB0aGlzLm9wdGlvbnNGb3JtLm1ldGhvZDtcblx0XHRhY3RpdmVGb3JtLmFwcGVuZENoaWxkKCBhY3RpdmVUYWJsZS5jbG9uZU5vZGUoIHRydWUgKSApO1xuXG5cdFx0Y29uc3QgYWN0aXZlSW5wdXRzID0gWyAuLi5hY3RpdmVUYWJsZS5xdWVyeVNlbGVjdG9yQWxsKCAnaW5wdXQnICkgXTtcblx0XHRhY3RpdmVJbnB1dHMubWFwKCAoIGlucHV0ICkgPT4ge1xuXHRcdFx0cmV0dXJuICggYWN0aXZlRm9ybS5xdWVyeVNlbGVjdG9yKCAnIycgKyBpbnB1dC5pZCApLnZhbHVlID1cblx0XHRcdFx0aW5wdXQudmFsdWUgKTtcblx0XHR9ICk7XG5cblx0XHRjb25zdCBoaWRkZW5JbnB1dHMgPSBbXG5cdFx0XHQuLi50aGlzLm9wdGlvbnNGb3JtLnF1ZXJ5U2VsZWN0b3JBbGwoICdpbnB1dFt0eXBlPVwiaGlkZGVuXCJdJyApLFxuXHRcdF07XG5cdFx0aGlkZGVuSW5wdXRzLm1hcCggKCBpbnB1dCApID0+IHtcblx0XHRcdHJldHVybiBhY3RpdmVGb3JtLmFwcGVuZENoaWxkKCBpbnB1dC5jbG9uZU5vZGUoIHRydWUgKSApO1xuXHRcdH0gKTtcblx0XHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKCBhY3RpdmVGb3JtICk7XG5cblx0XHRyZXR1cm4gZmV0Y2goIHRoaXMub3B0aW9uc0Zvcm0uZ2V0QXR0cmlidXRlKCAnYWN0aW9uJyApLCB7XG5cdFx0XHRtZXRob2Q6IGFjdGl2ZUZvcm0ubWV0aG9kLFxuXHRcdFx0Ym9keTogbmV3IFVSTFNlYXJjaFBhcmFtcyggWyAuLi5uZXcgRm9ybURhdGEoIGFjdGl2ZUZvcm0gKSBdICksXG5cdFx0fSApXG5cdFx0XHQudGhlbiggKCByZXNwb25zZSApID0+IHtcblx0XHRcdFx0aWYgKCByZXNwb25zZS5vayApIHtcblx0XHRcdFx0XHR0aGlzLnNob3dNZXNzYWdlKFxuXHRcdFx0XHRcdFx0dGhpcy5zdWNjZXNzTWVzc2FnZSxcblx0XHRcdFx0XHRcdHRoaXMub3B0aW9uc1NhdmVTdWNjZXNzTWVzc2FnZVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0dGhpcy50YWJsZXNEYXRhID0gdGhpcy5nZXRUYWJsZXNEYXRhKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5zaG93TWVzc2FnZShcblx0XHRcdFx0XHRcdHRoaXMuZXJyb3JNZXNzYWdlLFxuXHRcdFx0XHRcdFx0dGhpcy5vcHRpb25zU2F2ZUVycm9yTWVzc2FnZVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuXHRcdFx0fSApXG5cdFx0XHQuZmluYWxseSggKCkgPT4ge1xuXHRcdFx0XHRhY3RpdmVGb3JtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGFjdGl2ZUZvcm0gKTtcblx0XHRcdFx0dGhpcy5zZXRTdWJtaXRTdGF0dXMoKTtcblx0XHRcdH0gKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgdGFibGUgZGF0YS5cblx0ICpcblx0ICogQHBhcmFtIHtFbGVtZW50fSB0YWJsZSBUYWJsZS5cblx0ICogQHJldHVybiB7e31bXX0gVGFibGUgZGF0YS5cblx0ICovXG5cdGdldFRhYmxlRGF0YSggdGFibGUgKSB7XG5cdFx0Y29uc3QgaW5wdXRzID0gWyAuLi50YWJsZS5xdWVyeVNlbGVjdG9yQWxsKCAnaW5wdXQnICkgXTtcblxuXHRcdGNvbnN0IGRhdGEgPSB7fTtcblx0XHRpbnB1dHMuZm9yRWFjaCggKCBpbnB1dCApID0+IHtcblx0XHRcdGNvbnN0IGxhYmVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihcblx0XHRcdFx0dGhpcy5PUFRJT05TX0ZPUk1fU0VMRUNUT1IgKyAnIGxhYmVsW2Zvcj1cIicgKyBpbnB1dC5pZCArICdcIl0nXG5cdFx0XHQpO1xuXG5cdFx0XHRkYXRhWyBsYWJlbC5pbm5lckhUTUwgXSA9IGlucHV0LnZhbHVlO1xuXHRcdH0gKTtcblxuXHRcdHJldHVybiBkYXRhO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBkYXRhIGZyb20gYWxsIHRhYmxlcy5cblx0ICpcblx0ICogQHJldHVybiB7e31bXVtdfSBEYXRhIGZyb20gYWxsIHRhYmxlcy5cblx0ICovXG5cdGdldFRhYmxlc0RhdGEoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0VGFibGVzKCkubWFwKCAoIHRhYmxlICkgPT4ge1xuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0VGFibGVEYXRhKCB0YWJsZSApO1xuXHRcdH0gKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgYWN0aXZlIHRhYmxlIGRhdGEuXG5cdCAqXG5cdCAqIEByZXR1cm4ge3t9W119IEFjdGl2ZSB0YWJsZSBkYXRhLlxuXHQgKi9cblx0Z2V0QWN0aXZlVGFibGVEYXRhKCkge1xuXHRcdHJldHVybiB0aGlzLmdldFRhYmxlRGF0YSggdGhpcy5nZXRBY3RpdmVUYWJsZSgpICk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkIHdyYXBwZXIuXG5cdCAqL1xuXHRhZGRXcmFwcGVyKCkge1xuXHRcdHRoaXMud3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICd1bCcgKTtcblx0XHR0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmFkZCggJ25hdi10YWItd3JhcHBlcicgKTtcblx0XHR0aGlzLm9wdGlvbnNGb3JtLmluc2VydEJlZm9yZShcblx0XHRcdHRoaXMud3JhcHBlcixcblx0XHRcdHRoaXMub3B0aW9uc0Zvcm0uZmlyc3RDaGlsZFxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkIG1lc3NhZ2UgbGluZS5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IGlkIE1lc3NhZ2UgaWQuXG5cdCAqIEByZXR1cm4ge0hUTUxEaXZFbGVtZW50fSBNZXNzYWdlIGxpbmUuXG5cdCAqL1xuXHRhZGRNZXNzYWdlTGluZSggaWQgKSB7XG5cdFx0Y29uc3QgbWVzc2FnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdkaXYnICk7XG5cdFx0bWVzc2FnZS5pZCA9IGlkO1xuXHRcdHRoaXMub3B0aW9uc0Zvcm0uaW5zZXJ0QmVmb3JlKCBtZXNzYWdlLCB0aGlzLm9wdGlvbnNGb3JtLmZpcnN0Q2hpbGQgKTtcblxuXHRcdHJldHVybiBtZXNzYWdlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZCBzdWNjZXNzIGFuZCBlcnJvciBtZXNzYWdlIGxpbmVzLlxuXHQgKi9cblx0YWRkTWVzc2FnZUxpbmVzKCkge1xuXHRcdHRoaXMuc3VjY2Vzc01lc3NhZ2UgPSB0aGlzLmFkZE1lc3NhZ2VMaW5lKCAnY3RsLXN1Y2Nlc3MnICk7XG5cdFx0dGhpcy5lcnJvck1lc3NhZ2UgPSB0aGlzLmFkZE1lc3NhZ2VMaW5lKCAnY3RsLWVycm9yJyApO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1ha2UgdGFicyB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgZm9ybS5cblx0ICovXG5cdG1vdmVUYWJzKCkge1xuXHRcdGNvbnN0IHRhYnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCAnLmN0bC1zZXR0aW5ncy10YWJzJyApO1xuXHRcdGlmICggdGFicyApIHtcblx0XHRcdHRoaXMub3B0aW9uc0Zvcm0uaW5zZXJ0QmVmb3JlKCB0YWJzLCB0aGlzLm9wdGlvbnNGb3JtLmZpcnN0Q2hpbGQgKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQWRkIGVkaXQgbGFiZWwgaW5wdXQuXG5cdCAqL1xuXHRhZGRFZGl0TGFiZWxJbnB1dCgpIHtcblx0XHR0aGlzLmVkaXRMYWJlbElucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2lucHV0JyApO1xuXHRcdHRoaXMuZWRpdExhYmVsSW5wdXQuaWQgPSB0aGlzLkVESVRfTEFCRUxfSUQ7XG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoIHRoaXMuZWRpdExhYmVsSW5wdXQgKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBIaWRlIGVkaXQgbGFiZWwgaW5wdXQuXG5cdCAqL1xuXHRoaWRlRWRpdExhYmVsSW5wdXQoKSB7XG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdHRoaXMuZWRpdExhYmVsSW5wdXQuY2xhc3NMaXN0LnJlbW92ZSggdGhpcy5FRElUX0xBQkVMX0VSUk9SX0NMQVNTICk7XG5cdFx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggdGhpcy5lZGl0TGFiZWxJbnB1dCApO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBsYXN0IGNlbGwgaW4gYWN0aXZlIHRhYmxlLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBMYXN0IGNlbGwuXG5cdCAqL1xuXHRnZXRMYXN0Q2VsbCgpIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihcblx0XHRcdHRoaXMuT1BUSU9OU19GT1JNX1NFTEVDVE9SICtcblx0XHRcdFx0JyAuJyArXG5cdFx0XHRcdHRoaXMuQUNUSVZFX1RBQkxFX0NMQVNTICtcblx0XHRcdFx0JyAuJyArXG5cdFx0XHRcdHRoaXMuUExVU19DTEFTU1xuXHRcdCkucHJldmlvdXNFbGVtZW50U2libGluZztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGQgbmV3IGNlbGwgdG8gdGhlIGFjdGl2ZSB0YWJsZS5cblx0ICovXG5cdGFkZENlbGwoKSB7XG5cdFx0bGV0IGxhc3RDZWxsID0gdGhpcy5nZXRMYXN0Q2VsbCgpO1xuXHRcdGxhc3RDZWxsLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKFxuXHRcdFx0bGFzdENlbGwuY2xvbmVOb2RlKCB0cnVlICksXG5cdFx0XHRsYXN0Q2VsbC5uZXh0RWxlbWVudFNpYmxpbmdcblx0XHQpO1xuXG5cdFx0bGFzdENlbGwgPSB0aGlzLmdldExhc3RDZWxsKCk7XG5cdFx0Y29uc3QgbGFiZWwgPSBsYXN0Q2VsbC5xdWVyeVNlbGVjdG9yKCAnbGFiZWwnICk7XG5cdFx0Y29uc3QgaW5wdXQgPSBsYXN0Q2VsbC5xdWVyeVNlbGVjdG9yKCAnaW5wdXQnICk7XG5cblx0XHRjb25zdCBpZEFyciA9IGlucHV0LmlkLnNwbGl0KCAnLScgKTtcblx0XHRjb25zdCBuZXdJZCA9IGlkQXJyWyAwIF0gKyAnLScgKyAoIHBhcnNlSW50KCBpZEFyclsgMSBdICkgKyAxICk7XG5cblx0XHRsYWJlbC5odG1sRm9yID0gbmV3SWQ7XG5cdFx0bGFiZWwuaW5uZXJIVE1MID0gJyc7XG5cblx0XHRpbnB1dC5pZCA9IG5ld0lkO1xuXHRcdGlucHV0LnZhbHVlID0gJyc7XG5cdFx0aW5wdXQuc2V0QXR0cmlidXRlKCAndmFsdWUnLCAnJyApO1xuXHRcdHRoaXMucmVwbGFjZU5hbWUoIGlucHV0LCAnJyApO1xuXG5cdFx0dGhpcy5iaW5kRXZlbnRzKCk7XG5cblx0XHR0aGlzLmVkaXRMYWJlbCggbGFiZWwgKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBIaWRlIGNvbnZlcnNpb24gdGFibGVzIGV4Y2VwdCB0aGUgZmlyc3Qgb25lLlxuXHQgKiBDcmVhdGUgbmF2aWdhdGlvbiB0YWJzLlxuXHQgKi9cblx0aGlkZVRhYmxlcygpIHtcblx0XHRsZXQgY3VycmVudEluZGV4ID0gMDtcblxuXHRcdHRoaXMuZ2V0VGFibGVzKCkubWFwKCAoIHRhYmxlLCBpbmRleCApID0+IHtcblx0XHRcdHRhYmxlLmNsYXNzTGlzdC5hZGQoICdjdGwtdGFibGUnICk7XG5cblx0XHRcdGlmICggdGhpcy5DVVJSRU5UX1NUVUJfSUQgPT09IHRhYmxlLnByZXZpb3VzRWxlbWVudFNpYmxpbmcuaWQgKSB7XG5cdFx0XHRcdGN1cnJlbnRJbmRleCA9IGluZGV4O1xuXHRcdFx0XHR0YWJsZS5jbGFzc0xpc3QuYWRkKCB0aGlzLkFDVElWRV9UQUJMRV9DTEFTUyApO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCBwbHVzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2RpdicgKTtcblx0XHRcdHBsdXMuY2xhc3NMaXN0LmFkZCggdGhpcy5QTFVTX0NMQVNTICk7XG5cdFx0XHRwbHVzLmlubmVySFRNTCA9IHRoaXMucGx1c0J1dHRvbjtcblx0XHRcdHRhYmxlLnF1ZXJ5U2VsZWN0b3IoICd0ZCcgKS5hcHBlbmRDaGlsZCggcGx1cyApO1xuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9ICk7XG5cblx0XHR0aGlzLmdldEhlYWRlcnMoKS5tYXAoICggaGVhZGVyLCBpbmRleCApID0+IHtcblx0XHRcdGhlYWRlci5jbGFzc0xpc3QuYWRkKCAnbmF2LXRhYicgKTtcblx0XHRcdGhlYWRlci5kYXRhc2V0LmluZGV4ID0gaW5kZXg7XG5cblx0XHRcdHRoaXMud3JhcHBlci5hcHBlbmRDaGlsZCggaGVhZGVyICk7XG5cdFx0XHRpZiAoIGluZGV4ID09PSBjdXJyZW50SW5kZXggKSB7XG5cdFx0XHRcdGhlYWRlci5jbGFzc0xpc3QuYWRkKCB0aGlzLkNVUlJFTlRfTkFWX1RBQl9DTEFTUyApO1xuXHRcdFx0XHRoZWFkZXIuY2xhc3NMaXN0LmFkZCggdGhpcy5BQ1RJVkVfTkFWX1RBQl9DTEFTUyApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9ICk7XG5cdH1cblxuXHQvKipcblx0ICogQmluZCBldmVudHMgdG8gbWV0aG9kcy5cblx0ICovXG5cdGJpbmRFdmVudHMoKSB7XG5cdFx0dGhpcy5nZXRIZWFkZXJzKCkubWFwKCAoIGhlYWRlciwgaSwgaGVhZGVycyApID0+IHtcblx0XHRcdGhlYWRlci5vbmNsaWNrID0gKCBldmVudCApID0+IHtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuXHRcdFx0XHRjb25zdCBpbmRleCA9IGV2ZW50LnRhcmdldC5kYXRhc2V0LmluZGV4O1xuXHRcdFx0XHRjb25zdCBhY3RpdmVJbmRleCA9IHRoaXMuZ2V0QWN0aXZlSW5kZXgoKTtcblxuXHRcdFx0XHRpZiAoIGluZGV4ID09PSBhY3RpdmVJbmRleCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLnNhdmVBY3RpdmVUYWJsZSgpO1xuXG5cdFx0XHRcdGhlYWRlcnMubWFwKCAoIGFIZWFkZXIgKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIGFIZWFkZXIuY2xhc3NMaXN0LnJlbW92ZShcblx0XHRcdFx0XHRcdHRoaXMuQUNUSVZFX05BVl9UQUJfQ0xBU1Ncblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHRcdGhlYWRlcnNbIGluZGV4IF0uY2xhc3NMaXN0LmFkZCggdGhpcy5BQ1RJVkVfTkFWX1RBQl9DTEFTUyApO1xuXG5cdFx0XHRcdGNvbnN0IHRhYmxlcyA9IHRoaXMuZ2V0VGFibGVzKCk7XG5cdFx0XHRcdHRhYmxlcy5tYXAoICggdGFibGUgKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHRhYmxlLmNsYXNzTGlzdC5yZW1vdmUoIHRoaXMuQUNUSVZFX1RBQkxFX0NMQVNTICk7XG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0dGFibGVzWyBpbmRleCBdLmNsYXNzTGlzdC5hZGQoIHRoaXMuQUNUSVZFX1RBQkxFX0NMQVNTICk7XG5cblx0XHRcdFx0dGhpcy5zZXRTdWJtaXRTdGF0dXMoKTtcblxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9O1xuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9ICk7XG5cblx0XHR0aGlzLmdldElucHV0cygpLm1hcCggKCBpbnB1dCApID0+IHtcblx0XHRcdGlucHV0Lm9uaW5wdXQgPSAoKSA9PiB7XG5cdFx0XHRcdHRoaXMuc2V0U3VibWl0U3RhdHVzKCk7XG5cdFx0XHR9O1xuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9ICk7XG5cblx0XHR0aGlzLmdldExhYmVscygpLm1hcCggKCBsYWJlbCApID0+IHtcblx0XHRcdGxhYmVsLm9uY2xpY2sgPSAoIGV2ZW50ICkgPT4ge1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR0aGlzLmVkaXRMYWJlbCggZXZlbnQudGFyZ2V0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH07XG5cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH0gKTtcblxuXHRcdHRoaXMuZWRpdExhYmVsSW5wdXQub25ibHVyID0gKCkgPT4ge1xuXHRcdFx0dGhpcy5zYXZlTGFiZWwoKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5vbmtleXVwID0gKCBlICkgPT4ge1xuXHRcdFx0aWYgKCAnRXNjYXBlJyA9PT0gZS5rZXkgKSB7XG5cdFx0XHRcdHRoaXMuc2F2ZUxhYmVsKCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggJ0VudGVyJyA9PT0gZS5rZXkgKSB7XG5cdFx0XHRcdHRoaXMuc2F2ZUxhYmVsKCk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0UGx1c0J1dHRvbnMoKS5tYXAoICggcGx1cyApID0+IHtcblx0XHRcdHBsdXMub25jbGljayA9ICggZXZlbnQgKSA9PiB7XG5cdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdHRoaXMuYWRkQ2VsbCggZXZlbnQudGFyZ2V0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH07XG5cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH0gKTtcblxuXHRcdHRoaXMuc3VibWl0QnV0dG9uLm9uY2xpY2sgPSAoIGV2ZW50ICkgPT4ge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdHRoaXMuc2F2ZUFjdGl2ZVRhYmxlKCk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFZGl0IGxhYmVsLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGxhYmVsIExhYmVsIHRvIGVkaXQuXG5cdCAqL1xuXHRlZGl0TGFiZWwoIGxhYmVsICkge1xuXHRcdGxhYmVsLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoIHRoaXMuZWRpdExhYmVsSW5wdXQgKTtcblx0XHR0aGlzLmVkaXRMYWJlbElucHV0LnZhbHVlID0gbGFiZWwuaW5uZXJIVE1MO1xuXG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5jbGFzc0xpc3QucmVtb3ZlKCB0aGlzLkVESVRfTEFCRUxfRVJST1JfQ0xBU1MgKTtcblx0XHR0aGlzLmVkaXRMYWJlbElucHV0LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXHRcdHRoaXMuZWRpdExhYmVsSW5wdXQuZm9jdXMoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBJcyBuZXcgdmFsdWUgb2YgZWRpdGVkIGxhYmVsIHVuaXF1ZSBpbiBhY3RpdmUgdGFibGUuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuZXdWYWx1ZSBOZXcgVmFsdWUgZnJvbSBlZGl0ZWQgbGFiZWwuXG5cdCAqIEByZXR1cm4geyp9IElmIG5ldyB2YWx1ZSBvZiBlZGl0ZWQgbGFiZWwgaXMgdW5pcXVlIGluIGFjdGl2ZSB0YWJsZS5cblx0ICovXG5cdGlzVW5pcXVlTGFiZWwoIG5ld1ZhbHVlICkge1xuXHRcdHJldHVybiBbIC4uLnRoaXMuZ2V0QWN0aXZlVGFibGUoKS5xdWVyeVNlbGVjdG9yQWxsKCAnbGFiZWwnICkgXS5yZWR1Y2UoXG5cdFx0XHQoIGFjYywgbGFiZWwgKSA9PiB7XG5cdFx0XHRcdHJldHVybiBhY2MgJiYgbGFiZWwuaW5uZXJIVE1MICE9PSBuZXdWYWx1ZTtcblx0XHRcdH0sXG5cdFx0XHR0cnVlXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTYXZlIG1vZGlmaWVkIGxhYmVsLlxuXHQgKlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGNhbmNlbCBDYW5jZWwuXG5cdCAqL1xuXHRzYXZlTGFiZWwoIGNhbmNlbCA9IGZhbHNlICkge1xuXHRcdGlmICggJ25vbmUnID09PSB0aGlzLmVkaXRMYWJlbElucHV0LnN0eWxlLmRpc3BsYXkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgbmV3VmFsdWUgPSB0aGlzLmVkaXRMYWJlbElucHV0LnZhbHVlLnRyaW0oKTtcblxuXHRcdGlmICggJycgPT09IG5ld1ZhbHVlICkge1xuXHRcdFx0Y29uc3QgZWRpdGVkQ2VsbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCB0aGlzLkVESVRfTEFCRUxfSUQgKVxuXHRcdFx0XHQucGFyZW50RWxlbWVudDtcblx0XHRcdHRoaXMuaGlkZUVkaXRMYWJlbElucHV0KCk7XG5cdFx0XHRlZGl0ZWRDZWxsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGVkaXRlZENlbGwgKTtcblx0XHRcdHRoaXMuc2V0U3VibWl0U3RhdHVzKCk7XG5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBsYWJlbCA9IHRoaXMuZWRpdExhYmVsSW5wdXQucGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yKCAnbGFiZWwnICk7XG5cdFx0aWYgKCBjYW5jZWwgfHwgbmV3VmFsdWUgPT09IGxhYmVsLmlubmVySFRNTCApIHtcblx0XHRcdHRoaXMuaGlkZUVkaXRMYWJlbElucHV0KCk7XG5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoICEgdGhpcy5pc1VuaXF1ZUxhYmVsKCBuZXdWYWx1ZSApICkge1xuXHRcdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5jbGFzc0xpc3QuYWRkKCB0aGlzLkVESVRfTEFCRUxfRVJST1JfQ0xBU1MgKTtcblxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGlucHV0ID0gdGhpcy5lZGl0TGFiZWxJbnB1dC5wYXJlbnROb2RlLnF1ZXJ5U2VsZWN0b3IoICdpbnB1dCcgKTtcblxuXHRcdHRoaXMuaGlkZUVkaXRMYWJlbElucHV0KCk7XG5cblx0XHRsYWJlbC5pbm5lckhUTUwgPSBuZXdWYWx1ZTtcblx0XHR0aGlzLnJlcGxhY2VOYW1lKCBpbnB1dCwgbmV3VmFsdWUgKTtcblxuXHRcdHRoaXMuc2V0U3VibWl0U3RhdHVzKCk7XG5cdH1cblxuXHQvKipcblx0ICogUmVwbGFjZSBpbnB1dCBuYW1lIGFjY29yZGluZyB0byB0aGUgbmV3IGxhYmVsIHZhbHVlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGlucHV0IElucHV0XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuZXdWYWx1ZSBOZXcgbGFiZWwgdmFsdWVcblx0ICovXG5cdHJlcGxhY2VOYW1lKCBpbnB1dCwgbmV3VmFsdWUgKSB7XG5cdFx0Ly8gbm9pbnNwZWN0aW9uIEpTVW5yZXNvbHZlZFZhcmlhYmxlXG5cdFx0aW5wdXQubmFtZSA9IGlucHV0Lm5hbWUucmVwbGFjZShcblx0XHRcdC8oLitcXFsuK10pXFxbLipdL2csXG5cdFx0XHQnJDFbJyArIG5ld1ZhbHVlICsgJ10nXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDbGVhciBtZXNzYWdlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0hUTUxEaXZFbGVtZW50fSBtZXNzYWdlIE1lc3NhZ2UuXG5cdCAqL1xuXHRjbGVhck1lc3NhZ2UoIG1lc3NhZ2UgKSB7XG5cdFx0bWVzc2FnZS5pbm5lckhUTUwgPSAnJztcblx0XHRtZXNzYWdlLmNsYXNzTGlzdC5yZW1vdmUoICdhY3RpdmUnICk7XG5cdH1cblxuXHQvKipcblx0ICogQ2xlYXIgbWVzc2FnZXMuXG5cdCAqL1xuXHRjbGVhck1lc3NhZ2VzKCkge1xuXHRcdHRoaXMuY2xlYXJNZXNzYWdlKCB0aGlzLnN1Y2Nlc3NNZXNzYWdlICk7XG5cdFx0dGhpcy5jbGVhck1lc3NhZ2UoIHRoaXMuZXJyb3JNZXNzYWdlICk7XG5cdFx0Y2xlYXJUaW1lb3V0KCB0aGlzLm1zZ1RpbWVyICk7XG5cdH1cblxuXHQvKipcblx0ICogU2hvdyBtZXNzYWdlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0hUTUxEaXZFbGVtZW50fSBlbCBFbGVtZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBNZXNzYWdlLlxuXHQgKi9cblx0c2hvd01lc3NhZ2UoIGVsLCBtZXNzYWdlICkge1xuXHRcdGVsLmlubmVySFRNTCA9IG1lc3NhZ2U7XG5cdFx0ZWwuY2xhc3NMaXN0LmFkZCggJ2FjdGl2ZScgKTtcblxuXHRcdHRoaXMubXNnVGltZXIgPSBzZXRUaW1lb3V0KCAoKSA9PiB7XG5cdFx0XHR0aGlzLmNsZWFyTWVzc2FnZXMoKTtcblx0XHR9LCA1MDAwICk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVGFibGVzO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==
classes/class-settings.php DELETED
@@ -1,785 +0,0 @@
1
- <?php
2
- /**
3
- * Plugin Settings.
4
- *
5
- * @package cyr-to-lat
6
- */
7
-
8
- namespace Cyr_To_Lat;
9
-
10
- use Cyr_To_Lat\Symfony\Polyfill\Mbstring\Mbstring;
11
-
12
- /**
13
- * Class Settings
14
- *
15
- * @class Settings
16
- */
17
- class Settings {
18
-
19
- /**
20
- * Admin screen id.
21
- */
22
- const SCREEN_ID = 'settings_page_cyr-to-lat';
23
-
24
- /**
25
- * Option group.
26
- */
27
- const OPTION_GROUP = 'cyr_to_lat_group';
28
-
29
- /**
30
- * Option page.
31
- */
32
- const PAGE = 'cyr-to-lat';
33
-
34
- /**
35
- * Plugin options name.
36
- */
37
- const OPTION_NAME = 'cyr_to_lat_settings';
38
-
39
- /**
40
- * Script handle.
41
- */
42
- const HANDLE = 'cyr-to-lat-settings';
43
-
44
- /**
45
- * Script localization object.
46
- */
47
- const OBJECT = 'Cyr2LatSettingsObject';
48
-
49
- /**
50
- * Form fields.
51
- *
52
- * @var array
53
- */
54
- public $form_fields;
55
-
56
- /**
57
- * Plugin options.
58
- *
59
- * @var array
60
- */
61
- public $settings;
62
-
63
- /**
64
- * Served locales.
65
- *
66
- * @var array
67
- */
68
- protected $locales = [];
69
-
70
- /**
71
- * Settings constructor.
72
- */
73
- public function __construct() {
74
- add_action( 'plugins_loaded', [ $this, 'init' ] );
75
- }
76
-
77
- /**
78
- * Init plugin.
79
- */
80
- public function init() {
81
- $this->load_plugin_textdomain();
82
- $this->init_form_fields();
83
- $this->init_settings();
84
- $this->init_hooks();
85
- }
86
-
87
- /**
88
- * Init class hooks.
89
- */
90
- public function init_hooks() {
91
- add_filter(
92
- 'plugin_action_links_' . plugin_basename( constant( 'CYR_TO_LAT_FILE' ) ),
93
- [ $this, 'add_settings_link' ],
94
- 10,
95
- 4
96
- );
97
-
98
- add_action( 'admin_menu', [ $this, 'add_settings_page' ] );
99
- add_action( 'current_screen', [ $this, 'setup_sections' ] );
100
- add_action( 'current_screen', [ $this, 'setup_fields' ] );
101
-
102
- add_filter( 'pre_update_option_' . self::OPTION_NAME, [ $this, 'pre_update_option_filter' ], 10, 3 );
103
-
104
- add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
105
- add_action( 'in_admin_header', [ $this, 'in_admin_header' ] );
106
- }
107
-
108
- /**
109
- * Add link to plugin setting page on plugins page.
110
- *
111
- * @param array $actions An array of plugin action links. By default this can include 'activate',
112
- * 'deactivate', and 'delete'. With Multisite active this can also include
113
- * 'network_active' and 'network_only' items.
114
- * @param string $plugin_file Path to the plugin file relative to the plugins directory.
115
- * @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
116
- * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive',
117
- * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
118
- *
119
- * @return array|mixed Plugin links
120
- * @noinspection PhpUnusedParameterInspection
121
- */
122
- public function add_settings_link( $actions, $plugin_file, $plugin_data, $context ) {
123
- $ctl_actions = [
124
- 'settings' =>
125
- '<a href="' . admin_url( 'options-general.php?page=' . self::PAGE ) .
126
- '" aria-label="' . esc_attr__( 'View Cyr To Lat settings', 'cyr2lat' ) . '">' .
127
- esc_html__( 'Settings', 'cyr2lat' ) . '</a>',
128
- ];
129
-
130
- return array_merge( $ctl_actions, $actions );
131
- }
132
-
133
- /**
134
- * Init locales.
135
- */
136
- protected function init_locales() {
137
- if ( ! empty( $this->locales ) ) {
138
- return;
139
- }
140
-
141
- $this->locales = [
142
- 'iso9' => [
143
- 'label' => __( 'ISO9 Table', 'cyr2lat' ),
144
- ],
145
- 'bel' => [
146
- 'label' => __( 'bel Table', 'cyr2lat' ),
147
- ],
148
- 'uk' => [
149
- 'label' => __( 'uk Table', 'cyr2lat' ),
150
- ],
151
- 'bg_BG' => [
152
- 'label' => __( 'bg_BG Table', 'cyr2lat' ),
153
- ],
154
- 'mk_MK' => [
155
- 'label' => __( 'mk_MK Table', 'cyr2lat' ),
156
- ],
157
- 'sr_RS' => [
158
- 'label' => __( 'sr_RS Table', 'cyr2lat' ),
159
- ],
160
- 'el' => [
161
- 'label' => __( 'el Table', 'cyr2lat' ),
162
- ],
163
- 'hy' => [
164
- 'label' => __( 'hy Table', 'cyr2lat' ),
165
- ],
166
- 'ka_GE' => [
167
- 'label' => __( 'ka_GE Table', 'cyr2lat' ),
168
- ],
169
- 'kk' => [
170
- 'label' => __( 'kk Table', 'cyr2lat' ),
171
- ],
172
- 'he_IL' => [
173
- 'label' => __( 'he_IL Table', 'cyr2lat' ),
174
- ],
175
- 'zh_CN' => [
176
- 'label' => __( 'zh_CN Table', 'cyr2lat' ),
177
- ],
178
- ];
179
- }
180
-
181
- /**
182
- * Get current locale.
183
- *
184
- * @return string
185
- */
186
- private function get_current_locale() {
187
- $current_locale = get_locale();
188
-
189
- return array_key_exists( $current_locale, $this->locales ) ? $current_locale : 'iso9';
190
- }
191
-
192
- /**
193
- * Init options form fields.
194
- */
195
- public function init_form_fields() {
196
- $this->init_locales();
197
-
198
- $current_locale = $this->get_current_locale();
199
-
200
- $this->form_fields = [];
201
-
202
- foreach ( $this->locales as $locale => $info ) {
203
- $current = ( $locale === $current_locale ) ? '<br>' . __( '(current)', 'cyr2lat' ) : '';
204
-
205
- $this->form_fields[ $locale ] = [
206
- 'label' => $info['label'] . $current,
207
- 'section' => $locale . '_section',
208
- 'type' => 'table',
209
- 'placeholder' => '',
210
- 'helper' => '',
211
- 'supplemental' => '',
212
- 'default' => Conversion_Tables::get( $locale ),
213
- ];
214
- }
215
- }
216
-
217
- /**
218
- * Initialise Settings.
219
- *
220
- * Store all settings in a single database entry
221
- * and make sure the $settings array is either the default
222
- * or the settings stored in the database.
223
- */
224
- public function init_settings() {
225
- $this->settings = get_option( self::OPTION_NAME, null );
226
-
227
- $form_fields = $this->get_form_fields();
228
-
229
- // If there are no settings defined, use defaults.
230
- if ( ! is_array( $this->settings ) ) {
231
- $this->settings = array_merge( array_fill_keys( array_keys( $form_fields ), '' ), wp_list_pluck( $form_fields, 'default' ) );
232
- } else {
233
- $this->settings = array_merge( wp_list_pluck( $form_fields, 'default' ), $this->settings );
234
- }
235
- }
236
-
237
- /**
238
- * Get the form fields after they are initialized.
239
- *
240
- * @return array of options
241
- */
242
- public function get_form_fields() {
243
- if ( empty( $this->form_fields ) ) {
244
- $this->init_form_fields();
245
- }
246
-
247
- return array_map( [ $this, 'set_defaults' ], $this->form_fields );
248
- }
249
-
250
- /**
251
- * Set default required properties for each field.
252
- *
253
- * @param array $field Settings field.
254
- *
255
- * @return array
256
- */
257
- protected function set_defaults( $field ) {
258
- if ( ! isset( $field['default'] ) ) {
259
- $field['default'] = '';
260
- }
261
-
262
- return $field;
263
- }
264
-
265
- /**
266
- * Add settings page to the menu.
267
- */
268
- public function add_settings_page() {
269
- $parent_slug = 'options-general.php';
270
- $page_title = __( 'Cyr To Lat', 'cyr2lat' );
271
- $menu_title = __( 'Cyr To Lat', 'cyr2lat' );
272
- $capability = 'manage_options';
273
- $slug = self::PAGE;
274
- $callback = [ $this, 'settings_page' ];
275
- add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $slug, $callback );
276
- }
277
-
278
- /**
279
- * Settings page.
280
- */
281
- public function settings_page() {
282
- if ( ! $this->is_options_screen() ) {
283
- return;
284
- }
285
-
286
- ?>
287
- <div class="wrap">
288
- <h2 id="title">
289
- <?php
290
- // Admin panel title.
291
- echo( esc_html( __( 'Cyr To Lat Plugin Options', 'cyr2lat' ) ) );
292
- ?>
293
- </h2>
294
-
295
- <form id="ctl-options" action="<?php echo esc_url( admin_url( 'options.php' ) ); ?>" method="post">
296
- <?php
297
- do_settings_sections( self::PAGE ); // Sections with options.
298
- settings_fields( self::OPTION_GROUP ); // Hidden protection fields.
299
- submit_button();
300
- ?>
301
- </form>
302
-
303
- <form id="ctl-convert-existing-slugs" action="" method="post">
304
- <input type="hidden" name="ctl-convert" />
305
- <?php
306
- wp_nonce_field( self::OPTION_GROUP . '-options' );
307
- submit_button( __( 'Convert Existing Slugs', 'cyr2lat' ), 'secondary', 'ctl-convert-button' );
308
- ?>
309
- </form>
310
-
311
- <div id="appreciation">
312
- <h2>
313
- <?php echo esc_html( __( 'Your appreciation', 'cyr2lat' ) ); ?>
314
- </h2>
315
- <a
316
- target="_blank"
317
- href="https://wordpress.org/support/view/plugin-reviews/cyr2lat?rate=5#postform">
318
- <?php echo esc_html( __( 'Leave a ★★★★★ plugin review on WordPress.org', 'cyr2lat' ) ); ?>
319
- </a>
320
- </div>
321
- </div>
322
- <?php
323
- }
324
-
325
- /**
326
- * Setup settings sections.
327
- */
328
- public function setup_sections() {
329
- if ( ! $this->is_options_screen() ) {
330
- return;
331
- }
332
-
333
- foreach ( $this->form_fields as $form_field ) {
334
- add_settings_section(
335
- $form_field['section'],
336
- $form_field['label'],
337
- [ $this, 'section_callback' ],
338
- self::PAGE
339
- );
340
- }
341
- }
342
-
343
- /**
344
- * Section callback.
345
- *
346
- * @param array $arguments Section arguments.
347
- */
348
- public function section_callback( $arguments ) {
349
- $locale = str_replace( '_section', '', $arguments['id'] );
350
- if ( $this->get_current_locale() === $locale ) {
351
- echo '<div id="ctl-current"></div>';
352
- }
353
- }
354
-
355
- /**
356
- * Setup settings fields.
357
- */
358
- public function setup_fields() {
359
- if ( ! $this->is_options_screen() ) {
360
- return;
361
- }
362
-
363
- register_setting( self::OPTION_GROUP, self::OPTION_NAME );
364
-
365
- foreach ( $this->form_fields as $key => $field ) {
366
- $field['field_id'] = $key;
367
-
368
- add_settings_field(
369
- $key,
370
- $field['label'],
371
- [ $this, 'field_callback' ],
372
- self::PAGE,
373
- $field['section'],
374
- $field
375
- );
376
- }
377
- }
378
-
379
- /**
380
- * Output settings field.
381
- *
382
- * @param array $arguments Field arguments.
383
- */
384
- public function field_callback( $arguments ) {
385
- if ( ! isset( $arguments['field_id'] ) ) {
386
- return;
387
- }
388
-
389
- $value = $this->get_option( $arguments['field_id'] );
390
-
391
- // Check which type of field we want.
392
- switch ( $arguments['type'] ) {
393
- case 'text':
394
- case 'password':
395
- case 'number':
396
- printf(
397
- '<input name="%1$s[%2$s]" id="%2$s" type="%3$s" placeholder="%4$s" value="%5$s" class="regular-text" />',
398
- esc_html( self::OPTION_NAME ),
399
- esc_attr( $arguments['field_id'] ),
400
- esc_attr( $arguments['type'] ),
401
- esc_attr( $arguments['placeholder'] ),
402
- esc_html( $value )
403
- );
404
- break;
405
- case 'textarea':
406
- printf(
407
- '<textarea name="%1$s[%2$s]" id="%2$s" placeholder="%3$s" rows="5" cols="50">%4$s</textarea>',
408
- esc_html( self::OPTION_NAME ),
409
- esc_attr( $arguments['field_id'] ),
410
- esc_attr( $arguments['placeholder'] ),
411
- wp_kses_post( $value )
412
- );
413
- break;
414
- case 'checkbox':
415
- case 'radio':
416
- if ( 'checkbox' === $arguments['type'] ) {
417
- $arguments['options'] = [ 'yes' => '' ];
418
- }
419
-
420
- if ( ! empty( $arguments['options'] ) && is_array( $arguments['options'] ) ) {
421
- $options_markup = '';
422
- $iterator = 0;
423
- foreach ( $arguments['options'] as $key => $label ) {
424
- $iterator ++;
425
- $options_markup .= sprintf(
426
- '<label for="%2$s_%7$s"><input id="%2$s_%7$s" name="%1$s[%2$s]" type="%3$s" value="%4$s" %5$s /> %6$s</label><br/>',
427
- esc_html( self::OPTION_NAME ),
428
- $arguments['field_id'],
429
- $arguments['type'],
430
- $key,
431
- checked( $value, $key, false ),
432
- $label,
433
- $iterator
434
- );
435
- }
436
- printf(
437
- '<fieldset>%s</fieldset>',
438
- wp_kses(
439
- $options_markup,
440
- [
441
- 'label' => [
442
- 'for' => [],
443
- ],
444
- 'input' => [
445
- 'id' => [],
446
- 'name' => [],
447
- 'type' => [],
448
- 'value' => [],
449
- 'checked' => [],
450
- ],
451
- 'br' => [],
452
- ]
453
- )
454
- );
455
- }
456
- break;
457
- case 'select': // If it is a select dropdown.
458
- if ( ! empty( $arguments['options'] ) && is_array( $arguments['options'] ) ) {
459
- $options_markup = '';
460
- foreach ( $arguments['options'] as $key => $label ) {
461
- $options_markup .= sprintf(
462
- '<option value="%s" %s>%s</option>',
463
- $key,
464
- selected( $value, $key, false ),
465
- $label
466
- );
467
- }
468
- printf(
469
- '<select name="%1$s[%2$s]">%3$s</select>',
470
- esc_html( self::OPTION_NAME ),
471
- esc_html( $arguments['field_id'] ),
472
- wp_kses(
473
- $options_markup,
474
- [
475
- 'option' => [
476
- 'value' => [],
477
- 'selected' => [],
478
- ],
479
- ]
480
- )
481
- );
482
- }
483
- break;
484
- case 'multiple': // If it is a multiple select dropdown.
485
- if ( ! empty( $arguments['options'] ) && is_array( $arguments['options'] ) ) {
486
- $options_markup = '';
487
- foreach ( $arguments['options'] as $key => $label ) {
488
- $selected = '';
489
- if ( is_array( $value ) && in_array( $key, $value, true ) ) {
490
- $selected = selected( $key, $key, false );
491
- }
492
- $options_markup .= sprintf(
493
- '<option value="%s" %s>%s</option>',
494
- $key,
495
- $selected,
496
- $label
497
- );
498
- }
499
- printf(
500
- '<select multiple="multiple" name="%1$s[%2$s][]">%3$s</select>',
501
- esc_html( self::OPTION_NAME ),
502
- esc_html( $arguments['field_id'] ),
503
- wp_kses(
504
- $options_markup,
505
- [
506
- 'option' => [
507
- 'value' => [],
508
- 'selected' => [],
509
- ],
510
- ]
511
- )
512
- );
513
- }
514
- break;
515
- case 'table':
516
- if ( is_array( $value ) ) {
517
- $iterator = 0;
518
- foreach ( $value as $key => $cell_value ) {
519
- $id = $arguments['field_id'] . '-' . $iterator;
520
-
521
- echo '<div class="ctl-table-cell">';
522
- printf(
523
- '<label for="%1$s">%2$s</label>',
524
- esc_html( $id ),
525
- esc_html( $key )
526
- );
527
- printf(
528
- '<input name="%1$s[%2$s][%3$s]" id="%4$s" type="%5$s" placeholder="%6$s" value="%7$s" class="regular-text" />',
529
- esc_html( self::OPTION_NAME ),
530
- esc_attr( $arguments['field_id'] ),
531
- esc_attr( $key ),
532
- esc_attr( $id ),
533
- 'text',
534
- esc_attr( $arguments['placeholder'] ),
535
- esc_html( $cell_value )
536
- );
537
- echo '</div>';
538
-
539
- $iterator ++;
540
- }
541
- }
542
- break;
543
- default:
544
- break;
545
- }
546
-
547
- // If there is help text.
548
- $helper = $arguments['helper'];
549
- if ( $helper ) {
550
- printf( '<span class="helper"> %s</span>', esc_html( $helper ) );
551
- }
552
-
553
- // If there is supplemental text.
554
- $supplemental = $arguments['supplemental'];
555
- if ( $supplemental ) {
556
- printf( '<p class="description">%s</p>', esc_html( $supplemental ) );
557
- }
558
- }
559
-
560
- /**
561
- * Get plugin option.
562
- *
563
- * @param string $key Setting name.
564
- * @param mixed $empty_value Empty value for this setting.
565
- *
566
- * @return string|array The value specified for the option or a default value for the option.
567
- */
568
- public function get_option( $key, $empty_value = null ) {
569
- if ( empty( $this->settings ) ) {
570
- $this->init_settings();
571
- }
572
-
573
- // Get option default if unset.
574
- if ( ! isset( $this->settings[ $key ] ) ) {
575
- $form_fields = $this->get_form_fields();
576
- $this->settings[ $key ] = isset( $form_fields[ $key ] ) ? $this->get_field_default( $form_fields[ $key ] ) : '';
577
- }
578
-
579
- if ( '' === $this->settings[ $key ] && ! is_null( $empty_value ) ) {
580
- $this->settings[ $key ] = $empty_value;
581
- }
582
-
583
- return $this->settings[ $key ];
584
- }
585
-
586
- /**
587
- * Get a field default value. Defaults to '' if not set.
588
- *
589
- * @param array $field Setting field default value.
590
- *
591
- * @return string
592
- */
593
- protected function get_field_default( $field ) {
594
- return empty( $field['default'] ) ? '' : $field['default'];
595
- }
596
-
597
- /**
598
- * Set plugin option.
599
- *
600
- * @param string $key Setting name.
601
- * @param mixed $value Setting value.
602
- */
603
- public function set_option( $key, $value ) {
604
- if ( empty( $this->settings ) ) {
605
- $this->init_settings();
606
- }
607
-
608
- $this->settings[ $key ] = $value;
609
- update_option( self::OPTION_NAME, $this->settings );
610
- }
611
-
612
- /**
613
- * Filter plugin option update.
614
- *
615
- * @param mixed $value New option value.
616
- * @param mixed $old_value Old option value.
617
- * @param string $option Option name.
618
- *
619
- * @return mixed
620
- * @noinspection PhpUnusedParameterInspection
621
- */
622
- public function pre_update_option_filter( $value, $old_value, $option ) {
623
- if ( $value === $old_value ) {
624
- return $value;
625
- }
626
-
627
- // We save only one table, so merge with all existing tables.
628
- if ( is_array( $old_value ) && ( is_array( $value ) ) ) {
629
- $value = array_merge( $old_value, $value );
630
- }
631
-
632
- $form_fields = $this->get_form_fields();
633
- foreach ( $form_fields as $key => $form_field ) {
634
- if ( 'checkbox' === $form_field['type'] ) {
635
- $form_field_value = isset( $value[ $key ] ) ? $value[ $key ] : 'no';
636
- $form_field_value = '1' === $form_field_value || 'yes' === $form_field_value ? 'yes' : 'no';
637
- $value[ $key ] = $form_field_value;
638
- }
639
- }
640
-
641
- return $value;
642
- }
643
-
644
- /**
645
- * Enqueue class scripts.
646
- */
647
- public function admin_enqueue_scripts() {
648
- if ( ! $this->is_options_screen() ) {
649
- return;
650
- }
651
-
652
- wp_enqueue_script(
653
- self::HANDLE,
654
- constant( 'CYR_TO_LAT_URL' ) . '/dist/js/settings/app.js',
655
- [],
656
- constant( 'CYR_TO_LAT_VERSION' ),
657
- true
658
- );
659
-
660
- wp_localize_script(
661
- self::HANDLE,
662
- self::OBJECT,
663
- [
664
- 'optionsSaveSuccessMessage' => __( 'Options saved.', 'cyr2lat' ),
665
- 'optionsSaveErrorMessage' => __( 'Error saving options.', 'cyr2lat' ),
666
- ]
667
- );
668
-
669
- wp_enqueue_style(
670
- self::HANDLE,
671
- constant( 'CYR_TO_LAT_URL' ) . '/css/cyr-to-lat-admin.css',
672
- [],
673
- constant( 'CYR_TO_LAT_VERSION' )
674
- );
675
- }
676
-
677
- /**
678
- * Output convert confirmation popup.
679
- */
680
- public function in_admin_header() {
681
- if ( ! $this->is_options_screen() ) {
682
- return;
683
- }
684
-
685
- ?>
686
- <div id="ctl-confirm-popup">
687
- <div id="ctl-confirm-content">
688
- <p>
689
- <strong><?php esc_html_e( 'Important:', 'cyr2lat' ); ?></strong>
690
- <?php
691
- esc_html_e(
692
- 'This operation is irreversible. Please make sure that you have made backup copy of your database.',
693
- 'cyr2lat'
694
- );
695
- ?>
696
- </p>
697
- <p><?php esc_html_e( 'Are you sure to continue?', 'cyr2lat' ); ?></p>
698
- <div id="ctl-confirm-buttons">
699
- <input
700
- type="button" id="ctl-confirm-ok" class="button button-primary"
701
- value="<?php esc_html_e( 'OK', 'cyr2lat' ); ?>">
702
- <button
703
- type="button" id="ctl-confirm-cancel" class="button button-secondary">
704
- <?php esc_html_e( 'Cancel', 'cyr2lat' ); ?>
705
- </button>
706
- </div>
707
- </div>
708
- </div>
709
- <?php
710
- }
711
-
712
- /**
713
- * Load plugin text domain.
714
- */
715
- public function load_plugin_textdomain() {
716
- load_plugin_textdomain(
717
- 'cyr2lat',
718
- false,
719
- dirname( plugin_basename( constant( 'CYR_TO_LAT_FILE' ) ) ) . '/languages/'
720
- );
721
- }
722
-
723
- /**
724
- * Get transliteration table.
725
- *
726
- * @return array
727
- */
728
- public function get_table() {
729
- // List of locales: https://make.wordpress.org/polyglots/teams/.
730
- $locale = get_locale();
731
- $table = $this->get_option( $locale );
732
- if ( empty( $table ) ) {
733
- $table = $this->get_option( 'iso9' );
734
- }
735
-
736
- return $this->transpose_chinese_table( $table );
737
- }
738
-
739
- /**
740
- * Is current locale a Chinese one.
741
- *
742
- * @return bool
743
- */
744
- public function is_chinese_locale() {
745
- $chinese_locales = [ 'zh_CN', 'zh_HK', 'zh_SG', 'zh_TW' ];
746
-
747
- return in_array( get_locale(), $chinese_locales, true );
748
- }
749
-
750
- /**
751
- * Transpose Chinese table.
752
- *
753
- * Chinese tables are stored in different way, to show them compact.
754
- *
755
- * @param array $table Table.
756
- *
757
- * @return array
758
- */
759
- protected function transpose_chinese_table( $table ) {
760
- if ( ! $this->is_chinese_locale() ) {
761
- return $table;
762
- }
763
-
764
- $transposed_table = [];
765
- foreach ( $table as $key => $item ) {
766
- $hieroglyphs = Mbstring::mb_str_split( $item );
767
- foreach ( $hieroglyphs as $hieroglyph ) {
768
- $transposed_table[ $hieroglyph ] = $key;
769
- }
770
- }
771
-
772
- return $transposed_table;
773
- }
774
-
775
- /**
776
- * Is current admin screen the plugin options screen.
777
- *
778
- * @return bool
779
- */
780
- protected function is_options_screen() {
781
- $current_screen = get_current_screen();
782
-
783
- return $current_screen && ( 'options' === $current_screen->id || self::SCREEN_ID === $current_screen->id );
784
- }
785
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cyr-to-lat.php CHANGED
@@ -2,21 +2,23 @@
2
  /**
3
  * Cyr-To-Lat
4
  *
5
- * Plugin Name: Cyr-To-Lat
6
- * Plugin URI: https://wordpress.org/plugins/cyr2lat/
7
- * Description: Converts Cyrillic characters in post and term slugs to Latin characters. Useful for creating human-readable URLs. Based on the original plugin by Anton Skorobogatov.
8
- * Author: Sergey Biryukov, Mikhail Kobzarev, Igor Gergel
9
- * Author URI: https://profiles.wordpress.org/sergeybiryukov/
10
- * Requires at least: 5.1
11
- * Tested up to: 5.7
12
- * Version: 4.6.4
13
- * Stable tag: 4.6.4
14
- *
15
- * Text Domain: cyr2lat
16
- * Domain Path: /languages/
17
  *
18
- * @package cyr-to-lat
19
- * @author Sergey Biryukov, Mikhail Kobzarev, Igor Gergel
 
 
 
 
 
 
 
 
 
 
20
  */
21
 
22
  namespace Cyr_To_Lat;
@@ -34,7 +36,7 @@ if ( defined( 'CYR_TO_LAT_VERSION' ) ) {
34
  /**
35
  * Plugin version.
36
  */
37
- define( 'CYR_TO_LAT_VERSION', '4.6.4' );
38
 
39
  /**
40
  * Path to the plugin dir.
@@ -79,14 +81,9 @@ define( 'CYR_TO_LAT_REQUIRED_MAX_INPUT_VARS', 1000 );
79
  /**
80
  * Init plugin on plugin load.
81
  */
82
- require_once constant( 'CYR_TO_LAT_PATH' ) . '/vendor/autoload.php';
83
-
84
- $cyr_to_lat_requirements = new Requirements();
85
-
86
- if ( ! $cyr_to_lat_requirements->are_requirements_met() ) {
87
- return;
88
- }
89
 
90
  global $cyr_to_lat_plugin;
91
 
92
  $cyr_to_lat_plugin = new Main();
 
2
  /**
3
  * Cyr-To-Lat
4
  *
5
+ * @package cyr-to-lat
6
+ * @author Sergey Biryukov, Mikhail Kobzarev, Igor Gergel
7
+ * @license GPL-2.0-or-later
8
+ * @wordpress-plugin
 
 
 
 
 
 
 
 
9
  *
10
+ * Plugin Name: Cyr-To-Lat
11
+ * Plugin URI: https://wordpress.org/plugins/cyr2lat/
12
+ * Description: Converts Cyrillic characters in post and term slugs to Latin characters. Useful for creating human-readable URLs. Based on the original plugin by Anton Skorobogatov.
13
+ * Version: 5.0.0
14
+ * Requires at least: 5.1
15
+ * Requires PHP: 5.6.20
16
+ * Author: Sergey Biryukov, Mikhail Kobzarev, Igor Gergel
17
+ * Author URI: https://profiles.wordpress.org/sergeybiryukov/
18
+ * License: GPL v2 or later
19
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
20
+ * Text Domain: cyr2lat
21
+ * Domain Path: /languages/
22
  */
23
 
24
  namespace Cyr_To_Lat;
36
  /**
37
  * Plugin version.
38
  */
39
+ define( 'CYR_TO_LAT_VERSION', '5.0.0' );
40
 
41
  /**
42
  * Path to the plugin dir.
81
  /**
82
  * Init plugin on plugin load.
83
  */
84
+ require_once 'vendor/autoload.php';
 
 
 
 
 
 
85
 
86
  global $cyr_to_lat_plugin;
87
 
88
  $cyr_to_lat_plugin = new Main();
89
+ $cyr_to_lat_plugin->init();
dist/js/settings/app.js DELETED
@@ -1,2 +0,0 @@
1
- !function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){n(1),t.exports=n(2)},function(t,e){var n=function(t){function e(){this.fetch=!1,this.DOMException=t.DOMException}return e.prototype=t,new e}("undefined"!=typeof self?self:this);!function(t){!function(e){var n="URLSearchParams"in t,r="Symbol"in t&&"iterator"in Symbol,i="FileReader"in t&&"Blob"in t&&function(){try{return new Blob,!0}catch(t){return!1}}(),o="FormData"in t,s="ArrayBuffer"in t;if(s)var a=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],u=ArrayBuffer.isView||function(t){return t&&a.indexOf(Object.prototype.toString.call(t))>-1};function l(t){if("string"!=typeof t&&(t=String(t)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(t))throw new TypeError("Invalid character in header field name");return t.toLowerCase()}function c(t){return"string"!=typeof t&&(t=String(t)),t}function h(t){var e={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return r&&(e[Symbol.iterator]=function(){return e}),e}function d(t){this.map={},t instanceof d?t.forEach((function(t,e){this.append(e,t)}),this):Array.isArray(t)?t.forEach((function(t){this.append(t[0],t[1])}),this):t&&Object.getOwnPropertyNames(t).forEach((function(e){this.append(e,t[e])}),this)}function p(t){if(t.bodyUsed)return Promise.reject(new TypeError("Already read"));t.bodyUsed=!0}function f(t){return new Promise((function(e,n){t.onload=function(){e(t.result)},t.onerror=function(){n(t.error)}}))}function y(t){var e=new FileReader,n=f(e);return e.readAsArrayBuffer(t),n}function b(t){if(t.slice)return t.slice(0);var e=new Uint8Array(t.byteLength);return e.set(new Uint8Array(t)),e.buffer}function v(){return this.bodyUsed=!1,this._initBody=function(t){var e;this._bodyInit=t,t?"string"==typeof t?this._bodyText=t:i&&Blob.prototype.isPrototypeOf(t)?this._bodyBlob=t:o&&FormData.prototype.isPrototypeOf(t)?this._bodyFormData=t:n&&URLSearchParams.prototype.isPrototypeOf(t)?this._bodyText=t.toString():s&&i&&((e=t)&&DataView.prototype.isPrototypeOf(e))?(this._bodyArrayBuffer=b(t.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):s&&(ArrayBuffer.prototype.isPrototypeOf(t)||u(t))?this._bodyArrayBuffer=b(t):this._bodyText=t=Object.prototype.toString.call(t):this._bodyText="",this.headers.get("content-type")||("string"==typeof t?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):n&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},i&&(this.blob=function(){var t=p(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?p(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(y)}),this.text=function(){var t,e,n,r=p(this);if(r)return r;if(this._bodyBlob)return t=this._bodyBlob,e=new FileReader,n=f(e),e.readAsText(t),n;if(this._bodyArrayBuffer)return Promise.resolve(function(t){for(var e=new Uint8Array(t),n=new Array(e.length),r=0;r<e.length;r++)n[r]=String.fromCharCode(e[r]);return n.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},o&&(this.formData=function(){return this.text().then(S)}),this.json=function(){return this.text().then(JSON.parse)},this}d.prototype.append=function(t,e){t=l(t),e=c(e);var n=this.map[t];this.map[t]=n?n+", "+e:e},d.prototype.delete=function(t){delete this.map[l(t)]},d.prototype.get=function(t){return t=l(t),this.has(t)?this.map[t]:null},d.prototype.has=function(t){return this.map.hasOwnProperty(l(t))},d.prototype.set=function(t,e){this.map[l(t)]=c(e)},d.prototype.forEach=function(t,e){for(var n in this.map)this.map.hasOwnProperty(n)&&t.call(e,this.map[n],n,this)},d.prototype.keys=function(){var t=[];return this.forEach((function(e,n){t.push(n)})),h(t)},d.prototype.values=function(){var t=[];return this.forEach((function(e){t.push(e)})),h(t)},d.prototype.entries=function(){var t=[];return this.forEach((function(e,n){t.push([n,e])})),h(t)},r&&(d.prototype[Symbol.iterator]=d.prototype.entries);var m=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];function E(t,e){var n,r,i=(e=e||{}).body;if(t instanceof E){if(t.bodyUsed)throw new TypeError("Already read");this.url=t.url,this.credentials=t.credentials,e.headers||(this.headers=new d(t.headers)),this.method=t.method,this.mode=t.mode,this.signal=t.signal,i||null==t._bodyInit||(i=t._bodyInit,t.bodyUsed=!0)}else this.url=String(t);if(this.credentials=e.credentials||this.credentials||"same-origin",!e.headers&&this.headers||(this.headers=new d(e.headers)),this.method=(n=e.method||this.method||"GET",r=n.toUpperCase(),m.indexOf(r)>-1?r:n),this.mode=e.mode||this.mode||null,this.signal=e.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&i)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(i)}function S(t){var e=new FormData;return t.trim().split("&").forEach((function(t){if(t){var n=t.split("="),r=n.shift().replace(/\+/g," "),i=n.join("=").replace(/\+/g," ");e.append(decodeURIComponent(r),decodeURIComponent(i))}})),e}function L(t,e){e||(e={}),this.type="default",this.status=void 0===e.status?200:e.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in e?e.statusText:"OK",this.headers=new d(e.headers),this.url=e.url||"",this._initBody(t)}E.prototype.clone=function(){return new E(this,{body:this._bodyInit})},v.call(E.prototype),v.call(L.prototype),L.prototype.clone=function(){return new L(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new d(this.headers),url:this.url})},L.error=function(){var t=new L(null,{status:0,statusText:""});return t.type="error",t};var T=[301,302,303,307,308];L.redirect=function(t,e){if(-1===T.indexOf(e))throw new RangeError("Invalid status code");return new L(null,{status:e,headers:{location:t}})},e.DOMException=t.DOMException;try{new e.DOMException}catch(t){e.DOMException=function(t,e){this.message=t,this.name=e;var n=Error(t);this.stack=n.stack},e.DOMException.prototype=Object.create(Error.prototype),e.DOMException.prototype.constructor=e.DOMException}function _(t,n){return new Promise((function(r,o){var s=new E(t,n);if(s.signal&&s.signal.aborted)return o(new e.DOMException("Aborted","AbortError"));var a=new XMLHttpRequest;function u(){a.abort()}a.onload=function(){var t,e,n={status:a.status,statusText:a.statusText,headers:(t=a.getAllResponseHeaders()||"",e=new d,t.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach((function(t){var n=t.split(":"),r=n.shift().trim();if(r){var i=n.join(":").trim();e.append(r,i)}})),e)};n.url="responseURL"in a?a.responseURL:n.headers.get("X-Request-URL");var i="response"in a?a.response:a.responseText;r(new L(i,n))},a.onerror=function(){o(new TypeError("Network request failed"))},a.ontimeout=function(){o(new TypeError("Network request failed"))},a.onabort=function(){o(new e.DOMException("Aborted","AbortError"))},a.open(s.method,s.url,!0),"include"===s.credentials?a.withCredentials=!0:"omit"===s.credentials&&(a.withCredentials=!1),"responseType"in a&&i&&(a.responseType="blob"),s.headers.forEach((function(t,e){a.setRequestHeader(e,t)})),s.signal&&(s.signal.addEventListener("abort",u),a.onreadystatechange=function(){4===a.readyState&&s.signal.removeEventListener("abort",u)}),a.send(void 0===s._bodyInit?null:s._bodyInit)}))}_.polyfill=!0,t.fetch||(t.fetch=_,t.Headers=d,t.Request=E,t.Response=L),e.Headers=d,e.Request=E,e.Response=L,e.fetch=_}({})}(n),delete n.fetch.polyfill,(e=n.fetch).default=n.fetch,e.fetch=n.fetch,e.Headers=n.Headers,e.Request=n.Request,e.Response=n.Response,t.exports=e},function(t,e,n){"use strict";var r,i=n(3),o=(r=i)&&r.__esModule?r:{default:r};document.addEventListener("DOMContentLoaded",(function(){new o.default}))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}();function i(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e<t.length;e++)n[e]=t[e];return n}return Array.from(t)}var o=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.OPTIONS_FORM_SELECTOR="#ctl-options",this.HEADER_SELECTOR=this.OPTIONS_FORM_SELECTOR+" h2",this.TABLE_SELECTOR=this.OPTIONS_FORM_SELECTOR+" table",this.SUBMIT_SELECTOR=this.OPTIONS_FORM_SELECTOR+" #submit",this.CONVERT_FORM_SELECTOR="#ctl-convert-existing-slugs",this.CONVERT_BUTTON_SELECTOR="#ctl-convert-button",this.CONFIRM_POPUP_SELECTOR="#ctl-confirm-popup",this.CONFIRM_OK_SELECTOR="#ctl-confirm-ok",this.CONFIRM_CANCEL_SELECTOR="#ctl-confirm-cancel",this.CURRENT_STUB_ID="ctl-current",this.CURRENT_NAV_TAB_CLASS="nav-tab-current",this.ACTIVE_NAV_TAB_CLASS="nav-tab-active",this.ACTIVE_TABLE_CLASS="active",this.EDIT_LABEL_ID="ctl-edit-label",this.EDIT_LABEL_ERROR_CLASS="ctl-edit-label-error",this.plusButton='<button type="button" aria-haspopup="true" aria-expanded="false" class="components-button block-editor-inserter__toggle has-icon" aria-label="Добавить блок"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" role="img" aria-hidden="true" focusable="false"><path d="M10 1c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 16c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7zm1-11H9v3H6v2h3v3h2v-3h3V9h-3V6zM10 1c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 16c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7zm1-11H9v3H6v2h3v3h2v-3h3V9h-3V6z"></path></svg></button>',this.PLUS_CLASS="ctl-plus",this.optionsForm=document.querySelector(this.OPTIONS_FORM_SELECTOR),this.tablesData=this.getTablesData(),this.submitButton=document.querySelector(this.SUBMIT_SELECTOR),this.confirmPopup=document.querySelector(this.CONFIRM_POPUP_SELECTOR),this.optionsSaveSuccessMessage=Cyr2LatSettingsObject.optionsSaveSuccessMessage,this.optionsSaveErrorMessage=Cyr2LatSettingsObject.optionsSaveErrorMessage,this.addWrapper(),this.addMessageLines(),this.addEditLabelInput(),this.hideTables(),this.bindEvents(),this.setSubmitStatus()}return r(t,[{key:"getHeaders",value:function(){return[].concat(i(document.querySelectorAll(this.HEADER_SELECTOR)))}},{key:"getActiveHeader",value:function(){return document.querySelector(this.HEADER_SELECTOR+"."+this.ACTIVE_NAV_TAB_CLASS)}},{key:"getActiveIndex",value:function(){return this.getActiveHeader().dataset.index}},{key:"getTables",value:function(){return[].concat(i(document.querySelectorAll(this.TABLE_SELECTOR)))}},{key:"getActiveTable",value:function(){return document.querySelector(this.TABLE_SELECTOR+"."+this.ACTIVE_TABLE_CLASS)}},{key:"getInputs",value:function(){return[].concat(i(document.querySelectorAll(this.OPTIONS_FORM_SELECTOR+" input")))}},{key:"getLabels",value:function(){return[].concat(i(document.querySelectorAll(this.OPTIONS_FORM_SELECTOR+" label")))}},{key:"getPlusButtons",value:function(){return[].concat(i(document.querySelectorAll(this.OPTIONS_FORM_SELECTOR+" ."+this.PLUS_CLASS)))}},{key:"isActiveTableChanged",value:function(){var t=this.getActiveIndex();return JSON.stringify(this.getActiveTableData())!==JSON.stringify(this.tablesData[t])}},{key:"setSubmitStatus",value:function(){this.submitButton.disabled=!this.isActiveTableChanged()}},{key:"saveActiveTable",value:function(){var t=this;if(this.isActiveTableChanged()){var e=this.getActiveTable(),n=document.createElement("form");return n.action=this.optionsForm.getAttribute("action"),n.method=this.optionsForm.method,n.appendChild(e.cloneNode(!0)),[].concat(i(e.querySelectorAll("input"))).map((function(t){return n.querySelector("#"+t.id).value=t.value})),[].concat(i(this.optionsForm.querySelectorAll('input[type="hidden"]'))).map((function(t){return n.appendChild(t.cloneNode(!0))})),document.body.appendChild(n),fetch(this.optionsForm.getAttribute("action"),{method:n.method,body:new URLSearchParams([].concat(i(new FormData(n))))}).then((function(e){return e.ok?(t.showMessage(t.successMessage,t.optionsSaveSuccessMessage),t.tablesData=t.getTablesData()):t.showMessage(t.errorMessage,t.optionsSaveErrorMessage),e.json()})).finally((function(){n.parentNode.removeChild(n),t.setSubmitStatus()}))}}},{key:"getTableData",value:function(t){var e=this,n=[].concat(i(t.querySelectorAll("input"))),r={};return n.forEach((function(t){var n=document.querySelector(e.OPTIONS_FORM_SELECTOR+' label[for="'+t.id+'"]');r[n.innerHTML]=t.value})),r}},{key:"getTablesData",value:function(){var t=this;return this.getTables().map((function(e){return t.getTableData(e)}))}},{key:"getActiveTableData",value:function(){return this.getTableData(this.getActiveTable())}},{key:"addWrapper",value:function(){this.wrapper=document.createElement("ul"),this.wrapper.classList.add("nav-tab-wrapper"),this.optionsForm.insertBefore(this.wrapper,this.optionsForm.firstChild)}},{key:"addMessageLine",value:function(t){var e=document.createElement("div");return e.id=t,this.optionsForm.insertBefore(e,this.optionsForm.firstChild),e}},{key:"addMessageLines",value:function(){this.successMessage=this.addMessageLine("ctl-success"),this.errorMessage=this.addMessageLine("ctl-error")}},{key:"addEditLabelInput",value:function(){this.editLabelInput=document.createElement("input"),this.editLabelInput.id=this.EDIT_LABEL_ID,this.editLabelInput.style.display="none",document.body.appendChild(this.editLabelInput)}},{key:"hideEditLabelInput",value:function(){this.editLabelInput.style.display="none",this.editLabelInput.classList.remove(this.EDIT_LABEL_ERROR_CLASS),document.body.appendChild(this.editLabelInput)}},{key:"getLastCell",value:function(){return document.querySelector(this.OPTIONS_FORM_SELECTOR+" ."+this.ACTIVE_TABLE_CLASS+" ."+this.PLUS_CLASS).previousElementSibling}},{key:"addCell",value:function(){var t=this.getLastCell();t.parentElement.insertBefore(t.cloneNode(!0),t.nextElementSibling);var e=(t=this.getLastCell()).querySelector("label"),n=t.querySelector("input"),r=n.id.split("-"),i=r[0]+"-"+(parseInt(r[1])+1);e.htmlFor=i,e.innerHTML="",n.id=i,n.value="",n.setAttribute("value",""),this.replaceName(n,""),this.bindEvents(),this.editLabel(e)}},{key:"hideTables",value:function(){var t=this,e=0;this.getTables().map((function(n,r){n.classList.add("ctl-table"),t.CURRENT_STUB_ID===n.previousElementSibling.id&&(e=r,n.classList.add(t.ACTIVE_TABLE_CLASS));var i=document.createElement("div");return i.classList.add(t.PLUS_CLASS),i.innerHTML=t.plusButton,n.querySelector("td").appendChild(i),null})),this.getHeaders().map((function(n,r){return n.classList.add("nav-tab"),n.dataset.index=r,t.wrapper.appendChild(n),r===e&&(n.classList.add(t.CURRENT_NAV_TAB_CLASS),n.classList.add(t.ACTIVE_NAV_TAB_CLASS)),null}))}},{key:"bindEvents",value:function(){var t=this;this.getHeaders().map((function(e,n,r){return e.onclick=function(e){e.preventDefault();var n=e.target.dataset.index;if(n===t.getActiveIndex())return!1;t.saveActiveTable(),r.map((function(e){return e.classList.remove(t.ACTIVE_NAV_TAB_CLASS)})),r[n].classList.add(t.ACTIVE_NAV_TAB_CLASS);var i=t.getTables();return i.map((function(e){return e.classList.remove(t.ACTIVE_TABLE_CLASS)})),i[n].classList.add(t.ACTIVE_TABLE_CLASS),t.setSubmitStatus(),!1},null})),this.getInputs().map((function(e){return e.oninput=function(){t.setSubmitStatus()},null})),this.getLabels().map((function(e){return e.onclick=function(e){return e.preventDefault(),t.editLabel(e.target),!1},null})),this.editLabelInput.onblur=function(){t.saveLabel()},this.editLabelInput.onkeyup=function(e){"Escape"===e.key&&t.saveLabel(!0),"Enter"===e.key&&t.saveLabel()},this.getPlusButtons().map((function(e){return e.onclick=function(e){return e.preventDefault(),t.addCell(e.target),!1},null})),this.submitButton.onclick=function(e){return e.preventDefault(),t.saveActiveTable(),!1},document.querySelector(this.CONVERT_BUTTON_SELECTOR).onclick=function(e){return e.preventDefault(),t.confirmPopup.style.display="block",!1},this.confirmPopup.onclick=function(){t.hideConfirmPopup()},document.querySelector(this.CONFIRM_OK_SELECTOR).onclick=function(e){e.stopPropagation(),t.hideConfirmPopup(),document.querySelector(t.CONVERT_FORM_SELECTOR).submit()},document.querySelector(this.CONFIRM_CANCEL_SELECTOR).onclick=function(e){e.stopPropagation(),t.hideConfirmPopup()}}},{key:"hideConfirmPopup",value:function(){this.confirmPopup.style.display="none"}},{key:"editLabel",value:function(t){t.parentNode.appendChild(this.editLabelInput),this.editLabelInput.value=t.innerHTML,this.editLabelInput.classList.remove(this.EDIT_LABEL_ERROR_CLASS),this.editLabelInput.style.display="block",this.editLabelInput.focus()}},{key:"isUniqueLabel",value:function(t){return[].concat(i(this.getActiveTable().querySelectorAll("label"))).reduce((function(e,n){return e&&n.innerHTML!==t}),!0)}},{key:"saveLabel",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if("none"!==this.editLabelInput.style.display){var e=this.editLabelInput.value.trim();if(""===e){var n=document.getElementById(this.EDIT_LABEL_ID).parentElement;return this.hideEditLabelInput(),n.parentNode.removeChild(n),void this.setSubmitStatus()}var r=this.editLabelInput.parentNode.querySelector("label");if(t||e===r.innerHTML)this.hideEditLabelInput();else if(this.isUniqueLabel(e)){var i=this.editLabelInput.parentNode.querySelector("input");this.hideEditLabelInput(),r.innerHTML=e,this.replaceName(i,e),this.setSubmitStatus()}else this.editLabelInput.classList.add(this.EDIT_LABEL_ERROR_CLASS)}}},{key:"replaceName",value:function(t,e){t.name=t.name.replace(/(.+\[.+])\[.*]/g,"$1["+e+"]")}},{key:"clearMessage",value:function(t){t.innerHTML="",t.classList.remove("active")}},{key:"clearMessages",value:function(){this.clearMessage(this.successMessage),this.clearMessage(this.errorMessage),clearTimeout(this.msgTimer)}},{key:"showMessage",value:function(t,e){var n=this;t.innerHTML=e,t.classList.add("active"),this.msgTimer=setTimeout((function(){n.clearMessages()}),5e3)}}]),t}();e.default=o}]);
2
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2Nyb3NzLWZldGNoL2Rpc3QvYnJvd3Nlci1wb255ZmlsbC5qcyIsIndlYnBhY2s6Ly8vLi9qcy9zZXR0aW5ncy9hcHAuanMiLCJ3ZWJwYWNrOi8vLy4vanMvc2V0dGluZ3Mvc2V0dGluZ3MuanMiXSwibmFtZXMiOlsiaW5zdGFsbGVkTW9kdWxlcyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsImV4cG9ydHMiLCJtb2R1bGUiLCJpIiwibCIsIm1vZHVsZXMiLCJjYWxsIiwibSIsImMiLCJkIiwibmFtZSIsImdldHRlciIsIm8iLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImVudW1lcmFibGUiLCJnZXQiLCJyIiwiU3ltYm9sIiwidG9TdHJpbmdUYWciLCJ2YWx1ZSIsInQiLCJtb2RlIiwiX19lc01vZHVsZSIsIm5zIiwiY3JlYXRlIiwia2V5IiwiYmluZCIsIm4iLCJvYmplY3QiLCJwcm9wZXJ0eSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwicCIsInMiLCJfX3NlbGZfXyIsInJvb3QiLCJGIiwidGhpcyIsImZldGNoIiwiRE9NRXhjZXB0aW9uIiwic2VsZiIsInN1cHBvcnQiLCJCbG9iIiwiZSIsInZpZXdDbGFzc2VzIiwiaXNBcnJheUJ1ZmZlclZpZXciLCJBcnJheUJ1ZmZlciIsImlzVmlldyIsIm9iaiIsImluZGV4T2YiLCJ0b1N0cmluZyIsIm5vcm1hbGl6ZU5hbWUiLCJTdHJpbmciLCJ0ZXN0IiwiVHlwZUVycm9yIiwidG9Mb3dlckNhc2UiLCJub3JtYWxpemVWYWx1ZSIsIml0ZXJhdG9yRm9yIiwiaXRlbXMiLCJpdGVyYXRvciIsIm5leHQiLCJzaGlmdCIsImRvbmUiLCJ1bmRlZmluZWQiLCJIZWFkZXJzIiwiaGVhZGVycyIsIm1hcCIsImZvckVhY2giLCJhcHBlbmQiLCJBcnJheSIsImlzQXJyYXkiLCJoZWFkZXIiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwiY29uc3VtZWQiLCJib2R5IiwiYm9keVVzZWQiLCJQcm9taXNlIiwicmVqZWN0IiwiZmlsZVJlYWRlclJlYWR5IiwicmVhZGVyIiwicmVzb2x2ZSIsIm9ubG9hZCIsInJlc3VsdCIsIm9uZXJyb3IiLCJlcnJvciIsInJlYWRCbG9iQXNBcnJheUJ1ZmZlciIsImJsb2IiLCJGaWxlUmVhZGVyIiwicHJvbWlzZSIsInJlYWRBc0FycmF5QnVmZmVyIiwiYnVmZmVyQ2xvbmUiLCJidWYiLCJzbGljZSIsInZpZXciLCJVaW50OEFycmF5IiwiYnl0ZUxlbmd0aCIsInNldCIsImJ1ZmZlciIsIkJvZHkiLCJfaW5pdEJvZHkiLCJfYm9keUluaXQiLCJfYm9keVRleHQiLCJpc1Byb3RvdHlwZU9mIiwiX2JvZHlCbG9iIiwiRm9ybURhdGEiLCJfYm9keUZvcm1EYXRhIiwiVVJMU2VhcmNoUGFyYW1zIiwiRGF0YVZpZXciLCJfYm9keUFycmF5QnVmZmVyIiwidHlwZSIsInJlamVjdGVkIiwiRXJyb3IiLCJhcnJheUJ1ZmZlciIsInRoZW4iLCJ0ZXh0IiwicmVhZEFzVGV4dCIsImNoYXJzIiwibGVuZ3RoIiwiZnJvbUNoYXJDb2RlIiwiam9pbiIsInJlYWRBcnJheUJ1ZmZlckFzVGV4dCIsImZvcm1EYXRhIiwiZGVjb2RlIiwianNvbiIsIkpTT04iLCJwYXJzZSIsIm9sZFZhbHVlIiwiaGFzIiwiY2FsbGJhY2siLCJ0aGlzQXJnIiwia2V5cyIsInB1c2giLCJ2YWx1ZXMiLCJlbnRyaWVzIiwibWV0aG9kcyIsIlJlcXVlc3QiLCJpbnB1dCIsIm9wdGlvbnMiLCJtZXRob2QiLCJ1cGNhc2VkIiwidXJsIiwiY3JlZGVudGlhbHMiLCJzaWduYWwiLCJ0b1VwcGVyQ2FzZSIsInJlZmVycmVyIiwiZm9ybSIsInRyaW0iLCJzcGxpdCIsImJ5dGVzIiwicmVwbGFjZSIsImRlY29kZVVSSUNvbXBvbmVudCIsIlJlc3BvbnNlIiwiYm9keUluaXQiLCJzdGF0dXMiLCJvayIsInN0YXR1c1RleHQiLCJjbG9uZSIsInJlc3BvbnNlIiwicmVkaXJlY3RTdGF0dXNlcyIsInJlZGlyZWN0IiwiUmFuZ2VFcnJvciIsImxvY2F0aW9uIiwiZXJyIiwibWVzc2FnZSIsInN0YWNrIiwiY29uc3RydWN0b3IiLCJpbml0IiwicmVxdWVzdCIsImFib3J0ZWQiLCJ4aHIiLCJYTUxIdHRwUmVxdWVzdCIsImFib3J0WGhyIiwiYWJvcnQiLCJyYXdIZWFkZXJzIiwiZ2V0QWxsUmVzcG9uc2VIZWFkZXJzIiwibGluZSIsInBhcnRzIiwicmVzcG9uc2VVUkwiLCJyZXNwb25zZVRleHQiLCJvbnRpbWVvdXQiLCJvbmFib3J0Iiwib3BlbiIsIndpdGhDcmVkZW50aWFscyIsInJlc3BvbnNlVHlwZSIsInNldFJlcXVlc3RIZWFkZXIiLCJhZGRFdmVudExpc3RlbmVyIiwib25yZWFkeXN0YXRlY2hhbmdlIiwicmVhZHlTdGF0ZSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJzZW5kIiwicG9seWZpbGwiLCJkZWZhdWx0IiwiZG9jdW1lbnQiLCJTZXR0aW5ncyIsIk9QVElPTlNfRk9STV9TRUxFQ1RPUiIsIkhFQURFUl9TRUxFQ1RPUiIsIlRBQkxFX1NFTEVDVE9SIiwiU1VCTUlUX1NFTEVDVE9SIiwiQ09OVkVSVF9GT1JNX1NFTEVDVE9SIiwiQ09OVkVSVF9CVVRUT05fU0VMRUNUT1IiLCJDT05GSVJNX1BPUFVQX1NFTEVDVE9SIiwiQ09ORklSTV9PS19TRUxFQ1RPUiIsIkNPTkZJUk1fQ0FOQ0VMX1NFTEVDVE9SIiwiQ1VSUkVOVF9TVFVCX0lEIiwiQ1VSUkVOVF9OQVZfVEFCX0NMQVNTIiwiQUNUSVZFX05BVl9UQUJfQ0xBU1MiLCJBQ1RJVkVfVEFCTEVfQ0xBU1MiLCJFRElUX0xBQkVMX0lEIiwiRURJVF9MQUJFTF9FUlJPUl9DTEFTUyIsInBsdXNCdXR0b24iLCJQTFVTX0NMQVNTIiwib3B0aW9uc0Zvcm0iLCJxdWVyeVNlbGVjdG9yIiwidGFibGVzRGF0YSIsImdldFRhYmxlc0RhdGEiLCJzdWJtaXRCdXR0b24iLCJjb25maXJtUG9wdXAiLCJvcHRpb25zU2F2ZVN1Y2Nlc3NNZXNzYWdlIiwiQ3lyMkxhdFNldHRpbmdzT2JqZWN0Iiwib3B0aW9uc1NhdmVFcnJvck1lc3NhZ2UiLCJhZGRXcmFwcGVyIiwiYWRkTWVzc2FnZUxpbmVzIiwiYWRkRWRpdExhYmVsSW5wdXQiLCJoaWRlVGFibGVzIiwiYmluZEV2ZW50cyIsInNldFN1Ym1pdFN0YXR1cyIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJnZXRBY3RpdmVIZWFkZXIiLCJkYXRhc2V0IiwiaW5kZXgiLCJhY3RpdmVJbmRleCIsImdldEFjdGl2ZUluZGV4Iiwic3RyaW5naWZ5IiwiZ2V0QWN0aXZlVGFibGVEYXRhIiwiZGlzYWJsZWQiLCJpc0FjdGl2ZVRhYmxlQ2hhbmdlZCIsImFjdGl2ZVRhYmxlIiwiZ2V0QWN0aXZlVGFibGUiLCJhY3RpdmVGb3JtIiwiY3JlYXRlRWxlbWVudCIsImFjdGlvbiIsImdldEF0dHJpYnV0ZSIsImFwcGVuZENoaWxkIiwiY2xvbmVOb2RlIiwiYWN0aXZlSW5wdXRzIiwiaWQiLCJoaWRkZW5JbnB1dHMiLCJzaG93TWVzc2FnZSIsInN1Y2Nlc3NNZXNzYWdlIiwiZXJyb3JNZXNzYWdlIiwiZmluYWxseSIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsInRhYmxlIiwiaW5wdXRzIiwiZGF0YSIsImxhYmVsIiwiaW5uZXJIVE1MIiwiZ2V0VGFibGVzIiwiZ2V0VGFibGVEYXRhIiwid3JhcHBlciIsImNsYXNzTGlzdCIsImFkZCIsImluc2VydEJlZm9yZSIsImZpcnN0Q2hpbGQiLCJhZGRNZXNzYWdlTGluZSIsImVkaXRMYWJlbElucHV0Iiwic3R5bGUiLCJkaXNwbGF5IiwicmVtb3ZlIiwicHJldmlvdXNFbGVtZW50U2libGluZyIsImxhc3RDZWxsIiwiZ2V0TGFzdENlbGwiLCJwYXJlbnRFbGVtZW50IiwibmV4dEVsZW1lbnRTaWJsaW5nIiwiaWRBcnIiLCJuZXdJZCIsInBhcnNlSW50IiwiaHRtbEZvciIsInNldEF0dHJpYnV0ZSIsInJlcGxhY2VOYW1lIiwiZWRpdExhYmVsIiwiY3VycmVudEluZGV4IiwicGx1cyIsImdldEhlYWRlcnMiLCJvbmNsaWNrIiwiZXZlbnQiLCJwcmV2ZW50RGVmYXVsdCIsInRhcmdldCIsInNhdmVBY3RpdmVUYWJsZSIsImFIZWFkZXIiLCJ0YWJsZXMiLCJnZXRJbnB1dHMiLCJvbmlucHV0IiwiZ2V0TGFiZWxzIiwib25ibHVyIiwic2F2ZUxhYmVsIiwib25rZXl1cCIsImdldFBsdXNCdXR0b25zIiwiYWRkQ2VsbCIsImhpZGVDb25maXJtUG9wdXAiLCJzdG9wUHJvcGFnYXRpb24iLCJzdWJtaXQiLCJmb2N1cyIsIm5ld1ZhbHVlIiwicmVkdWNlIiwiYWNjIiwiY2FuY2VsIiwiZWRpdGVkQ2VsbCIsImdldEVsZW1lbnRCeUlkIiwiaGlkZUVkaXRMYWJlbElucHV0IiwiaXNVbmlxdWVMYWJlbCIsImNsZWFyTWVzc2FnZSIsImNsZWFyVGltZW91dCIsIm1zZ1RpbWVyIiwiZWwiLCJzZXRUaW1lb3V0IiwiY2xlYXJNZXNzYWdlcyJdLCJtYXBwaW5ncyI6ImFBQ0UsSUFBSUEsRUFBbUIsR0FHdkIsU0FBU0MsRUFBb0JDLEdBRzVCLEdBQUdGLEVBQWlCRSxHQUNuQixPQUFPRixFQUFpQkUsR0FBVUMsUUFHbkMsSUFBSUMsRUFBU0osRUFBaUJFLEdBQVksQ0FDekNHLEVBQUdILEVBQ0hJLEdBQUcsRUFDSEgsUUFBUyxJQVVWLE9BTkFJLEVBQVFMLEdBQVVNLEtBQUtKLEVBQU9ELFFBQVNDLEVBQVFBLEVBQU9ELFFBQVNGLEdBRy9ERyxFQUFPRSxHQUFJLEVBR0pGLEVBQU9ELFFBS2ZGLEVBQW9CUSxFQUFJRixFQUd4Qk4sRUFBb0JTLEVBQUlWLEVBR3hCQyxFQUFvQlUsRUFBSSxTQUFTUixFQUFTUyxFQUFNQyxHQUMzQ1osRUFBb0JhLEVBQUVYLEVBQVNTLElBQ2xDRyxPQUFPQyxlQUFlYixFQUFTUyxFQUFNLENBQUVLLFlBQVksRUFBTUMsSUFBS0wsS0FLaEVaLEVBQW9Ca0IsRUFBSSxTQUFTaEIsR0FDWCxvQkFBWGlCLFFBQTBCQSxPQUFPQyxhQUMxQ04sT0FBT0MsZUFBZWIsRUFBU2lCLE9BQU9DLFlBQWEsQ0FBRUMsTUFBTyxXQUU3RFAsT0FBT0MsZUFBZWIsRUFBUyxhQUFjLENBQUVtQixPQUFPLEtBUXZEckIsRUFBb0JzQixFQUFJLFNBQVNELEVBQU9FLEdBRXZDLEdBRFUsRUFBUEEsSUFBVUYsRUFBUXJCLEVBQW9CcUIsSUFDL0IsRUFBUEUsRUFBVSxPQUFPRixFQUNwQixHQUFXLEVBQVBFLEdBQThCLGlCQUFWRixHQUFzQkEsR0FBU0EsRUFBTUcsV0FBWSxPQUFPSCxFQUNoRixJQUFJSSxFQUFLWCxPQUFPWSxPQUFPLE1BR3ZCLEdBRkExQixFQUFvQmtCLEVBQUVPLEdBQ3RCWCxPQUFPQyxlQUFlVSxFQUFJLFVBQVcsQ0FBRVQsWUFBWSxFQUFNSyxNQUFPQSxJQUN0RCxFQUFQRSxHQUE0QixpQkFBVEYsRUFBbUIsSUFBSSxJQUFJTSxLQUFPTixFQUFPckIsRUFBb0JVLEVBQUVlLEVBQUlFLEVBQUssU0FBU0EsR0FBTyxPQUFPTixFQUFNTSxJQUFRQyxLQUFLLEtBQU1ELElBQzlJLE9BQU9GLEdBSVJ6QixFQUFvQjZCLEVBQUksU0FBUzFCLEdBQ2hDLElBQUlTLEVBQVNULEdBQVVBLEVBQU9xQixXQUM3QixXQUF3QixPQUFPckIsRUFBZ0IsU0FDL0MsV0FBOEIsT0FBT0EsR0FFdEMsT0FEQUgsRUFBb0JVLEVBQUVFLEVBQVEsSUFBS0EsR0FDNUJBLEdBSVJaLEVBQW9CYSxFQUFJLFNBQVNpQixFQUFRQyxHQUFZLE9BQU9qQixPQUFPa0IsVUFBVUMsZUFBZTFCLEtBQUt1QixFQUFRQyxJQUd6Ry9CLEVBQW9Ca0MsRUFBSSxHQUlqQmxDLEVBQW9CQSxFQUFvQm1DLEVBQUksRyxxRENsRnJELElBQUlDLEVBQVcsU0FBV0MsR0FDMUIsU0FBU0MsSUFDVEMsS0FBS0MsT0FBUSxFQUNiRCxLQUFLRSxhQUFlSixFQUFLSSxhQUd6QixPQURBSCxFQUFFTixVQUFZSyxFQUNQLElBQUlDLEVBTkksQ0FPSSxvQkFBVEksS0FBdUJBLEtBQU9ILE9BQ3hDLFNBQVVHLElBRVEsU0FBVXhDLEdBRTFCLElBQUl5QyxFQUNZLG9CQUFxQkQsRUFEakNDLEVBRVEsV0FBWUQsR0FBUSxhQUFjdkIsT0FGMUN3QixFQUlBLGVBQWdCRCxHQUNoQixTQUFVQSxHQUNWLFdBQ0UsSUFFRSxPQURBLElBQUlFLE1BQ0csRUFDUCxNQUFPQyxHQUNQLE9BQU8sR0FMWCxHQU5BRixFQWNRLGFBQWNELEVBZHRCQyxFQWVXLGdCQUFpQkQsRUFPaEMsR0FBSUMsRUFDRixJQUFJRyxFQUFjLENBQ2hCLHFCQUNBLHNCQUNBLDZCQUNBLHNCQUNBLHVCQUNBLHNCQUNBLHVCQUNBLHdCQUNBLHlCQUdFQyxFQUNGQyxZQUFZQyxRQUNaLFNBQVNDLEdBQ1AsT0FBT0EsR0FBT0osRUFBWUssUUFBUXJDLE9BQU9rQixVQUFVb0IsU0FBUzdDLEtBQUsyQyxLQUFTLEdBSWhGLFNBQVNHLEVBQWMxQyxHQUlyQixHQUhvQixpQkFBVEEsSUFDVEEsRUFBTzJDLE9BQU8zQyxJQUVaLDRCQUE0QjRDLEtBQUs1QyxHQUNuQyxNQUFNLElBQUk2QyxVQUFVLDBDQUV0QixPQUFPN0MsRUFBSzhDLGNBR2QsU0FBU0MsRUFBZXJDLEdBSXRCLE1BSHFCLGlCQUFWQSxJQUNUQSxFQUFRaUMsT0FBT2pDLElBRVZBLEVBSVQsU0FBU3NDLEVBQVlDLEdBQ25CLElBQUlDLEVBQVcsQ0FDYkMsS0FBTSxXQUNKLElBQUl6QyxFQUFRdUMsRUFBTUcsUUFDbEIsTUFBTyxDQUFDQyxVQUFnQkMsSUFBVjVDLEVBQXFCQSxNQUFPQSxLQVU5QyxPQU5Jc0IsSUFDRmtCLEVBQVMxQyxPQUFPMEMsVUFBWSxXQUMxQixPQUFPQSxJQUlKQSxFQUdULFNBQVNLLEVBQVFDLEdBQ2Y1QixLQUFLNkIsSUFBTSxHQUVQRCxhQUFtQkQsRUFDckJDLEVBQVFFLFNBQVEsU0FBU2hELEVBQU9WLEdBQzlCNEIsS0FBSytCLE9BQU8zRCxFQUFNVSxLQUNqQmtCLE1BQ01nQyxNQUFNQyxRQUFRTCxHQUN2QkEsRUFBUUUsU0FBUSxTQUFTSSxHQUN2QmxDLEtBQUsrQixPQUFPRyxFQUFPLEdBQUlBLEVBQU8sTUFDN0JsQyxNQUNNNEIsR0FDVHJELE9BQU80RCxvQkFBb0JQLEdBQVNFLFNBQVEsU0FBUzFELEdBQ25ENEIsS0FBSytCLE9BQU8zRCxFQUFNd0QsRUFBUXhELE1BQ3pCNEIsTUFnRVAsU0FBU29DLEVBQVNDLEdBQ2hCLEdBQUlBLEVBQUtDLFNBQ1AsT0FBT0MsUUFBUUMsT0FBTyxJQUFJdkIsVUFBVSxpQkFFdENvQixFQUFLQyxVQUFXLEVBR2xCLFNBQVNHLEVBQWdCQyxHQUN2QixPQUFPLElBQUlILFNBQVEsU0FBU0ksRUFBU0gsR0FDbkNFLEVBQU9FLE9BQVMsV0FDZEQsRUFBUUQsRUFBT0csU0FFakJILEVBQU9JLFFBQVUsV0FDZk4sRUFBT0UsRUFBT0ssV0FLcEIsU0FBU0MsRUFBc0JDLEdBQzdCLElBQUlQLEVBQVMsSUFBSVEsV0FDYkMsRUFBVVYsRUFBZ0JDLEdBRTlCLE9BREFBLEVBQU9VLGtCQUFrQkgsR0FDbEJFLEVBb0JULFNBQVNFLEVBQVlDLEdBQ25CLEdBQUlBLEVBQUlDLE1BQ04sT0FBT0QsRUFBSUMsTUFBTSxHQUVqQixJQUFJQyxFQUFPLElBQUlDLFdBQVdILEVBQUlJLFlBRTlCLE9BREFGLEVBQUtHLElBQUksSUFBSUYsV0FBV0gsSUFDakJFLEVBQUtJLE9BSWhCLFNBQVNDLElBMEZQLE9BekZBN0QsS0FBS3NDLFVBQVcsRUFFaEJ0QyxLQUFLOEQsVUFBWSxTQUFTekIsR0FoTTVCLElBQW9CMUIsRUFpTWhCWCxLQUFLK0QsVUFBWTFCLEVBQ1pBLEVBRXNCLGlCQUFUQSxFQUNoQnJDLEtBQUtnRSxVQUFZM0IsRUFDUmpDLEdBQWdCQyxLQUFLWixVQUFVd0UsY0FBYzVCLEdBQ3REckMsS0FBS2tFLFVBQVk3QixFQUNSakMsR0FBb0IrRCxTQUFTMUUsVUFBVXdFLGNBQWM1QixHQUM5RHJDLEtBQUtvRSxjQUFnQi9CLEVBQ1pqQyxHQUF3QmlFLGdCQUFnQjVFLFVBQVV3RSxjQUFjNUIsR0FDekVyQyxLQUFLZ0UsVUFBWTNCLEVBQUt4QixXQUNiVCxHQUF1QkEsS0E1TWxCTyxFQTRNNkMwQixJQTNNakRpQyxTQUFTN0UsVUFBVXdFLGNBQWN0RCxLQTRNM0NYLEtBQUt1RSxpQkFBbUJsQixFQUFZaEIsRUFBS3VCLFFBRXpDNUQsS0FBSytELFVBQVksSUFBSTFELEtBQUssQ0FBQ0wsS0FBS3VFLG9CQUN2Qm5FLElBQXdCSyxZQUFZaEIsVUFBVXdFLGNBQWM1QixJQUFTN0IsRUFBa0I2QixJQUNoR3JDLEtBQUt1RSxpQkFBbUJsQixFQUFZaEIsR0FFcENyQyxLQUFLZ0UsVUFBWTNCLEVBQU85RCxPQUFPa0IsVUFBVW9CLFNBQVM3QyxLQUFLcUUsR0FoQnZEckMsS0FBS2dFLFVBQVksR0FtQmRoRSxLQUFLNEIsUUFBUWxELElBQUksa0JBQ0EsaUJBQVQyRCxFQUNUckMsS0FBSzRCLFFBQVErQixJQUFJLGVBQWdCLDRCQUN4QjNELEtBQUtrRSxXQUFhbEUsS0FBS2tFLFVBQVVNLEtBQzFDeEUsS0FBSzRCLFFBQVErQixJQUFJLGVBQWdCM0QsS0FBS2tFLFVBQVVNLE1BQ3ZDcEUsR0FBd0JpRSxnQkFBZ0I1RSxVQUFVd0UsY0FBYzVCLElBQ3pFckMsS0FBSzRCLFFBQVErQixJQUFJLGVBQWdCLHFEQUtuQ3ZELElBQ0ZKLEtBQUtpRCxLQUFPLFdBQ1YsSUFBSXdCLEVBQVdyQyxFQUFTcEMsTUFDeEIsR0FBSXlFLEVBQ0YsT0FBT0EsRUFHVCxHQUFJekUsS0FBS2tFLFVBQ1AsT0FBTzNCLFFBQVFJLFFBQVEzQyxLQUFLa0UsV0FDdkIsR0FBSWxFLEtBQUt1RSxpQkFDZCxPQUFPaEMsUUFBUUksUUFBUSxJQUFJdEMsS0FBSyxDQUFDTCxLQUFLdUUsb0JBQ2pDLEdBQUl2RSxLQUFLb0UsY0FDZCxNQUFNLElBQUlNLE1BQU0sd0NBRWhCLE9BQU9uQyxRQUFRSSxRQUFRLElBQUl0QyxLQUFLLENBQUNMLEtBQUtnRSxjQUkxQ2hFLEtBQUsyRSxZQUFjLFdBQ2pCLE9BQUkzRSxLQUFLdUUsaUJBQ0FuQyxFQUFTcEMsT0FBU3VDLFFBQVFJLFFBQVEzQyxLQUFLdUUsa0JBRXZDdkUsS0FBS2lELE9BQU8yQixLQUFLNUIsS0FLOUJoRCxLQUFLNkUsS0FBTyxXQUNWLElBM0ZvQjVCLEVBQ2xCUCxFQUNBUyxFQXlGRXNCLEVBQVdyQyxFQUFTcEMsTUFDeEIsR0FBSXlFLEVBQ0YsT0FBT0EsRUFHVCxHQUFJekUsS0FBS2tFLFVBQ1AsT0FqR2tCakIsRUFpR0lqRCxLQUFLa0UsVUFoRzNCeEIsRUFBUyxJQUFJUSxXQUNiQyxFQUFVVixFQUFnQkMsR0FDOUJBLEVBQU9vQyxXQUFXN0IsR0FDWEUsRUE4RkUsR0FBSW5ELEtBQUt1RSxpQkFDZCxPQUFPaEMsUUFBUUksUUE1RnJCLFNBQStCVyxHQUk3QixJQUhBLElBQUlFLEVBQU8sSUFBSUMsV0FBV0gsR0FDdEJ5QixFQUFRLElBQUkvQyxNQUFNd0IsRUFBS3dCLFFBRWxCbkgsRUFBSSxFQUFHQSxFQUFJMkYsRUFBS3dCLE9BQVFuSCxJQUMvQmtILEVBQU1sSCxHQUFLa0QsT0FBT2tFLGFBQWF6QixFQUFLM0YsSUFFdEMsT0FBT2tILEVBQU1HLEtBQUssSUFxRlNDLENBQXNCbkYsS0FBS3VFLG1CQUM3QyxHQUFJdkUsS0FBS29FLGNBQ2QsTUFBTSxJQUFJTSxNQUFNLHdDQUVoQixPQUFPbkMsUUFBUUksUUFBUTNDLEtBQUtnRSxZQUk1QjVELElBQ0ZKLEtBQUtvRixTQUFXLFdBQ2QsT0FBT3BGLEtBQUs2RSxPQUFPRCxLQUFLUyxLQUk1QnJGLEtBQUtzRixLQUFPLFdBQ1YsT0FBT3RGLEtBQUs2RSxPQUFPRCxLQUFLVyxLQUFLQyxRQUd4QnhGLEtBMU1UMkIsRUFBUWxDLFVBQVVzQyxPQUFTLFNBQVMzRCxFQUFNVSxHQUN4Q1YsRUFBTzBDLEVBQWMxQyxHQUNyQlUsRUFBUXFDLEVBQWVyQyxHQUN2QixJQUFJMkcsRUFBV3pGLEtBQUs2QixJQUFJekQsR0FDeEI0QixLQUFLNkIsSUFBSXpELEdBQVFxSCxFQUFXQSxFQUFXLEtBQU8zRyxFQUFRQSxHQUd4RDZDLEVBQVFsQyxVQUFrQixPQUFJLFNBQVNyQixVQUM5QjRCLEtBQUs2QixJQUFJZixFQUFjMUMsS0FHaEN1RCxFQUFRbEMsVUFBVWYsSUFBTSxTQUFTTixHQUUvQixPQURBQSxFQUFPMEMsRUFBYzFDLEdBQ2Q0QixLQUFLMEYsSUFBSXRILEdBQVE0QixLQUFLNkIsSUFBSXpELEdBQVEsTUFHM0N1RCxFQUFRbEMsVUFBVWlHLElBQU0sU0FBU3RILEdBQy9CLE9BQU80QixLQUFLNkIsSUFBSW5DLGVBQWVvQixFQUFjMUMsS0FHL0N1RCxFQUFRbEMsVUFBVWtFLElBQU0sU0FBU3ZGLEVBQU1VLEdBQ3JDa0IsS0FBSzZCLElBQUlmLEVBQWMxQyxJQUFTK0MsRUFBZXJDLElBR2pENkMsRUFBUWxDLFVBQVVxQyxRQUFVLFNBQVM2RCxFQUFVQyxHQUM3QyxJQUFLLElBQUl4SCxLQUFRNEIsS0FBSzZCLElBQ2hCN0IsS0FBSzZCLElBQUluQyxlQUFldEIsSUFDMUJ1SCxFQUFTM0gsS0FBSzRILEVBQVM1RixLQUFLNkIsSUFBSXpELEdBQU9BLEVBQU00QixPQUtuRDJCLEVBQVFsQyxVQUFVb0csS0FBTyxXQUN2QixJQUFJeEUsRUFBUSxHQUlaLE9BSEFyQixLQUFLOEIsU0FBUSxTQUFTaEQsRUFBT1YsR0FDM0JpRCxFQUFNeUUsS0FBSzFILE1BRU5nRCxFQUFZQyxJQUdyQk0sRUFBUWxDLFVBQVVzRyxPQUFTLFdBQ3pCLElBQUkxRSxFQUFRLEdBSVosT0FIQXJCLEtBQUs4QixTQUFRLFNBQVNoRCxHQUNwQnVDLEVBQU15RSxLQUFLaEgsTUFFTnNDLEVBQVlDLElBR3JCTSxFQUFRbEMsVUFBVXVHLFFBQVUsV0FDMUIsSUFBSTNFLEVBQVEsR0FJWixPQUhBckIsS0FBSzhCLFNBQVEsU0FBU2hELEVBQU9WLEdBQzNCaUQsRUFBTXlFLEtBQUssQ0FBQzFILEVBQU1VLE9BRWJzQyxFQUFZQyxJQUdqQmpCLElBQ0Z1QixFQUFRbEMsVUFBVWIsT0FBTzBDLFVBQVlLLEVBQVFsQyxVQUFVdUcsU0FxSnpELElBQUlDLEVBQVUsQ0FBQyxTQUFVLE1BQU8sT0FBUSxVQUFXLE9BQVEsT0FPM0QsU0FBU0MsRUFBUUMsRUFBT0MsR0FFdEIsSUFQdUJDLEVBQ25CQyxFQU1BakUsR0FESitELEVBQVVBLEdBQVcsSUFDRi9ELEtBRW5CLEdBQUk4RCxhQUFpQkQsRUFBUyxDQUM1QixHQUFJQyxFQUFNN0QsU0FDUixNQUFNLElBQUlyQixVQUFVLGdCQUV0QmpCLEtBQUt1RyxJQUFNSixFQUFNSSxJQUNqQnZHLEtBQUt3RyxZQUFjTCxFQUFNSyxZQUNwQkosRUFBUXhFLFVBQ1g1QixLQUFLNEIsUUFBVSxJQUFJRCxFQUFRd0UsRUFBTXZFLFVBRW5DNUIsS0FBS3FHLE9BQVNGLEVBQU1FLE9BQ3BCckcsS0FBS2hCLEtBQU9tSCxFQUFNbkgsS0FDbEJnQixLQUFLeUcsT0FBU04sRUFBTU0sT0FDZnBFLEdBQTJCLE1BQW5COEQsRUFBTXBDLFlBQ2pCMUIsRUFBTzhELEVBQU1wQyxVQUNib0MsRUFBTTdELFVBQVcsUUFHbkJ0QyxLQUFLdUcsSUFBTXhGLE9BQU9vRixHQVlwQixHQVRBbkcsS0FBS3dHLFlBQWNKLEVBQVFJLGFBQWV4RyxLQUFLd0csYUFBZSxlQUMxREosRUFBUXhFLFNBQVk1QixLQUFLNEIsVUFDM0I1QixLQUFLNEIsUUFBVSxJQUFJRCxFQUFReUUsRUFBUXhFLFVBRXJDNUIsS0FBS3FHLFFBakNrQkEsRUFpQ09ELEVBQVFDLFFBQVVyRyxLQUFLcUcsUUFBVSxNQWhDM0RDLEVBQVVELEVBQU9LLGNBQ2RULEVBQVFyRixRQUFRMEYsSUFBWSxFQUFJQSxFQUFVRCxHQWdDakRyRyxLQUFLaEIsS0FBT29ILEVBQVFwSCxNQUFRZ0IsS0FBS2hCLE1BQVEsS0FDekNnQixLQUFLeUcsT0FBU0wsRUFBUUssUUFBVXpHLEtBQUt5RyxPQUNyQ3pHLEtBQUsyRyxTQUFXLE1BRUssUUFBaEIzRyxLQUFLcUcsUUFBb0MsU0FBaEJyRyxLQUFLcUcsU0FBc0JoRSxFQUN2RCxNQUFNLElBQUlwQixVQUFVLDZDQUV0QmpCLEtBQUs4RCxVQUFVekIsR0FPakIsU0FBU2dELEVBQU9oRCxHQUNkLElBQUl1RSxFQUFPLElBQUl6QyxTQVlmLE9BWEE5QixFQUNHd0UsT0FDQUMsTUFBTSxLQUNOaEYsU0FBUSxTQUFTaUYsR0FDaEIsR0FBSUEsRUFBTyxDQUNULElBQUlELEVBQVFDLEVBQU1ELE1BQU0sS0FDcEIxSSxFQUFPMEksRUFBTXRGLFFBQVF3RixRQUFRLE1BQU8sS0FDcENsSSxFQUFRZ0ksRUFBTTVCLEtBQUssS0FBSzhCLFFBQVEsTUFBTyxLQUMzQ0osRUFBSzdFLE9BQU9rRixtQkFBbUI3SSxHQUFPNkksbUJBQW1CbkksUUFHeEQ4SCxFQXFCVCxTQUFTTSxFQUFTQyxFQUFVZixHQUNyQkEsSUFDSEEsRUFBVSxJQUdacEcsS0FBS3dFLEtBQU8sVUFDWnhFLEtBQUtvSCxZQUE0QjFGLElBQW5CMEUsRUFBUWdCLE9BQXVCLElBQU1oQixFQUFRZ0IsT0FDM0RwSCxLQUFLcUgsR0FBS3JILEtBQUtvSCxRQUFVLEtBQU9wSCxLQUFLb0gsT0FBUyxJQUM5Q3BILEtBQUtzSCxXQUFhLGVBQWdCbEIsRUFBVUEsRUFBUWtCLFdBQWEsS0FDakV0SCxLQUFLNEIsUUFBVSxJQUFJRCxFQUFReUUsRUFBUXhFLFNBQ25DNUIsS0FBS3VHLElBQU1ILEVBQVFHLEtBQU8sR0FDMUJ2RyxLQUFLOEQsVUFBVXFELEdBakRqQmpCLEVBQVF6RyxVQUFVOEgsTUFBUSxXQUN4QixPQUFPLElBQUlyQixFQUFRbEcsS0FBTSxDQUFDcUMsS0FBTXJDLEtBQUsrRCxhQW1DdkNGLEVBQUs3RixLQUFLa0ksRUFBUXpHLFdBZ0JsQm9FLEVBQUs3RixLQUFLa0osRUFBU3pILFdBRW5CeUgsRUFBU3pILFVBQVU4SCxNQUFRLFdBQ3pCLE9BQU8sSUFBSUwsRUFBU2xILEtBQUsrRCxVQUFXLENBQ2xDcUQsT0FBUXBILEtBQUtvSCxPQUNiRSxXQUFZdEgsS0FBS3NILFdBQ2pCMUYsUUFBUyxJQUFJRCxFQUFRM0IsS0FBSzRCLFNBQzFCMkUsSUFBS3ZHLEtBQUt1RyxPQUlkVyxFQUFTbkUsTUFBUSxXQUNmLElBQUl5RSxFQUFXLElBQUlOLEVBQVMsS0FBTSxDQUFDRSxPQUFRLEVBQUdFLFdBQVksS0FFMUQsT0FEQUUsRUFBU2hELEtBQU8sUUFDVGdELEdBR1QsSUFBSUMsRUFBbUIsQ0FBQyxJQUFLLElBQUssSUFBSyxJQUFLLEtBRTVDUCxFQUFTUSxTQUFXLFNBQVNuQixFQUFLYSxHQUNoQyxJQUEwQyxJQUF0Q0ssRUFBaUI3RyxRQUFRd0csR0FDM0IsTUFBTSxJQUFJTyxXQUFXLHVCQUd2QixPQUFPLElBQUlULEVBQVMsS0FBTSxDQUFDRSxPQUFRQSxFQUFReEYsUUFBUyxDQUFDZ0csU0FBVXJCLE1BR2pFNUksRUFBUXVDLGFBQWVDLEVBQUtELGFBQzVCLElBQ0UsSUFBSXZDLEVBQVF1QyxhQUNaLE1BQU8ySCxHQUNQbEssRUFBUXVDLGFBQWUsU0FBUzRILEVBQVMxSixHQUN2QzRCLEtBQUs4SCxRQUFVQSxFQUNmOUgsS0FBSzVCLEtBQU9BLEVBQ1osSUFBSTJFLEVBQVEyQixNQUFNb0QsR0FDbEI5SCxLQUFLK0gsTUFBUWhGLEVBQU1nRixPQUVyQnBLLEVBQVF1QyxhQUFhVCxVQUFZbEIsT0FBT1ksT0FBT3VGLE1BQU1qRixXQUNyRDlCLEVBQVF1QyxhQUFhVCxVQUFVdUksWUFBY3JLLEVBQVF1QyxhQUd2RCxTQUFTRCxFQUFNa0csRUFBTzhCLEdBQ3BCLE9BQU8sSUFBSTFGLFNBQVEsU0FBU0ksRUFBU0gsR0FDbkMsSUFBSTBGLEVBQVUsSUFBSWhDLEVBQVFDLEVBQU84QixHQUVqQyxHQUFJQyxFQUFRekIsUUFBVXlCLEVBQVF6QixPQUFPMEIsUUFDbkMsT0FBTzNGLEVBQU8sSUFBSTdFLEVBQVF1QyxhQUFhLFVBQVcsZUFHcEQsSUFBSWtJLEVBQU0sSUFBSUMsZUFFZCxTQUFTQyxJQUNQRixFQUFJRyxRQUdOSCxFQUFJeEYsT0FBUyxXQUNYLElBeEZnQjRGLEVBQ2hCNUcsRUF1Rkl3RSxFQUFVLENBQ1pnQixPQUFRZ0IsRUFBSWhCLE9BQ1pFLFdBQVljLEVBQUlkLFdBQ2hCMUYsU0EzRmM0RyxFQTJGUUosRUFBSUsseUJBQTJCLEdBMUZ2RDdHLEVBQVUsSUFBSUQsRUFHUTZHLEVBQVd4QixRQUFRLGVBQWdCLEtBQ3pDRixNQUFNLFNBQVNoRixTQUFRLFNBQVM0RyxHQUNsRCxJQUFJQyxFQUFRRCxFQUFLNUIsTUFBTSxLQUNuQjFILEVBQU11SixFQUFNbkgsUUFBUXFGLE9BQ3hCLEdBQUl6SCxFQUFLLENBQ1AsSUFBSU4sRUFBUTZKLEVBQU16RCxLQUFLLEtBQUsyQixPQUM1QmpGLEVBQVFHLE9BQU8zQyxFQUFLTixPQUdqQjhDLElBZ0ZId0UsRUFBUUcsSUFBTSxnQkFBaUI2QixFQUFNQSxFQUFJUSxZQUFjeEMsRUFBUXhFLFFBQVFsRCxJQUFJLGlCQUMzRSxJQUFJMkQsRUFBTyxhQUFjK0YsRUFBTUEsRUFBSVosU0FBV1ksRUFBSVMsYUFDbERsRyxFQUFRLElBQUl1RSxFQUFTN0UsRUFBTStELEtBRzdCZ0MsRUFBSXRGLFFBQVUsV0FDWk4sRUFBTyxJQUFJdkIsVUFBVSw0QkFHdkJtSCxFQUFJVSxVQUFZLFdBQ2R0RyxFQUFPLElBQUl2QixVQUFVLDRCQUd2Qm1ILEVBQUlXLFFBQVUsV0FDWnZHLEVBQU8sSUFBSTdFLEVBQVF1QyxhQUFhLFVBQVcsZ0JBRzdDa0ksRUFBSVksS0FBS2QsRUFBUTdCLE9BQVE2QixFQUFRM0IsS0FBSyxHQUVWLFlBQXhCMkIsRUFBUTFCLFlBQ1Y0QixFQUFJYSxpQkFBa0IsRUFDVyxTQUF4QmYsRUFBUTFCLGNBQ2pCNEIsRUFBSWEsaUJBQWtCLEdBR3BCLGlCQUFrQmIsR0FBT2hJLElBQzNCZ0ksRUFBSWMsYUFBZSxRQUdyQmhCLEVBQVF0RyxRQUFRRSxTQUFRLFNBQVNoRCxFQUFPVixHQUN0Q2dLLEVBQUllLGlCQUFpQi9LLEVBQU1VLE1BR3pCb0osRUFBUXpCLFNBQ1Z5QixFQUFRekIsT0FBTzJDLGlCQUFpQixRQUFTZCxHQUV6Q0YsRUFBSWlCLG1CQUFxQixXQUVBLElBQW5CakIsRUFBSWtCLFlBQ05wQixFQUFRekIsT0FBTzhDLG9CQUFvQixRQUFTakIsS0FLbERGLEVBQUlvQixVQUFrQyxJQUF0QnRCLEVBQVFuRSxVQUE0QixLQUFPbUUsRUFBUW5FLGNBSXZFOUQsRUFBTXdKLFVBQVcsRUFFWnRKLEVBQUtGLFFBQ1JFLEVBQUtGLE1BQVFBLEVBQ2JFLEVBQUt3QixRQUFVQSxFQUNmeEIsRUFBSytGLFFBQVVBLEVBQ2YvRixFQUFLK0csU0FBV0EsR0FHbEJ2SixFQUFRZ0UsUUFBVUEsRUFDbEJoRSxFQUFRdUksUUFBVUEsRUFDbEJ2SSxFQUFRdUosU0FBV0EsRUFDbkJ2SixFQUFRc0MsTUFBUUEsRUExZ0JELENBOGdCZixJQWhoQkYsQ0FpaEJHSixVQUNJQSxFQUFTSSxNQUFNd0osVUFDdEI5TCxFQUFVa0MsRUFBU0ksT0FDWHlKLFFBQVU3SixFQUFTSSxNQUMzQnRDLEVBQVFzQyxNQUFRSixFQUFTSSxNQUN6QnRDLEVBQVFnRSxRQUFVOUIsRUFBUzhCLFFBQzNCaEUsRUFBUXVJLFFBQVVyRyxFQUFTcUcsUUFDM0J2SSxFQUFRdUosU0FBV3JILEVBQVNxSCxTQUM1QnRKLEVBQU9ELFFBQVVBLEcsNkJDOWhCakIsSSxFQUFBLE8sb0NBRUFnTSxTQUFTUCxpQkFBa0Isb0JBQW9CLFdBQzlDLElBQUlRLGMsbWNDQUNBLEUsV0FJTCxjLDRGQUFjLFNBQ2I1SixLQUFLNkosc0JBQXdCLGVBQzdCN0osS0FBSzhKLGdCQUFrQjlKLEtBQUs2SixzQkFBd0IsTUFDcEQ3SixLQUFLK0osZUFBaUIvSixLQUFLNkosc0JBQXdCLFNBQ25EN0osS0FBS2dLLGdCQUFrQmhLLEtBQUs2SixzQkFBd0IsV0FDcEQ3SixLQUFLaUssc0JBQXdCLDhCQUM3QmpLLEtBQUtrSyx3QkFBMEIsc0JBQy9CbEssS0FBS21LLHVCQUF5QixxQkFDOUJuSyxLQUFLb0ssb0JBQXNCLGtCQUMzQnBLLEtBQUtxSyx3QkFBMEIsc0JBQy9CckssS0FBS3NLLGdCQUFrQixjQUN2QnRLLEtBQUt1SyxzQkFBd0Isa0JBQzdCdkssS0FBS3dLLHFCQUF1QixpQkFDNUJ4SyxLQUFLeUssbUJBQXFCLFNBQzFCekssS0FBSzBLLGNBQWdCLGlCQUNyQjFLLEtBQUsySyx1QkFBeUIsdUJBQzlCM0ssS0FBSzRLLFdBQ0osc2tCQU1ENUssS0FBSzZLLFdBQWEsV0FFbEI3SyxLQUFLOEssWUFBY25CLFNBQVNvQixjQUFlL0ssS0FBSzZKLHVCQUNoRDdKLEtBQUtnTCxXQUFhaEwsS0FBS2lMLGdCQUN2QmpMLEtBQUtrTCxhQUFldkIsU0FBU29CLGNBQWUvSyxLQUFLZ0ssaUJBQ2pEaEssS0FBS21MLGFBQWV4QixTQUFTb0IsY0FDNUIvSyxLQUFLbUssd0JBSU5uSyxLQUFLb0wsMEJBQ0pDLHNCQUFzQkQsMEJBQ3ZCcEwsS0FBS3NMLHdCQUNKRCxzQkFBc0JDLHdCQUV2QnRMLEtBQUt1TCxhQUNMdkwsS0FBS3dMLGtCQUNMeEwsS0FBS3lMLG9CQUNMekwsS0FBSzBMLGFBQ0wxTCxLQUFLMkwsYUFDTDNMLEtBQUs0TCxrQiwrQ0FTTCxrQkFBWWpDLFNBQVNrQyxpQkFBa0I3TCxLQUFLOEoscUIsd0NBUzVDLE9BQU9ILFNBQVNvQixjQUNmL0ssS0FBSzhKLGdCQUFrQixJQUFNOUosS0FBS3dLLHdCLHVDQVVuQyxPQUFPeEssS0FBSzhMLGtCQUFrQkMsUUFBUUMsUSxrQ0FTdEMsa0JBQVlyQyxTQUFTa0MsaUJBQWtCN0wsS0FBSytKLG9CLHVDQVM1QyxPQUFPSixTQUFTb0IsY0FDZi9LLEtBQUsrSixlQUFpQixJQUFNL0osS0FBS3lLLHNCLGtDQVVsQyxrQkFDSWQsU0FBU2tDLGlCQUNYN0wsS0FBSzZKLHNCQUF3QixjLGtDQVcvQixrQkFDSUYsU0FBU2tDLGlCQUNYN0wsS0FBSzZKLHNCQUF3QixjLHVDQVcvQixrQkFDSUYsU0FBU2tDLGlCQUNYN0wsS0FBSzZKLHNCQUF3QixLQUFPN0osS0FBSzZLLGdCLDZDQVczQyxJQUFNb0IsRUFBY2pNLEtBQUtrTSxpQkFFekIsT0FDQzNHLEtBQUs0RyxVQUFXbk0sS0FBS29NLHdCQUNyQjdHLEtBQUs0RyxVQUFXbk0sS0FBS2dMLFdBQVlpQixNLHdDQVFsQ2pNLEtBQUtrTCxhQUFhbUIsVUFBYXJNLEtBQUtzTSx5Qix3Q0FNbkIsV0FDakIsR0FBT3RNLEtBQUtzTSx1QkFBWixDQUlBLElBQU1DLEVBQWN2TSxLQUFLd00saUJBRW5CQyxFQUFhOUMsU0FBUytDLGNBQWUsUUFtQjNDLE9BbEJBRCxFQUFXRSxPQUFTM00sS0FBSzhLLFlBQVk4QixhQUFjLFVBQ25ESCxFQUFXcEcsT0FBU3JHLEtBQUs4SyxZQUFZekUsT0FDckNvRyxFQUFXSSxZQUFhTixFQUFZTyxXQUFXLElBRTFCQyxHQUFmQSxTQUFvQlIsRUFBWVYsaUJBQWtCLFdBQzNDaEssS0FBSyxTQUFFc0UsR0FDbkIsT0FBU3NHLEVBQVcxQixjQUFlLElBQU01RSxFQUFNNkcsSUFBS2xPLE1BQ25EcUgsRUFBTXJILFNBR2FtTyxHQUFmQSxTQUNGak4sS0FBSzhLLFlBQVllLGlCQUFrQiwwQkFFMUJoSyxLQUFLLFNBQUVzRSxHQUNuQixPQUFPc0csRUFBV0ksWUFBYTFHLEVBQU0yRyxXQUFXLE9BRWpEbkQsU0FBU3RILEtBQUt3SyxZQUFhSixHQUVwQnhNLE1BQU9ELEtBQUs4SyxZQUFZOEIsYUFBYyxVQUFZLENBQ3hEdkcsT0FBUW9HLEVBQVdwRyxPQUNuQmhFLEtBQU0sSUFBSWdDLGdCQUFKLFlBQTBCLElBQUlGLFNBQVVzSSxRQUU3QzdILE1BQU0sU0FBRTRDLEdBY1IsT0FiS0EsRUFBU0gsSUFDYixFQUFLNkYsWUFDSixFQUFLQyxlQUNMLEVBQUsvQiwyQkFFTixFQUFLSixXQUFhLEVBQUtDLGlCQUV2QixFQUFLaUMsWUFDSixFQUFLRSxhQUNMLEVBQUs5Qix5QkFJQTlELEVBQVNsQyxVQUVoQitILFNBQVMsV0FDVFosRUFBV2EsV0FBV0MsWUFBYWQsR0FDbkMsRUFBS2Isd0IsbUNBVU00QixHQUFRLFdBQ2ZDLEVBQVNBLEdBQVRBLFNBQWNELEVBQU0zQixpQkFBa0IsV0FFdEM2QixFQUFPLEdBU2IsT0FSQUQsRUFBTzNMLFNBQVMsU0FBRXFFLEdBQ2pCLElBQU13SCxFQUFRaEUsU0FBU29CLGNBQ3RCLEVBQUtsQixzQkFBd0IsZUFBaUIxRCxFQUFNNkcsR0FBSyxNQUcxRFUsRUFBTUMsRUFBTUMsV0FBY3pILEVBQU1ySCxTQUcxQjRPLEksc0NBUVEsV0FDZixPQUFPMU4sS0FBSzZOLFlBQVloTSxLQUFLLFNBQUUyTCxHQUM5QixPQUFPLEVBQUtNLGFBQWNOLFEsMkNBVTNCLE9BQU94TixLQUFLOE4sYUFBYzlOLEtBQUt3TSxvQixtQ0FPL0J4TSxLQUFLK04sUUFBVXBFLFNBQVMrQyxjQUFlLE1BQ3ZDMU0sS0FBSytOLFFBQVFDLFVBQVVDLElBQUssbUJBQzVCak8sS0FBSzhLLFlBQVlvRCxhQUNoQmxPLEtBQUsrTixRQUNML04sS0FBSzhLLFlBQVlxRCxjLHFDQVVIbkIsR0FDZixJQUFNbEYsRUFBVTZCLFNBQVMrQyxjQUFlLE9BSXhDLE9BSEE1RSxFQUFRa0YsR0FBS0EsRUFDYmhOLEtBQUs4SyxZQUFZb0QsYUFBY3BHLEVBQVM5SCxLQUFLOEssWUFBWXFELFlBRWxEckcsSSx3Q0FPUDlILEtBQUttTixlQUFpQm5OLEtBQUtvTyxlQUFnQixlQUMzQ3BPLEtBQUtvTixhQUFlcE4sS0FBS29PLGVBQWdCLGUsMENBT3pDcE8sS0FBS3FPLGVBQWlCMUUsU0FBUytDLGNBQWUsU0FDOUMxTSxLQUFLcU8sZUFBZXJCLEdBQUtoTixLQUFLMEssY0FDOUIxSyxLQUFLcU8sZUFBZUMsTUFBTUMsUUFBVSxPQUNwQzVFLFNBQVN0SCxLQUFLd0ssWUFBYTdNLEtBQUtxTyxrQiwyQ0FPaENyTyxLQUFLcU8sZUFBZUMsTUFBTUMsUUFBVSxPQUNwQ3ZPLEtBQUtxTyxlQUFlTCxVQUFVUSxPQUFReE8sS0FBSzJLLHdCQUMzQ2hCLFNBQVN0SCxLQUFLd0ssWUFBYTdNLEtBQUtxTyxrQixvQ0FTaEMsT0FBTzFFLFNBQVNvQixjQUNmL0ssS0FBSzZKLHNCQUNKLEtBQ0E3SixLQUFLeUssbUJBQ0wsS0FDQXpLLEtBQUs2SyxZQUNMNEQseUIsZ0NBT0YsSUFBSUMsRUFBVzFPLEtBQUsyTyxjQUNwQkQsRUFBU0UsY0FBY1YsYUFDdEJRLEVBQVM1QixXQUFXLEdBQ3BCNEIsRUFBU0csb0JBSVYsSUFBTWxCLEdBRE5lLEVBQVcxTyxLQUFLMk8sZUFDTzVELGNBQWUsU0FDaEM1RSxFQUFRdUksRUFBUzNELGNBQWUsU0FFaEMrRCxFQUFRM0ksRUFBTTZHLEdBQUdsRyxNQUFPLEtBQ3hCaUksRUFBUUQsRUFBTyxHQUFNLEtBQVFFLFNBQVVGLEVBQU8sSUFBUSxHQUU1RG5CLEVBQU1zQixRQUFVRixFQUNoQnBCLEVBQU1DLFVBQVksR0FFbEJ6SCxFQUFNNkcsR0FBSytCLEVBQ1g1SSxFQUFNckgsTUFBUSxHQUNkcUgsRUFBTStJLGFBQWMsUUFBUyxJQUM3QmxQLEtBQUttUCxZQUFhaEosRUFBTyxJQUV6Qm5HLEtBQUsyTCxhQUVMM0wsS0FBS29QLFVBQVd6QixLLG1DQU9KLFdBQ1IwQixFQUFlLEVBRW5CclAsS0FBSzZOLFlBQVloTSxLQUFLLFNBQUUyTCxFQUFPeEIsR0FDOUJ3QixFQUFNUSxVQUFVQyxJQUFLLGFBRWhCLEVBQUszRCxrQkFBb0JrRCxFQUFNaUIsdUJBQXVCekIsS0FDMURxQyxFQUFlckQsRUFDZndCLEVBQU1RLFVBQVVDLElBQUssRUFBS3hELHFCQUczQixJQUFNNkUsRUFBTzNGLFNBQVMrQyxjQUFlLE9BS3JDLE9BSkE0QyxFQUFLdEIsVUFBVUMsSUFBSyxFQUFLcEQsWUFDekJ5RSxFQUFLMUIsVUFBWSxFQUFLaEQsV0FDdEI0QyxFQUFNekMsY0FBZSxNQUFPOEIsWUFBYXlDLEdBRWxDLFFBR1J0UCxLQUFLdVAsYUFBYTFOLEtBQUssU0FBRUssRUFBUThKLEdBVWhDLE9BVEE5SixFQUFPOEwsVUFBVUMsSUFBSyxXQUN0Qi9MLEVBQU82SixRQUFRQyxNQUFRQSxFQUV2QixFQUFLK0IsUUFBUWxCLFlBQWEzSyxHQUNyQjhKLElBQVVxRCxJQUNkbk4sRUFBTzhMLFVBQVVDLElBQUssRUFBSzFELHVCQUMzQnJJLEVBQU84TCxVQUFVQyxJQUFLLEVBQUt6RCx1QkFHckIsVSxtQ0FPSSxXQUNaeEssS0FBS3VQLGFBQWExTixLQUFLLFNBQUVLLEVBQVFyRSxFQUFHK0QsR0ErQm5DLE9BOUJBTSxFQUFPc04sUUFBVSxTQUFFQyxHQUNsQkEsRUFBTUMsaUJBRU4sSUFBTTFELEVBQVF5RCxFQUFNRSxPQUFPNUQsUUFBUUMsTUFHbkMsR0FBS0EsSUFGZSxFQUFLRSxpQkFHeEIsT0FBTyxFQUdSLEVBQUswRCxrQkFFTGhPLEVBQVFDLEtBQUssU0FBRWdPLEdBQ2QsT0FBT0EsRUFBUTdCLFVBQVVRLE9BQ3hCLEVBQUtoRSx5QkFHUDVJLEVBQVNvSyxHQUFRZ0MsVUFBVUMsSUFBSyxFQUFLekQsc0JBRXJDLElBQU1zRixFQUFTLEVBQUtqQyxZQVFwQixPQVBBaUMsRUFBT2pPLEtBQUssU0FBRTJMLEdBQ2IsT0FBT0EsRUFBTVEsVUFBVVEsT0FBUSxFQUFLL0QsdUJBRXJDcUYsRUFBUTlELEdBQVFnQyxVQUFVQyxJQUFLLEVBQUt4RCxvQkFFcEMsRUFBS21CLG1CQUVFLEdBR0QsUUFHUjVMLEtBQUsrUCxZQUFZbE8sS0FBSyxTQUFFc0UsR0FLdkIsT0FKQUEsRUFBTTZKLFFBQVUsV0FDZixFQUFLcEUsbUJBR0MsUUFHUjVMLEtBQUtpUSxZQUFZcE8sS0FBSyxTQUFFOEwsR0FPdkIsT0FOQUEsRUFBTTZCLFFBQVUsU0FBRUMsR0FHakIsT0FGQUEsRUFBTUMsaUJBQ04sRUFBS04sVUFBV0ssRUFBTUUsU0FDZixHQUdELFFBR1IzUCxLQUFLcU8sZUFBZTZCLE9BQVMsV0FDNUIsRUFBS0MsYUFHTm5RLEtBQUtxTyxlQUFlK0IsUUFBVSxTQUFFOVAsR0FDMUIsV0FBYUEsRUFBRWxCLEtBQ25CLEVBQUsrUSxXQUFXLEdBR1osVUFBWTdQLEVBQUVsQixLQUNsQixFQUFLK1EsYUFJUG5RLEtBQUtxUSxpQkFBaUJ4TyxLQUFLLFNBQUV5TixHQU81QixPQU5BQSxFQUFLRSxRQUFVLFNBQUVDLEdBR2hCLE9BRkFBLEVBQU1DLGlCQUNOLEVBQUtZLFFBQVNiLEVBQU1FLFNBQ2IsR0FHRCxRQUdSM1AsS0FBS2tMLGFBQWFzRSxRQUFVLFNBQUVDLEdBRzdCLE9BRkFBLEVBQU1DLGlCQUNOLEVBQUtFLG1CQUNFLEdBR1JqRyxTQUFTb0IsY0FBZS9LLEtBQUtrSyx5QkFBMEJzRixRQUFVLFNBQ2hFQyxHQUlBLE9BRkFBLEVBQU1DLGlCQUNOLEVBQUt2RSxhQUFhbUQsTUFBTUMsUUFBVSxTQUMzQixHQUdSdk8sS0FBS21MLGFBQWFxRSxRQUFVLFdBQzNCLEVBQUtlLG9CQUdONUcsU0FBU29CLGNBQWUvSyxLQUFLb0sscUJBQXNCb0YsUUFBVSxTQUM1REMsR0FFQUEsRUFBTWUsa0JBQ04sRUFBS0QsbUJBQ0w1RyxTQUFTb0IsY0FBZSxFQUFLZCx1QkFBd0J3RyxVQUd0RDlHLFNBQVNvQixjQUFlL0ssS0FBS3FLLHlCQUEwQm1GLFFBQVUsU0FDaEVDLEdBRUFBLEVBQU1lLGtCQUNOLEVBQUtELHNCLHlDQVFOdlEsS0FBS21MLGFBQWFtRCxNQUFNQyxRQUFVLFMsZ0NBUXhCWixHQUNWQSxFQUFNTCxXQUFXVCxZQUFhN00sS0FBS3FPLGdCQUNuQ3JPLEtBQUtxTyxlQUFldlAsTUFBUTZPLEVBQU1DLFVBRWxDNU4sS0FBS3FPLGVBQWVMLFVBQVVRLE9BQVF4TyxLQUFLMkssd0JBQzNDM0ssS0FBS3FPLGVBQWVDLE1BQU1DLFFBQVUsUUFDcEN2TyxLQUFLcU8sZUFBZXFDLFUsb0NBU05DLEdBQ2QsTUFBTyxZQUFLM1EsS0FBS3dNLGlCQUFpQlgsaUJBQWtCLFdBQVkrRSxRQUMvRCxTQUFFQyxFQUFLbEQsR0FDTixPQUFPa0QsR0FBT2xELEVBQU1DLFlBQWMrQyxLQUVuQyxLLGtDQVMwQixJQUFqQkcsRUFBaUIsd0RBQzNCLEdBQUssU0FBVzlRLEtBQUtxTyxlQUFlQyxNQUFNQyxRQUExQyxDQUlBLElBQU1vQyxFQUFXM1EsS0FBS3FPLGVBQWV2UCxNQUFNK0gsT0FFM0MsR0FBSyxLQUFPOEosRUFBVyxDQUN0QixJQUFNSSxFQUFhcEgsU0FBU3FILGVBQWdCaFIsS0FBSzBLLGVBQy9Da0UsY0FLRixPQUpBNU8sS0FBS2lSLHFCQUNMRixFQUFXekQsV0FBV0MsWUFBYXdELFFBQ25DL1EsS0FBSzRMLGtCQUtOLElBQU0rQixFQUFRM04sS0FBS3FPLGVBQWVmLFdBQVd2QyxjQUFlLFNBQzVELEdBQUsrRixHQUFVSCxJQUFhaEQsRUFBTUMsVUFDakM1TixLQUFLaVIsMEJBS04sR0FBT2pSLEtBQUtrUixjQUFlUCxHQUEzQixDQU1BLElBQU14SyxFQUFRbkcsS0FBS3FPLGVBQWVmLFdBQVd2QyxjQUFlLFNBRTVEL0ssS0FBS2lSLHFCQUVMdEQsRUFBTUMsVUFBWStDLEVBQ2xCM1EsS0FBS21QLFlBQWFoSixFQUFPd0ssR0FFekIzUSxLQUFLNEwsdUJBWko1TCxLQUFLcU8sZUFBZUwsVUFBVUMsSUFBS2pPLEtBQUsySywyQixrQ0FxQjdCeEUsRUFBT3dLLEdBRW5CeEssRUFBTS9ILEtBQU8rSCxFQUFNL0gsS0FBSzRJLFFBQ3ZCLGtCQUNBLE1BQVEySixFQUFXLE8sbUNBU1A3SSxHQUNiQSxFQUFROEYsVUFBWSxHQUNwQjlGLEVBQVFrRyxVQUFVUSxPQUFRLFksc0NBTzFCeE8sS0FBS21SLGFBQWNuUixLQUFLbU4sZ0JBQ3hCbk4sS0FBS21SLGFBQWNuUixLQUFLb04sY0FDeEJnRSxhQUFjcFIsS0FBS3FSLFksa0NBU1BDLEVBQUl4SixHQUFVLFdBQzFCd0osRUFBRzFELFVBQVk5RixFQUNmd0osRUFBR3RELFVBQVVDLElBQUssVUFFbEJqTyxLQUFLcVIsU0FBV0UsWUFBWSxXQUMzQixFQUFLQyxrQkFDSCxTLGVBSVU1SCIsImZpbGUiOiJqcy9zZXR0aW5ncy9hcHAuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG4iLCJ2YXIgX19zZWxmX18gPSAoZnVuY3Rpb24gKHJvb3QpIHtcbmZ1bmN0aW9uIEYoKSB7XG50aGlzLmZldGNoID0gZmFsc2U7XG50aGlzLkRPTUV4Y2VwdGlvbiA9IHJvb3QuRE9NRXhjZXB0aW9uXG59XG5GLnByb3RvdHlwZSA9IHJvb3Q7XG5yZXR1cm4gbmV3IEYoKTtcbn0pKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOiB0aGlzKTtcbihmdW5jdGlvbihzZWxmKSB7XG5cbnZhciBpcnJlbGV2YW50ID0gKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cbiAgdmFyIHN1cHBvcnQgPSB7XG4gICAgc2VhcmNoUGFyYW1zOiAnVVJMU2VhcmNoUGFyYW1zJyBpbiBzZWxmLFxuICAgIGl0ZXJhYmxlOiAnU3ltYm9sJyBpbiBzZWxmICYmICdpdGVyYXRvcicgaW4gU3ltYm9sLFxuICAgIGJsb2I6XG4gICAgICAnRmlsZVJlYWRlcicgaW4gc2VsZiAmJlxuICAgICAgJ0Jsb2InIGluIHNlbGYgJiZcbiAgICAgIChmdW5jdGlvbigpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBuZXcgQmxvYigpO1xuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICBmb3JtRGF0YTogJ0Zvcm1EYXRhJyBpbiBzZWxmLFxuICAgIGFycmF5QnVmZmVyOiAnQXJyYXlCdWZmZXInIGluIHNlbGZcbiAgfTtcblxuICBmdW5jdGlvbiBpc0RhdGFWaWV3KG9iaikge1xuICAgIHJldHVybiBvYmogJiYgRGF0YVZpZXcucHJvdG90eXBlLmlzUHJvdG90eXBlT2Yob2JqKVxuICB9XG5cbiAgaWYgKHN1cHBvcnQuYXJyYXlCdWZmZXIpIHtcbiAgICB2YXIgdmlld0NsYXNzZXMgPSBbXG4gICAgICAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICAgICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICAgICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgICAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgICAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgVWludDMyQXJyYXldJyxcbiAgICAgICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgRmxvYXQ2NEFycmF5XSdcbiAgICBdO1xuXG4gICAgdmFyIGlzQXJyYXlCdWZmZXJWaWV3ID1cbiAgICAgIEFycmF5QnVmZmVyLmlzVmlldyB8fFxuICAgICAgZnVuY3Rpb24ob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogJiYgdmlld0NsYXNzZXMuaW5kZXhPZihPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSkgPiAtMVxuICAgICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZU5hbWUobmFtZSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIG5hbWUgPSBTdHJpbmcobmFtZSk7XG4gICAgfVxuICAgIGlmICgvW15hLXowLTlcXC0jJCUmJyorLl5fYHx+XS9pLnRlc3QobmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgY2hhcmFjdGVyIGluIGhlYWRlciBmaWVsZCBuYW1lJylcbiAgICB9XG4gICAgcmV0dXJuIG5hbWUudG9Mb3dlckNhc2UoKVxuICB9XG5cbiAgZnVuY3Rpb24gbm9ybWFsaXplVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIC8vIEJ1aWxkIGEgZGVzdHJ1Y3RpdmUgaXRlcmF0b3IgZm9yIHRoZSB2YWx1ZSBsaXN0XG4gIGZ1bmN0aW9uIGl0ZXJhdG9yRm9yKGl0ZW1zKSB7XG4gICAgdmFyIGl0ZXJhdG9yID0ge1xuICAgICAgbmV4dDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGl0ZW1zLnNoaWZ0KCk7XG4gICAgICAgIHJldHVybiB7ZG9uZTogdmFsdWUgPT09IHVuZGVmaW5lZCwgdmFsdWU6IHZhbHVlfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoc3VwcG9ydC5pdGVyYWJsZSkge1xuICAgICAgaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGl0ZXJhdG9yXG4gIH1cblxuICBmdW5jdGlvbiBIZWFkZXJzKGhlYWRlcnMpIHtcbiAgICB0aGlzLm1hcCA9IHt9O1xuXG4gICAgaWYgKGhlYWRlcnMgaW5zdGFuY2VvZiBIZWFkZXJzKSB7XG4gICAgICBoZWFkZXJzLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICAgICAgdGhpcy5hcHBlbmQobmFtZSwgdmFsdWUpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGhlYWRlcnMpKSB7XG4gICAgICBoZWFkZXJzLmZvckVhY2goZnVuY3Rpb24oaGVhZGVyKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kKGhlYWRlclswXSwgaGVhZGVyWzFdKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoaGVhZGVycykge1xuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoaGVhZGVycykuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kKG5hbWUsIGhlYWRlcnNbbmFtZV0pO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfVxuICB9XG5cbiAgSGVhZGVycy5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICBuYW1lID0gbm9ybWFsaXplTmFtZShuYW1lKTtcbiAgICB2YWx1ZSA9IG5vcm1hbGl6ZVZhbHVlKHZhbHVlKTtcbiAgICB2YXIgb2xkVmFsdWUgPSB0aGlzLm1hcFtuYW1lXTtcbiAgICB0aGlzLm1hcFtuYW1lXSA9IG9sZFZhbHVlID8gb2xkVmFsdWUgKyAnLCAnICsgdmFsdWUgOiB2YWx1ZTtcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgZGVsZXRlIHRoaXMubWFwW25vcm1hbGl6ZU5hbWUobmFtZSldO1xuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBuYW1lID0gbm9ybWFsaXplTmFtZShuYW1lKTtcbiAgICByZXR1cm4gdGhpcy5oYXMobmFtZSkgPyB0aGlzLm1hcFtuYW1lXSA6IG51bGxcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwLmhhc093blByb3BlcnR5KG5vcm1hbGl6ZU5hbWUobmFtZSkpXG4gIH07XG5cbiAgSGVhZGVycy5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICB0aGlzLm1hcFtub3JtYWxpemVOYW1lKG5hbWUpXSA9IG5vcm1hbGl6ZVZhbHVlKHZhbHVlKTtcbiAgfTtcblxuICBIZWFkZXJzLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24oY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMubWFwKSB7XG4gICAgICBpZiAodGhpcy5tYXAuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB0aGlzLm1hcFtuYW1lXSwgbmFtZSwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLmtleXMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICAgIGl0ZW1zLnB1c2gobmFtZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yRm9yKGl0ZW1zKVxuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLnZhbHVlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBpdGVtcyA9IFtdO1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaXRlbXMucHVzaCh2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yRm9yKGl0ZW1zKVxuICB9O1xuXG4gIEhlYWRlcnMucHJvdG90eXBlLmVudHJpZXMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICAgIGl0ZW1zLnB1c2goW25hbWUsIHZhbHVlXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZXJhdG9yRm9yKGl0ZW1zKVxuICB9O1xuXG4gIGlmIChzdXBwb3J0Lml0ZXJhYmxlKSB7XG4gICAgSGVhZGVycy5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9IEhlYWRlcnMucHJvdG90eXBlLmVudHJpZXM7XG4gIH1cblxuICBmdW5jdGlvbiBjb25zdW1lZChib2R5KSB7XG4gICAgaWYgKGJvZHkuYm9keVVzZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgVHlwZUVycm9yKCdBbHJlYWR5IHJlYWQnKSlcbiAgICB9XG4gICAgYm9keS5ib2R5VXNlZCA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiBmaWxlUmVhZGVyUmVhZHkocmVhZGVyKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXNvbHZlKHJlYWRlci5yZXN1bHQpO1xuICAgICAgfTtcbiAgICAgIHJlYWRlci5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJlamVjdChyZWFkZXIuZXJyb3IpO1xuICAgICAgfTtcbiAgICB9KVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZEJsb2JBc0FycmF5QnVmZmVyKGJsb2IpIHtcbiAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICB2YXIgcHJvbWlzZSA9IGZpbGVSZWFkZXJSZWFkeShyZWFkZXIpO1xuICAgIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihibG9iKTtcbiAgICByZXR1cm4gcHJvbWlzZVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZEJsb2JBc1RleHQoYmxvYikge1xuICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgIHZhciBwcm9taXNlID0gZmlsZVJlYWRlclJlYWR5KHJlYWRlcik7XG4gICAgcmVhZGVyLnJlYWRBc1RleHQoYmxvYik7XG4gICAgcmV0dXJuIHByb21pc2VcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWRBcnJheUJ1ZmZlckFzVGV4dChidWYpIHtcbiAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1Zik7XG4gICAgdmFyIGNoYXJzID0gbmV3IEFycmF5KHZpZXcubGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgY2hhcnNbaV0gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHZpZXdbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gY2hhcnMuam9pbignJylcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1ZmZlckNsb25lKGJ1Zikge1xuICAgIGlmIChidWYuc2xpY2UpIHtcbiAgICAgIHJldHVybiBidWYuc2xpY2UoMClcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShidWYuYnl0ZUxlbmd0aCk7XG4gICAgICB2aWV3LnNldChuZXcgVWludDhBcnJheShidWYpKTtcbiAgICAgIHJldHVybiB2aWV3LmJ1ZmZlclxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIEJvZHkoKSB7XG4gICAgdGhpcy5ib2R5VXNlZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5faW5pdEJvZHkgPSBmdW5jdGlvbihib2R5KSB7XG4gICAgICB0aGlzLl9ib2R5SW5pdCA9IGJvZHk7XG4gICAgICBpZiAoIWJvZHkpIHtcbiAgICAgICAgdGhpcy5fYm9keVRleHQgPSAnJztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGJvZHkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMuX2JvZHlUZXh0ID0gYm9keTtcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5ibG9iICYmIEJsb2IucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkpIHtcbiAgICAgICAgdGhpcy5fYm9keUJsb2IgPSBib2R5O1xuICAgICAgfSBlbHNlIGlmIChzdXBwb3J0LmZvcm1EYXRhICYmIEZvcm1EYXRhLnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKGJvZHkpKSB7XG4gICAgICAgIHRoaXMuX2JvZHlGb3JtRGF0YSA9IGJvZHk7XG4gICAgICB9IGVsc2UgaWYgKHN1cHBvcnQuc2VhcmNoUGFyYW1zICYmIFVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihib2R5KSkge1xuICAgICAgICB0aGlzLl9ib2R5VGV4dCA9IGJvZHkudG9TdHJpbmcoKTtcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5hcnJheUJ1ZmZlciAmJiBzdXBwb3J0LmJsb2IgJiYgaXNEYXRhVmlldyhib2R5KSkge1xuICAgICAgICB0aGlzLl9ib2R5QXJyYXlCdWZmZXIgPSBidWZmZXJDbG9uZShib2R5LmJ1ZmZlcik7XG4gICAgICAgIC8vIElFIDEwLTExIGNhbid0IGhhbmRsZSBhIERhdGFWaWV3IGJvZHkuXG4gICAgICAgIHRoaXMuX2JvZHlJbml0ID0gbmV3IEJsb2IoW3RoaXMuX2JvZHlBcnJheUJ1ZmZlcl0pO1xuICAgICAgfSBlbHNlIGlmIChzdXBwb3J0LmFycmF5QnVmZmVyICYmIChBcnJheUJ1ZmZlci5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihib2R5KSB8fCBpc0FycmF5QnVmZmVyVmlldyhib2R5KSkpIHtcbiAgICAgICAgdGhpcy5fYm9keUFycmF5QnVmZmVyID0gYnVmZmVyQ2xvbmUoYm9keSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9ib2R5VGV4dCA9IGJvZHkgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYm9keSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5oZWFkZXJzLmdldCgnY29udGVudC10eXBlJykpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRoaXMuaGVhZGVycy5zZXQoJ2NvbnRlbnQtdHlwZScsICd0ZXh0L3BsYWluO2NoYXJzZXQ9VVRGLTgnKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9ib2R5QmxvYiAmJiB0aGlzLl9ib2R5QmxvYi50eXBlKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXJzLnNldCgnY29udGVudC10eXBlJywgdGhpcy5fYm9keUJsb2IudHlwZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5zZWFyY2hQYXJhbXMgJiYgVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKGJvZHkpKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXJzLnNldCgnY29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDtjaGFyc2V0PVVURi04Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHN1cHBvcnQuYmxvYikge1xuICAgICAgdGhpcy5ibG9iID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciByZWplY3RlZCA9IGNvbnN1bWVkKHRoaXMpO1xuICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0ZWRcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9ib2R5QmxvYikge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keUJsb2IpXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYm9keUFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgQmxvYihbdGhpcy5fYm9keUFycmF5QnVmZmVyXSkpXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYm9keUZvcm1EYXRhKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgcmVhZCBGb3JtRGF0YSBib2R5IGFzIGJsb2InKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEJsb2IoW3RoaXMuX2JvZHlUZXh0XSkpXG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHRoaXMuYXJyYXlCdWZmZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2JvZHlBcnJheUJ1ZmZlcikge1xuICAgICAgICAgIHJldHVybiBjb25zdW1lZCh0aGlzKSB8fCBQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keUFycmF5QnVmZmVyKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmJsb2IoKS50aGVuKHJlYWRCbG9iQXNBcnJheUJ1ZmZlcilcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLnRleHQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWplY3RlZCA9IGNvbnN1bWVkKHRoaXMpO1xuICAgICAgaWYgKHJlamVjdGVkKSB7XG4gICAgICAgIHJldHVybiByZWplY3RlZFxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fYm9keUJsb2IpIHtcbiAgICAgICAgcmV0dXJuIHJlYWRCbG9iQXNUZXh0KHRoaXMuX2JvZHlCbG9iKVxuICAgICAgfSBlbHNlIGlmICh0aGlzLl9ib2R5QXJyYXlCdWZmZXIpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZWFkQXJyYXlCdWZmZXJBc1RleHQodGhpcy5fYm9keUFycmF5QnVmZmVyKSlcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fYm9keUZvcm1EYXRhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY291bGQgbm90IHJlYWQgRm9ybURhdGEgYm9keSBhcyB0ZXh0JylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keVRleHQpXG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChzdXBwb3J0LmZvcm1EYXRhKSB7XG4gICAgICB0aGlzLmZvcm1EYXRhID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRleHQoKS50aGVuKGRlY29kZSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5qc29uID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50ZXh0KCkudGhlbihKU09OLnBhcnNlKVxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLy8gSFRUUCBtZXRob2RzIHdob3NlIGNhcGl0YWxpemF0aW9uIHNob3VsZCBiZSBub3JtYWxpemVkXG4gIHZhciBtZXRob2RzID0gWydERUxFVEUnLCAnR0VUJywgJ0hFQUQnLCAnT1BUSU9OUycsICdQT1NUJywgJ1BVVCddO1xuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZU1ldGhvZChtZXRob2QpIHtcbiAgICB2YXIgdXBjYXNlZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgIHJldHVybiBtZXRob2RzLmluZGV4T2YodXBjYXNlZCkgPiAtMSA/IHVwY2FzZWQgOiBtZXRob2RcbiAgfVxuXG4gIGZ1bmN0aW9uIFJlcXVlc3QoaW5wdXQsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgYm9keSA9IG9wdGlvbnMuYm9keTtcblxuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIFJlcXVlc3QpIHtcbiAgICAgIGlmIChpbnB1dC5ib2R5VXNlZCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBbHJlYWR5IHJlYWQnKVxuICAgICAgfVxuICAgICAgdGhpcy51cmwgPSBpbnB1dC51cmw7XG4gICAgICB0aGlzLmNyZWRlbnRpYWxzID0gaW5wdXQuY3JlZGVudGlhbHM7XG4gICAgICBpZiAoIW9wdGlvbnMuaGVhZGVycykge1xuICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgSGVhZGVycyhpbnB1dC5oZWFkZXJzKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWV0aG9kID0gaW5wdXQubWV0aG9kO1xuICAgICAgdGhpcy5tb2RlID0gaW5wdXQubW9kZTtcbiAgICAgIHRoaXMuc2lnbmFsID0gaW5wdXQuc2lnbmFsO1xuICAgICAgaWYgKCFib2R5ICYmIGlucHV0Ll9ib2R5SW5pdCAhPSBudWxsKSB7XG4gICAgICAgIGJvZHkgPSBpbnB1dC5fYm9keUluaXQ7XG4gICAgICAgIGlucHV0LmJvZHlVc2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cmwgPSBTdHJpbmcoaW5wdXQpO1xuICAgIH1cblxuICAgIHRoaXMuY3JlZGVudGlhbHMgPSBvcHRpb25zLmNyZWRlbnRpYWxzIHx8IHRoaXMuY3JlZGVudGlhbHMgfHwgJ3NhbWUtb3JpZ2luJztcbiAgICBpZiAob3B0aW9ucy5oZWFkZXJzIHx8ICF0aGlzLmhlYWRlcnMpIHtcbiAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyBIZWFkZXJzKG9wdGlvbnMuaGVhZGVycyk7XG4gICAgfVxuICAgIHRoaXMubWV0aG9kID0gbm9ybWFsaXplTWV0aG9kKG9wdGlvbnMubWV0aG9kIHx8IHRoaXMubWV0aG9kIHx8ICdHRVQnKTtcbiAgICB0aGlzLm1vZGUgPSBvcHRpb25zLm1vZGUgfHwgdGhpcy5tb2RlIHx8IG51bGw7XG4gICAgdGhpcy5zaWduYWwgPSBvcHRpb25zLnNpZ25hbCB8fCB0aGlzLnNpZ25hbDtcbiAgICB0aGlzLnJlZmVycmVyID0gbnVsbDtcblxuICAgIGlmICgodGhpcy5tZXRob2QgPT09ICdHRVQnIHx8IHRoaXMubWV0aG9kID09PSAnSEVBRCcpICYmIGJvZHkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0JvZHkgbm90IGFsbG93ZWQgZm9yIEdFVCBvciBIRUFEIHJlcXVlc3RzJylcbiAgICB9XG4gICAgdGhpcy5faW5pdEJvZHkoYm9keSk7XG4gIH1cblxuICBSZXF1ZXN0LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdCh0aGlzLCB7Ym9keTogdGhpcy5fYm9keUluaXR9KVxuICB9O1xuXG4gIGZ1bmN0aW9uIGRlY29kZShib2R5KSB7XG4gICAgdmFyIGZvcm0gPSBuZXcgRm9ybURhdGEoKTtcbiAgICBib2R5XG4gICAgICAudHJpbSgpXG4gICAgICAuc3BsaXQoJyYnKVxuICAgICAgLmZvckVhY2goZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAgICAgaWYgKGJ5dGVzKSB7XG4gICAgICAgICAgdmFyIHNwbGl0ID0gYnl0ZXMuc3BsaXQoJz0nKTtcbiAgICAgICAgICB2YXIgbmFtZSA9IHNwbGl0LnNoaWZ0KCkucmVwbGFjZSgvXFwrL2csICcgJyk7XG4gICAgICAgICAgdmFyIHZhbHVlID0gc3BsaXQuam9pbignPScpLnJlcGxhY2UoL1xcKy9nLCAnICcpO1xuICAgICAgICAgIGZvcm0uYXBwZW5kKGRlY29kZVVSSUNvbXBvbmVudChuYW1lKSwgZGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIHJldHVybiBmb3JtXG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZUhlYWRlcnMocmF3SGVhZGVycykge1xuICAgIHZhciBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAvLyBSZXBsYWNlIGluc3RhbmNlcyBvZiBcXHJcXG4gYW5kIFxcbiBmb2xsb3dlZCBieSBhdCBsZWFzdCBvbmUgc3BhY2Ugb3IgaG9yaXpvbnRhbCB0YWIgd2l0aCBhIHNwYWNlXG4gICAgLy8gaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzcyMzAjc2VjdGlvbi0zLjJcbiAgICB2YXIgcHJlUHJvY2Vzc2VkSGVhZGVycyA9IHJhd0hlYWRlcnMucmVwbGFjZSgvXFxyP1xcbltcXHQgXSsvZywgJyAnKTtcbiAgICBwcmVQcm9jZXNzZWRIZWFkZXJzLnNwbGl0KC9cXHI/XFxuLykuZm9yRWFjaChmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgcGFydHMgPSBsaW5lLnNwbGl0KCc6Jyk7XG4gICAgICB2YXIga2V5ID0gcGFydHMuc2hpZnQoKS50cmltKCk7XG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHBhcnRzLmpvaW4oJzonKS50cmltKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBoZWFkZXJzXG4gIH1cblxuICBCb2R5LmNhbGwoUmVxdWVzdC5wcm90b3R5cGUpO1xuXG4gIGZ1bmN0aW9uIFJlc3BvbnNlKGJvZHlJbml0LCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICBvcHRpb25zID0ge307XG4gICAgfVxuXG4gICAgdGhpcy50eXBlID0gJ2RlZmF1bHQnO1xuICAgIHRoaXMuc3RhdHVzID0gb3B0aW9ucy5zdGF0dXMgPT09IHVuZGVmaW5lZCA/IDIwMCA6IG9wdGlvbnMuc3RhdHVzO1xuICAgIHRoaXMub2sgPSB0aGlzLnN0YXR1cyA+PSAyMDAgJiYgdGhpcy5zdGF0dXMgPCAzMDA7XG4gICAgdGhpcy5zdGF0dXNUZXh0ID0gJ3N0YXR1c1RleHQnIGluIG9wdGlvbnMgPyBvcHRpb25zLnN0YXR1c1RleHQgOiAnT0snO1xuICAgIHRoaXMuaGVhZGVycyA9IG5ldyBIZWFkZXJzKG9wdGlvbnMuaGVhZGVycyk7XG4gICAgdGhpcy51cmwgPSBvcHRpb25zLnVybCB8fCAnJztcbiAgICB0aGlzLl9pbml0Qm9keShib2R5SW5pdCk7XG4gIH1cblxuICBCb2R5LmNhbGwoUmVzcG9uc2UucHJvdG90eXBlKTtcblxuICBSZXNwb25zZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKHRoaXMuX2JvZHlJbml0LCB7XG4gICAgICBzdGF0dXM6IHRoaXMuc3RhdHVzLFxuICAgICAgc3RhdHVzVGV4dDogdGhpcy5zdGF0dXNUZXh0LFxuICAgICAgaGVhZGVyczogbmV3IEhlYWRlcnModGhpcy5oZWFkZXJzKSxcbiAgICAgIHVybDogdGhpcy51cmxcbiAgICB9KVxuICB9O1xuXG4gIFJlc3BvbnNlLmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKG51bGwsIHtzdGF0dXM6IDAsIHN0YXR1c1RleHQ6ICcnfSk7XG4gICAgcmVzcG9uc2UudHlwZSA9ICdlcnJvcic7XG4gICAgcmV0dXJuIHJlc3BvbnNlXG4gIH07XG5cbiAgdmFyIHJlZGlyZWN0U3RhdHVzZXMgPSBbMzAxLCAzMDIsIDMwMywgMzA3LCAzMDhdO1xuXG4gIFJlc3BvbnNlLnJlZGlyZWN0ID0gZnVuY3Rpb24odXJsLCBzdGF0dXMpIHtcbiAgICBpZiAocmVkaXJlY3RTdGF0dXNlcy5pbmRleE9mKHN0YXR1cykgPT09IC0xKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCBzdGF0dXMgY29kZScpXG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZShudWxsLCB7c3RhdHVzOiBzdGF0dXMsIGhlYWRlcnM6IHtsb2NhdGlvbjogdXJsfX0pXG4gIH07XG5cbiAgZXhwb3J0cy5ET01FeGNlcHRpb24gPSBzZWxmLkRPTUV4Y2VwdGlvbjtcbiAgdHJ5IHtcbiAgICBuZXcgZXhwb3J0cy5ET01FeGNlcHRpb24oKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXhwb3J0cy5ET01FeGNlcHRpb24gPSBmdW5jdGlvbihtZXNzYWdlLCBuYW1lKSB7XG4gICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgIHZhciBlcnJvciA9IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgdGhpcy5zdGFjayA9IGVycm9yLnN0YWNrO1xuICAgIH07XG4gICAgZXhwb3J0cy5ET01FeGNlcHRpb24ucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUpO1xuICAgIGV4cG9ydHMuRE9NRXhjZXB0aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGV4cG9ydHMuRE9NRXhjZXB0aW9uO1xuICB9XG5cbiAgZnVuY3Rpb24gZmV0Y2goaW5wdXQsIGluaXQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KGlucHV0LCBpbml0KTtcblxuICAgICAgaWYgKHJlcXVlc3Quc2lnbmFsICYmIHJlcXVlc3Quc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgZXhwb3J0cy5ET01FeGNlcHRpb24oJ0Fib3J0ZWQnLCAnQWJvcnRFcnJvcicpKVxuICAgICAgfVxuXG4gICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cbiAgICAgIGZ1bmN0aW9uIGFib3J0WGhyKCkge1xuICAgICAgICB4aHIuYWJvcnQoKTtcbiAgICAgIH1cblxuICAgICAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgICBzdGF0dXM6IHhoci5zdGF0dXMsXG4gICAgICAgICAgc3RhdHVzVGV4dDogeGhyLnN0YXR1c1RleHQsXG4gICAgICAgICAgaGVhZGVyczogcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSB8fCAnJylcbiAgICAgICAgfTtcbiAgICAgICAgb3B0aW9ucy51cmwgPSAncmVzcG9uc2VVUkwnIGluIHhociA/IHhoci5yZXNwb25zZVVSTCA6IG9wdGlvbnMuaGVhZGVycy5nZXQoJ1gtUmVxdWVzdC1VUkwnKTtcbiAgICAgICAgdmFyIGJvZHkgPSAncmVzcG9uc2UnIGluIHhociA/IHhoci5yZXNwb25zZSA6IHhoci5yZXNwb25zZVRleHQ7XG4gICAgICAgIHJlc29sdmUobmV3IFJlc3BvbnNlKGJvZHksIG9wdGlvbnMpKTtcbiAgICAgIH07XG5cbiAgICAgIHhoci5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJlamVjdChuZXcgVHlwZUVycm9yKCdOZXR3b3JrIHJlcXVlc3QgZmFpbGVkJykpO1xuICAgICAgfTtcblxuICAgICAgeGhyLm9udGltZW91dCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZWplY3QobmV3IFR5cGVFcnJvcignTmV0d29yayByZXF1ZXN0IGZhaWxlZCcpKTtcbiAgICAgIH07XG5cbiAgICAgIHhoci5vbmFib3J0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJlamVjdChuZXcgZXhwb3J0cy5ET01FeGNlcHRpb24oJ0Fib3J0ZWQnLCAnQWJvcnRFcnJvcicpKTtcbiAgICAgIH07XG5cbiAgICAgIHhoci5vcGVuKHJlcXVlc3QubWV0aG9kLCByZXF1ZXN0LnVybCwgdHJ1ZSk7XG5cbiAgICAgIGlmIChyZXF1ZXN0LmNyZWRlbnRpYWxzID09PSAnaW5jbHVkZScpIHtcbiAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKHJlcXVlc3QuY3JlZGVudGlhbHMgPT09ICdvbWl0Jykge1xuICAgICAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICgncmVzcG9uc2VUeXBlJyBpbiB4aHIgJiYgc3VwcG9ydC5ibG9iKSB7XG4gICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAnYmxvYic7XG4gICAgICB9XG5cbiAgICAgIHJlcXVlc3QuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKG5hbWUsIHZhbHVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocmVxdWVzdC5zaWduYWwpIHtcbiAgICAgICAgcmVxdWVzdC5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydFhocik7XG5cbiAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIC8vIERPTkUgKHN1Y2Nlc3Mgb3IgZmFpbHVyZSlcbiAgICAgICAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgIHJlcXVlc3Quc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnRYaHIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgeGhyLnNlbmQodHlwZW9mIHJlcXVlc3QuX2JvZHlJbml0ID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiByZXF1ZXN0Ll9ib2R5SW5pdCk7XG4gICAgfSlcbiAgfVxuXG4gIGZldGNoLnBvbHlmaWxsID0gdHJ1ZTtcblxuICBpZiAoIXNlbGYuZmV0Y2gpIHtcbiAgICBzZWxmLmZldGNoID0gZmV0Y2g7XG4gICAgc2VsZi5IZWFkZXJzID0gSGVhZGVycztcbiAgICBzZWxmLlJlcXVlc3QgPSBSZXF1ZXN0O1xuICAgIHNlbGYuUmVzcG9uc2UgPSBSZXNwb25zZTtcbiAgfVxuXG4gIGV4cG9ydHMuSGVhZGVycyA9IEhlYWRlcnM7XG4gIGV4cG9ydHMuUmVxdWVzdCA9IFJlcXVlc3Q7XG4gIGV4cG9ydHMuUmVzcG9uc2UgPSBSZXNwb25zZTtcbiAgZXhwb3J0cy5mZXRjaCA9IGZldGNoO1xuXG4gIHJldHVybiBleHBvcnRzO1xuXG59KHt9KSk7XG59KShfX3NlbGZfXyk7XG5kZWxldGUgX19zZWxmX18uZmV0Y2gucG9seWZpbGxcbmV4cG9ydHMgPSBfX3NlbGZfXy5mZXRjaCAvLyBUbyBlbmFibGU6IGltcG9ydCBmZXRjaCBmcm9tICdjcm9zcy1mZXRjaCdcbmV4cG9ydHMuZGVmYXVsdCA9IF9fc2VsZl9fLmZldGNoIC8vIEZvciBUeXBlU2NyaXB0IGNvbnN1bWVycyB3aXRob3V0IGVzTW9kdWxlSW50ZXJvcC5cbmV4cG9ydHMuZmV0Y2ggPSBfX3NlbGZfXy5mZXRjaCAvLyBUbyBlbmFibGU6IGltcG9ydCB7ZmV0Y2h9IGZyb20gJ2Nyb3NzLWZldGNoJ1xuZXhwb3J0cy5IZWFkZXJzID0gX19zZWxmX18uSGVhZGVyc1xuZXhwb3J0cy5SZXF1ZXN0ID0gX19zZWxmX18uUmVxdWVzdFxuZXhwb3J0cy5SZXNwb25zZSA9IF9fc2VsZl9fLlJlc3BvbnNlXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNcbiIsIi8qKlxuICogQGZpbGUgU2V0dGluZ3MgQXBwbGljYXRpb24uXG4gKi9cbmltcG9ydCBTZXR0aW5ncyBmcm9tICcuL3NldHRpbmdzJztcblxuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggJ0RPTUNvbnRlbnRMb2FkZWQnLCAoKSA9PiB7XG5cdG5ldyBTZXR0aW5ncygpO1xufSApO1xuIiwiLyoqXG4gKiBAZmlsZSBjbGFzcyBTZXR0aW5ncy5cbiAqL1xuXG4vKiBnbG9iYWwgQ3lyMkxhdFNldHRpbmdzT2JqZWN0ICovXG5cbmNsYXNzIFNldHRpbmdzIHtcblx0LyoqXG5cdCAqIENsYXNzIGNvbnN0cnVjdG9yLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy5PUFRJT05TX0ZPUk1fU0VMRUNUT1IgPSAnI2N0bC1vcHRpb25zJztcblx0XHR0aGlzLkhFQURFUl9TRUxFQ1RPUiA9IHRoaXMuT1BUSU9OU19GT1JNX1NFTEVDVE9SICsgJyBoMic7XG5cdFx0dGhpcy5UQUJMRV9TRUxFQ1RPUiA9IHRoaXMuT1BUSU9OU19GT1JNX1NFTEVDVE9SICsgJyB0YWJsZSc7XG5cdFx0dGhpcy5TVUJNSVRfU0VMRUNUT1IgPSB0aGlzLk9QVElPTlNfRk9STV9TRUxFQ1RPUiArICcgI3N1Ym1pdCc7XG5cdFx0dGhpcy5DT05WRVJUX0ZPUk1fU0VMRUNUT1IgPSAnI2N0bC1jb252ZXJ0LWV4aXN0aW5nLXNsdWdzJztcblx0XHR0aGlzLkNPTlZFUlRfQlVUVE9OX1NFTEVDVE9SID0gJyNjdGwtY29udmVydC1idXR0b24nO1xuXHRcdHRoaXMuQ09ORklSTV9QT1BVUF9TRUxFQ1RPUiA9ICcjY3RsLWNvbmZpcm0tcG9wdXAnO1xuXHRcdHRoaXMuQ09ORklSTV9PS19TRUxFQ1RPUiA9ICcjY3RsLWNvbmZpcm0tb2snO1xuXHRcdHRoaXMuQ09ORklSTV9DQU5DRUxfU0VMRUNUT1IgPSAnI2N0bC1jb25maXJtLWNhbmNlbCc7XG5cdFx0dGhpcy5DVVJSRU5UX1NUVUJfSUQgPSAnY3RsLWN1cnJlbnQnO1xuXHRcdHRoaXMuQ1VSUkVOVF9OQVZfVEFCX0NMQVNTID0gJ25hdi10YWItY3VycmVudCc7XG5cdFx0dGhpcy5BQ1RJVkVfTkFWX1RBQl9DTEFTUyA9ICduYXYtdGFiLWFjdGl2ZSc7XG5cdFx0dGhpcy5BQ1RJVkVfVEFCTEVfQ0xBU1MgPSAnYWN0aXZlJztcblx0XHR0aGlzLkVESVRfTEFCRUxfSUQgPSAnY3RsLWVkaXQtbGFiZWwnO1xuXHRcdHRoaXMuRURJVF9MQUJFTF9FUlJPUl9DTEFTUyA9ICdjdGwtZWRpdC1sYWJlbC1lcnJvcic7XG5cdFx0dGhpcy5wbHVzQnV0dG9uID1cblx0XHRcdCc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBhcmlhLWhhc3BvcHVwPVwidHJ1ZVwiIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiIGNsYXNzPVwiY29tcG9uZW50cy1idXR0b24gYmxvY2stZWRpdG9yLWluc2VydGVyX190b2dnbGUgaGFzLWljb25cIiBhcmlhLWxhYmVsPVwi0JTQvtCx0LDQstC40YLRjCDQsdC70L7QulwiPicgK1xuXHRcdFx0Jzxzdmcgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCItMiAtMiAyNCAyNFwiIHJvbGU9XCJpbWdcIiBhcmlhLWhpZGRlbj1cInRydWVcIiBmb2N1c2FibGU9XCJmYWxzZVwiPicgK1xuXHRcdFx0JzxwYXRoIGQ9XCJNMTAgMWMtNSAwLTkgNC05IDlzNCA5IDkgOSA5LTQgOS05LTQtOS05LTl6bTAgMTZjLTMuOSAwLTctMy4xLTctN3MzLjEtNyA3LTcgNyAzLjEgNyA3LTMuMSA3LTcgN3ptMS0xMUg5djNINnYyaDN2M2gydi0zaDNWOWgtM1Y2ek0xMCAxYy01IDAtOSA0LTkgOXM0IDkgOSA5IDktNCA5LTktNC05LTktOXptMCAxNmMtMy45IDAtNy0zLjEtNy03czMuMS03IDctNyA3IDMuMSA3IDctMy4xIDctNyA3em0xLTExSDl2M0g2djJoM3YzaDJ2LTNoM1Y5aC0zVjZ6XCI+JyArXG5cdFx0XHQnPC9wYXRoPicgK1xuXHRcdFx0Jzwvc3ZnPicgK1xuXHRcdFx0JzwvYnV0dG9uPic7XG5cdFx0dGhpcy5QTFVTX0NMQVNTID0gJ2N0bC1wbHVzJztcblxuXHRcdHRoaXMub3B0aW9uc0Zvcm0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCB0aGlzLk9QVElPTlNfRk9STV9TRUxFQ1RPUiApO1xuXHRcdHRoaXMudGFibGVzRGF0YSA9IHRoaXMuZ2V0VGFibGVzRGF0YSgpO1xuXHRcdHRoaXMuc3VibWl0QnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvciggdGhpcy5TVUJNSVRfU0VMRUNUT1IgKTtcblx0XHR0aGlzLmNvbmZpcm1Qb3B1cCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG5cdFx0XHR0aGlzLkNPTkZJUk1fUE9QVVBfU0VMRUNUT1Jcblx0XHQpO1xuXG5cdFx0Ly8gQ29weSB0byBjbGFzcyBwcm9wZXJ0aWVzLCBvdGhlcndpc2UgZXNsaW50IG1hcmtzIHNvbWUgcHJvcGVydGllcyBvZiBnbG9iYWwgb2JqZWN0IGFzIHVucmVzb2x2ZWQuXG5cdFx0dGhpcy5vcHRpb25zU2F2ZVN1Y2Nlc3NNZXNzYWdlID1cblx0XHRcdEN5cjJMYXRTZXR0aW5nc09iamVjdC5vcHRpb25zU2F2ZVN1Y2Nlc3NNZXNzYWdlO1xuXHRcdHRoaXMub3B0aW9uc1NhdmVFcnJvck1lc3NhZ2UgPVxuXHRcdFx0Q3lyMkxhdFNldHRpbmdzT2JqZWN0Lm9wdGlvbnNTYXZlRXJyb3JNZXNzYWdlO1xuXG5cdFx0dGhpcy5hZGRXcmFwcGVyKCk7XG5cdFx0dGhpcy5hZGRNZXNzYWdlTGluZXMoKTtcblx0XHR0aGlzLmFkZEVkaXRMYWJlbElucHV0KCk7XG5cdFx0dGhpcy5oaWRlVGFibGVzKCk7XG5cdFx0dGhpcy5iaW5kRXZlbnRzKCk7XG5cdFx0dGhpcy5zZXRTdWJtaXRTdGF0dXMoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgaGVhZGVycy5cblx0ICpcblx0ICogQHJldHVybiB7KltdfSBIZWFkZXJzLlxuXHQgKi9cblx0Z2V0SGVhZGVycygpIHtcblx0XHRyZXR1cm4gWyAuLi5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCB0aGlzLkhFQURFUl9TRUxFQ1RPUiApIF07XG5cdH1cblxuXHQvKipcblx0ICogR2V0IGFjdGl2ZSBoZWFkZXIuXG5cdCAqXG5cdCAqIEByZXR1cm4ge0VsZW1lbnR9IEFjdGl2ZSBoZWFkZXIuXG5cdCAqL1xuXHRnZXRBY3RpdmVIZWFkZXIoKSB7XG5cdFx0cmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG5cdFx0XHR0aGlzLkhFQURFUl9TRUxFQ1RPUiArICcuJyArIHRoaXMuQUNUSVZFX05BVl9UQUJfQ0xBU1Ncblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBhY3RpdmUgaW5kZXguXG5cdCAqXG5cdCAqIEByZXR1cm4geyp9IEFjdGl2ZSBpbmRleC5cblx0ICovXG5cdGdldEFjdGl2ZUluZGV4KCkge1xuXHRcdHJldHVybiB0aGlzLmdldEFjdGl2ZUhlYWRlcigpLmRhdGFzZXQuaW5kZXg7XG5cdH1cblxuXHQvKipcblx0ICogR2V0IHRhYmxlcy5cblx0ICpcblx0ICogQHJldHVybiB7KltdfSBUYWJsZXMuXG5cdCAqL1xuXHRnZXRUYWJsZXMoKSB7XG5cdFx0cmV0dXJuIFsgLi4uZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCggdGhpcy5UQUJMRV9TRUxFQ1RPUiApIF07XG5cdH1cblxuXHQvKipcblx0ICogR2V0IGFjdGl2ZSB0YWJsZS5cblx0ICpcblx0ICogQHJldHVybiB7RWxlbWVudH0gQWN0aXZlIHRhYmxlLlxuXHQgKi9cblx0Z2V0QWN0aXZlVGFibGUoKSB7XG5cdFx0cmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG5cdFx0XHR0aGlzLlRBQkxFX1NFTEVDVE9SICsgJy4nICsgdGhpcy5BQ1RJVkVfVEFCTEVfQ0xBU1Ncblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBpbnB1dHMuXG5cdCAqXG5cdCAqIEByZXR1cm4geypbXX0gSW5wdXRzLlxuXHQgKi9cblx0Z2V0SW5wdXRzKCkge1xuXHRcdHJldHVybiBbXG5cdFx0XHQuLi5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuXHRcdFx0XHR0aGlzLk9QVElPTlNfRk9STV9TRUxFQ1RPUiArICcgaW5wdXQnXG5cdFx0XHQpLFxuXHRcdF07XG5cdH1cblxuXHQvKipcblx0ICogR2V0IGxhYmVscy5cblx0ICpcblx0ICogQHJldHVybiB7KltdfSBMYWJlbHMuXG5cdCAqL1xuXHRnZXRMYWJlbHMoKSB7XG5cdFx0cmV0dXJuIFtcblx0XHRcdC4uLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG5cdFx0XHRcdHRoaXMuT1BUSU9OU19GT1JNX1NFTEVDVE9SICsgJyBsYWJlbCdcblx0XHRcdCksXG5cdFx0XTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgcGx1cyBidXR0b25zLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHsqW119IFBsdXMgYnV0dG9ucy5cblx0ICovXG5cdGdldFBsdXNCdXR0b25zKCkge1xuXHRcdHJldHVybiBbXG5cdFx0XHQuLi5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuXHRcdFx0XHR0aGlzLk9QVElPTlNfRk9STV9TRUxFQ1RPUiArICcgLicgKyB0aGlzLlBMVVNfQ0xBU1Ncblx0XHRcdCksXG5cdFx0XTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVjayBvZiBhY3RpdmUgdGFibGUgd2FzIGNoYW5nZWQuXG5cdCAqXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IElmIGFjdGl2ZSB0YWJsZSB3YXMgY2hhbmdlZC5cblx0ICovXG5cdGlzQWN0aXZlVGFibGVDaGFuZ2VkKCkge1xuXHRcdGNvbnN0IGFjdGl2ZUluZGV4ID0gdGhpcy5nZXRBY3RpdmVJbmRleCgpO1xuXG5cdFx0cmV0dXJuIChcblx0XHRcdEpTT04uc3RyaW5naWZ5KCB0aGlzLmdldEFjdGl2ZVRhYmxlRGF0YSgpICkgIT09XG5cdFx0XHRKU09OLnN0cmluZ2lmeSggdGhpcy50YWJsZXNEYXRhWyBhY3RpdmVJbmRleCBdIClcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldCBzdGF0dXMgb2Ygc3VibWl0IGJ1dHRvbi5cblx0ICovXG5cdHNldFN1Ym1pdFN0YXR1cygpIHtcblx0XHR0aGlzLnN1Ym1pdEJ1dHRvbi5kaXNhYmxlZCA9ICEgdGhpcy5pc0FjdGl2ZVRhYmxlQ2hhbmdlZCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNhdmUgYWN0aXZlIHRhYmxlLlxuXHQgKi9cblx0c2F2ZUFjdGl2ZVRhYmxlKCkge1xuXHRcdGlmICggISB0aGlzLmlzQWN0aXZlVGFibGVDaGFuZ2VkKCkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgYWN0aXZlVGFibGUgPSB0aGlzLmdldEFjdGl2ZVRhYmxlKCk7XG5cblx0XHRjb25zdCBhY3RpdmVGb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2Zvcm0nICk7XG5cdFx0YWN0aXZlRm9ybS5hY3Rpb24gPSB0aGlzLm9wdGlvbnNGb3JtLmdldEF0dHJpYnV0ZSggJ2FjdGlvbicgKTtcblx0XHRhY3RpdmVGb3JtLm1ldGhvZCA9IHRoaXMub3B0aW9uc0Zvcm0ubWV0aG9kO1xuXHRcdGFjdGl2ZUZvcm0uYXBwZW5kQ2hpbGQoIGFjdGl2ZVRhYmxlLmNsb25lTm9kZSggdHJ1ZSApICk7XG5cblx0XHRjb25zdCBhY3RpdmVJbnB1dHMgPSBbIC4uLmFjdGl2ZVRhYmxlLnF1ZXJ5U2VsZWN0b3JBbGwoICdpbnB1dCcgKSBdO1xuXHRcdGFjdGl2ZUlucHV0cy5tYXAoICggaW5wdXQgKSA9PiB7XG5cdFx0XHRyZXR1cm4gKCBhY3RpdmVGb3JtLnF1ZXJ5U2VsZWN0b3IoICcjJyArIGlucHV0LmlkICkudmFsdWUgPVxuXHRcdFx0XHRpbnB1dC52YWx1ZSApO1xuXHRcdH0gKTtcblxuXHRcdGNvbnN0IGhpZGRlbklucHV0cyA9IFtcblx0XHRcdC4uLnRoaXMub3B0aW9uc0Zvcm0ucXVlcnlTZWxlY3RvckFsbCggJ2lucHV0W3R5cGU9XCJoaWRkZW5cIl0nICksXG5cdFx0XTtcblx0XHRoaWRkZW5JbnB1dHMubWFwKCAoIGlucHV0ICkgPT4ge1xuXHRcdFx0cmV0dXJuIGFjdGl2ZUZvcm0uYXBwZW5kQ2hpbGQoIGlucHV0LmNsb25lTm9kZSggdHJ1ZSApICk7XG5cdFx0fSApO1xuXHRcdGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoIGFjdGl2ZUZvcm0gKTtcblxuXHRcdHJldHVybiBmZXRjaCggdGhpcy5vcHRpb25zRm9ybS5nZXRBdHRyaWJ1dGUoICdhY3Rpb24nICksIHtcblx0XHRcdG1ldGhvZDogYWN0aXZlRm9ybS5tZXRob2QsXG5cdFx0XHRib2R5OiBuZXcgVVJMU2VhcmNoUGFyYW1zKCBbIC4uLm5ldyBGb3JtRGF0YSggYWN0aXZlRm9ybSApIF0gKSxcblx0XHR9IClcblx0XHRcdC50aGVuKCAoIHJlc3BvbnNlICkgPT4ge1xuXHRcdFx0XHRpZiAoIHJlc3BvbnNlLm9rICkge1xuXHRcdFx0XHRcdHRoaXMuc2hvd01lc3NhZ2UoXG5cdFx0XHRcdFx0XHR0aGlzLnN1Y2Nlc3NNZXNzYWdlLFxuXHRcdFx0XHRcdFx0dGhpcy5vcHRpb25zU2F2ZVN1Y2Nlc3NNZXNzYWdlXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR0aGlzLnRhYmxlc0RhdGEgPSB0aGlzLmdldFRhYmxlc0RhdGEoKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLnNob3dNZXNzYWdlKFxuXHRcdFx0XHRcdFx0dGhpcy5lcnJvck1lc3NhZ2UsXG5cdFx0XHRcdFx0XHR0aGlzLm9wdGlvbnNTYXZlRXJyb3JNZXNzYWdlXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiByZXNwb25zZS5qc29uKCk7XG5cdFx0XHR9IClcblx0XHRcdC5maW5hbGx5KCAoKSA9PiB7XG5cdFx0XHRcdGFjdGl2ZUZvcm0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggYWN0aXZlRm9ybSApO1xuXHRcdFx0XHR0aGlzLnNldFN1Ym1pdFN0YXR1cygpO1xuXHRcdFx0fSApO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCB0YWJsZSBkYXRhLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IHRhYmxlIFRhYmxlLlxuXHQgKiBAcmV0dXJuIHt7fVtdfSBUYWJsZSBkYXRhLlxuXHQgKi9cblx0Z2V0VGFibGVEYXRhKCB0YWJsZSApIHtcblx0XHRjb25zdCBpbnB1dHMgPSBbIC4uLnRhYmxlLnF1ZXJ5U2VsZWN0b3JBbGwoICdpbnB1dCcgKSBdO1xuXG5cdFx0Y29uc3QgZGF0YSA9IHt9O1xuXHRcdGlucHV0cy5mb3JFYWNoKCAoIGlucHV0ICkgPT4ge1xuXHRcdFx0Y29uc3QgbGFiZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuXHRcdFx0XHR0aGlzLk9QVElPTlNfRk9STV9TRUxFQ1RPUiArICcgbGFiZWxbZm9yPVwiJyArIGlucHV0LmlkICsgJ1wiXSdcblx0XHRcdCk7XG5cblx0XHRcdGRhdGFbIGxhYmVsLmlubmVySFRNTCBdID0gaW5wdXQudmFsdWU7XG5cdFx0fSApO1xuXG5cdFx0cmV0dXJuIGRhdGE7XG5cdH1cblxuXHQvKipcblx0ICogR2V0IGRhdGEgZnJvbSBhbGwgdGFibGVzLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHt7fVtdW119IERhdGEgZnJvbSBhbGwgdGFibGVzLlxuXHQgKi9cblx0Z2V0VGFibGVzRGF0YSgpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRUYWJsZXMoKS5tYXAoICggdGFibGUgKSA9PiB7XG5cdFx0XHRyZXR1cm4gdGhpcy5nZXRUYWJsZURhdGEoIHRhYmxlICk7XG5cdFx0fSApO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBhY3RpdmUgdGFibGUgZGF0YS5cblx0ICpcblx0ICogQHJldHVybiB7e31bXX0gQWN0aXZlIHRhYmxlIGRhdGEuXG5cdCAqL1xuXHRnZXRBY3RpdmVUYWJsZURhdGEoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0VGFibGVEYXRhKCB0aGlzLmdldEFjdGl2ZVRhYmxlKCkgKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGQgd3JhcHBlci5cblx0ICovXG5cdGFkZFdyYXBwZXIoKSB7XG5cdFx0dGhpcy53cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ3VsJyApO1xuXHRcdHRoaXMud3JhcHBlci5jbGFzc0xpc3QuYWRkKCAnbmF2LXRhYi13cmFwcGVyJyApO1xuXHRcdHRoaXMub3B0aW9uc0Zvcm0uaW5zZXJ0QmVmb3JlKFxuXHRcdFx0dGhpcy53cmFwcGVyLFxuXHRcdFx0dGhpcy5vcHRpb25zRm9ybS5maXJzdENoaWxkXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGQgbWVzc2FnZSBsaW5lLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaWQgTWVzc2FnZSBpZC5cblx0ICogQHJldHVybiB7SFRNTERpdkVsZW1lbnR9IE1lc3NhZ2UgbGluZS5cblx0ICovXG5cdGFkZE1lc3NhZ2VMaW5lKCBpZCApIHtcblx0XHRjb25zdCBtZXNzYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2RpdicgKTtcblx0XHRtZXNzYWdlLmlkID0gaWQ7XG5cdFx0dGhpcy5vcHRpb25zRm9ybS5pbnNlcnRCZWZvcmUoIG1lc3NhZ2UsIHRoaXMub3B0aW9uc0Zvcm0uZmlyc3RDaGlsZCApO1xuXG5cdFx0cmV0dXJuIG1lc3NhZ2U7XG5cdH1cblxuXHQvKipcblx0ICogQWRkIHN1Y2Nlc3MgYW5kIGVycm9yIG1lc3NhZ2UgbGluZXMuXG5cdCAqL1xuXHRhZGRNZXNzYWdlTGluZXMoKSB7XG5cdFx0dGhpcy5zdWNjZXNzTWVzc2FnZSA9IHRoaXMuYWRkTWVzc2FnZUxpbmUoICdjdGwtc3VjY2VzcycgKTtcblx0XHR0aGlzLmVycm9yTWVzc2FnZSA9IHRoaXMuYWRkTWVzc2FnZUxpbmUoICdjdGwtZXJyb3InICk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkIGVkaXQgbGFiZWwgaW5wdXQuXG5cdCAqL1xuXHRhZGRFZGl0TGFiZWxJbnB1dCgpIHtcblx0XHR0aGlzLmVkaXRMYWJlbElucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2lucHV0JyApO1xuXHRcdHRoaXMuZWRpdExhYmVsSW5wdXQuaWQgPSB0aGlzLkVESVRfTEFCRUxfSUQ7XG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoIHRoaXMuZWRpdExhYmVsSW5wdXQgKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBIaWRlIGVkaXQgbGFiZWwgaW5wdXQuXG5cdCAqL1xuXHRoaWRlRWRpdExhYmVsSW5wdXQoKSB7XG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdHRoaXMuZWRpdExhYmVsSW5wdXQuY2xhc3NMaXN0LnJlbW92ZSggdGhpcy5FRElUX0xBQkVMX0VSUk9SX0NMQVNTICk7XG5cdFx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggdGhpcy5lZGl0TGFiZWxJbnB1dCApO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBsYXN0IGNlbGwgaW4gYWN0aXZlIHRhYmxlLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBMYXN0IGNlbGwuXG5cdCAqL1xuXHRnZXRMYXN0Q2VsbCgpIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihcblx0XHRcdHRoaXMuT1BUSU9OU19GT1JNX1NFTEVDVE9SICtcblx0XHRcdFx0JyAuJyArXG5cdFx0XHRcdHRoaXMuQUNUSVZFX1RBQkxFX0NMQVNTICtcblx0XHRcdFx0JyAuJyArXG5cdFx0XHRcdHRoaXMuUExVU19DTEFTU1xuXHRcdCkucHJldmlvdXNFbGVtZW50U2libGluZztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGQgbmV3IGNlbGwgdG8gdGhlIGFjdGl2ZSB0YWJsZS5cblx0ICovXG5cdGFkZENlbGwoKSB7XG5cdFx0bGV0IGxhc3RDZWxsID0gdGhpcy5nZXRMYXN0Q2VsbCgpO1xuXHRcdGxhc3RDZWxsLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKFxuXHRcdFx0bGFzdENlbGwuY2xvbmVOb2RlKCB0cnVlICksXG5cdFx0XHRsYXN0Q2VsbC5uZXh0RWxlbWVudFNpYmxpbmdcblx0XHQpO1xuXG5cdFx0bGFzdENlbGwgPSB0aGlzLmdldExhc3RDZWxsKCk7XG5cdFx0Y29uc3QgbGFiZWwgPSBsYXN0Q2VsbC5xdWVyeVNlbGVjdG9yKCAnbGFiZWwnICk7XG5cdFx0Y29uc3QgaW5wdXQgPSBsYXN0Q2VsbC5xdWVyeVNlbGVjdG9yKCAnaW5wdXQnICk7XG5cblx0XHRjb25zdCBpZEFyciA9IGlucHV0LmlkLnNwbGl0KCAnLScgKTtcblx0XHRjb25zdCBuZXdJZCA9IGlkQXJyWyAwIF0gKyAnLScgKyAoIHBhcnNlSW50KCBpZEFyclsgMSBdICkgKyAxICk7XG5cblx0XHRsYWJlbC5odG1sRm9yID0gbmV3SWQ7XG5cdFx0bGFiZWwuaW5uZXJIVE1MID0gJyc7XG5cblx0XHRpbnB1dC5pZCA9IG5ld0lkO1xuXHRcdGlucHV0LnZhbHVlID0gJyc7XG5cdFx0aW5wdXQuc2V0QXR0cmlidXRlKCAndmFsdWUnLCAnJyApO1xuXHRcdHRoaXMucmVwbGFjZU5hbWUoIGlucHV0LCAnJyApO1xuXG5cdFx0dGhpcy5iaW5kRXZlbnRzKCk7XG5cblx0XHR0aGlzLmVkaXRMYWJlbCggbGFiZWwgKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBIaWRlIGNvbnZlcnNpb24gdGFibGVzIGV4Y2VwdCB0aGUgZmlyc3Qgb25lLlxuXHQgKiBDcmVhdGUgbmF2aWdhdGlvbiB0YWJzLlxuXHQgKi9cblx0aGlkZVRhYmxlcygpIHtcblx0XHRsZXQgY3VycmVudEluZGV4ID0gMDtcblxuXHRcdHRoaXMuZ2V0VGFibGVzKCkubWFwKCAoIHRhYmxlLCBpbmRleCApID0+IHtcblx0XHRcdHRhYmxlLmNsYXNzTGlzdC5hZGQoICdjdGwtdGFibGUnICk7XG5cblx0XHRcdGlmICggdGhpcy5DVVJSRU5UX1NUVUJfSUQgPT09IHRhYmxlLnByZXZpb3VzRWxlbWVudFNpYmxpbmcuaWQgKSB7XG5cdFx0XHRcdGN1cnJlbnRJbmRleCA9IGluZGV4O1xuXHRcdFx0XHR0YWJsZS5jbGFzc0xpc3QuYWRkKCB0aGlzLkFDVElWRV9UQUJMRV9DTEFTUyApO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCBwbHVzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2RpdicgKTtcblx0XHRcdHBsdXMuY2xhc3NMaXN0LmFkZCggdGhpcy5QTFVTX0NMQVNTICk7XG5cdFx0XHRwbHVzLmlubmVySFRNTCA9IHRoaXMucGx1c0J1dHRvbjtcblx0XHRcdHRhYmxlLnF1ZXJ5U2VsZWN0b3IoICd0ZCcgKS5hcHBlbmRDaGlsZCggcGx1cyApO1xuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9ICk7XG5cblx0XHR0aGlzLmdldEhlYWRlcnMoKS5tYXAoICggaGVhZGVyLCBpbmRleCApID0+IHtcblx0XHRcdGhlYWRlci5jbGFzc0xpc3QuYWRkKCAnbmF2LXRhYicgKTtcblx0XHRcdGhlYWRlci5kYXRhc2V0LmluZGV4ID0gaW5kZXg7XG5cblx0XHRcdHRoaXMud3JhcHBlci5hcHBlbmRDaGlsZCggaGVhZGVyICk7XG5cdFx0XHRpZiAoIGluZGV4ID09PSBjdXJyZW50SW5kZXggKSB7XG5cdFx0XHRcdGhlYWRlci5jbGFzc0xpc3QuYWRkKCB0aGlzLkNVUlJFTlRfTkFWX1RBQl9DTEFTUyApO1xuXHRcdFx0XHRoZWFkZXIuY2xhc3NMaXN0LmFkZCggdGhpcy5BQ1RJVkVfTkFWX1RBQl9DTEFTUyApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9ICk7XG5cdH1cblxuXHQvKipcblx0ICogQmluZCBldmVudHMgdG8gbWV0aG9kcy5cblx0ICovXG5cdGJpbmRFdmVudHMoKSB7XG5cdFx0dGhpcy5nZXRIZWFkZXJzKCkubWFwKCAoIGhlYWRlciwgaSwgaGVhZGVycyApID0+IHtcblx0XHRcdGhlYWRlci5vbmNsaWNrID0gKCBldmVudCApID0+IHtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuXHRcdFx0XHRjb25zdCBpbmRleCA9IGV2ZW50LnRhcmdldC5kYXRhc2V0LmluZGV4O1xuXHRcdFx0XHRjb25zdCBhY3RpdmVJbmRleCA9IHRoaXMuZ2V0QWN0aXZlSW5kZXgoKTtcblxuXHRcdFx0XHRpZiAoIGluZGV4ID09PSBhY3RpdmVJbmRleCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLnNhdmVBY3RpdmVUYWJsZSgpO1xuXG5cdFx0XHRcdGhlYWRlcnMubWFwKCAoIGFIZWFkZXIgKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIGFIZWFkZXIuY2xhc3NMaXN0LnJlbW92ZShcblx0XHRcdFx0XHRcdHRoaXMuQUNUSVZFX05BVl9UQUJfQ0xBU1Ncblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHRcdGhlYWRlcnNbIGluZGV4IF0uY2xhc3NMaXN0LmFkZCggdGhpcy5BQ1RJVkVfTkFWX1RBQl9DTEFTUyApO1xuXG5cdFx0XHRcdGNvbnN0IHRhYmxlcyA9IHRoaXMuZ2V0VGFibGVzKCk7XG5cdFx0XHRcdHRhYmxlcy5tYXAoICggdGFibGUgKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHRhYmxlLmNsYXNzTGlzdC5yZW1vdmUoIHRoaXMuQUNUSVZFX1RBQkxFX0NMQVNTICk7XG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0dGFibGVzWyBpbmRleCBdLmNsYXNzTGlzdC5hZGQoIHRoaXMuQUNUSVZFX1RBQkxFX0NMQVNTICk7XG5cblx0XHRcdFx0dGhpcy5zZXRTdWJtaXRTdGF0dXMoKTtcblxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9O1xuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9ICk7XG5cblx0XHR0aGlzLmdldElucHV0cygpLm1hcCggKCBpbnB1dCApID0+IHtcblx0XHRcdGlucHV0Lm9uaW5wdXQgPSAoKSA9PiB7XG5cdFx0XHRcdHRoaXMuc2V0U3VibWl0U3RhdHVzKCk7XG5cdFx0XHR9O1xuXG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9ICk7XG5cblx0XHR0aGlzLmdldExhYmVscygpLm1hcCggKCBsYWJlbCApID0+IHtcblx0XHRcdGxhYmVsLm9uY2xpY2sgPSAoIGV2ZW50ICkgPT4ge1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR0aGlzLmVkaXRMYWJlbCggZXZlbnQudGFyZ2V0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH07XG5cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH0gKTtcblxuXHRcdHRoaXMuZWRpdExhYmVsSW5wdXQub25ibHVyID0gKCkgPT4ge1xuXHRcdFx0dGhpcy5zYXZlTGFiZWwoKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5vbmtleXVwID0gKCBlICkgPT4ge1xuXHRcdFx0aWYgKCAnRXNjYXBlJyA9PT0gZS5rZXkgKSB7XG5cdFx0XHRcdHRoaXMuc2F2ZUxhYmVsKCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggJ0VudGVyJyA9PT0gZS5rZXkgKSB7XG5cdFx0XHRcdHRoaXMuc2F2ZUxhYmVsKCk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0UGx1c0J1dHRvbnMoKS5tYXAoICggcGx1cyApID0+IHtcblx0XHRcdHBsdXMub25jbGljayA9ICggZXZlbnQgKSA9PiB7XG5cdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdHRoaXMuYWRkQ2VsbCggZXZlbnQudGFyZ2V0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH07XG5cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH0gKTtcblxuXHRcdHRoaXMuc3VibWl0QnV0dG9uLm9uY2xpY2sgPSAoIGV2ZW50ICkgPT4ge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdHRoaXMuc2F2ZUFjdGl2ZVRhYmxlKCk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcblxuXHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIHRoaXMuQ09OVkVSVF9CVVRUT05fU0VMRUNUT1IgKS5vbmNsaWNrID0gKFxuXHRcdFx0ZXZlbnRcblx0XHQpID0+IHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHR0aGlzLmNvbmZpcm1Qb3B1cC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5jb25maXJtUG9wdXAub25jbGljayA9ICgpID0+IHtcblx0XHRcdHRoaXMuaGlkZUNvbmZpcm1Qb3B1cCgpO1xuXHRcdH07XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCB0aGlzLkNPTkZJUk1fT0tfU0VMRUNUT1IgKS5vbmNsaWNrID0gKFxuXHRcdFx0ZXZlbnRcblx0XHQpID0+IHtcblx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0dGhpcy5oaWRlQ29uZmlybVBvcHVwKCk7XG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCB0aGlzLkNPTlZFUlRfRk9STV9TRUxFQ1RPUiApLnN1Ym1pdCgpO1xuXHRcdH07XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCB0aGlzLkNPTkZJUk1fQ0FOQ0VMX1NFTEVDVE9SICkub25jbGljayA9IChcblx0XHRcdGV2ZW50XG5cdFx0KSA9PiB7XG5cdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdHRoaXMuaGlkZUNvbmZpcm1Qb3B1cCgpO1xuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogSGlkZSBjb25maXJtYXRpb24gcG9wdXAuXG5cdCAqL1xuXHRoaWRlQ29uZmlybVBvcHVwKCkge1xuXHRcdHRoaXMuY29uZmlybVBvcHVwLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdH1cblxuXHQvKipcblx0ICogRWRpdCBsYWJlbC5cblx0ICpcblx0ICogQHBhcmFtIHtFbGVtZW50fSBsYWJlbCBMYWJlbCB0byBlZGl0LlxuXHQgKi9cblx0ZWRpdExhYmVsKCBsYWJlbCApIHtcblx0XHRsYWJlbC5wYXJlbnROb2RlLmFwcGVuZENoaWxkKCB0aGlzLmVkaXRMYWJlbElucHV0ICk7XG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC52YWx1ZSA9IGxhYmVsLmlubmVySFRNTDtcblxuXHRcdHRoaXMuZWRpdExhYmVsSW5wdXQuY2xhc3NMaXN0LnJlbW92ZSggdGhpcy5FRElUX0xBQkVMX0VSUk9SX0NMQVNTICk7XG5cdFx0dGhpcy5lZGl0TGFiZWxJbnB1dC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblx0XHR0aGlzLmVkaXRMYWJlbElucHV0LmZvY3VzKCk7XG5cdH1cblxuXHQvKipcblx0ICogSXMgbmV3IHZhbHVlIG9mIGVkaXRlZCBsYWJlbCB1bmlxdWUgaW4gYWN0aXZlIHRhYmxlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmV3VmFsdWUgTmV3IFZhbHVlIGZyb20gZWRpdGVkIGxhYmVsLlxuXHQgKiBAcmV0dXJuIHsqfSBJZiBuZXcgdmFsdWUgb2YgZWRpdGVkIGxhYmVsIGlzIHVuaXF1ZSBpbiBhY3RpdmUgdGFibGUuXG5cdCAqL1xuXHRpc1VuaXF1ZUxhYmVsKCBuZXdWYWx1ZSApIHtcblx0XHRyZXR1cm4gWyAuLi50aGlzLmdldEFjdGl2ZVRhYmxlKCkucXVlcnlTZWxlY3RvckFsbCggJ2xhYmVsJyApIF0ucmVkdWNlKFxuXHRcdFx0KCBhY2MsIGxhYmVsICkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gYWNjICYmIGxhYmVsLmlubmVySFRNTCAhPT0gbmV3VmFsdWU7XG5cdFx0XHR9LFxuXHRcdFx0dHJ1ZVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogU2F2ZSBtb2RpZmllZCBsYWJlbC5cblx0ICpcblx0ICogQHBhcmFtIHtib29sZWFufSBjYW5jZWwgQ2FuY2VsLlxuXHQgKi9cblx0c2F2ZUxhYmVsKCBjYW5jZWwgPSBmYWxzZSApIHtcblx0XHRpZiAoICdub25lJyA9PT0gdGhpcy5lZGl0TGFiZWxJbnB1dC5zdHlsZS5kaXNwbGF5ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IG5ld1ZhbHVlID0gdGhpcy5lZGl0TGFiZWxJbnB1dC52YWx1ZS50cmltKCk7XG5cblx0XHRpZiAoICcnID09PSBuZXdWYWx1ZSApIHtcblx0XHRcdGNvbnN0IGVkaXRlZENlbGwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggdGhpcy5FRElUX0xBQkVMX0lEIClcblx0XHRcdFx0LnBhcmVudEVsZW1lbnQ7XG5cdFx0XHR0aGlzLmhpZGVFZGl0TGFiZWxJbnB1dCgpO1xuXHRcdFx0ZWRpdGVkQ2VsbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBlZGl0ZWRDZWxsICk7XG5cdFx0XHR0aGlzLnNldFN1Ym1pdFN0YXR1cygpO1xuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgbGFiZWwgPSB0aGlzLmVkaXRMYWJlbElucHV0LnBhcmVudE5vZGUucXVlcnlTZWxlY3RvciggJ2xhYmVsJyApO1xuXHRcdGlmICggY2FuY2VsIHx8IG5ld1ZhbHVlID09PSBsYWJlbC5pbm5lckhUTUwgKSB7XG5cdFx0XHR0aGlzLmhpZGVFZGl0TGFiZWxJbnB1dCgpO1xuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCAhIHRoaXMuaXNVbmlxdWVMYWJlbCggbmV3VmFsdWUgKSApIHtcblx0XHRcdHRoaXMuZWRpdExhYmVsSW5wdXQuY2xhc3NMaXN0LmFkZCggdGhpcy5FRElUX0xBQkVMX0VSUk9SX0NMQVNTICk7XG5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBpbnB1dCA9IHRoaXMuZWRpdExhYmVsSW5wdXQucGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yKCAnaW5wdXQnICk7XG5cblx0XHR0aGlzLmhpZGVFZGl0TGFiZWxJbnB1dCgpO1xuXG5cdFx0bGFiZWwuaW5uZXJIVE1MID0gbmV3VmFsdWU7XG5cdFx0dGhpcy5yZXBsYWNlTmFtZSggaW5wdXQsIG5ld1ZhbHVlICk7XG5cblx0XHR0aGlzLnNldFN1Ym1pdFN0YXR1cygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlcGxhY2UgaW5wdXQgbmFtZSBhY2NvcmRpbmcgdG8gdGhlIG5ldyBsYWJlbCB2YWx1ZS5cblx0ICpcblx0ICogQHBhcmFtIHtFbGVtZW50fSBpbnB1dCBJbnB1dFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmV3VmFsdWUgTmV3IGxhYmVsIHZhbHVlXG5cdCAqL1xuXHRyZXBsYWNlTmFtZSggaW5wdXQsIG5ld1ZhbHVlICkge1xuXHRcdC8vIG5vaW5zcGVjdGlvbiBKU1VucmVzb2x2ZWRWYXJpYWJsZVxuXHRcdGlucHV0Lm5hbWUgPSBpbnB1dC5uYW1lLnJlcGxhY2UoXG5cdFx0XHQvKC4rXFxbLitdKVxcWy4qXS9nLFxuXHRcdFx0JyQxWycgKyBuZXdWYWx1ZSArICddJ1xuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQ2xlYXIgbWVzc2FnZS5cblx0ICpcblx0ICogQHBhcmFtIHtIVE1MRGl2RWxlbWVudH0gbWVzc2FnZSBNZXNzYWdlLlxuXHQgKi9cblx0Y2xlYXJNZXNzYWdlKCBtZXNzYWdlICkge1xuXHRcdG1lc3NhZ2UuaW5uZXJIVE1MID0gJyc7XG5cdFx0bWVzc2FnZS5jbGFzc0xpc3QucmVtb3ZlKCAnYWN0aXZlJyApO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFyIG1lc3NhZ2VzLlxuXHQgKi9cblx0Y2xlYXJNZXNzYWdlcygpIHtcblx0XHR0aGlzLmNsZWFyTWVzc2FnZSggdGhpcy5zdWNjZXNzTWVzc2FnZSApO1xuXHRcdHRoaXMuY2xlYXJNZXNzYWdlKCB0aGlzLmVycm9yTWVzc2FnZSApO1xuXHRcdGNsZWFyVGltZW91dCggdGhpcy5tc2dUaW1lciApO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgbWVzc2FnZS5cblx0ICpcblx0ICogQHBhcmFtIHtIVE1MRGl2RWxlbWVudH0gZWwgRWxlbWVudC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgTWVzc2FnZS5cblx0ICovXG5cdHNob3dNZXNzYWdlKCBlbCwgbWVzc2FnZSApIHtcblx0XHRlbC5pbm5lckhUTUwgPSBtZXNzYWdlO1xuXHRcdGVsLmNsYXNzTGlzdC5hZGQoICdhY3RpdmUnICk7XG5cblx0XHR0aGlzLm1zZ1RpbWVyID0gc2V0VGltZW91dCggKCkgPT4ge1xuXHRcdFx0dGhpcy5jbGVhck1lc3NhZ2VzKCk7XG5cdFx0fSwgNTAwMCApO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNldHRpbmdzO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==
 
 
languages/cyr2lat-ru_RU.mo CHANGED
Binary file
languages/cyr2lat-ru_RU.po CHANGED
@@ -1,8 +1,8 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: Cyr To Lat\n"
4
- "POT-Creation-Date: 2021-02-10 14:55+0200\n"
5
- "PO-Revision-Date: 2021-02-10 14:57+0200\n"
6
  "Last-Translator: KAGG Design <info@kagg.eu>\n"
7
  "Language-Team: KAGG Design\n"
8
  "Language: ru_RU\n"
@@ -17,96 +17,219 @@ msgstr ""
17
  "X-Poedit-Flags-xgettext: --add-comments\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
  "X-Poedit-SearchPathExcluded-0: .git\n"
20
- "X-Poedit-SearchPathExcluded-1: .make\n"
21
- "X-Poedit-SearchPathExcluded-2: assets\n"
22
- "X-Poedit-SearchPathExcluded-3: css\n"
23
- "X-Poedit-SearchPathExcluded-4: dist\n"
24
- "X-Poedit-SearchPathExcluded-5: js\n"
25
- "X-Poedit-SearchPathExcluded-6: languages\n"
26
  "X-Poedit-SearchPathExcluded-7: node_modules\n"
27
- "X-Poedit-SearchPathExcluded-8: src\n"
28
  "X-Poedit-SearchPathExcluded-9: tests\n"
29
  "X-Poedit-SearchPathExcluded-10: vendor\n"
30
 
31
- #: classes/background-processes/class-post-conversion-process.php:73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  msgid "Post slug converted:"
33
  msgstr "Ярлык поста сконвертирован:"
34
 
35
- #: classes/background-processes/class-post-conversion-process.php:102
36
  msgid "Attachment file converted:"
37
  msgstr "Файл вложения сконвертирован:"
38
 
39
- #: classes/background-processes/class-post-conversion-process.php:108
40
  msgid "Cannot convert attachment file for attachment id:"
41
  msgstr "Невозможно сконвертировать файл вложения для вложения с id:"
42
 
43
- #: classes/background-processes/class-post-conversion-process.php:126
44
  msgid "Thumbnail file renamed:"
45
  msgstr "Файл миниатюры переименован:"
46
 
47
- #: classes/background-processes/class-post-conversion-process.php:129
48
  msgid "Cannot rename thumbnail file:"
49
  msgstr "Невозможно переименовать файл миниатюры:"
50
 
51
- #: classes/background-processes/class-post-conversion-process.php:198
52
  msgid "Post slugs conversion completed."
53
  msgstr "Конвертация ярлыков постов завершена."
54
 
55
- #: classes/background-processes/class-term-conversion-process.php:72
56
  msgid "Term slug converted:"
57
  msgstr "Ярлык термина сконвертирован:"
58
 
59
- #: classes/background-processes/class-term-conversion-process.php:84
60
  msgid "Term slugs conversion completed."
61
  msgstr "Конвертация ярлыков терминов завершена."
62
 
63
- #: classes/class-converter.php:106
64
  msgid "Cyr To Lat converts existing post slugs in the background process."
65
  msgstr "Cyr To Lat конвертирует существующие ярлыки постов в фоновом процессе."
66
 
67
- #: classes/class-converter.php:113
68
  msgid "Cyr To Lat converts existing term slugs in the background process."
69
  msgstr ""
70
  "Cyr To Lat конвертирует существующие ярлыки терминов в фоновом процессе."
71
 
72
- #: classes/class-converter.php:120
73
  msgid "Cyr To Lat completed conversion of existing post slugs."
74
  msgstr "Cyr To Lat завершил конвертацию существующих ярлыков постов."
75
 
76
- #: classes/class-converter.php:127
77
  msgid "Cyr To Lat completed conversion of existing term slugs."
78
  msgstr "Cyr To Lat завершил конвертацию существующих ярлыков терминов."
79
 
80
- #: classes/class-converter.php:205
81
  msgid "Cyr To Lat has not found existing post slugs for conversion."
82
  msgstr "Cyr To Lat не нашёл существующих ярлыков постов для конвертации."
83
 
84
- #: classes/class-converter.php:216
85
  msgid "Post slugs conversion started."
86
  msgstr "Начата конвертация ярлыков постов."
87
 
88
- #: classes/class-converter.php:218
89
  msgid "Cyr To Lat started conversion of existing post slugs."
90
  msgstr "Cyr To Lat начал конвертацию существующих ярлыков постов."
91
 
92
- #: classes/class-converter.php:242
93
  msgid "Cyr To Lat has not found existing term slugs for conversion."
94
  msgstr "Cyr To Lat не нашёл существующих ярлыков терминов для конвертации."
95
 
96
- #: classes/class-converter.php:253
97
  msgid "Term slugs conversion started."
98
  msgstr "Начата конвертация ярлыков терминов."
99
 
100
- #: classes/class-converter.php:255
101
  msgid "Cyr To Lat started conversion of existing term slugs."
102
  msgstr "Cyr To Lat начал конвертацию существующих ярлыков терминов."
103
 
104
- #: classes/class-requirements.php:101
105
  msgid "Cyr To Lat plugin has been deactivated."
106
  msgstr "Плагин Cyr To Lat был деактивирован."
107
 
108
  #. translators: 1: Current PHP version number, 2: Cyr To Lat version, 3: Minimum required PHP version number
109
- #: classes/class-requirements.php:116
110
  #, php-format
111
  msgid ""
112
  "Your server is running PHP version %1$s but Cyr To Lat %2$s requires at "
@@ -115,12 +238,12 @@ msgstr ""
115
  "На сервере установлен PHP версии %1$s, однако для Cyr To Lat %2$s требуется "
116
  "хотя бы %3$s."
117
 
118
- #: classes/class-requirements.php:137
119
  msgid "Unable to get filesystem access."
120
  msgstr "Невозможно получить доступ к файловой системе."
121
 
122
  #. translators: 1: max_input_vars value, 2: Cyr To Lat version, 3: Minimum required max_input_vars
123
- #: classes/class-requirements.php:154
124
  #, php-format
125
  msgid ""
126
  "Your server is running PHP with max_input_vars=%1$d but Cyr To Lat %2$s "
@@ -130,166 +253,25 @@ msgstr ""
130
  "требуется хотя бы %3$d."
131
 
132
  #. translators: 1: .user.ini filename
133
- #: classes/class-requirements.php:158
134
  #, php-format
135
  msgid "We have updated settings in %s."
136
  msgstr "Мы обновили настройки в %s."
137
 
138
  #. translators: 1: Wait time in seconds
139
- #: classes/class-requirements.php:161
140
  #, php-format
141
  msgid "Please try again in %d s."
142
  msgstr "Пожалуйста, попробуйте снова через %d сек."
143
 
144
- #: classes/class-requirements.php:226
145
  msgid "Please increase max input vars limit up to 1500."
146
  msgstr "Пожалуйста, увеличьте лимит max input vars до 1500."
147
 
148
- #: classes/class-requirements.php:229
149
  msgid ""
150
  "See: <a href=\"http://sevenspark.com/docs/ubermenu-3/faqs/menu-item-limit\" "
151
  "target=\"_blank\">Increasing max input vars limit.</a>"
152
  msgstr ""
153
  "См.: <a href=\"http://sevenspark.com/docs/ubermenu-3/faqs/menu-item-limit\" "
154
  "target=\"_blank\">Увеличение лимита max input vars.</a>"
155
-
156
- #: classes/class-settings.php:126
157
- msgid "View Cyr To Lat settings"
158
- msgstr "Посмотреть настройки Cyr To Lat"
159
-
160
- #: classes/class-settings.php:127
161
- msgid "Settings"
162
- msgstr "Настройки"
163
-
164
- #: classes/class-settings.php:143
165
- msgid "ISO9 Table"
166
- msgstr "Таблица ISO9"
167
-
168
- #: classes/class-settings.php:146
169
- msgid "bel Table"
170
- msgstr "Таблица bel"
171
-
172
- #: classes/class-settings.php:149
173
- msgid "uk Table"
174
- msgstr "Таблица uk"
175
-
176
- #: classes/class-settings.php:152
177
- msgid "bg_BG Table"
178
- msgstr "Таблица bg_BG"
179
-
180
- #: classes/class-settings.php:155
181
- msgid "mk_MK Table"
182
- msgstr "Таблица mk_MK"
183
-
184
- #: classes/class-settings.php:158
185
- msgid "sr_RS Table"
186
- msgstr "Таблица sr_RS"
187
-
188
- #: classes/class-settings.php:161
189
- msgid "el Table"
190
- msgstr "Таблица el"
191
-
192
- #: classes/class-settings.php:164
193
- msgid "hy Table"
194
- msgstr "Таблица hy"
195
-
196
- #: classes/class-settings.php:167
197
- msgid "ka_GE Table"
198
- msgstr "Таблица ka_GE"
199
-
200
- #: classes/class-settings.php:170
201
- msgid "kk Table"
202
- msgstr "Таблица kk"
203
-
204
- #: classes/class-settings.php:173
205
- msgid "he_IL Table"
206
- msgstr "Таблица he_IL"
207
-
208
- #: classes/class-settings.php:176
209
- msgid "zh_CN Table"
210
- msgstr "Таблица zh_CN"
211
-
212
- #: classes/class-settings.php:203
213
- msgid "(current)"
214
- msgstr "(текущая)"
215
-
216
- #: classes/class-settings.php:270 classes/class-settings.php:271
217
- msgid "Cyr To Lat"
218
- msgstr "Cyr To Lat"
219
-
220
- #. Admin panel title.
221
- #: classes/class-settings.php:291
222
- msgid "Cyr To Lat Plugin Options"
223
- msgstr "Опции плагина Cyr To Lat"
224
-
225
- #: classes/class-settings.php:307
226
- msgid "Convert Existing Slugs"
227
- msgstr "Конвертировать существующие ярлыки"
228
-
229
- #: classes/class-settings.php:313
230
- msgid "Your appreciation"
231
- msgstr "Ваша оценка"
232
-
233
- #: classes/class-settings.php:318
234
- msgid "Leave a ★★★★★ plugin review on WordPress.org"
235
- msgstr "Оставьте ★★★★★ обзор плагина на WordPress.org"
236
-
237
- #: classes/class-settings.php:664
238
- msgid "Options saved."
239
- msgstr "Настройки сохранены."
240
-
241
- #: classes/class-settings.php:665
242
- msgid "Error saving options."
243
- msgstr "Ошибка сохранения настроек."
244
-
245
- #: classes/class-settings.php:689
246
- msgid "Important:"
247
- msgstr "Важно:"
248
-
249
- #: classes/class-settings.php:692
250
- msgid ""
251
- "This operation is irreversible. Please make sure that you have made backup "
252
- "copy of your database."
253
- msgstr ""
254
- "Эта операция необратима. Пожалуйста, убедитесь, что вы сделали копию базы "
255
- "данных."
256
-
257
- #: classes/class-settings.php:697
258
- msgid "Are you sure to continue?"
259
- msgstr "Вы уверены, что хотите продолжить?"
260
-
261
- #: classes/class-settings.php:701
262
- msgid "OK"
263
- msgstr "OK"
264
-
265
- #: classes/class-settings.php:704
266
- msgid "Cancel"
267
- msgstr "Отмена"
268
-
269
- #. translators: %d: cron interval
270
- #: lib/wp-background-processing/class-wp-background-process.php:399
271
- #, php-format
272
- msgid "Every %d Minutes"
273
- msgstr "Каждые %d минут"
274
-
275
- #~ msgid "Donate"
276
- #~ msgstr "Пожертвовать"
277
-
278
- #~ msgid "Would you like to support the advancement of this plugin?"
279
- #~ msgstr "Хотите поддержать развитие этого плагина?"
280
-
281
- #~ msgid "Please try again."
282
- #~ msgstr "Пожалуйста, попробуйте снова."
283
-
284
- #~ msgid "Unable to get filesystem access"
285
- #~ msgstr "Невозможно получить доступ к файловой системе"
286
-
287
- #~ msgid ""
288
- #~ "Your server is running PHP version %1$s but Cyr To Lat version %2$s "
289
- #~ "requires at least %3$s."
290
- #~ msgstr ""
291
- #~ "На сервере установлен PHP версии %1$s, однако для Cyr To Lat %2$s "
292
- #~ "требуется хотя бы %3$s."
293
-
294
- #~ msgid "General Options"
295
- #~ msgstr "Общие настройки"
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: Cyr To Lat\n"
4
+ "POT-Creation-Date: 2021-02-24 22:11+0200\n"
5
+ "PO-Revision-Date: 2021-02-24 22:14+0200\n"
6
  "Last-Translator: KAGG Design <info@kagg.eu>\n"
7
  "Language-Team: KAGG Design\n"
8
  "Language: ru_RU\n"
17
  "X-Poedit-Flags-xgettext: --add-comments\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
  "X-Poedit-SearchPathExcluded-0: .git\n"
20
+ "X-Poedit-SearchPathExcluded-1: .github\n"
21
+ "X-Poedit-SearchPathExcluded-2: .make\n"
22
+ "X-Poedit-SearchPathExcluded-3: .wordpress-org\n"
23
+ "X-Poedit-SearchPathExcluded-4: assets\n"
24
+ "X-Poedit-SearchPathExcluded-5: languages\n"
25
+ "X-Poedit-SearchPathExcluded-6: lib\n"
26
  "X-Poedit-SearchPathExcluded-7: node_modules\n"
27
+ "X-Poedit-SearchPathExcluded-8: src/js\n"
28
  "X-Poedit-SearchPathExcluded-9: tests\n"
29
  "X-Poedit-SearchPathExcluded-10: vendor\n"
30
 
31
+ #: src/php/Settings/Converter.php:59 src/php/Settings/Converter.php:68
32
+ msgid "Converter"
33
+ msgstr "Конвертация"
34
+
35
+ #. Admin panel title.
36
+ #: src/php/Settings/Converter.php:113 src/php/Settings/Tables.php:202
37
+ #: src/php/class-settings.php:291
38
+ msgid "Cyr To Lat Plugin Options"
39
+ msgstr "Опции плагина Cyr To Lat"
40
+
41
+ #: src/php/Settings/Converter.php:128 src/php/class-settings.php:307
42
+ msgid "Convert Existing Slugs"
43
+ msgstr "Конвертировать существующие ярлыки"
44
+
45
+ #: src/php/Settings/Converter.php:161 src/php/class-settings.php:689
46
+ msgid "Important:"
47
+ msgstr "Важно:"
48
+
49
+ #: src/php/Settings/Converter.php:164
50
+ msgid ""
51
+ "This operation is irreversible. Please make sure that you have made a backup "
52
+ "copy of your database."
53
+ msgstr ""
54
+ "Эта операция необратима. Пожалуйста, убедитесь, что вы сделали копию базы "
55
+ "данных."
56
+
57
+ #: src/php/Settings/Converter.php:169 src/php/class-settings.php:697
58
+ msgid "Are you sure to continue?"
59
+ msgstr "Вы уверены, что хотите продолжить?"
60
+
61
+ #: src/php/Settings/Converter.php:173 src/php/class-settings.php:701
62
+ msgid "OK"
63
+ msgstr "OK"
64
+
65
+ #: src/php/Settings/Converter.php:176 src/php/class-settings.php:704
66
+ msgid "Cancel"
67
+ msgstr "Отмена"
68
+
69
+ #: src/php/Settings/PluginSettingsBase.php:52 src/php/class-settings.php:126
70
+ msgid "View Cyr To Lat settings"
71
+ msgstr "Посмотреть настройки Cyr To Lat"
72
+
73
+ #: src/php/Settings/PluginSettingsBase.php:61 src/php/class-settings.php:127
74
+ msgid "Settings"
75
+ msgstr "Настройки"
76
+
77
+ #: src/php/Settings/Tables.php:78
78
+ msgid "Tables"
79
+ msgstr "Таблицы"
80
+
81
+ #: src/php/Settings/Tables.php:87 src/php/class-settings.php:270
82
+ #: src/php/class-settings.php:271
83
+ msgid "Cyr To Lat"
84
+ msgstr "Cyr To Lat"
85
+
86
+ #: src/php/Settings/Tables.php:119 src/php/class-settings.php:143
87
+ msgid "ISO9 Table"
88
+ msgstr "Таблица ISO9"
89
+
90
+ #: src/php/Settings/Tables.php:122 src/php/class-settings.php:146
91
+ msgid "bel Table"
92
+ msgstr "Таблица bel"
93
+
94
+ #: src/php/Settings/Tables.php:125 src/php/class-settings.php:149
95
+ msgid "uk Table"
96
+ msgstr "Таблица uk"
97
+
98
+ #: src/php/Settings/Tables.php:128 src/php/class-settings.php:152
99
+ msgid "bg_BG Table"
100
+ msgstr "Таблица bg_BG"
101
+
102
+ #: src/php/Settings/Tables.php:131 src/php/class-settings.php:155
103
+ msgid "mk_MK Table"
104
+ msgstr "Таблица mk_MK"
105
+
106
+ #: src/php/Settings/Tables.php:134 src/php/class-settings.php:158
107
+ msgid "sr_RS Table"
108
+ msgstr "Таблица sr_RS"
109
+
110
+ #: src/php/Settings/Tables.php:137 src/php/class-settings.php:161
111
+ msgid "el Table"
112
+ msgstr "Таблица el"
113
+
114
+ #: src/php/Settings/Tables.php:140 src/php/class-settings.php:164
115
+ msgid "hy Table"
116
+ msgstr "Таблица hy"
117
+
118
+ #: src/php/Settings/Tables.php:143 src/php/class-settings.php:167
119
+ msgid "ka_GE Table"
120
+ msgstr "Таблица ka_GE"
121
+
122
+ #: src/php/Settings/Tables.php:146 src/php/class-settings.php:170
123
+ msgid "kk Table"
124
+ msgstr "Таблица kk"
125
+
126
+ #: src/php/Settings/Tables.php:149 src/php/class-settings.php:173
127
+ msgid "he_IL Table"
128
+ msgstr "Таблица he_IL"
129
+
130
+ #: src/php/Settings/Tables.php:152 src/php/class-settings.php:176
131
+ msgid "zh_CN Table"
132
+ msgstr "Таблица zh_CN"
133
+
134
+ #: src/php/Settings/Tables.php:179 src/php/class-settings.php:203
135
+ msgid "(current)"
136
+ msgstr "(текущая)"
137
+
138
+ #: src/php/Settings/Tables.php:216 src/php/class-settings.php:313
139
+ msgid "Your appreciation"
140
+ msgstr "Ваша оценка"
141
+
142
+ #: src/php/Settings/Tables.php:221 src/php/class-settings.php:318
143
+ msgid "Leave a ★★★★★ plugin review on WordPress.org"
144
+ msgstr "Оставьте ★★★★★ обзор плагина на WordPress.org"
145
+
146
+ #: src/php/Settings/Tables.php:260 src/php/class-settings.php:664
147
+ msgid "Options saved."
148
+ msgstr "Настройки сохранены."
149
+
150
+ #: src/php/Settings/Tables.php:261 src/php/class-settings.php:665
151
+ msgid "Error saving options."
152
+ msgstr "Ошибка сохранения настроек."
153
+
154
+ #: src/php/background-processes/class-post-conversion-process.php:73
155
  msgid "Post slug converted:"
156
  msgstr "Ярлык поста сконвертирован:"
157
 
158
+ #: src/php/background-processes/class-post-conversion-process.php:102
159
  msgid "Attachment file converted:"
160
  msgstr "Файл вложения сконвертирован:"
161
 
162
+ #: src/php/background-processes/class-post-conversion-process.php:108
163
  msgid "Cannot convert attachment file for attachment id:"
164
  msgstr "Невозможно сконвертировать файл вложения для вложения с id:"
165
 
166
+ #: src/php/background-processes/class-post-conversion-process.php:126
167
  msgid "Thumbnail file renamed:"
168
  msgstr "Файл миниатюры переименован:"
169
 
170
+ #: src/php/background-processes/class-post-conversion-process.php:129
171
  msgid "Cannot rename thumbnail file:"
172
  msgstr "Невозможно переименовать файл миниатюры:"
173
 
174
+ #: src/php/background-processes/class-post-conversion-process.php:198
175
  msgid "Post slugs conversion completed."
176
  msgstr "Конвертация ярлыков постов завершена."
177
 
178
+ #: src/php/background-processes/class-term-conversion-process.php:72
179
  msgid "Term slug converted:"
180
  msgstr "Ярлык термина сконвертирован:"
181
 
182
+ #: src/php/background-processes/class-term-conversion-process.php:84
183
  msgid "Term slugs conversion completed."
184
  msgstr "Конвертация ярлыков терминов завершена."
185
 
186
+ #: src/php/class-converter.php:106
187
  msgid "Cyr To Lat converts existing post slugs in the background process."
188
  msgstr "Cyr To Lat конвертирует существующие ярлыки постов в фоновом процессе."
189
 
190
+ #: src/php/class-converter.php:113
191
  msgid "Cyr To Lat converts existing term slugs in the background process."
192
  msgstr ""
193
  "Cyr To Lat конвертирует существующие ярлыки терминов в фоновом процессе."
194
 
195
+ #: src/php/class-converter.php:120
196
  msgid "Cyr To Lat completed conversion of existing post slugs."
197
  msgstr "Cyr To Lat завершил конвертацию существующих ярлыков постов."
198
 
199
+ #: src/php/class-converter.php:127
200
  msgid "Cyr To Lat completed conversion of existing term slugs."
201
  msgstr "Cyr To Lat завершил конвертацию существующих ярлыков терминов."
202
 
203
+ #: src/php/class-converter.php:208
204
  msgid "Cyr To Lat has not found existing post slugs for conversion."
205
  msgstr "Cyr To Lat не нашёл существующих ярлыков постов для конвертации."
206
 
207
+ #: src/php/class-converter.php:219
208
  msgid "Post slugs conversion started."
209
  msgstr "Начата конвертация ярлыков постов."
210
 
211
+ #: src/php/class-converter.php:221
212
  msgid "Cyr To Lat started conversion of existing post slugs."
213
  msgstr "Cyr To Lat начал конвертацию существующих ярлыков постов."
214
 
215
+ #: src/php/class-converter.php:245
216
  msgid "Cyr To Lat has not found existing term slugs for conversion."
217
  msgstr "Cyr To Lat не нашёл существующих ярлыков терминов для конвертации."
218
 
219
+ #: src/php/class-converter.php:256
220
  msgid "Term slugs conversion started."
221
  msgstr "Начата конвертация ярлыков терминов."
222
 
223
+ #: src/php/class-converter.php:258
224
  msgid "Cyr To Lat started conversion of existing term slugs."
225
  msgstr "Cyr To Lat начал конвертацию существующих ярлыков терминов."
226
 
227
+ #: src/php/class-requirements.php:101
228
  msgid "Cyr To Lat plugin has been deactivated."
229
  msgstr "Плагин Cyr To Lat был деактивирован."
230
 
231
  #. translators: 1: Current PHP version number, 2: Cyr To Lat version, 3: Minimum required PHP version number
232
+ #: src/php/class-requirements.php:116
233
  #, php-format
234
  msgid ""
235
  "Your server is running PHP version %1$s but Cyr To Lat %2$s requires at "
238
  "На сервере установлен PHP версии %1$s, однако для Cyr To Lat %2$s требуется "
239
  "хотя бы %3$s."
240
 
241
+ #: src/php/class-requirements.php:137
242
  msgid "Unable to get filesystem access."
243
  msgstr "Невозможно получить доступ к файловой системе."
244
 
245
  #. translators: 1: max_input_vars value, 2: Cyr To Lat version, 3: Minimum required max_input_vars
246
+ #: src/php/class-requirements.php:154
247
  #, php-format
248
  msgid ""
249
  "Your server is running PHP with max_input_vars=%1$d but Cyr To Lat %2$s "
253
  "требуется хотя бы %3$d."
254
 
255
  #. translators: 1: .user.ini filename
256
+ #: src/php/class-requirements.php:158
257
  #, php-format
258
  msgid "We have updated settings in %s."
259
  msgstr "Мы обновили настройки в %s."
260
 
261
  #. translators: 1: Wait time in seconds
262
+ #: src/php/class-requirements.php:161
263
  #, php-format
264
  msgid "Please try again in %d s."
265
  msgstr "Пожалуйста, попробуйте снова через %d сек."
266
 
267
+ #: src/php/class-requirements.php:226
268
  msgid "Please increase max input vars limit up to 1500."
269
  msgstr "Пожалуйста, увеличьте лимит max input vars до 1500."
270
 
271
+ #: src/php/class-requirements.php:229
272
  msgid ""
273
  "See: <a href=\"http://sevenspark.com/docs/ubermenu-3/faqs/menu-item-limit\" "
274
  "target=\"_blank\">Increasing max input vars limit.</a>"
275
  msgstr ""
276
  "См.: <a href=\"http://sevenspark.com/docs/ubermenu-3/faqs/menu-item-limit\" "
277
  "target=\"_blank\">Увеличение лимита max input vars.</a>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/cyr2lat-sv.po CHANGED
@@ -16,14 +16,14 @@ msgstr ""
16
  "X-Poedit-Flags-xgettext: --add-comments\n"
17
  "X-Poedit-SearchPath-0: .\n"
18
  "X-Poedit-SearchPathExcluded-0: .git\n"
19
- "X-Poedit-SearchPathExcluded-1: .make\n"
20
- "X-Poedit-SearchPathExcluded-2: assets\n"
21
- "X-Poedit-SearchPathExcluded-3: css\n"
22
- "X-Poedit-SearchPathExcluded-4: dist\n"
23
- "X-Poedit-SearchPathExcluded-5: js\n"
24
- "X-Poedit-SearchPathExcluded-6: languages\n"
25
  "X-Poedit-SearchPathExcluded-7: node_modules\n"
26
- "X-Poedit-SearchPathExcluded-8: src\n"
27
  "X-Poedit-SearchPathExcluded-9: tests\n"
28
  "X-Poedit-SearchPathExcluded-10: vendor\n"
29
 
16
  "X-Poedit-Flags-xgettext: --add-comments\n"
17
  "X-Poedit-SearchPath-0: .\n"
18
  "X-Poedit-SearchPathExcluded-0: .git\n"
19
+ "X-Poedit-SearchPathExcluded-1: .github\n"
20
+ "X-Poedit-SearchPathExcluded-2: .make\n"
21
+ "X-Poedit-SearchPathExcluded-3: .wordpress-org\n"
22
+ "X-Poedit-SearchPathExcluded-4: assets\n"
23
+ "X-Poedit-SearchPathExcluded-5: languages\n"
24
+ "X-Poedit-SearchPathExcluded-6: lib\n"
25
  "X-Poedit-SearchPathExcluded-7: node_modules\n"
26
+ "X-Poedit-SearchPathExcluded-8: src/js\n"
27
  "X-Poedit-SearchPathExcluded-9: tests\n"
28
  "X-Poedit-SearchPathExcluded-10: vendor\n"
29
 
languages/cyr2lat-uk.po CHANGED
@@ -17,14 +17,14 @@ msgstr ""
17
  "X-Poedit-Flags-xgettext: --add-comments\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
  "X-Poedit-SearchPathExcluded-0: .git\n"
20
- "X-Poedit-SearchPathExcluded-1: .make\n"
21
- "X-Poedit-SearchPathExcluded-2: assets\n"
22
- "X-Poedit-SearchPathExcluded-3: css\n"
23
- "X-Poedit-SearchPathExcluded-4: dist\n"
24
- "X-Poedit-SearchPathExcluded-5: js\n"
25
- "X-Poedit-SearchPathExcluded-6: languages\n"
26
  "X-Poedit-SearchPathExcluded-7: node_modules\n"
27
- "X-Poedit-SearchPathExcluded-8: src\n"
28
  "X-Poedit-SearchPathExcluded-9: tests\n"
29
  "X-Poedit-SearchPathExcluded-10: vendor\n"
30
 
17
  "X-Poedit-Flags-xgettext: --add-comments\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
  "X-Poedit-SearchPathExcluded-0: .git\n"
20
+ "X-Poedit-SearchPathExcluded-1: .github\n"
21
+ "X-Poedit-SearchPathExcluded-2: .make\n"
22
+ "X-Poedit-SearchPathExcluded-3: .wordpress-org\n"
23
+ "X-Poedit-SearchPathExcluded-4: assets\n"
24
+ "X-Poedit-SearchPathExcluded-5: languages\n"
25
+ "X-Poedit-SearchPathExcluded-6: lib\n"
26
  "X-Poedit-SearchPathExcluded-7: node_modules\n"
27
+ "X-Poedit-SearchPathExcluded-8: src/js\n"
28
  "X-Poedit-SearchPathExcluded-9: tests\n"
29
  "X-Poedit-SearchPathExcluded-10: vendor\n"
30
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: SergeyBiryukov, mihdan, karevn, webvitaly, kaggdesign
3
  Tags: cyrillic, belorussian, ukrainian, bulgarian, macedonian, georgian, kazakh, latin, l10n, russian, cyr-to-lat, cyr2lat, rustolat, slugs, translations, transliteration
4
  Requires at least: 5.1
5
  Tested up to: 5.7
6
- Stable tag: 4.6.4
7
  Requires PHP: 5.6.20
8
 
9
  Converts Cyrillic characters in post, page and term slugs to Latin characters.
@@ -21,11 +21,15 @@ Converts Cyrillic characters in post, page and term slugs to Latin characters. U
21
  * [Has many advantages over similar plugins](https://kagg.eu/en/the-benefits-of-cyr-to-lat/)
22
  * [Officially compatible with WPML](https://wpml.org/plugin/cyr-to-lat/)
23
 
24
- ![WPML Certificate](https://ps.w.org/cyr2lat/assets/Cyr-To-Lat---WPML-Compatibility-Certificate-240x250.png)
25
 
26
  Based on the original Rus-To-Lat plugin by Anton Skorobogatov.
27
 
28
- [](http://coderisk.com/wp/plugin/cyr2lat/RIPS-nt7iXCmzoc)
 
 
 
 
29
 
30
  == Installation ==
31
 
@@ -174,6 +178,12 @@ Yes you can!
174
 
175
  == Changelog ==
176
 
 
 
 
 
 
 
177
  = 4.6.4 (03.03.2021) =
178
  * Tested up to WordPress 5.7
179
 
3
  Tags: cyrillic, belorussian, ukrainian, bulgarian, macedonian, georgian, kazakh, latin, l10n, russian, cyr-to-lat, cyr2lat, rustolat, slugs, translations, transliteration
4
  Requires at least: 5.1
5
  Tested up to: 5.7
6
+ Stable tag: 5.0.0
7
  Requires PHP: 5.6.20
8
 
9
  Converts Cyrillic characters in post, page and term slugs to Latin characters.
21
  * [Has many advantages over similar plugins](https://kagg.eu/en/the-benefits-of-cyr-to-lat/)
22
  * [Officially compatible with WPML](https://wpml.org/plugin/cyr-to-lat/)
23
 
24
+ <img src="https://ps.w.org/cyr2lat/assets/Cyr-To-Lat---WPML-Compatibility-Certificate-240x250.png" alt="WPML Certificate" />
25
 
26
  Based on the original Rus-To-Lat plugin by Anton Skorobogatov.
27
 
28
+ == Screenshots ==
29
+
30
+ 1. Tables settings page
31
+ 2. Converter settings page
32
+ 3. Block editor with transliterated slug
33
 
34
  == Installation ==
35
 
178
 
179
  == Changelog ==
180
 
181
+ = 5.0.0 (18.03.2021) =
182
+ * Introduce tabs on options page
183
+ * Add options to select post types and statuses for background conversion
184
+ * Make colors compatible to WP official palette
185
+ * Fix bug with Polylang when locale is not equal to language slug
186
+
187
  = 4.6.4 (03.03.2021) =
188
  * Tested up to WordPress 5.7
189
 
src/php/Settings/Abstracts/SettingsBase.php ADDED
@@ -0,0 +1,956 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SettingsBase class file.
4
+ *
5
+ * @package cyr-to-lat
6
+ */
7
+
8
+ namespace Cyr_To_Lat\Settings\Abstracts;
9
+
10
+ /**
11
+ * Class SettingsBase
12
+ *
13
+ * This is an abstract class to create the settings page in any plugin.
14
+ * It uses WordPress Settings API and general output of fields of any type.
15
+ * Similar approach is used in many plugins, including WooCommerce.
16
+ */
17
+ abstract class SettingsBase {
18
+
19
+ /**
20
+ * Admin script handle.
21
+ */
22
+ const HANDLE = 'ctl-settings-base';
23
+
24
+ /**
25
+ * Form fields.
26
+ *
27
+ * @var array
28
+ */
29
+ protected $form_fields;
30
+
31
+ /**
32
+ * Plugin options.
33
+ *
34
+ * @var array
35
+ */
36
+ protected $settings;
37
+
38
+ /**
39
+ * Tabs of this settings page.
40
+ *
41
+ * @var array|null
42
+ */
43
+ protected $tabs;
44
+
45
+ /**
46
+ * Get screen id.
47
+ *
48
+ * @return string
49
+ */
50
+ abstract public function screen_id();
51
+
52
+ /**
53
+ * Get option group.
54
+ *
55
+ * @return string
56
+ */
57
+ abstract protected function option_group();
58
+
59
+ /**
60
+ * Get option page.
61
+ *
62
+ * @return string
63
+ */
64
+ abstract protected function option_page();
65
+
66
+ /**
67
+ * Get option name.
68
+ *
69
+ * @return string
70
+ */
71
+ abstract protected function option_name();
72
+
73
+ /**
74
+ * Get plugin base name.
75
+ *
76
+ * @return string
77
+ */
78
+ abstract protected function plugin_basename();
79
+
80
+ /**
81
+ * Get plugin url.
82
+ *
83
+ * @return string
84
+ */
85
+ abstract protected function plugin_url();
86
+
87
+ /**
88
+ * Get plugin version.
89
+ *
90
+ * @return string
91
+ */
92
+ abstract protected function plugin_version();
93
+
94
+ /**
95
+ * Get settings link label.
96
+ *
97
+ * @return string
98
+ */
99
+ abstract protected function settings_link_label();
100
+
101
+ /**
102
+ * Get settings link text.
103
+ *
104
+ * @return string
105
+ */
106
+ abstract protected function settings_link_text();
107
+
108
+ /**
109
+ * Init form fields.
110
+ */
111
+ abstract protected function init_form_fields();
112
+
113
+ /**
114
+ * Get page title.
115
+ *
116
+ * @return string
117
+ */
118
+ abstract protected function page_title();
119
+
120
+ /**
121
+ * Get menu title.
122
+ *
123
+ * @return string
124
+ */
125
+ abstract protected function menu_title();
126
+
127
+ /**
128
+ * Show setting page.
129
+ */
130
+ abstract public function settings_page();
131
+
132
+ /**
133
+ * Get section title.
134
+ *
135
+ * @return string
136
+ */
137
+ abstract protected function section_title();
138
+
139
+ /**
140
+ * Show section.
141
+ *
142
+ * @param array $arguments Arguments.
143
+ */
144
+ abstract public function section_callback( $arguments );
145
+
146
+ /**
147
+ * Enqueue scripts in admin.
148
+ */
149
+ abstract public function admin_enqueue_scripts();
150
+
151
+ /**
152
+ * Get text domain.
153
+ *
154
+ * @return string
155
+ */
156
+ abstract protected function text_domain();
157
+
158
+ /**
159
+ * SettingsBase constructor.
160
+ *
161
+ * @param array $tabs Tabs of this settings page.
162
+ */
163
+ public function __construct( $tabs = [] ) {
164
+ $this->tabs = $tabs;
165
+
166
+ if ( ! $this->is_tab() ) {
167
+ add_action( 'current_screen', [ $this, 'setup_tabs_section' ] );
168
+ }
169
+
170
+ if ( $this->is_tab_active( $this ) ) {
171
+ add_action( 'plugins_loaded', [ $this, 'init' ] );
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Init class.
177
+ */
178
+ public function init() {
179
+ $this->load_plugin_textdomain();
180
+ $this->init_form_fields();
181
+ $this->init_settings();
182
+ $this->init_hooks();
183
+ }
184
+
185
+ /**
186
+ * Init class hooks.
187
+ */
188
+ protected function init_hooks() {
189
+ add_filter(
190
+ 'plugin_action_links_' . $this->plugin_basename(),
191
+ [ $this, 'add_settings_link' ],
192
+ 10
193
+ );
194
+
195
+ add_action( 'admin_menu', [ $this, 'add_settings_page' ] );
196
+ add_action( 'current_screen', [ $this, 'setup_sections' ] );
197
+ add_action( 'current_screen', [ $this, 'setup_fields' ] );
198
+
199
+ add_filter( 'pre_update_option_' . $this->option_name(), [ $this, 'pre_update_option_filter' ], 10, 2 );
200
+
201
+ add_action( 'admin_enqueue_scripts', [ $this, 'base_admin_enqueue_scripts' ] );
202
+ }
203
+
204
+ /**
205
+ * Get parent slug.
206
+ *
207
+ * @return string
208
+ */
209
+ protected function parent_slug() {
210
+ // By default, add menu pages to Options menu.
211
+ return 'options-general.php';
212
+ }
213
+
214
+ /**
215
+ * Is this the main menu page.
216
+ *
217
+ * @return bool
218
+ */
219
+ protected function is_main_menu_page() {
220
+ // Main menu page should have empty string as parent slug.
221
+ return ! (bool) $this->parent_slug();
222
+ }
223
+
224
+ /**
225
+ * Get tab name.
226
+ *
227
+ * @return string
228
+ */
229
+ protected function tab_name() {
230
+ return $this->get_class_name();
231
+ }
232
+
233
+ /**
234
+ * Get class name without namespace.
235
+ *
236
+ * @return string
237
+ */
238
+ protected function get_class_name() {
239
+ $path = explode( '\\', get_class( $this ) );
240
+
241
+ return array_pop( $path );
242
+ }
243
+
244
+ /**
245
+ * Is this a tab.
246
+ *
247
+ * @return bool
248
+ */
249
+ protected function is_tab() {
250
+ // Tab has null in tabs property.
251
+ return null === $this->tabs;
252
+ }
253
+
254
+ /**
255
+ * Add link to plugin setting page on plugins page.
256
+ *
257
+ * @param array $actions An array of plugin action links.
258
+ * By default this can include 'activate', 'deactivate', and 'delete'.
259
+ * With Multisite active this can also include
260
+ * 'network_active' and 'network_only' items.
261
+ *
262
+ * @return array|mixed Plugin links
263
+ */
264
+ public function add_settings_link( array $actions ) {
265
+ $new_actions = [
266
+ 'settings' =>
267
+ '<a href="' . admin_url( 'options-general.php?page=' . $this->option_page() ) .
268
+ '" aria-label="' . esc_attr( $this->settings_link_label() ) . '">' .
269
+ esc_html( $this->settings_link_text() ) . '</a>',
270
+ ];
271
+
272
+ return array_merge( $new_actions, $actions );
273
+ }
274
+
275
+ /**
276
+ * Initialise Settings.
277
+ *
278
+ * Store all settings in a single database entry
279
+ * and make sure the $settings array is either the default
280
+ * or the settings stored in the database.
281
+ */
282
+ protected function init_settings() {
283
+ $this->settings = get_option( $this->option_name(), null );
284
+
285
+ $form_fields = $this->form_fields();
286
+
287
+ if ( is_array( $this->settings ) ) {
288
+ $this->settings = array_merge( wp_list_pluck( $form_fields, 'default' ), $this->settings );
289
+
290
+ return;
291
+ }
292
+
293
+ // If there are no settings defined, use defaults.
294
+ $this->settings = array_merge(
295
+ array_fill_keys( array_keys( $form_fields ), '' ),
296
+ wp_list_pluck( $form_fields, 'default' )
297
+ );
298
+ }
299
+
300
+ /**
301
+ * Get the form fields after initialization.
302
+ *
303
+ * @return array of options
304
+ */
305
+ protected function form_fields() {
306
+ if ( empty( $this->form_fields ) ) {
307
+ $this->init_form_fields();
308
+ }
309
+
310
+ return array_map( [ $this, 'set_defaults' ], $this->form_fields );
311
+ }
312
+
313
+ /**
314
+ * Set default required properties for each field.
315
+ *
316
+ * @param array $field Settings field.
317
+ *
318
+ * @return array
319
+ */
320
+ protected function set_defaults( $field ) {
321
+ if ( ! isset( $field['default'] ) ) {
322
+ $field['default'] = '';
323
+ }
324
+
325
+ return $field;
326
+ }
327
+
328
+ /**
329
+ * Add settings page to the menu.
330
+ */
331
+ public function add_settings_page() {
332
+ if ( $this->is_main_menu_page() ) {
333
+ add_menu_page(
334
+ $this->page_title(),
335
+ $this->menu_title(),
336
+ 'manage_options',
337
+ $this->option_page(),
338
+ [ $this, 'settings_base_page' ]
339
+ );
340
+
341
+ return;
342
+ }
343
+
344
+ add_submenu_page(
345
+ $this->parent_slug(),
346
+ $this->page_title(),
347
+ $this->menu_title(),
348
+ 'manage_options',
349
+ $this->option_page(),
350
+ [ $this, 'settings_base_page' ]
351
+ );
352
+ }
353
+
354
+ /**
355
+ * Invoke relevant settings_page() basing on tabs.
356
+ */
357
+ public function settings_base_page() {
358
+ $this->get_active_tab()->settings_page();
359
+ }
360
+
361
+ /**
362
+ * Invoke relevant admin_enqueue_scripts() basing on tabs.
363
+ */
364
+ public function base_admin_enqueue_scripts() {
365
+ $this->get_active_tab()->admin_enqueue_scripts();
366
+
367
+ wp_enqueue_style(
368
+ self::HANDLE,
369
+ $this->plugin_url() . '/assets/css/settings-base.css',
370
+ [],
371
+ $this->plugin_version()
372
+ );
373
+ }
374
+
375
+ /**
376
+ * Setup settings sections.
377
+ */
378
+ public function setup_sections() {
379
+ $tab = $this->get_active_tab();
380
+
381
+ foreach ( $this->form_fields as $form_field ) {
382
+ $title = isset( $form_field['title'] ) ? $form_field['title'] : '';
383
+ add_settings_section(
384
+ $form_field['section'],
385
+ $title,
386
+ [ $tab, 'section_callback' ],
387
+ $tab->option_page()
388
+ );
389
+ }
390
+ }
391
+
392
+ /**
393
+ * Setup tabs section.
394
+ */
395
+ public function setup_tabs_section() {
396
+ $tab = $this->get_active_tab();
397
+
398
+ add_settings_section(
399
+ 'tabs_section',
400
+ '',
401
+ [ $this, 'tabs_callback' ],
402
+ $tab->option_page()
403
+ );
404
+ }
405
+
406
+ /**
407
+ * Show tabs.
408
+ */
409
+ public function tabs_callback() {
410
+ ?>
411
+ <div class="ctl-settings-tabs">
412
+ <?php
413
+ $this->tab_link( $this );
414
+
415
+ foreach ( $this->tabs as $tab ) {
416
+ $this->tab_link( $tab );
417
+ }
418
+ ?>
419
+ </div>
420
+ <?php
421
+ }
422
+
423
+ /**
424
+ * Show tab link.
425
+ *
426
+ * @param SettingsBase $tab Tabs of the current settings page.
427
+ */
428
+ private function tab_link( $tab ) {
429
+ $url = menu_page_url( $this->option_page(), false );
430
+ $url = add_query_arg( 'tab', strtolower( $tab->get_class_name() ), $url );
431
+ $active = $this->is_tab_active( $tab ) ? ' active' : '';
432
+
433
+ ?>
434
+ <a class="ctl-settings-tab<?php echo esc_attr( $active ); ?>" href="<?php echo esc_url( $url ); ?>">
435
+ <?php echo esc_html( $tab->tab_name() ); ?>
436
+ </a>
437
+ <?php
438
+ }
439
+
440
+ /**
441
+ * Check if tab is active.
442
+ *
443
+ * @param SettingsBase $tab Tab of the current settings page.
444
+ *
445
+ * @return bool
446
+ */
447
+ protected function is_tab_active( $tab ) {
448
+ $current_tab_name = filter_input( INPUT_GET, 'tab', FILTER_SANITIZE_STRING );
449
+
450
+ if ( null === $current_tab_name && ! $tab->is_tab() ) {
451
+ return true;
452
+ }
453
+
454
+ return strtolower( $tab->get_class_name() ) === $current_tab_name;
455
+ }
456
+
457
+ /**
458
+ * Get active tab.
459
+ *
460
+ * @return SettingsBase
461
+ */
462
+ protected function get_active_tab() {
463
+ if ( ! empty( $this->tabs ) ) {
464
+ foreach ( $this->tabs as $tab ) {
465
+ if ( $this->is_tab_active( $tab ) ) {
466
+ return $tab;
467
+ }
468
+ }
469
+ }
470
+
471
+ return $this;
472
+ }
473
+
474
+ /**
475
+ * Setup settings fields.
476
+ */
477
+ public function setup_fields() {
478
+ if ( ! $this->is_options_screen() ) {
479
+ return;
480
+ }
481
+
482
+ register_setting( $this->option_group(), $this->option_name() );
483
+
484
+ foreach ( $this->form_fields as $key => $field ) {
485
+ $field['field_id'] = $key;
486
+
487
+ add_settings_field(
488
+ $key,
489
+ $field['label'],
490
+ [ $this, 'field_callback' ],
491
+ $this->option_page(),
492
+ $field['section'],
493
+ $field
494
+ );
495
+ }
496
+ }
497
+
498
+ /**
499
+ * Print text/password field.
500
+ *
501
+ * @param array $arguments Field arguments.
502
+ *
503
+ * @noinspection PhpUnusedPrivateMethodInspection
504
+ */
505
+ private function print_text_field( array $arguments ) {
506
+ $value = $this->get( $arguments['field_id'] );
507
+
508
+ printf(
509
+ '<input name="%1$s[%2$s]" id="%2$s" type="%3$s"' .
510
+ ' placeholder="%4$s" value="%5$s" class="regular-text" />',
511
+ esc_html( $this->option_name() ),
512
+ esc_attr( $arguments['field_id'] ),
513
+ esc_attr( $arguments['type'] ),
514
+ esc_attr( $arguments['placeholder'] ),
515
+ esc_html( $value )
516
+ );
517
+ }
518
+
519
+ /**
520
+ * Print number field.
521
+ *
522
+ * @param array $arguments Field arguments.
523
+ *
524
+ * @noinspection PhpUnusedPrivateMethodInspection
525
+ */
526
+ private function print_number_field( array $arguments ) {
527
+ $value = $this->get( $arguments['field_id'] );
528
+ $min = isset( $arguments['min'] ) ? $arguments['min'] : '';
529
+ $max = isset( $arguments['max'] ) ? $arguments['max'] : '';
530
+
531
+ printf(
532
+ '<input name="%1$s[%2$s]" id="%2$s" type="%3$s"' .
533
+ ' placeholder="%4$s" value="%5$s" class="regular-text" min="%6$s" max="%7$s" />',
534
+ esc_html( $this->option_name() ),
535
+ esc_attr( $arguments['field_id'] ),
536
+ esc_attr( $arguments['type'] ),
537
+ esc_attr( $arguments['placeholder'] ),
538
+ esc_html( $value ),
539
+ esc_attr( $min ),
540
+ esc_attr( $max )
541
+ );
542
+ }
543
+
544
+ /**
545
+ * Print textarea field.
546
+ *
547
+ * @param array $arguments Field arguments.
548
+ *
549
+ * @noinspection PhpUnusedPrivateMethodInspection
550
+ */
551
+ private function print_text_area_field( array $arguments ) {
552
+ $value = $this->get( $arguments['field_id'] );
553
+
554
+ printf(
555
+ '<textarea name="%1$s[%2$s]" id="%2$s" placeholder="%3$s" rows="5" cols="50">%4$s</textarea>',
556
+ esc_html( $this->option_name() ),
557
+ esc_attr( $arguments['field_id'] ),
558
+ esc_attr( $arguments['placeholder'] ),
559
+ wp_kses_post( $value )
560
+ );
561
+ }
562
+
563
+ /**
564
+ * Print checkbox field.
565
+ *
566
+ * @param array $arguments Field arguments.
567
+ *
568
+ * @noinspection PhpUnusedPrivateMethodInspection
569
+ */
570
+ private function print_check_box_field( array $arguments ) {
571
+ $value = (array) $this->get( $arguments['field_id'] );
572
+
573
+ if ( empty( $arguments['options'] ) || ! is_array( $arguments['options'] ) ) {
574
+ $arguments['options'] = [ 'yes' => '' ];
575
+ }
576
+
577
+ $options_markup = '';
578
+ $iterator = 0;
579
+ foreach ( $arguments['options'] as $key => $label ) {
580
+ $iterator ++;
581
+ $checked = false;
582
+ if ( is_array( $value ) && in_array( $key, $value, true ) ) {
583
+ $checked = checked( $key, $key, false );
584
+ }
585
+ $options_markup .= sprintf(
586
+ '<label for="%2$s_%7$s">' .
587
+ '<input id="%2$s_%7$s" name="%1$s[%2$s][]" type="%3$s" value="%4$s" %5$s />' .
588
+ ' %6$s' .
589
+ '</label>' .
590
+ '<br/>',
591
+ esc_html( $this->option_name() ),
592
+ $arguments['field_id'],
593
+ $arguments['type'],
594
+ $key,
595
+ $checked,
596
+ $label,
597
+ $iterator
598
+ );
599
+ }
600
+
601
+ printf(
602
+ '<fieldset>%s</fieldset>',
603
+ wp_kses(
604
+ $options_markup,
605
+ [
606
+ 'label' => [
607
+ 'for' => [],
608
+ ],
609
+ 'input' => [
610
+ 'id' => [],
611
+ 'name' => [],
612
+ 'type' => [],
613
+ 'value' => [],
614
+ 'checked' => [],
615
+ ],
616
+ 'br' => [],
617
+ ]
618
+ )
619
+ );
620
+ }
621
+
622
+ /**
623
+ * Print radio field.
624
+ *
625
+ * @param array $arguments Field arguments.
626
+ *
627
+ * @noinspection PhpUnusedPrivateMethodInspection
628
+ */
629
+ private function print_radio_field( array $arguments ) {
630
+ $value = $this->get( $arguments['field_id'] );
631
+
632
+ if ( empty( $arguments['options'] ) || ! is_array( $arguments['options'] ) ) {
633
+ return;
634
+ }
635
+
636
+ $options_markup = '';
637
+ $iterator = 0;
638
+ foreach ( $arguments['options'] as $key => $label ) {
639
+ $iterator ++;
640
+ $options_markup .= sprintf(
641
+ '<label for="%2$s_%7$s">' .
642
+ '<input id="%2$s_%7$s" name="%1$s[%2$s]" type="%3$s" value="%4$s" %5$s />' .
643
+ ' %6$s' .
644
+ '</label>' .
645
+ '<br/>',
646
+ esc_html( $this->option_name() ),
647
+ $arguments['field_id'],
648
+ $arguments['type'],
649
+ $key,
650
+ checked( $value, $key, false ),
651
+ $label,
652
+ $iterator
653
+ );
654
+ }
655
+
656
+ printf(
657
+ '<fieldset>%s</fieldset>',
658
+ wp_kses(
659
+ $options_markup,
660
+ [
661
+ 'label' => [
662
+ 'for' => [],
663
+ ],
664
+ 'input' => [
665
+ 'id' => [],
666
+ 'name' => [],
667
+ 'type' => [],
668
+ 'value' => [],
669
+ 'checked' => [],
670
+ ],
671
+ 'br' => [],
672
+ ]
673
+ )
674
+ );
675
+ }
676
+
677
+ /**
678
+ * Print select field.
679
+ *
680
+ * @param array $arguments Field arguments.
681
+ *
682
+ * @noinspection PhpUnusedPrivateMethodInspection
683
+ */
684
+ private function print_select_field( array $arguments ) {
685
+ $value = $this->get( $arguments['field_id'] );
686
+
687
+ if ( empty( $arguments['options'] ) || ! is_array( $arguments['options'] ) ) {
688
+ return;
689
+ }
690
+
691
+ $options_markup = '';
692
+ foreach ( $arguments['options'] as $key => $label ) {
693
+ $options_markup .= sprintf(
694
+ '<option value="%s" %s>%s</option>',
695
+ $key,
696
+ selected( $value, $key, false ),
697
+ $label
698
+ );
699
+ }
700
+
701
+ printf(
702
+ '<select name="%1$s[%2$s]">%3$s</select>',
703
+ esc_html( $this->option_name() ),
704
+ esc_html( $arguments['field_id'] ),
705
+ wp_kses(
706
+ $options_markup,
707
+ [
708
+ 'option' => [
709
+ 'value' => [],
710
+ 'selected' => [],
711
+ ],
712
+ ]
713
+ )
714
+ );
715
+ }
716
+
717
+ /**
718
+ * Print multiple select field.
719
+ *
720
+ * @param array $arguments Field arguments.
721
+ *
722
+ * @noinspection PhpUnusedPrivateMethodInspection
723
+ */
724
+ private function print_multiple_select_field( array $arguments ) {
725
+ $value = $this->get( $arguments['field_id'] );
726
+
727
+ if ( empty( $arguments['options'] ) || ! is_array( $arguments['options'] ) ) {
728
+ return;
729
+ }
730
+
731
+ $options_markup = '';
732
+ foreach ( $arguments['options'] as $key => $label ) {
733
+ $selected = '';
734
+ if ( is_array( $value ) && in_array( $key, $value, true ) ) {
735
+ $selected = selected( $key, $key, false );
736
+ }
737
+ $options_markup .= sprintf(
738
+ '<option value="%s" %s>%s</option>',
739
+ $key,
740
+ $selected,
741
+ $label
742
+ );
743
+ }
744
+
745
+ printf(
746
+ '<select multiple="multiple" name="%1$s[%2$s][]">%3$s</select>',
747
+ esc_html( $this->option_name() ),
748
+ esc_html( $arguments['field_id'] ),
749
+ wp_kses(
750
+ $options_markup,
751
+ [
752
+ 'option' => [
753
+ 'value' => [],
754
+ 'selected' => [],
755
+ ],
756
+ ]
757
+ )
758
+ );
759
+ }
760
+
761
+ /**
762
+ * Print table field.
763
+ *
764
+ * @param array $arguments Field arguments.
765
+ *
766
+ * @noinspection PhpUnusedPrivateMethodInspection
767
+ */
768
+ private function print_table_field( array $arguments ) {
769
+ $value = $this->get( $arguments['field_id'] );
770
+
771
+ if ( ! is_array( $value ) ) {
772
+ return;
773
+ }
774
+
775
+ $iterator = 0;
776
+ foreach ( $value as $key => $cell_value ) {
777
+ $id = $arguments['field_id'] . '-' . $iterator;
778
+
779
+ echo '<div class="ctl-table-cell">';
780
+ printf(
781
+ '<label for="%1$s">%2$s</label>',
782
+ esc_html( $id ),
783
+ esc_html( $key )
784
+ );
785
+ printf(
786
+ '<input name="%1$s[%2$s][%3$s]" id="%4$s" type="%5$s"' .
787
+ ' placeholder="%6$s" value="%7$s" class="regular-text" />',
788
+ esc_html( $this->option_name() ),
789
+ esc_attr( $arguments['field_id'] ),
790
+ esc_attr( $key ),
791
+ esc_attr( $id ),
792
+ 'text',
793
+ esc_attr( $arguments['placeholder'] ),
794
+ esc_html( $cell_value )
795
+ );
796
+ echo '</div>';
797
+
798
+ $iterator ++;
799
+ }
800
+ }
801
+
802
+ /**
803
+ * Output settings field.
804
+ *
805
+ * @param array $arguments Field arguments.
806
+ */
807
+ public function field_callback( array $arguments ) {
808
+ if ( ! isset( $arguments['field_id'] ) ) {
809
+ return;
810
+ }
811
+
812
+ $types = [
813
+ 'text' => 'print_text_field',
814
+ 'password' => 'print_text_field',
815
+ 'number' => 'print_number_field',
816
+ 'textarea' => 'print_text_area_field',
817
+ 'checkbox' => 'print_check_box_field',
818
+ 'radio' => 'print_radio_field',
819
+ 'select' => 'print_select_field',
820
+ 'multiple' => 'print_multiple_select_field',
821
+ 'table' => 'print_table_field',
822
+ ];
823
+
824
+ $type = $arguments['type'];
825
+
826
+ if ( ! array_key_exists( $type, $types ) ) {
827
+ return;
828
+ }
829
+
830
+ // If there is help text.
831
+ $helper = $arguments['helper'];
832
+ if ( $helper ) {
833
+ printf(
834
+ '<span class="helper"><span class="helper-content">%s</span></span>',
835
+ wp_kses_post( $helper )
836
+ );
837
+ }
838
+
839
+ $this->{$types[ $type ]}( $arguments );
840
+
841
+ // If there is supplemental text.
842
+ $supplemental = $arguments['supplemental'];
843
+ if ( $supplemental ) {
844
+ printf( '<p class="description">%s</p>', wp_kses_post( $supplemental ) );
845
+ }
846
+ }
847
+
848
+ /**
849
+ * Get plugin option.
850
+ *
851
+ * @param string $key Setting name.
852
+ * @param mixed $empty_value Empty value for this setting.
853
+ *
854
+ * @return string|array The value specified for the option or a default value for the option.
855
+ */
856
+ public function get( $key, $empty_value = null ) {
857
+ if ( empty( $this->settings ) ) {
858
+ $this->init_settings();
859
+ }
860
+
861
+ // Get option default if unset.
862
+ if ( ! isset( $this->settings[ $key ] ) ) {
863
+ $form_fields = $this->form_fields();
864
+ $this->settings[ $key ] = isset( $form_fields[ $key ] ) ? $this->field_default( $form_fields[ $key ] ) : '';
865
+ }
866
+
867
+ if ( '' === $this->settings[ $key ] && ! is_null( $empty_value ) ) {
868
+ $this->settings[ $key ] = $empty_value;
869
+ }
870
+
871
+ return $this->settings[ $key ];
872
+ }
873
+
874
+ /**
875
+ * Get a field default value. Defaults to '' if not set.
876
+ *
877
+ * @param array $field Setting field default value.
878
+ *
879
+ * @return string
880
+ */
881
+ protected function field_default( array $field ) {
882
+ return empty( $field['default'] ) ? '' : $field['default'];
883
+ }
884
+
885
+ /**
886
+ * Update plugin option.
887
+ *
888
+ * @param string $key Setting name.
889
+ * @param mixed $value Setting value.
890
+ */
891
+ public function update_option( $key, $value ) {
892
+ if ( empty( $this->settings ) ) {
893
+ $this->init_settings();
894
+ }
895
+
896
+ $this->settings[ $key ] = $value;
897
+ update_option( $this->option_name(), $this->settings );
898
+ }
899
+
900
+ /**
901
+ * Filter plugin option update.
902
+ *
903
+ * @param mixed $value New option value.
904
+ * @param mixed $old_value Old option value.
905
+ *
906
+ * @return mixed
907
+ */
908
+ public function pre_update_option_filter( $value, $old_value ) {
909
+ if ( $value === $old_value ) {
910
+ return $value;
911
+ }
912
+
913
+ // We save only one table, so merge with all existing tables.
914
+ if ( is_array( $old_value ) && ( is_array( $value ) ) ) {
915
+ $value = array_merge( $old_value, $value );
916
+ }
917
+
918
+ $form_fields = $this->form_fields();
919
+ foreach ( $form_fields as $key => $form_field ) {
920
+ if ( 'checkbox' === $form_field['type'] ) {
921
+ $form_field_value = isset( $value[ $key ] ) ? $value[ $key ] : 'no';
922
+ $form_field_value = '1' === $form_field_value || 'yes' === $form_field_value ? 'yes' : 'no';
923
+ $value[ $key ] = $form_field_value;
924
+ }
925
+ }
926
+
927
+ return $value;
928
+ }
929
+
930
+ /**
931
+ * Load plugin text domain.
932
+ */
933
+ public function load_plugin_textdomain() {
934
+ load_plugin_textdomain(
935
+ $this->text_domain(),
936
+ false,
937
+ dirname( $this->plugin_basename() ) . '/languages/'
938
+ );
939
+ }
940
+
941
+ /**
942
+ * Is current admin screen the plugin options screen.
943
+ *
944
+ * @return bool
945
+ */
946
+ protected function is_options_screen() {
947
+ $current_screen = get_current_screen();
948
+
949
+ $screen_id = $this->screen_id();
950
+ if ( $this->is_main_menu_page() ) {
951
+ $screen_id = str_replace( 'settings_page', 'toplevel_page', $screen_id );
952
+ }
953
+
954
+ return $current_screen && ( 'options' === $current_screen->id || $screen_id === $current_screen->id );
955
+ }
956
+ }
src/php/Settings/Abstracts/SettingsInterface.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SettingsInterface interface file.
4
+ *
5
+ * @package cyr-to-lat
6
+ */
7
+
8
+ namespace Cyr_To_Lat\Settings\Abstracts;
9
+
10
+ /**
11
+ * Interface SettingsInterface.
12
+ */
13
+ interface SettingsInterface {
14
+ /**
15
+ * Get plugin option.
16
+ *
17
+ * @param string $key Setting name.
18
+ * @param mixed $empty_value Empty value for this setting.
19
+ *
20
+ * @return string|array The value specified for the option or a default value for the option.
21
+ */
22
+ public function get( $key, $empty_value = null );
23
+ }
src/php/Settings/Converter.php ADDED
@@ -0,0 +1,295 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Converter class file.
4
+ *
5
+ * @package cyr-to-lat
6
+ */
7
+
8
+ namespace Cyr_To_Lat\Settings;
9
+
10
+ /**
11
+ * Class Converter
12
+ *
13
+ * Settings page "Converter".
14
+ */
15
+ class Converter extends PluginSettingsBase {
16
+
17
+ /**
18
+ * Admin script handle.
19
+ */
20
+ const HANDLE = 'cyr-to-lat-settings';
21
+
22
+ /**
23
+ * Converter nonce.
24
+ */
25
+ const NONCE = 'cyr-to-lat-converter-nonce';
26
+
27
+ /**
28
+ * Get screen id.
29
+ *
30
+ * @return string
31
+ */
32
+ public function screen_id() {
33
+ return 'settings_page_cyr-to-lat';
34
+ }
35
+
36
+ /**
37
+ * Get option group.
38
+ *
39
+ * @return string
40
+ */
41
+ protected function option_group() {
42
+ return 'cyr_to_lat_group';
43
+ }
44
+
45
+ /**
46
+ * Get option page.
47
+ *
48
+ * @return string
49
+ */
50
+ protected function option_page() {
51
+ return 'cyr-to-lat';
52
+ }
53
+
54
+ /**
55
+ * Get option name.
56
+ *
57
+ * @return string
58
+ */
59
+ protected function option_name() {
60
+ return 'cyr_to_lat_settings';
61
+ }
62
+
63
+ /**
64
+ * Get page title.
65
+ *
66
+ * @return string
67
+ */
68
+ protected function page_title() {
69
+ return __( 'Converter', 'cyr2lat' );
70
+ }
71
+
72
+ /**
73
+ * Get menu title.
74
+ *
75
+ * @return string
76
+ */
77
+ protected function menu_title() {
78
+ return __( 'Cyr To Lat', 'cyr2lat' );
79
+ }
80
+
81
+ /**
82
+ * Get section title.
83
+ *
84
+ * @return string
85
+ */
86
+ protected function section_title() {
87
+ return '';
88
+ }
89
+
90
+ /**
91
+ * Get parent slug.
92
+ *
93
+ * @return string
94
+ */
95
+ protected function parent_slug() {
96
+ return 'options-general.php';
97
+ }
98
+
99
+ /**
100
+ * Init form fields.
101
+ */
102
+ public function init_form_fields() {
103
+ $default_post_types = [ 'post', 'page', 'nav_menu_item' ];
104
+ $post_types = get_post_types( [ 'public' => true ] );
105
+
106
+ $post_types += [ 'nav_menu_item' => 'nav_menu_item' ];
107
+
108
+ $filtered_post_types = apply_filters( 'ctl_post_types', $post_types );
109
+
110
+ $this->form_fields = [];
111
+
112
+ $this->form_fields['background_post_types'] = [
113
+ 'label' => __( 'Post Types', 'cyr2lat' ),
114
+ 'section' => 'background_section',
115
+ 'type' => 'checkbox',
116
+ 'placeholder' => '',
117
+ 'helper' => __( 'Post types included in the conversion.', 'cyr2lat' ),
118
+ 'supplemental' => '',
119
+ 'options' => [],
120
+ ];
121
+
122
+ foreach ( $post_types as $post_type ) {
123
+ $label = $post_type;
124
+
125
+ $this->form_fields['background_post_types']['options'][ $post_type ] = $label;
126
+ }
127
+
128
+ $this->form_fields['background_post_types']['default'] = $default_post_types;
129
+ $this->form_fields['background_post_types']['disabled'] = array_diff( $default_post_types, $filtered_post_types );
130
+
131
+ $default_post_statuses = [ 'publish', 'future', 'private' ];
132
+ $post_statuses = [ 'publish', 'future', 'private', 'draft', 'pending' ];
133
+
134
+ $this->form_fields['background_post_statuses'] = [
135
+ 'label' => __( 'Post Statuses', 'cyr2lat' ),
136
+ 'section' => 'background_section',
137
+ 'type' => 'checkbox',
138
+ 'placeholder' => '',
139
+ 'helper' => __( 'Post statuses included in the conversion.', 'cyr2lat' ),
140
+ 'supplemental' => '',
141
+ 'options' => [],
142
+ ];
143
+
144
+ foreach ( $post_statuses as $post_status ) {
145
+ $label = $post_status;
146
+
147
+ $this->form_fields['background_post_statuses']['options'][ $post_status ] = $label;
148
+ }
149
+
150
+ $this->form_fields['background_post_statuses']['default'] = $default_post_statuses;
151
+ }
152
+
153
+ /**
154
+ * Init class hooks.
155
+ */
156
+ protected function init_hooks() {
157
+ parent::init_hooks();
158
+
159
+ add_action( 'in_admin_header', [ $this, 'in_admin_header' ] );
160
+ }
161
+
162
+ /**
163
+ * Show settings page.
164
+ */
165
+ public function settings_page() {
166
+ ?>
167
+ <div class="wrap">
168
+ <h1>
169
+ <?php
170
+ esc_html_e( 'Cyr To Lat Plugin Options', 'cyr2lat' );
171
+ ?>
172
+ </h1>
173
+
174
+ <form id="ctl-options" action="<?php echo esc_url( admin_url( 'options.php' ) ); ?>" method="post">
175
+ <?php
176
+ do_settings_sections( $this->option_page() ); // Sections with options.
177
+ settings_fields( $this->option_group() ); // Hidden protection fields.
178
+ submit_button();
179
+ ?>
180
+ </form>
181
+
182
+ <form id="ctl-convert-existing-slugs" action="" method="post">
183
+ <input type="hidden" name="ctl-convert" />
184
+ <?php
185
+ wp_nonce_field( self::NONCE );
186
+ submit_button( __( 'Convert Existing Slugs', 'cyr2lat' ), 'secondary', 'ctl-convert-button' );
187
+ ?>
188
+ </form>
189
+ </div>
190
+ <?php
191
+ }
192
+
193
+ /**
194
+ * Section callback.
195
+ *
196
+ * @param array $arguments Section arguments.
197
+ */
198
+ public function section_callback( $arguments ) {
199
+ if ( 'background_section' === $arguments['id'] ) {
200
+ ?>
201
+ <h2 class="title">
202
+ <?php
203
+ esc_html_e( 'Existing Slugs Conversion Settings', 'cyr2lat' );
204
+ ?>
205
+ </h2>
206
+ <p>
207
+ <?php
208
+ echo wp_kses_post(
209
+ __(
210
+ 'Existing <strong>product attribute</strong> slugs will <strong>NOT</strong> be converted.',
211
+ 'cyr2lat'
212
+ )
213
+ );
214
+ ?>
215
+ </p>
216
+ <?php
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Output convert confirmation popup.
222
+ */
223
+ public function in_admin_header() {
224
+ if ( ! $this->is_options_screen() ) {
225
+ return;
226
+ }
227
+
228
+ ?>
229
+ <div id="ctl-confirm-popup">
230
+ <div id="ctl-confirm-content">
231
+ <p>
232
+ <strong><?php esc_html_e( 'Important:', 'cyr2lat' ); ?></strong>
233
+ <?php
234
+ esc_html_e(
235
+ 'This operation is irreversible. Please make sure that you have made a backup copy of your database.',
236
+ 'cyr2lat'
237
+ );
238
+ ?>
239
+ </p>
240
+ <p>
241
+ <?php
242
+ esc_html_e(
243
+ 'Also, you have to make a copy of your media files if the attachment post type is selected for
244
+ conversion.',
245
+ 'cyr2lat'
246
+ );
247
+ ?>
248
+ </p>
249
+ <p>
250
+ <?php
251
+ esc_html_e(
252
+ 'Upon conversion of attachments, please regenerate thumbnails.',
253
+ 'cyr2lat'
254
+ );
255
+ ?>
256
+ </p>
257
+ <p><?php esc_html_e( 'Are you sure to continue?', 'cyr2lat' ); ?></p>
258
+ <div id="ctl-confirm-buttons">
259
+ <input
260
+ type="button" id="ctl-confirm-ok" class="button button-primary"
261
+ value="<?php esc_html_e( 'OK', 'cyr2lat' ); ?>">
262
+ <button
263
+ type="button" id="ctl-confirm-cancel" class="button button-secondary">
264
+ <?php esc_html_e( 'Cancel', 'cyr2lat' ); ?>
265
+ </button>
266
+ </div>
267
+ </div>
268
+ </div>
269
+ <?php
270
+ }
271
+
272
+ /**
273
+ * Enqueue class scripts.
274
+ */
275
+ public function admin_enqueue_scripts() {
276
+ if ( ! $this->is_options_screen() ) {
277
+ return;
278
+ }
279
+
280
+ wp_enqueue_script(
281
+ self::HANDLE,
282
+ constant( 'CYR_TO_LAT_URL' ) . '/assets/js/converter/app.js',
283
+ [],
284
+ constant( 'CYR_TO_LAT_VERSION' ),
285
+ true
286
+ );
287
+
288
+ wp_enqueue_style(
289
+ self::HANDLE,
290
+ constant( 'CYR_TO_LAT_URL' ) . '/assets/css/converter.css',
291
+ [],
292
+ constant( 'CYR_TO_LAT_VERSION' )
293
+ );
294
+ }
295
+ }
src/php/Settings/PluginSettingsBase.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PluginSettingsBase class file.
4
+ *
5
+ * @package cyr-to-lat
6
+ */
7
+
8
+ namespace Cyr_To_Lat\Settings;
9
+
10
+ use Cyr_To_Lat\Settings\Abstracts\SettingsBase;
11
+
12
+ /**
13
+ * Class PluginSettingsBase
14
+ *
15
+ * Extends general SettingsBase suitable for any plugin with current plugin related methods.
16
+ */
17
+ abstract class PluginSettingsBase extends SettingsBase {
18
+
19
+ /**
20
+ * Get plugin base name.
21
+ *
22
+ * @return string
23
+ */
24
+ protected function plugin_basename() {
25
+ return plugin_basename( constant( 'CYR_TO_LAT_FILE' ) );
26
+ }
27
+
28
+ /**
29
+ * Get plugin url.
30
+ *
31
+ * @return string
32
+ */
33
+ protected function plugin_url() {
34
+ return constant( 'CYR_TO_LAT_URL' );
35
+ }
36
+
37
+ /**
38
+ * Get plugin version.
39
+ *
40
+ * @return string
41
+ */
42
+ protected function plugin_version() {
43
+ return constant( 'CYR_TO_LAT_VERSION' );
44
+ }
45
+
46
+ /**
47
+ * Get settings link label.
48
+ *
49
+ * @return string
50
+ */
51
+ protected function settings_link_label() {
52
+ return __( 'View Cyr To Lat settings', 'cyr2lat' );
53
+ }
54
+
55
+ /**
56
+ * Get settings link text.
57
+ *
58
+ * @return string
59
+ */
60
+ protected function settings_link_text() {
61
+ return __( 'Settings', 'cyr2lat' );
62
+ }
63
+
64
+ /**
65
+ * Get text domain.
66
+ *
67
+ * @return string
68
+ */
69
+ protected function text_domain() {
70
+ return 'cyr2lat';
71
+ }
72
+ }
src/php/Settings/Settings.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Settings class file.
4
+ *
5
+ * @package cyr-to-lat
6
+ */
7
+
8
+ namespace Cyr_To_Lat\Settings;
9
+
10
+ use Cyr_To_Lat\Settings\Abstracts\SettingsBase;
11
+ use Cyr_To_Lat\Settings\Abstracts\SettingsInterface;
12
+ use Cyr_To_Lat\Symfony\Polyfill\Mbstring\Mbstring;
13
+
14
+ /**
15
+ * Class Settings
16
+ *
17
+ * Central point to get settings from.
18
+ */
19
+ class Settings implements SettingsInterface {
20
+
21
+ /**
22
+ * Menu pages classes.
23
+ */
24
+ const MENU_PAGES = [
25
+ [ Tables::class, Converter::class ],
26
+ ];
27
+
28
+ /**
29
+ * Menu pages class instances.
30
+ *
31
+ * @var array
32
+ */
33
+ protected $menu_pages = [];
34
+
35
+ /**
36
+ * Screen ids of pages and tabs.
37
+ *
38
+ * @var array
39
+ */
40
+ private $screen_ids = [];
41
+
42
+ /**
43
+ * Settings constructor.
44
+ */
45
+ public function __construct() {
46
+ $this->init();
47
+ }
48
+
49
+ /**
50
+ * Init class.
51
+ */
52
+ protected function init() {
53
+ // Allow to specify MENU_PAGES item as one class, not an array.
54
+ $menu_pages = (array) self::MENU_PAGES;
55
+
56
+ foreach ( $menu_pages as $menu_page ) {
57
+ $tab_classes = (array) $menu_page;
58
+
59
+ // Allow to specify menu page as one class, without tabs.
60
+ $page_class = $tab_classes[0];
61
+ $tab_classes = array_slice( $tab_classes, 1 );
62
+
63
+ $tabs = [];
64
+ foreach ( $tab_classes as $tab_class ) {
65
+ /**
66
+ * Tab.
67
+ *
68
+ * @var PluginSettingsBase $tab
69
+ */
70
+ $tab = new $tab_class( null );
71
+ $tabs[] = $tab;
72
+ $this->screen_ids[] = $tab->screen_id();
73
+ }
74
+
75
+ /**
76
+ * Page.
77
+ *
78
+ * @var PluginSettingsBase $page_class
79
+ */
80
+ $this->menu_pages[] = new $page_class( $tabs );
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Get plugin option.
86
+ *
87
+ * @param string $key Setting name.
88
+ * @param mixed $empty_value Empty value for this setting.
89
+ *
90
+ * @return string|array The value specified for the option or a default value for the option.
91
+ */
92
+ public function get( $key, $empty_value = null ) {
93
+ return $this->get_main_page()->get( $key, $empty_value );
94
+ }
95
+
96
+ /**
97
+ * Get main admin page.
98
+ *
99
+ * @return SettingsBase
100
+ */
101
+ private function get_main_page() {
102
+ return $this->menu_pages[0];
103
+ }
104
+
105
+ /**
106
+ * Get screen ids of all settings pages and tabs.
107
+ *
108
+ * @return array
109
+ */
110
+ public function screen_ids() {
111
+ return $this->screen_ids;
112
+ }
113
+
114
+ /**
115
+ * Get transliteration table.
116
+ *
117
+ * @return array
118
+ */
119
+ public function get_table() {
120
+ // List of locales: https://make.wordpress.org/polyglots/teams/.
121
+ $locale = get_locale();
122
+ $table = $this->get( $locale );
123
+ if ( empty( $table ) ) {
124
+ $table = $this->get( 'iso9' );
125
+ }
126
+
127
+ return $this->transpose_chinese_table( $table );
128
+ }
129
+
130
+ /**
131
+ * Is current locale a Chinese one.
132
+ *
133
+ * @return bool
134
+ */
135
+ public function is_chinese_locale() {
136
+ $chinese_locales = [ 'zh_CN', 'zh_HK', 'zh_SG', 'zh_TW' ];
137
+
138
+ return in_array( get_locale(), $chinese_locales, true );
139
+ }
140
+
141
+ /**
142
+ * Transpose Chinese table.
143
+ *
144
+ * Chinese tables are stored in different way, to show them compact.
145
+ *
146
+ * @param array $table Table.
147
+ *
148
+ * @return array
149
+ */
150
+ protected function transpose_chinese_table( $table ) {
151
+ if ( ! $this->is_chinese_locale() ) {
152
+ return $table;
153
+ }
154
+
155
+ $transposed_table = [];
156
+ foreach ( $table as $key => $item ) {
157
+ $hieroglyphs = Mbstring::mb_str_split( $item );
158
+ foreach ( $hieroglyphs as $hieroglyph ) {
159
+ $transposed_table[ $hieroglyph ] = $key;
160
+ }
161
+ }
162
+
163
+ return $transposed_table;
164
+ }
165
+ }
src/php/Settings/Tables.php ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Tables class file.
4
+ *
5
+ * @package cyr-to-lat
6
+ */
7
+
8
+ namespace Cyr_To_Lat\Settings;
9
+
10
+ use Cyr_To_Lat\Conversion_Tables;
11
+
12
+ /**
13
+ * Class Tables
14
+ *
15
+ * Settings page "Tables" (main).
16
+ */
17
+ class Tables extends PluginSettingsBase {
18
+
19
+ /**
20
+ * Admin script handle.
21
+ */
22
+ const HANDLE = 'cyr-to-lat-tables';
23
+
24
+ /**
25
+ * Script localization object.
26
+ */
27
+ const OBJECT = ' Cyr2LatTablesObject';
28
+
29
+ /**
30
+ * Served locales.
31
+ *
32
+ * @var array
33
+ */
34
+ protected $locales = [];
35
+
36
+ /**
37
+ * Get screen id.
38
+ *
39
+ * @return string
40
+ */
41
+ public function screen_id() {
42
+ return 'settings_page_cyr-to-lat';
43
+ }
44
+
45
+ /**
46
+ * Get option group.
47
+ *
48
+ * @return string
49
+ */
50
+ protected function option_group() {
51
+ return 'cyr_to_lat_group';
52
+ }
53
+
54
+ /**
55
+ * Get option page.
56
+ *
57
+ * @return string
58
+ */
59
+ protected function option_page() {
60
+ return 'cyr-to-lat';
61
+ }
62
+
63
+ /**
64
+ * Get option name.
65
+ *
66
+ * @return string
67
+ */
68
+ protected function option_name() {
69
+ return 'cyr_to_lat_settings';
70
+ }
71
+
72
+ /**
73
+ * Get page title.
74
+ *
75
+ * @return string
76
+ */
77
+ protected function page_title() {
78
+ return __( 'Tables', 'cyr2lat' );
79
+ }
80
+
81
+ /**
82
+ * Get menu title.
83
+ *
84
+ * @return string
85
+ */
86
+ protected function menu_title() {
87
+ return __( 'Cyr To Lat', 'cyr2lat' );
88
+ }
89
+
90
+ /**
91
+ * Get section title.
92
+ *
93
+ * @return string
94
+ */
95
+ protected function section_title() {
96
+ return '';
97
+ }
98
+
99
+ /**
100
+ * Get parent slug.
101
+ *
102
+ * @return string
103
+ */
104
+ protected function parent_slug() {
105
+ // Indicate that it is the main menu page.
106
+ return 'options-general.php';
107
+ }
108
+
109
+ /**
110
+ * Init locales.
111
+ */
112
+ protected function init_locales() {
113
+ if ( ! empty( $this->locales ) ) {
114
+ return;
115
+ }
116
+
117
+ $this->locales = [
118
+ 'iso9' => [
119
+ 'label' => __( 'ISO9 Table', 'cyr2lat' ),
120
+ ],
121
+ 'bel' => [
122
+ 'label' => __( 'bel Table', 'cyr2lat' ),
123
+ ],
124
+ 'uk' => [
125
+ 'label' => __( 'uk Table', 'cyr2lat' ),
126
+ ],
127
+ 'bg_BG' => [
128
+ 'label' => __( 'bg_BG Table', 'cyr2lat' ),
129
+ ],
130
+ 'mk_MK' => [
131
+ 'label' => __( 'mk_MK Table', 'cyr2lat' ),
132
+ ],
133
+ 'sr_RS' => [
134
+ 'label' => __( 'sr_RS Table', 'cyr2lat' ),
135
+ ],
136
+ 'el' => [
137
+ 'label' => __( 'el Table', 'cyr2lat' ),
138
+ ],
139
+ 'hy' => [
140
+ 'label' => __( 'hy Table', 'cyr2lat' ),
141
+ ],
142
+ 'ka_GE' => [
143
+ 'label' => __( 'ka_GE Table', 'cyr2lat' ),
144
+ ],
145
+ 'kk' => [
146
+ 'label' => __( 'kk Table', 'cyr2lat' ),
147
+ ],
148
+ 'he_IL' => [
149
+ 'label' => __( 'he_IL Table', 'cyr2lat' ),
150
+ ],
151
+ 'zh_CN' => [
152
+ 'label' => __( 'zh_CN Table', 'cyr2lat' ),
153
+ ],
154
+ ];
155
+ }
156
+
157
+ /**
158
+ * Get current locale.
159
+ *
160
+ * @return string
161
+ */
162
+ private function get_current_locale() {
163
+ $current_locale = get_locale();
164
+
165
+ return array_key_exists( $current_locale, $this->locales ) ? $current_locale : 'iso9';
166
+ }
167
+
168
+ /**
169
+ * Init form fields.
170
+ */
171
+ public function init_form_fields() {
172
+ $this->init_locales();
173
+
174
+ $current_locale = $this->get_current_locale();
175
+
176
+ $this->form_fields = [];
177
+
178
+ foreach ( $this->locales as $locale => $info ) {
179
+ $current = ( $locale === $current_locale ) ? '<br>' . __( '(current)', 'cyr2lat' ) : '';
180
+
181
+ $this->form_fields[ $locale ] = [
182
+ 'label' => $info['label'] . $current,
183
+ 'section' => $locale . '_section',
184
+ 'type' => 'table',
185
+ 'placeholder' => '',
186
+ 'helper' => '',
187
+ 'supplemental' => '',
188
+ 'default' => Conversion_Tables::get( $locale ),
189
+ ];
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Show settings page.
195
+ */
196
+ public function settings_page() {
197
+ ?>
198
+ <div class="wrap">
199
+ <h1>
200
+ <?php
201
+ // Admin panel title.
202
+ esc_html_e( 'Cyr To Lat Plugin Options', 'cyr2lat' );
203
+ ?>
204
+ </h1>
205
+
206
+ <form id="ctl-options" action="<?php echo esc_url( admin_url( 'options.php' ) ); ?>" method="post">
207
+ <?php
208
+ do_settings_sections( $this->option_page() ); // Sections with options.
209
+ settings_fields( $this->option_group() ); // Hidden protection fields.
210
+ submit_button();
211
+ ?>
212
+ </form>
213
+
214
+ <div id="appreciation">
215
+ <h2>
216
+ <?php echo esc_html( __( 'Your Appreciation', 'cyr2lat' ) ); ?>
217
+ </h2>
218
+ <a
219
+ target="_blank"
220
+ href="https://wordpress.org/support/view/plugin-reviews/cyr2lat?rate=5#postform">
221
+ <?php echo esc_html( __( 'Leave a ★★★★★ plugin review on WordPress.org', 'cyr2lat' ) ); ?>
222
+ </a>
223
+ </div>
224
+ </div>
225
+ <?php
226
+ }
227
+
228
+ /**
229
+ * Section callback.
230
+ *
231
+ * @param array $arguments Section arguments.
232
+ */
233
+ public function section_callback( $arguments ) {
234
+ $locale = str_replace( '_section', '', $arguments['id'] );
235
+ if ( $this->get_current_locale() === $locale ) {
236
+ echo '<div id="ctl-current"></div>';
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Enqueue class scripts.
242
+ */
243
+ public function admin_enqueue_scripts() {
244
+ if ( ! $this->is_options_screen() ) {
245
+ return;
246
+ }
247
+
248
+ wp_enqueue_script(
249
+ self::HANDLE,
250
+ constant( 'CYR_TO_LAT_URL' ) . '/assets/js/tables/app.js',
251
+ [],
252
+ constant( 'CYR_TO_LAT_VERSION' ),
253
+ true
254
+ );
255
+
256
+ wp_localize_script(
257
+ self::HANDLE,
258
+ self::OBJECT,
259
+ [
260
+ 'optionsSaveSuccessMessage' => __( 'Options saved.', 'cyr2lat' ),
261
+ 'optionsSaveErrorMessage' => __( 'Error saving options.', 'cyr2lat' ),
262
+ ]
263
+ );
264
+
265
+ wp_enqueue_style(
266
+ self::HANDLE,
267
+ constant( 'CYR_TO_LAT_URL' ) . '/assets/css/tables.css',
268
+ [],
269
+ constant( 'CYR_TO_LAT_VERSION' )
270
+ );
271
+ }
272
+
273
+ /**
274
+ * Setup settings sections.
275
+ */
276
+ public function setup_sections() {
277
+ foreach ( $this->form_fields as $form_field ) {
278
+ add_settings_section(
279
+ $form_field['section'],
280
+ $form_field['label'],
281
+ [ $this, 'section_callback' ],
282
+ $this->option_page()
283
+ );
284
+ }
285
+ }
286
+ }
{classes → src/php}/background-processes/class-conversion-process.php RENAMED
File without changes
{classes → src/php}/background-processes/class-post-conversion-process.php RENAMED
File without changes
{classes → src/php}/background-processes/class-term-conversion-process.php RENAMED
File without changes
{classes → src/php}/class-acf.php RENAMED
@@ -7,6 +7,8 @@
7
 
8
  namespace Cyr_To_Lat;
9
 
 
 
10
  /**
11
  * Class ACF
12
  */
@@ -45,7 +47,7 @@ class ACF {
45
 
46
  wp_enqueue_script(
47
  'cyr-to-lat-acf-field-group',
48
- constant( 'CYR_TO_LAT_URL' ) . '/js/acf-field-group.js',
49
  [],
50
  constant( 'CYR_TO_LAT_VERSION' ),
51
  true
7
 
8
  namespace Cyr_To_Lat;
9
 
10
+ use Cyr_To_Lat\Settings\Settings;
11
+
12
  /**
13
  * Class ACF
14
  */
47
 
48
  wp_enqueue_script(
49
  'cyr-to-lat-acf-field-group',
50
+ constant( 'CYR_TO_LAT_URL' ) . '/assets/js/acf-field-group.js',
51
  [],
52
  constant( 'CYR_TO_LAT_VERSION' ),
53
  true
{classes → src/php}/class-admin-notices.php RENAMED
@@ -49,7 +49,7 @@ class Admin_Notices {
49
  */
50
  public function show_notices() {
51
  foreach ( $this->notices as $notice ) {
52
- if ( ! $this->is_page_allowed( $notice ) ) {
53
  continue;
54
  }
55
 
@@ -72,17 +72,16 @@ class Admin_Notices {
72
  *
73
  * @return bool
74
  */
75
- protected function is_page_allowed( $notice ) {
76
- $page = isset( $notice['options']['page'] ) ? $notice['options']['page'] : null;
77
- if ( ! $page ) {
78
  return true;
79
  }
80
- $pages = (array) $page;
81
 
82
  $current_screen = get_current_screen();
83
 
84
- foreach ( $pages as $page ) {
85
- if ( $current_screen && $page === $current_screen->id ) {
86
  return true;
87
  }
88
  }
49
  */
50
  public function show_notices() {
51
  foreach ( $this->notices as $notice ) {
52
+ if ( ! $this->is_screen_allowed( $notice ) ) {
53
  continue;
54
  }
55
 
72
  *
73
  * @return bool
74
  */
75
+ protected function is_screen_allowed( $notice ) {
76
+ $screen_ids = isset( $notice['options']['screen_ids'] ) ? (array) $notice['options']['screen_ids'] : null;
77
+ if ( empty( $screen_ids ) ) {
78
  return true;
79
  }
 
80
 
81
  $current_screen = get_current_screen();
82
 
83
+ foreach ( $screen_ids as $screen_id ) {
84
+ if ( $current_screen && $screen_id === $current_screen->id ) {
85
  return true;
86
  }
87
  }
{classes → src/php}/class-conversion-tables.php RENAMED
File without changes
{classes → src/php}/class-converter.php RENAMED
@@ -7,6 +7,8 @@
7
 
8
  namespace Cyr_To_Lat;
9
 
 
 
10
  /**
11
  * Class Converter
12
  *
@@ -34,47 +36,48 @@ class Converter {
34
  *
35
  * @var Main
36
  */
37
- private $main;
 
 
 
 
 
 
 
38
 
39
  /**
40
  * Background process to convert posts.
41
  *
42
  * @var Post_Conversion_Process
43
  */
44
- private $process_all_posts;
45
 
46
  /**
47
  * Background process to convert terms.
48
  *
49
  * @var Term_Conversion_Process
50
  */
51
- private $process_all_terms;
52
 
53
  /**
54
  * Admin notices.
55
  *
56
  * @var Admin_Notices
57
  */
58
- private $admin_notices;
59
-
60
- /**
61
- * Option group.
62
- *
63
- * @var string
64
- */
65
- private $option_group;
66
 
67
  /**
68
  * Converter constructor.
69
  *
70
  * @param Main $main Plugin main class.
 
71
  * @param Post_Conversion_Process $process_all_posts Post conversion process.
72
  * @param Term_Conversion_Process $process_all_terms Term conversion process.
73
  * @param Admin_Notices $admin_notices Admin notices.
74
  */
75
- public function __construct( $main, $process_all_posts, $process_all_terms, $admin_notices ) {
76
  $this->main = $main;
77
- $this->option_group = Settings::OPTION_GROUP;
78
  $this->process_all_posts = $process_all_posts;
79
  $this->process_all_terms = $process_all_terms;
80
  $this->admin_notices = $admin_notices;
@@ -137,7 +140,7 @@ class Converter {
137
  if ( ! isset( $_POST['ctl-convert'] ) ) {
138
  return;
139
  }
140
- check_admin_referer( $this->option_group . '-options' );
141
  $this->convert_existing_slugs();
142
  }
143
 
@@ -174,13 +177,12 @@ class Converter {
174
  protected function convert_existing_post_slugs( $args = [] ) {
175
  global $wpdb;
176
 
177
- $post_types = get_post_types( [ 'public' => true ] );
178
-
179
- $post_types += [ 'nav_menu_item' => 'nav_menu_item' ];
180
 
181
  $defaults = [
182
  'post_type' => apply_filters( 'ctl_post_types', $post_types ),
183
- 'post_status' => [ 'publish', 'future', 'private' ],
184
  ];
185
 
186
  $parsed_args = wp_parse_args( $args, $defaults );
@@ -191,7 +193,7 @@ class Converter {
191
  'post_status IN (' . $this->main->prepare_in( $parsed_args['post_status'] ) . ')' .
192
  ' AND post_type IN (' . $this->main->prepare_in( $parsed_args['post_type'] ) . ')';
193
 
194
- if ( isset( $parsed_args['post_type']['attachment'] ) ) {
195
  $media_sql = "post_status = 'inherit' AND post_type = 'attachment'";
196
  $post_sql = '(' . $post_sql . ') OR (' . $media_sql . ')';
197
  }
7
 
8
  namespace Cyr_To_Lat;
9
 
10
+ use Cyr_To_Lat\Settings\Settings;
11
+
12
  /**
13
  * Class Converter
14
  *
36
  *
37
  * @var Main
38
  */
39
+ protected $main;
40
+
41
+ /**
42
+ * Plugin settings class.
43
+ *
44
+ * @var Settings
45
+ */
46
+ protected $settings;
47
 
48
  /**
49
  * Background process to convert posts.
50
  *
51
  * @var Post_Conversion_Process
52
  */
53
+ protected $process_all_posts;
54
 
55
  /**
56
  * Background process to convert terms.
57
  *
58
  * @var Term_Conversion_Process
59
  */
60
+ protected $process_all_terms;
61
 
62
  /**
63
  * Admin notices.
64
  *
65
  * @var Admin_Notices
66
  */
67
+ protected $admin_notices;
 
 
 
 
 
 
 
68
 
69
  /**
70
  * Converter constructor.
71
  *
72
  * @param Main $main Plugin main class.
73
+ * @param Settings $settings Plugin settings.
74
  * @param Post_Conversion_Process $process_all_posts Post conversion process.
75
  * @param Term_Conversion_Process $process_all_terms Term conversion process.
76
  * @param Admin_Notices $admin_notices Admin notices.
77
  */
78
+ public function __construct( $main, $settings, $process_all_posts, $process_all_terms, $admin_notices ) {
79
  $this->main = $main;
80
+ $this->settings = $settings;
81
  $this->process_all_posts = $process_all_posts;
82
  $this->process_all_terms = $process_all_terms;
83
  $this->admin_notices = $admin_notices;
140
  if ( ! isset( $_POST['ctl-convert'] ) ) {
141
  return;
142
  }
143
+ check_admin_referer( \Cyr_To_Lat\Settings\Converter::NONCE );
144
  $this->convert_existing_slugs();
145
  }
146
 
177
  protected function convert_existing_post_slugs( $args = [] ) {
178
  global $wpdb;
179
 
180
+ $post_types = $this->settings->get( 'background_post_types' );
181
+ $post_statuses = $this->settings->get( 'background_post_statuses' );
 
182
 
183
  $defaults = [
184
  'post_type' => apply_filters( 'ctl_post_types', $post_types ),
185
+ 'post_status' => $post_statuses,
186
  ];
187
 
188
  $parsed_args = wp_parse_args( $args, $defaults );
193
  'post_status IN (' . $this->main->prepare_in( $parsed_args['post_status'] ) . ')' .
194
  ' AND post_type IN (' . $this->main->prepare_in( $parsed_args['post_type'] ) . ')';
195
 
196
+ if ( in_array( 'attachment', $parsed_args['post_type'], true ) ) {
197
  $media_sql = "post_status = 'inherit' AND post_type = 'attachment'";
198
  $post_sql = '(' . $post_sql . ') OR (' . $media_sql . ')';
199
  }
{classes → src/php}/class-main.php RENAMED
@@ -9,6 +9,7 @@ namespace Cyr_To_Lat;
9
 
10
  use wpdb;
11
  use Exception;
 
12
  use Cyr_To_Lat\Symfony\Polyfill\Mbstring\Mbstring;
13
 
14
  /**
@@ -76,12 +77,19 @@ class Main {
76
  * Main constructor.
77
  */
78
  public function __construct() {
79
- $this->settings = new Settings();
 
 
 
 
 
 
 
80
  $this->process_all_posts = new Post_Conversion_Process( $this );
81
  $this->process_all_terms = new Term_Conversion_Process( $this );
82
- $this->admin_notices = new Admin_Notices();
83
  $this->converter = new Converter(
84
  $this,
 
85
  $this->process_all_posts,
86
  $this->process_all_terms,
87
  $this->admin_notices
@@ -92,8 +100,6 @@ class Main {
92
  }
93
 
94
  $this->acf = new ACF( $this->settings );
95
-
96
- $this->init();
97
  }
98
 
99
  /**
@@ -468,17 +474,20 @@ class Main {
468
  // phpcs:disable WordPress.Security.NonceVerification.Recommended
469
  if ( isset( $_POST['post_ID'] ) ) {
470
  $pll_get_post_language = pll_get_post_language(
471
- (int) filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_STRING )
 
472
  );
473
  }
474
  if ( isset( $_POST['pll_post_id'] ) ) {
475
  $pll_get_post_language = pll_get_post_language(
476
- (int) filter_input( INPUT_POST, 'pll_post_id', FILTER_SANITIZE_STRING )
 
477
  );
478
  }
479
  if ( isset( $_GET['post'] ) ) {
480
  $pll_get_post_language = pll_get_post_language(
481
- (int) filter_input( INPUT_GET, 'post', FILTER_SANITIZE_STRING )
 
482
  );
483
  }
484
  // phpcs:enable WordPress.Security.NonceVerification.Recommended
@@ -506,7 +515,7 @@ class Main {
506
  );
507
 
508
  if ( $pll_get_language ) {
509
- $pll_get_term_language = $pll_get_language->slug;
510
  }
511
  }
512
  // phpcs:enable WordPress.Security.NonceVerification.Missing
9
 
10
  use wpdb;
11
  use Exception;
12
+ use Cyr_To_Lat\Settings\Settings;
13
  use Cyr_To_Lat\Symfony\Polyfill\Mbstring\Mbstring;
14
 
15
  /**
77
  * Main constructor.
78
  */
79
  public function __construct() {
80
+ $this->settings = new Settings();
81
+ $this->admin_notices = new Admin_Notices();
82
+ $requirements = new Requirements( $this->settings, $this->admin_notices );
83
+
84
+ if ( ! $requirements->are_requirements_met() ) {
85
+ return;
86
+ }
87
+
88
  $this->process_all_posts = new Post_Conversion_Process( $this );
89
  $this->process_all_terms = new Term_Conversion_Process( $this );
 
90
  $this->converter = new Converter(
91
  $this,
92
+ $this->settings,
93
  $this->process_all_posts,
94
  $this->process_all_terms,
95
  $this->admin_notices
100
  }
101
 
102
  $this->acf = new ACF( $this->settings );
 
 
103
  }
104
 
105
  /**
474
  // phpcs:disable WordPress.Security.NonceVerification.Recommended
475
  if ( isset( $_POST['post_ID'] ) ) {
476
  $pll_get_post_language = pll_get_post_language(
477
+ (int) filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_STRING ),
478
+ 'locale'
479
  );
480
  }
481
  if ( isset( $_POST['pll_post_id'] ) ) {
482
  $pll_get_post_language = pll_get_post_language(
483
+ (int) filter_input( INPUT_POST, 'pll_post_id', FILTER_SANITIZE_STRING ),
484
+ 'locale'
485
  );
486
  }
487
  if ( isset( $_GET['post'] ) ) {
488
  $pll_get_post_language = pll_get_post_language(
489
+ (int) filter_input( INPUT_GET, 'post', FILTER_SANITIZE_STRING ),
490
+ 'locale'
491
  );
492
  }
493
  // phpcs:enable WordPress.Security.NonceVerification.Recommended
515
  );
516
 
517
  if ( $pll_get_language ) {
518
+ $pll_get_term_language = $pll_get_language->locale;
519
  }
520
  }
521
  // phpcs:enable WordPress.Security.NonceVerification.Missing
{classes → src/php}/class-requirements.php RENAMED
@@ -7,6 +7,7 @@
7
 
8
  namespace Cyr_To_Lat;
9
 
 
10
  use WP_Filesystem_Direct;
11
 
12
  if ( ! class_exists( __NAMESPACE__ . '\Requirements' ) ) {
@@ -16,6 +17,13 @@ if ( ! class_exists( __NAMESPACE__ . '\Requirements' ) ) {
16
  */
17
  class Requirements {
18
 
 
 
 
 
 
 
 
19
  /**
20
  * Admin notices.
21
  *
@@ -31,27 +39,24 @@ if ( ! class_exists( __NAMESPACE__ . '\Requirements' ) ) {
31
  protected $wp_filesystem;
32
 
33
  /**
34
- * Restrict notice to Cyr To Lat settings page.
35
  *
36
  * @var array
37
  */
38
- protected $cyr2lat_page;
39
 
40
  /**
41
  * Requirements constructor.
42
  *
 
43
  * @param Admin_Notices $admin_notices Admin notices.
44
  * @param WP_Filesystem_Direct $wp_filesystem File system.
45
- *
46
- * @noinspection PhpIncludeInspection
47
  */
48
- public function __construct( $admin_notices = null, $wp_filesystem = null ) {
49
- $this->admin_notices = $admin_notices;
50
- if ( ! $this->admin_notices ) {
51
- $this->admin_notices = new Admin_Notices();
52
- }
53
 
54
- $this->cyr2lat_page = [ 'page' => Settings::SCREEN_ID ];
55
 
56
  // @codeCoverageIgnoreStart
57
  if ( ! function_exists( 'WP_Filesystem' ) ) {
@@ -136,7 +141,7 @@ if ( ! class_exists( __NAMESPACE__ . '\Requirements' ) ) {
136
  $this->admin_notices->add_notice(
137
  __( 'Unable to get filesystem access.', 'cyr2lat' ),
138
  'notice notice-error',
139
- $this->cyr2lat_page
140
  );
141
  $this->ask_to_increase_max_input_vars();
142
 
@@ -160,7 +165,7 @@ if ( ! class_exists( __NAMESPACE__ . '\Requirements' ) ) {
160
  /* translators: 1: Wait time in seconds */
161
  $message .= sprintf( __( 'Please try again in %d s.', 'cyr2lat' ), $time_left );
162
 
163
- $this->admin_notices->add_notice( $message, 'notice notice-error', $this->cyr2lat_page );
164
  } else {
165
  $this->ask_to_increase_max_input_vars();
166
  }
@@ -231,7 +236,7 @@ if ( ! class_exists( __NAMESPACE__ . '\Requirements' ) ) {
231
  $this->admin_notices->add_notice(
232
  $message,
233
  'notice notice-error',
234
- [ 'page' => Settings::SCREEN_ID ]
235
  );
236
  }
237
  }
7
 
8
  namespace Cyr_To_Lat;
9
 
10
+ use Cyr_To_Lat\Settings\Settings;
11
  use WP_Filesystem_Direct;
12
 
13
  if ( ! class_exists( __NAMESPACE__ . '\Requirements' ) ) {
17
  */
18
  class Requirements {
19
 
20
+ /**
21
+ * Settings.
22
+ *
23
+ * @var Settings
24
+ */
25
+ protected $settings;
26
+
27
  /**
28
  * Admin notices.
29
  *
39
  protected $wp_filesystem;
40
 
41
  /**
42
+ * Restrict notices to Cyr To Lat settings admin screens.
43
  *
44
  * @var array
45
  */
46
+ protected $screen_ids;
47
 
48
  /**
49
  * Requirements constructor.
50
  *
51
+ * @param Settings $settings Settings.
52
  * @param Admin_Notices $admin_notices Admin notices.
53
  * @param WP_Filesystem_Direct $wp_filesystem File system.
 
 
54
  */
55
+ public function __construct( $settings, $admin_notices, $wp_filesystem = null ) {
56
+ $this->settings = $settings;
57
+ $this->screen_ids = [ 'screen_ids' => $this->settings->screen_ids() ];
 
 
58
 
59
+ $this->admin_notices = $admin_notices;
60
 
61
  // @codeCoverageIgnoreStart
62
  if ( ! function_exists( 'WP_Filesystem' ) ) {
141
  $this->admin_notices->add_notice(
142
  __( 'Unable to get filesystem access.', 'cyr2lat' ),
143
  'notice notice-error',
144
+ $this->screen_ids
145
  );
146
  $this->ask_to_increase_max_input_vars();
147
 
165
  /* translators: 1: Wait time in seconds */
166
  $message .= sprintf( __( 'Please try again in %d s.', 'cyr2lat' ), $time_left );
167
 
168
+ $this->admin_notices->add_notice( $message, 'notice notice-error', $this->screen_ids );
169
  } else {
170
  $this->ask_to_increase_max_input_vars();
171
  }
236
  $this->admin_notices->add_notice(
237
  $message,
238
  'notice notice-error',
239
+ [ 'screen_ids' => $this->settings->screen_ids() ]
240
  );
241
  }
242
  }
{classes → src/php}/class-wp-cli.php RENAMED
File without changes
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInitab59197479483050e615845d183c2e8c::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitedbf0ae69d823c20f1f2c9984482bd8e::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -311,8 +311,10 @@ class ClassLoader
311
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
312
 
313
  if (null === $this->vendorDir) {
314
- //no-op
315
- } elseif ($prepend) {
 
 
316
  self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
317
  } else {
318
  unset(self::$registeredLoaders[$this->vendorDir]);
311
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
312
 
313
  if (null === $this->vendorDir) {
314
+ return;
315
+ }
316
+
317
+ if ($prepend) {
318
  self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
319
  } else {
320
  unset(self::$registeredLoaders[$this->vendorDir]);
vendor/composer/InstalledVersions.php CHANGED
@@ -25,12 +25,12 @@ class InstalledVersions
25
  private static $installed = array (
26
  'root' =>
27
  array (
28
- 'pretty_version' => '4.6.4',
29
- 'version' => '4.6.4.0',
30
  'aliases' =>
31
  array (
32
  ),
33
- 'reference' => '4117c3e807c8bed4120639cfcd1ef7f34cb2a543',
34
  'name' => 'mihdan/cyr2lat',
35
  ),
36
  'versions' =>
@@ -46,12 +46,12 @@ private static $installed = array (
46
  ),
47
  'mihdan/cyr2lat' =>
48
  array (
49
- 'pretty_version' => '4.6.4',
50
- 'version' => '4.6.4.0',
51
  'aliases' =>
52
  array (
53
  ),
54
- 'reference' => '4117c3e807c8bed4120639cfcd1ef7f34cb2a543',
55
  ),
56
  'roundcube/plugin-installer' =>
57
  array (
@@ -290,7 +290,6 @@ self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegist
290
  $installed = array();
291
 
292
  if (self::$canGetVendors) {
293
-
294
  foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
295
  if (isset(self::$installedByVendor[$vendorDir])) {
296
  $installed[] = self::$installedByVendor[$vendorDir];
25
  private static $installed = array (
26
  'root' =>
27
  array (
28
+ 'pretty_version' => '5.0.0',
29
+ 'version' => '5.0.0.0',
30
  'aliases' =>
31
  array (
32
  ),
33
+ 'reference' => 'a05290b03db0f9d0bddd9b489170e0e867b89b28',
34
  'name' => 'mihdan/cyr2lat',
35
  ),
36
  'versions' =>
46
  ),
47
  'mihdan/cyr2lat' =>
48
  array (
49
+ 'pretty_version' => '5.0.0',
50
+ 'version' => '5.0.0.0',
51
  'aliases' =>
52
  array (
53
  ),
54
+ 'reference' => 'a05290b03db0f9d0bddd9b489170e0e867b89b28',
55
  ),
56
  'roundcube/plugin-installer' =>
57
  array (
290
  $installed = array();
291
 
292
  if (self::$canGetVendors) {
 
293
  foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
294
  if (isset(self::$installedByVendor[$vendorDir])) {
295
  $installed[] = self::$installedByVendor[$vendorDir];
vendor/composer/autoload_classmap.php CHANGED
@@ -7,18 +7,23 @@ $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
  'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
- 'Cyr_To_Lat\\ACF' => $baseDir . '/classes/class-acf.php',
11
- 'Cyr_To_Lat\\Admin_Notices' => $baseDir . '/classes/class-admin-notices.php',
12
- 'Cyr_To_Lat\\Conversion_Process' => $baseDir . '/classes/background-processes/class-conversion-process.php',
13
- 'Cyr_To_Lat\\Conversion_Tables' => $baseDir . '/classes/class-conversion-tables.php',
14
- 'Cyr_To_Lat\\Converter' => $baseDir . '/classes/class-converter.php',
15
  'Cyr_To_Lat\\KAGG\\WP_Background_Processing\\WP_Async_Request' => $baseDir . '/lib/wp-background-processing/class-wp-async-request.php',
16
  'Cyr_To_Lat\\KAGG\\WP_Background_Processing\\WP_Background_Process' => $baseDir . '/lib/wp-background-processing/class-wp-background-process.php',
17
- 'Cyr_To_Lat\\Main' => $baseDir . '/classes/class-main.php',
18
- 'Cyr_To_Lat\\Post_Conversion_Process' => $baseDir . '/classes/background-processes/class-post-conversion-process.php',
19
- 'Cyr_To_Lat\\Requirements' => $baseDir . '/classes/class-requirements.php',
20
- 'Cyr_To_Lat\\Settings' => $baseDir . '/classes/class-settings.php',
 
 
 
 
 
21
  'Cyr_To_Lat\\Symfony\\Polyfill\\Mbstring\\Mbstring' => $baseDir . '/lib/polyfill-mbstring/Mbstring.php',
22
- 'Cyr_To_Lat\\Term_Conversion_Process' => $baseDir . '/classes/background-processes/class-term-conversion-process.php',
23
- 'Cyr_To_Lat\\WP_CLI' => $baseDir . '/classes/class-wp-cli.php',
24
  );
7
 
8
  return array(
9
  'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
+ 'Cyr_To_Lat\\ACF' => $baseDir . '/src/php/class-acf.php',
11
+ 'Cyr_To_Lat\\Admin_Notices' => $baseDir . '/src/php/class-admin-notices.php',
12
+ 'Cyr_To_Lat\\Conversion_Process' => $baseDir . '/src/php/background-processes/class-conversion-process.php',
13
+ 'Cyr_To_Lat\\Conversion_Tables' => $baseDir . '/src/php/class-conversion-tables.php',
14
+ 'Cyr_To_Lat\\Converter' => $baseDir . '/src/php/class-converter.php',
15
  'Cyr_To_Lat\\KAGG\\WP_Background_Processing\\WP_Async_Request' => $baseDir . '/lib/wp-background-processing/class-wp-async-request.php',
16
  'Cyr_To_Lat\\KAGG\\WP_Background_Processing\\WP_Background_Process' => $baseDir . '/lib/wp-background-processing/class-wp-background-process.php',
17
+ 'Cyr_To_Lat\\Main' => $baseDir . '/src/php/class-main.php',
18
+ 'Cyr_To_Lat\\Post_Conversion_Process' => $baseDir . '/src/php/background-processes/class-post-conversion-process.php',
19
+ 'Cyr_To_Lat\\Requirements' => $baseDir . '/src/php/class-requirements.php',
20
+ 'Cyr_To_Lat\\Settings\\Abstracts\\SettingsBase' => $baseDir . '/src/php/Settings/Abstracts/SettingsBase.php',
21
+ 'Cyr_To_Lat\\Settings\\Abstracts\\SettingsInterface' => $baseDir . '/src/php/Settings/Abstracts/SettingsInterface.php',
22
+ 'Cyr_To_Lat\\Settings\\Converter' => $baseDir . '/src/php/Settings/Converter.php',
23
+ 'Cyr_To_Lat\\Settings\\PluginSettingsBase' => $baseDir . '/src/php/Settings/PluginSettingsBase.php',
24
+ 'Cyr_To_Lat\\Settings\\Settings' => $baseDir . '/src/php/Settings/Settings.php',
25
+ 'Cyr_To_Lat\\Settings\\Tables' => $baseDir . '/src/php/Settings/Tables.php',
26
  'Cyr_To_Lat\\Symfony\\Polyfill\\Mbstring\\Mbstring' => $baseDir . '/lib/polyfill-mbstring/Mbstring.php',
27
+ 'Cyr_To_Lat\\Term_Conversion_Process' => $baseDir . '/src/php/background-processes/class-term-conversion-process.php',
28
+ 'Cyr_To_Lat\\WP_CLI' => $baseDir . '/src/php/class-wp-cli.php',
29
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInitab59197479483050e615845d183c2e8c
6
  {
7
  private static $loader;
8
 
@@ -22,15 +22,15 @@ class ComposerAutoloaderInitab59197479483050e615845d183c2e8c
22
  return self::$loader;
23
  }
24
 
25
- spl_autoload_register(array('ComposerAutoloaderInitab59197479483050e615845d183c2e8c', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
27
- spl_autoload_unregister(array('ComposerAutoloaderInitab59197479483050e615845d183c2e8c', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require __DIR__ . '/autoload_static.php';
32
 
33
- call_user_func(\Composer\Autoload\ComposerStaticInitab59197479483050e615845d183c2e8c::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
@@ -51,19 +51,19 @@ class ComposerAutoloaderInitab59197479483050e615845d183c2e8c
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
- $includeFiles = Composer\Autoload\ComposerStaticInitab59197479483050e615845d183c2e8c::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
- composerRequireab59197479483050e615845d183c2e8c($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
- function composerRequireab59197479483050e615845d183c2e8c($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitedbf0ae69d823c20f1f2c9984482bd8e
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInitedbf0ae69d823c20f1f2c9984482bd8e', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
27
+ spl_autoload_unregister(array('ComposerAutoloaderInitedbf0ae69d823c20f1f2c9984482bd8e', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require __DIR__ . '/autoload_static.php';
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInitedbf0ae69d823c20f1f2c9984482bd8e::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
+ $includeFiles = Composer\Autoload\ComposerStaticInitedbf0ae69d823c20f1f2c9984482bd8e::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequireedbf0ae69d823c20f1f2c9984482bd8e($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
+ function composerRequireedbf0ae69d823c20f1f2c9984482bd8e($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInitab59197479483050e615845d183c2e8c
8
  {
9
  public static $files = array (
10
  '344a0f93a05b8ca362c22e39586db500' => __DIR__ . '/../..' . '/lib/polyfill-mbstring/bootstrap.php',
@@ -26,28 +26,33 @@ class ComposerStaticInitab59197479483050e615845d183c2e8c
26
 
27
  public static $classMap = array (
28
  'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
29
- 'Cyr_To_Lat\\ACF' => __DIR__ . '/../..' . '/classes/class-acf.php',
30
- 'Cyr_To_Lat\\Admin_Notices' => __DIR__ . '/../..' . '/classes/class-admin-notices.php',
31
- 'Cyr_To_Lat\\Conversion_Process' => __DIR__ . '/../..' . '/classes/background-processes/class-conversion-process.php',
32
- 'Cyr_To_Lat\\Conversion_Tables' => __DIR__ . '/../..' . '/classes/class-conversion-tables.php',
33
- 'Cyr_To_Lat\\Converter' => __DIR__ . '/../..' . '/classes/class-converter.php',
34
  'Cyr_To_Lat\\KAGG\\WP_Background_Processing\\WP_Async_Request' => __DIR__ . '/../..' . '/lib/wp-background-processing/class-wp-async-request.php',
35
  'Cyr_To_Lat\\KAGG\\WP_Background_Processing\\WP_Background_Process' => __DIR__ . '/../..' . '/lib/wp-background-processing/class-wp-background-process.php',
36
- 'Cyr_To_Lat\\Main' => __DIR__ . '/../..' . '/classes/class-main.php',
37
- 'Cyr_To_Lat\\Post_Conversion_Process' => __DIR__ . '/../..' . '/classes/background-processes/class-post-conversion-process.php',
38
- 'Cyr_To_Lat\\Requirements' => __DIR__ . '/../..' . '/classes/class-requirements.php',
39
- 'Cyr_To_Lat\\Settings' => __DIR__ . '/../..' . '/classes/class-settings.php',
 
 
 
 
 
40
  'Cyr_To_Lat\\Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/../..' . '/lib/polyfill-mbstring/Mbstring.php',
41
- 'Cyr_To_Lat\\Term_Conversion_Process' => __DIR__ . '/../..' . '/classes/background-processes/class-term-conversion-process.php',
42
- 'Cyr_To_Lat\\WP_CLI' => __DIR__ . '/../..' . '/classes/class-wp-cli.php',
43
  );
44
 
45
  public static function getInitializer(ClassLoader $loader)
46
  {
47
  return \Closure::bind(function () use ($loader) {
48
- $loader->prefixLengthsPsr4 = ComposerStaticInitab59197479483050e615845d183c2e8c::$prefixLengthsPsr4;
49
- $loader->prefixDirsPsr4 = ComposerStaticInitab59197479483050e615845d183c2e8c::$prefixDirsPsr4;
50
- $loader->classMap = ComposerStaticInitab59197479483050e615845d183c2e8c::$classMap;
51
 
52
  }, null, ClassLoader::class);
53
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitedbf0ae69d823c20f1f2c9984482bd8e
8
  {
9
  public static $files = array (
10
  '344a0f93a05b8ca362c22e39586db500' => __DIR__ . '/../..' . '/lib/polyfill-mbstring/bootstrap.php',
26
 
27
  public static $classMap = array (
28
  'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
29
+ 'Cyr_To_Lat\\ACF' => __DIR__ . '/../..' . '/src/php/class-acf.php',
30
+ 'Cyr_To_Lat\\Admin_Notices' => __DIR__ . '/../..' . '/src/php/class-admin-notices.php',
31
+ 'Cyr_To_Lat\\Conversion_Process' => __DIR__ . '/../..' . '/src/php/background-processes/class-conversion-process.php',
32
+ 'Cyr_To_Lat\\Conversion_Tables' => __DIR__ . '/../..' . '/src/php/class-conversion-tables.php',
33
+ 'Cyr_To_Lat\\Converter' => __DIR__ . '/../..' . '/src/php/class-converter.php',
34
  'Cyr_To_Lat\\KAGG\\WP_Background_Processing\\WP_Async_Request' => __DIR__ . '/../..' . '/lib/wp-background-processing/class-wp-async-request.php',
35
  'Cyr_To_Lat\\KAGG\\WP_Background_Processing\\WP_Background_Process' => __DIR__ . '/../..' . '/lib/wp-background-processing/class-wp-background-process.php',
36
+ 'Cyr_To_Lat\\Main' => __DIR__ . '/../..' . '/src/php/class-main.php',
37
+ 'Cyr_To_Lat\\Post_Conversion_Process' => __DIR__ . '/../..' . '/src/php/background-processes/class-post-conversion-process.php',
38
+ 'Cyr_To_Lat\\Requirements' => __DIR__ . '/../..' . '/src/php/class-requirements.php',
39
+ 'Cyr_To_Lat\\Settings\\Abstracts\\SettingsBase' => __DIR__ . '/../..' . '/src/php/Settings/Abstracts/SettingsBase.php',
40
+ 'Cyr_To_Lat\\Settings\\Abstracts\\SettingsInterface' => __DIR__ . '/../..' . '/src/php/Settings/Abstracts/SettingsInterface.php',
41
+ 'Cyr_To_Lat\\Settings\\Converter' => __DIR__ . '/../..' . '/src/php/Settings/Converter.php',
42
+ 'Cyr_To_Lat\\Settings\\PluginSettingsBase' => __DIR__ . '/../..' . '/src/php/Settings/PluginSettingsBase.php',
43
+ 'Cyr_To_Lat\\Settings\\Settings' => __DIR__ . '/../..' . '/src/php/Settings/Settings.php',
44
+ 'Cyr_To_Lat\\Settings\\Tables' => __DIR__ . '/../..' . '/src/php/Settings/Tables.php',
45
  'Cyr_To_Lat\\Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/../..' . '/lib/polyfill-mbstring/Mbstring.php',
46
+ 'Cyr_To_Lat\\Term_Conversion_Process' => __DIR__ . '/../..' . '/src/php/background-processes/class-term-conversion-process.php',
47
+ 'Cyr_To_Lat\\WP_CLI' => __DIR__ . '/../..' . '/src/php/class-wp-cli.php',
48
  );
49
 
50
  public static function getInitializer(ClassLoader $loader)
51
  {
52
  return \Closure::bind(function () use ($loader) {
53
+ $loader->prefixLengthsPsr4 = ComposerStaticInitedbf0ae69d823c20f1f2c9984482bd8e::$prefixLengthsPsr4;
54
+ $loader->prefixDirsPsr4 = ComposerStaticInitedbf0ae69d823c20f1f2c9984482bd8e::$prefixDirsPsr4;
55
+ $loader->classMap = ComposerStaticInitedbf0ae69d823c20f1f2c9984482bd8e::$classMap;
56
 
57
  }, null, ClassLoader::class);
58
  }
vendor/composer/installed.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php return array (
2
  'root' =>
3
  array (
4
- 'pretty_version' => '4.6.4',
5
- 'version' => '4.6.4.0',
6
  'aliases' =>
7
  array (
8
  ),
9
- 'reference' => '4117c3e807c8bed4120639cfcd1ef7f34cb2a543',
10
  'name' => 'mihdan/cyr2lat',
11
  ),
12
  'versions' =>
@@ -22,12 +22,12 @@
22
  ),
23
  'mihdan/cyr2lat' =>
24
  array (
25
- 'pretty_version' => '4.6.4',
26
- 'version' => '4.6.4.0',
27
  'aliases' =>
28
  array (
29
  ),
30
- 'reference' => '4117c3e807c8bed4120639cfcd1ef7f34cb2a543',
31
  ),
32
  'roundcube/plugin-installer' =>
33
  array (
1
  <?php return array (
2
  'root' =>
3
  array (
4
+ 'pretty_version' => '5.0.0',
5
+ 'version' => '5.0.0.0',
6
  'aliases' =>
7
  array (
8
  ),
9
+ 'reference' => 'a05290b03db0f9d0bddd9b489170e0e867b89b28',
10
  'name' => 'mihdan/cyr2lat',
11
  ),
12
  'versions' =>
22
  ),
23
  'mihdan/cyr2lat' =>
24
  array (
25
+ 'pretty_version' => '5.0.0',
26
+ 'version' => '5.0.0.0',
27
  'aliases' =>
28
  array (
29
  ),
30
+ 'reference' => 'a05290b03db0f9d0bddd9b489170e0e867b89b28',
31
  ),
32
  'roundcube/plugin-installer' =>
33
  array (