@arsedizioni/ars-utils 18.5.62 → 19.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/fesm2022/arsedizioni-ars-utils-clipper.common.mjs +10 -10
  2. package/fesm2022/arsedizioni-ars-utils-clipper.common.mjs.map +1 -1
  3. package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs +41 -41
  4. package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs.map +1 -1
  5. package/fesm2022/arsedizioni-ars-utils-core.mjs +99 -99
  6. package/fesm2022/arsedizioni-ars-utils-core.mjs.map +1 -1
  7. package/fesm2022/arsedizioni-ars-utils-evolution.common.mjs +10 -10
  8. package/fesm2022/arsedizioni-ars-utils-evolution.common.mjs.map +1 -1
  9. package/fesm2022/arsedizioni-ars-utils-help.mjs +13 -13
  10. package/fesm2022/arsedizioni-ars-utils-help.mjs.map +1 -1
  11. package/fesm2022/arsedizioni-ars-utils-support.common.mjs +10 -10
  12. package/fesm2022/arsedizioni-ars-utils-support.common.mjs.map +1 -1
  13. package/fesm2022/arsedizioni-ars-utils-support.ui.mjs +6 -6
  14. package/fesm2022/arsedizioni-ars-utils-support.ui.mjs.map +1 -1
  15. package/fesm2022/arsedizioni-ars-utils-tinymce.mjs +7 -7
  16. package/fesm2022/arsedizioni-ars-utils-tinymce.mjs.map +1 -1
  17. package/fesm2022/arsedizioni-ars-utils-ui.application.mjs +58 -58
  18. package/fesm2022/arsedizioni-ars-utils-ui.application.mjs.map +1 -1
  19. package/fesm2022/arsedizioni-ars-utils-ui.mjs +34 -34
  20. package/fesm2022/arsedizioni-ars-utils-ui.mjs.map +1 -1
  21. package/fesm2022/arsedizioni-ars-utils-ui.oauth.mjs +7 -7
  22. package/fesm2022/arsedizioni-ars-utils-ui.oauth.mjs.map +1 -1
  23. package/package.json +5 -29
  24. package/esm2022/arsedizioni-ars-utils.mjs +0 -5
  25. package/esm2022/clipper.common/arsedizioni-ars-utils-clipper.common.mjs +0 -5
  26. package/esm2022/clipper.common/common/common.module.mjs +0 -16
  27. package/esm2022/clipper.common/common/definitions.mjs +0 -2041
  28. package/esm2022/clipper.common/common/interceptors/auth.interceptor.mjs +0 -100
  29. package/esm2022/clipper.common/common/messages.mjs +0 -36
  30. package/esm2022/clipper.common/common/services/clipper.service.mjs +0 -1011
  31. package/esm2022/clipper.common/public_api.mjs +0 -5
  32. package/esm2022/clipper.ui/arsedizioni-ars-utils-clipper.ui.mjs +0 -5
  33. package/esm2022/clipper.ui/documents.mjs +0 -50
  34. package/esm2022/clipper.ui/public_api.mjs +0 -18
  35. package/esm2022/clipper.ui/ui/browser-dialog/browser-dialog.component.mjs +0 -766
  36. package/esm2022/clipper.ui/ui/document/document.component.mjs +0 -688
  37. package/esm2022/clipper.ui/ui/document-index/document-index.component.mjs +0 -118
  38. package/esm2022/clipper.ui/ui/document-manager/document-manager.mjs +0 -441
  39. package/esm2022/clipper.ui/ui/document-menu/document-menu.component.mjs +0 -217
  40. package/esm2022/clipper.ui/ui/references/references.component.mjs +0 -380
  41. package/esm2022/clipper.ui/ui/search-calendar/search-calendar.component.mjs +0 -116
  42. package/esm2022/clipper.ui/ui/search-dialog/search-dialog.component.mjs +0 -339
  43. package/esm2022/clipper.ui/ui/search-facets/search-facets.component.mjs +0 -251
  44. package/esm2022/clipper.ui/ui/search-free-text-help/search-free-text-help.component.mjs +0 -17
  45. package/esm2022/clipper.ui/ui/search-free-text-query-builder/search-free-text-query-builder.component.mjs +0 -106
  46. package/esm2022/clipper.ui/ui/search-result-item/search-result-item.component.mjs +0 -120
  47. package/esm2022/clipper.ui/ui/search-result-manager/search-result-manager.mjs +0 -531
  48. package/esm2022/core/arsedizioni-ars-utils-core.mjs +0 -5
  49. package/esm2022/core/core.module.mjs +0 -151
  50. package/esm2022/core/dateFnsAdapter.mjs +0 -203
  51. package/esm2022/core/definitions.mjs +0 -47
  52. package/esm2022/core/directives/autoFocusDirective.mjs +0 -22
  53. package/esm2022/core/directives/changeDateIntervalDirective.mjs +0 -48
  54. package/esm2022/core/directives/copyClipboardDirective.mjs +0 -46
  55. package/esm2022/core/directives/validators.mjs +0 -502
  56. package/esm2022/core/pipes/format.pipe.mjs +0 -53
  57. package/esm2022/core/pipes/replace.pipe.mjs +0 -29
  58. package/esm2022/core/pipes/safe-html.pipe.mjs +0 -24
  59. package/esm2022/core/pipes/safe-url.pipe.mjs +0 -24
  60. package/esm2022/core/pipes/search-callback.pipe.mjs +0 -21
  61. package/esm2022/core/pipes/search-filter.pipe.mjs +0 -50
  62. package/esm2022/core/public_api.mjs +0 -22
  63. package/esm2022/core/selectable.mjs +0 -131
  64. package/esm2022/core/services/broadcast.service.mjs +0 -35
  65. package/esm2022/core/services/broadcastChannelManager.mjs +0 -80
  66. package/esm2022/core/services/environment.service.mjs +0 -29
  67. package/esm2022/core/services/screen.service.mjs +0 -23
  68. package/esm2022/core/services/theme.service.mjs +0 -140
  69. package/esm2022/core/system.mjs +0 -664
  70. package/esm2022/evolution.common/arsedizioni-ars-utils-evolution.common.mjs +0 -5
  71. package/esm2022/evolution.common/common/common.module.mjs +0 -16
  72. package/esm2022/evolution.common/common/definitions.mjs +0 -454
  73. package/esm2022/evolution.common/common/interceptors/auth.interceptor.mjs +0 -100
  74. package/esm2022/evolution.common/common/messages.mjs +0 -8
  75. package/esm2022/evolution.common/common/services/evolution.service.mjs +0 -490
  76. package/esm2022/evolution.common/public_api.mjs +0 -5
  77. package/esm2022/help/arsedizioni-ars-utils-help.mjs +0 -5
  78. package/esm2022/help/components/help-viewer/help-viewer.component.mjs +0 -442
  79. package/esm2022/help/definitions.mjs +0 -2
  80. package/esm2022/help/help.module.mjs +0 -12
  81. package/esm2022/help/public_api.mjs +0 -7
  82. package/esm2022/help/services/help.service.mjs +0 -77
  83. package/esm2022/public_api.mjs +0 -15
  84. package/esm2022/support.common/arsedizioni-ars-utils-support.common.mjs +0 -5
  85. package/esm2022/support.common/common/common.module.mjs +0 -16
  86. package/esm2022/support.common/common/definitions.mjs +0 -29
  87. package/esm2022/support.common/common/interceptors/auth.interceptor.mjs +0 -100
  88. package/esm2022/support.common/common/messages.mjs +0 -13
  89. package/esm2022/support.common/common/services/support.service.mjs +0 -289
  90. package/esm2022/support.common/public_api.mjs +0 -8
  91. package/esm2022/support.ui/arsedizioni-ars-utils-support.ui.mjs +0 -5
  92. package/esm2022/support.ui/public_api.mjs +0 -5
  93. package/esm2022/support.ui/ui/notifications-browser/notification/notification.component.mjs +0 -80
  94. package/esm2022/support.ui/ui/notifications-browser/notifications-browser.component.mjs +0 -233
  95. package/esm2022/tinymce/arsedizioni-ars-utils-tinymce.mjs +0 -5
  96. package/esm2022/tinymce/full-screen-editor/full-screen-editor.component.mjs +0 -48
  97. package/esm2022/tinymce/public_api.mjs +0 -7
  98. package/esm2022/tinymce/tinymce.module.mjs +0 -19
  99. package/esm2022/tinymce/utils.mjs +0 -150
  100. package/esm2022/ui/arsedizioni-ars-utils-ui.mjs +0 -5
  101. package/esm2022/ui/public_api.mjs +0 -12
  102. package/esm2022/ui/ui/components/button-selector/button-selector.component.mjs +0 -150
  103. package/esm2022/ui/ui/components/button-toggle/button-toggle.component.mjs +0 -51
  104. package/esm2022/ui/ui/components/calendar-empty-header/calendar-empy-header.component.mjs +0 -30
  105. package/esm2022/ui/ui/components/chips-selector/chips-selector.component.mjs +0 -272
  106. package/esm2022/ui/ui/components/file-input/file-input.component.mjs +0 -264
  107. package/esm2022/ui/ui/components/file-preview/file-preview.component.mjs +0 -73
  108. package/esm2022/ui/ui/components/filter-bar/filter-bar.component.mjs +0 -356
  109. package/esm2022/ui/ui/definitions.mjs +0 -2
  110. package/esm2022/ui/ui/dialogs/busy/busy-dialog.component.mjs +0 -47
  111. package/esm2022/ui/ui/dialogs/confirm/confirm-dialog.component.mjs +0 -101
  112. package/esm2022/ui/ui/dialogs/credentials/credentials-dialog.component.mjs +0 -86
  113. package/esm2022/ui/ui/dialogs/info/info-dialog.component.mjs +0 -51
  114. package/esm2022/ui/ui/dialogs/prompt/prompt-dialog.component.mjs +0 -77
  115. package/esm2022/ui/ui/dialogs/prompt-date/prompt-date-dialog.component.mjs +0 -79
  116. package/esm2022/ui/ui/dialogs/prompt-time/prompt-time-dialog.component.mjs +0 -72
  117. package/esm2022/ui/ui/dialogs/recover-password/recover-password-dialog.component.mjs +0 -49
  118. package/esm2022/ui/ui/dialogs/reset-password/reset-password-dialog.component.mjs +0 -89
  119. package/esm2022/ui/ui/dialogs/select/select-dialog.component.mjs +0 -374
  120. package/esm2022/ui/ui/dialogs/select-file/select-file-dialog.component.mjs +0 -106
  121. package/esm2022/ui/ui/dialogs/select-picture/select-picture-dialog.component.mjs +0 -62
  122. package/esm2022/ui/ui/dialogs/select-tree/select-tree-dialog.component.mjs +0 -277
  123. package/esm2022/ui/ui/dialogs/send-to/send-to-dialog.component.mjs +0 -90
  124. package/esm2022/ui/ui/dialogs/toast/toast.component.mjs +0 -32
  125. package/esm2022/ui/ui/directives/resize-table-column.directive.mjs +0 -63
  126. package/esm2022/ui/ui/filters.mjs +0 -43
  127. package/esm2022/ui/ui/paginatorIntl.mjs +0 -34
  128. package/esm2022/ui/ui/services/dialog.service.mjs +0 -417
  129. package/esm2022/ui/ui/services/ui.service.mjs +0 -21
  130. package/esm2022/ui/ui/ui.module.mjs +0 -21
  131. package/esm2022/ui.application/arsedizioni-ars-utils-ui.application.mjs +0 -5
  132. package/esm2022/ui.application/public_api.mjs +0 -21
  133. package/esm2022/ui.application/ui/components/button-selector/button-selector.component.mjs +0 -150
  134. package/esm2022/ui.application/ui/components/button-toggle/button-toggle.component.mjs +0 -51
  135. package/esm2022/ui.application/ui/components/calendar-empty-header/calendar-empy-header.component.mjs +0 -30
  136. package/esm2022/ui.application/ui/components/chips-selector/chips-selector.component.mjs +0 -272
  137. package/esm2022/ui.application/ui/components/file-input/file-input.component.mjs +0 -264
  138. package/esm2022/ui.application/ui/components/file-preview/file-preview.component.mjs +0 -73
  139. package/esm2022/ui.application/ui/components/filter-bar/filter-bar.component.mjs +0 -356
  140. package/esm2022/ui.application/ui/definitions.mjs +0 -31
  141. package/esm2022/ui.application/ui/dialogs/prompt/prompt-dialog.component.mjs +0 -77
  142. package/esm2022/ui.application/ui/dialogs/prompt-date/prompt-date-dialog.component.mjs +0 -79
  143. package/esm2022/ui.application/ui/dialogs/prompt-time/prompt-time-dialog.component.mjs +0 -72
  144. package/esm2022/ui.application/ui/dialogs/select/select-dialog.component.mjs +0 -374
  145. package/esm2022/ui.application/ui/dialogs/select-file/select-file-dialog.component.mjs +0 -106
  146. package/esm2022/ui.application/ui/dialogs/select-picture/select-picture-dialog.component.mjs +0 -62
  147. package/esm2022/ui.application/ui/dialogs/select-tree/select-tree-dialog.component.mjs +0 -277
  148. package/esm2022/ui.application/ui/dialogs/send-to/send-to-dialog.component.mjs +0 -90
  149. package/esm2022/ui.application/ui/directives/resize-table-column.directive.mjs +0 -63
  150. package/esm2022/ui.application/ui/filters.mjs +0 -43
  151. package/esm2022/ui.application/ui/services/applicationDialog.service.mjs +0 -304
  152. package/esm2022/ui.application/ui/ui.module.mjs +0 -30
  153. package/esm2022/ui.oauth/arsedizioni-ars-utils-ui.oauth.mjs +0 -5
  154. package/esm2022/ui.oauth/public_api.mjs +0 -6
  155. package/esm2022/ui.oauth/ui/components/login/login-oauth.component.mjs +0 -199
  156. package/esm2022/ui.oauth/ui/definitions.mjs +0 -7
  157. package/esm2022/ui.oauth/ui/ui.module.mjs +0 -13
  158. package/ui/ui/components/button-selector/button-selector.component.d.ts +0 -52
  159. package/ui/ui/components/button-toggle/button-toggle.component.d.ts +0 -28
  160. package/ui/ui/components/calendar-empty-header/calendar-empy-header.component.d.ts +0 -11
  161. package/ui/ui/components/chips-selector/chips-selector.component.d.ts +0 -82
  162. package/ui/ui/components/file-input/file-input.component.d.ts +0 -88
  163. package/ui/ui/components/file-preview/file-preview.component.d.ts +0 -26
  164. package/ui/ui/components/filter-bar/filter-bar.component.d.ts +0 -83
  165. package/ui/ui/dialogs/prompt/prompt-dialog.component.d.ts +0 -18
  166. package/ui/ui/dialogs/prompt-date/prompt-date-dialog.component.d.ts +0 -18
  167. package/ui/ui/dialogs/prompt-time/prompt-time-dialog.component.d.ts +0 -18
  168. package/ui/ui/dialogs/select/select-dialog.component.d.ts +0 -122
  169. package/ui/ui/dialogs/select-file/select-file-dialog.component.d.ts +0 -36
  170. package/ui/ui/dialogs/select-picture/select-picture-dialog.component.d.ts +0 -26
  171. package/ui/ui/dialogs/select-tree/select-tree-dialog.component.d.ts +0 -98
  172. package/ui/ui/dialogs/send-to/send-to-dialog.component.d.ts +0 -28
  173. package/ui/ui/directives/resize-table-column.directive.d.ts +0 -19
  174. package/ui/ui/filters.d.ts +0 -57
@@ -1,664 +0,0 @@
1
- import { HttpParams } from "@angular/common/http";
2
- import { format, parse, parseISO, setHours } from 'date-fns';
3
- import { it } from 'date-fns/locale';
4
- import { fromZonedTime } from 'date-fns-tz';
5
- export var DateFormat;
6
- (function (DateFormat) {
7
- DateFormat[DateFormat["Short"] = 1] = "Short";
8
- DateFormat[DateFormat["Long"] = 2] = "Long";
9
- DateFormat[DateFormat["LongWithShortMonth"] = 3] = "LongWithShortMonth";
10
- DateFormat[DateFormat["LongWithWeekDay"] = 4] = "LongWithWeekDay";
11
- DateFormat[DateFormat["LongWithShortWeekDay"] = 5] = "LongWithShortWeekDay";
12
- DateFormat[DateFormat["MonthAndYear"] = 6] = "MonthAndYear";
13
- DateFormat[DateFormat["LongMonthAndYear"] = 7] = "LongMonthAndYear";
14
- DateFormat[DateFormat["WeekDay"] = 8] = "WeekDay";
15
- DateFormat[DateFormat["LongWeekDay"] = 9] = "LongWeekDay";
16
- DateFormat[DateFormat["DayAndMonth"] = 10] = "DayAndMonth";
17
- DateFormat[DateFormat["ShortUS"] = 11] = "ShortUS";
18
- DateFormat[DateFormat["ShortISO8601"] = 12] = "ShortISO8601"; // yyyy-mm-dd
19
- })(DateFormat || (DateFormat = {}));
20
- export class SystemUtils {
21
- /**
22
- * Array find by key
23
- * @param array : the array to scan
24
- * @param key : key name
25
- * @param value : the value to search for
26
- * @returns : the property value or null
27
- */
28
- static arrayFindByKey(array, key, value) {
29
- if (!array)
30
- return null;
31
- for (const item of array) {
32
- if (item[key] === value) {
33
- return item;
34
- }
35
- }
36
- return null;
37
- }
38
- /**
39
- * Array find index by key
40
- * @param array : the array to scan
41
- * @param key : the key name
42
- * @param value : the value to search for
43
- * @returns : the array index or -1 if not found
44
- */
45
- static arrayFindIndexByKey(array, key, value) {
46
- if (!array)
47
- return -1;
48
- for (let i = 0; i < array.length; i++) {
49
- if (array[i][key] === value) {
50
- return i;
51
- }
52
- }
53
- return -1;
54
- }
55
- /**
56
- * Get a value from and array made of name|value items
57
- * @param array : the array to scan
58
- * @param value : the value to search for
59
- * @returns : the property value or null if not found
60
- */
61
- static arrayGetValue(array, value) {
62
- if (!array)
63
- return null;
64
- for (var i = 0; i < array.length; i++) {
65
- const item = array[i];
66
- if (item.value === value) {
67
- return item.name || item.id;
68
- }
69
- }
70
- return null;
71
- }
72
- /**
73
- * Convert items to nodes into a tree structure
74
- * @param items : list of nodes
75
- * @param parent : parent node
76
- * @returns : an array of INode objects
77
- */
78
- static arrayToNodes(items, parent = null) {
79
- const nodes = [];
80
- items.forEach((n) => {
81
- const node = {
82
- id: n.id.toString(),
83
- name: n.name,
84
- count: n.count ? n.count : 0,
85
- children: null,
86
- parent,
87
- bag: n,
88
- };
89
- nodes.push(node);
90
- node.children =
91
- n.children && n.children.length > 0
92
- ? this.arrayToNodes(n.children, node)
93
- : [];
94
- });
95
- return nodes;
96
- }
97
- /**
98
- * Used to copare items during an array of objects sorting
99
- * @param key : the property name to sort for
100
- * @param order : the order 'asc' or 'desc'
101
- * @returns : 0 if equals, 1 if bigger, -1 if lower
102
- */
103
- static arraySortCompare(key, order = "asc") {
104
- const result = function innerSort(a, b) {
105
- if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
106
- // property doesn't exist on either object
107
- return 0;
108
- }
109
- const varA = typeof a[key] === "string" ? a[key].toUpperCase() : a[key];
110
- const varB = typeof b[key] === "string" ? b[key].toUpperCase() : b[key];
111
- let comparison = 0;
112
- if (varA > varB)
113
- comparison = 1;
114
- else if (varA < varB)
115
- comparison = -1;
116
- return order === "desc" ? comparison * -1 : comparison;
117
- };
118
- return result;
119
- }
120
- /**
121
- * Format weight
122
- * @param gr : grams
123
- * @returns : the formatted string
124
- */
125
- static formatWeight(gr) {
126
- if (gr > 1000000)
127
- return (gr / 1000000).toFixed(2) + " t";
128
- else if (gr > 100000)
129
- return (gr / 100000).toFixed(2) + " q";
130
- else if (gr > 1000)
131
- return (gr / 1000).toFixed(2) + " kg";
132
- else
133
- return gr + " gr";
134
- }
135
- /**
136
- * Format file size
137
- * @param bytes : number of bytes
138
- * @returns : the formatted string
139
- */
140
- static formatFileSize(bytes) {
141
- if (bytes > 1024000)
142
- return (bytes / 1024000).toFixed(1) + " MB";
143
- if (bytes > 1024)
144
- return (bytes / 1024).toFixed(1) + " Kb";
145
- return bytes + " byte";
146
- }
147
- /**
148
- * Compare two string
149
- * @param a : string a
150
- * @param b : string b
151
- * @returns : 0 if equals, 1 if bigger, -1 if lower
152
- */
153
- static compareString(a, b) {
154
- if ((a ?? "").toLowerCase() > (b ?? "").toLowerCase())
155
- return 1;
156
- if ((a ?? "").toLowerCase() < (b ?? "").toLowerCase())
157
- return -1;
158
- return 0;
159
- }
160
- /**
161
- * Capitalize a string
162
- * @param s : the string to capitalize
163
- * @returns : the capitalized string
164
- */
165
- static capitalize(s) {
166
- if (!s)
167
- return null;
168
- let b = "";
169
- let cap = true;
170
- for (const char of s) {
171
- if (char === " ") {
172
- b += char;
173
- cap = true;
174
- }
175
- else if (cap) {
176
- b += char.toUpperCase();
177
- cap = false;
178
- }
179
- else {
180
- b += char.toLowerCase();
181
- }
182
- }
183
- return b;
184
- }
185
- /**
186
- * Truncate a string
187
- * @param s : the string to truncate
188
- * @param max : the max number of chars
189
- * @returns : the truncated string
190
- */
191
- static truncate(s, max = 500) {
192
- if (!s)
193
- return null;
194
- if (s.length < max)
195
- return s;
196
- let i = max - 1;
197
- while (i > 0) {
198
- if (s[i] === ' ')
199
- return s.slice(0, i);
200
- i--;
201
- }
202
- return s;
203
- }
204
- /**
205
- * Join a list of strings
206
- * @param items : the list of strings
207
- * @param sep : the separator string
208
- * @param max : the maximum resulting string
209
- * @returns : the joined string
210
- */
211
- static join(items, sep = " ", max = 350) {
212
- if (!items || items.length === 0)
213
- return null;
214
- if (items.length > 1) {
215
- let l = 0;
216
- let s = "";
217
- while (s.length < max && items.length > l) {
218
- if (l > 0) {
219
- s += sep;
220
- }
221
- s += items[l++];
222
- }
223
- if (items.length > l) {
224
- s += "...";
225
- }
226
- return s;
227
- }
228
- return items[0];
229
- }
230
- /**
231
- * Replace stuff in text html
232
- * @param s : the string to process
233
- * @returns : the replaced string
234
- */
235
- static replaceAsHtml(s) {
236
- const regex = /https?:\/\/.*[^\s]/ig;
237
- const m = regex.exec(s);
238
- if (m && m.length > 0) {
239
- let v = null;
240
- for (let i = 0; i < m.length; i++) {
241
- v = m[i];
242
- s = s.replace(v, '<a href="' + v + '" target="_blank">' + v + '</a>');
243
- }
244
- }
245
- return s;
246
- }
247
- /**
248
- * Compare two names
249
- * @param a : name a
250
- * @param b : name b
251
- * @returns : true if a equals b
252
- */
253
- static compareNames(a, b) {
254
- if (a)
255
- a = a.trim();
256
- if (b)
257
- b = b.trim();
258
- if (a && b && a.length !== b.length)
259
- return false;
260
- if (this.compareString(a, b) === 0)
261
- return true;
262
- const p1 = a.split(" ");
263
- const p2 = b.split(" ");
264
- if (p1.length !== p2.length)
265
- return false;
266
- let matches = p1.length;
267
- for (const s1 of p1) {
268
- for (const s2 of p2) {
269
- if (this.compareString(s1, s2) === 0) {
270
- matches--;
271
- break;
272
- }
273
- }
274
- }
275
- return matches === 0;
276
- }
277
- /**
278
- * Cipher a text
279
- * @param text : the text
280
- * @param key : the key
281
- * @param reverse : true to decode, false to encode
282
- * @returns :the ciphered text
283
- */
284
- static cipher(text, key, reverse = false) {
285
- // Surrogate pair limit
286
- var bound = 0x10000;
287
- // Create string from character codes
288
- return String.fromCharCode.apply(null,
289
- // Turn string to character codes
290
- text.split("").map(function (v, i) {
291
- // Get rotation from key
292
- var rotation = key.charCodeAt(i % key.length);
293
- // Are we decrypting?
294
- if (reverse)
295
- rotation = -rotation;
296
- // Return current character code + rotation
297
- return (v.charCodeAt() + rotation + bound) % bound;
298
- }));
299
- }
300
- /**
301
- * Clone an object using JSON
302
- * @param obj : the oblect to clone
303
- * @returns : a new object
304
- */
305
- static clone(obj) {
306
- if (!obj)
307
- return null;
308
- return JSON.parse(JSON.stringify(obj));
309
- }
310
- /**
311
- * Clone an object using deep cloning
312
- * @param obj : the oblect to clone
313
- * @returns : a new object
314
- */
315
- static deepClone(obj, dest = null) {
316
- const cloneObj = dest ? dest : obj.constructor();
317
- const attributes = Object.keys(obj);
318
- for (const attribute of attributes) {
319
- const property = obj[attribute];
320
- if (typeof property === "object" && property != null) {
321
- cloneObj[attribute] = this.deepClone(property);
322
- }
323
- else {
324
- cloneObj[attribute] = property;
325
- }
326
- }
327
- return cloneObj;
328
- }
329
- /**
330
- * Check if a string is a valid UUID
331
- * @param value : the value to parse
332
- * @returns : true if is a valid UUID
333
- */
334
- static parseUUID(value) {
335
- const regex = /^({|()?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(}|))?$/;
336
- return regex.test(value);
337
- }
338
- /**
339
- * Parse and ensure that UUID is not empty
340
- * @param value : the value to parse
341
- * @returns : true if valid and not empty
342
- */
343
- static parseUUIDNotEmpty(value) {
344
- const regex = /^({|()?0{8}-(0{4}-){3}0{12}(}|))?$/;
345
- return this.parseUUID(value) && !regex.test(value);
346
- }
347
- /**
348
- * Return an empty UUID
349
- * @returns : the empty UUID
350
- */
351
- static emptyUUID() { return "00000000-0000-0000-0000-000000000000"; }
352
- ;
353
- /**
354
- * Create a new UUID
355
- * @returns : the string UUID
356
- */
357
- static generateUUID() {
358
- const regex = /[xy]/g;
359
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(regex, function (c) {
360
- var r = (Math.random() * 16) | 0, v = c === "x" ? r : (r & 0x3) | 0x8;
361
- return v.toString(16);
362
- });
363
- }
364
- /**
365
- * Parse a text and return true if is a valid email or null
366
- * @param value : email
367
- * @returns : true if the email is valid or empty
368
- */
369
- static parseEmail(value) {
370
- if (!value)
371
- return true;
372
- const regex = /(?:[a-z0-9+!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/gi;
373
- return regex.test(value.trim().toLowerCase());
374
- }
375
- /**
376
- * Parse a text and return true if is a valid url or null
377
- * @param value : the url to parse
378
- * @returns : true if the url is valid or empty
379
- */
380
- static parseUrl(value) {
381
- if (!value)
382
- return true;
383
- const regex = new RegExp("(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})[/\\w .-]*/?");
384
- return regex.test(value.trim().toLowerCase());
385
- }
386
- /**
387
- * Get date parts from a string value
388
- * @param value : the string to parse
389
- * @returns : an array of numbers with year, month, day
390
- */
391
- static getDateParts(value) {
392
- if (!value)
393
- return null;
394
- let parts = [];
395
- if (value.indexOf("-") !== -1) {
396
- const p = value.split("-");
397
- if (p.length !== 3)
398
- return null;
399
- parts = [parseInt(p[0]), parseInt(p[1]) - 1, parseInt(p[2])];
400
- }
401
- else if (value.indexOf("/") !== -1) {
402
- const p = value.split("/");
403
- if (p.length !== 3)
404
- return null;
405
- parts = [parseInt(p[2]), parseInt(p[1]) - 1, parseInt(p[0])];
406
- }
407
- return parts;
408
- }
409
- /**
410
- * Parse a date
411
- * @param value : the value to check
412
- * @param locale : the locale to use
413
- * @returns : a valid Date object or null
414
- */
415
- static parseDate(value, locale = it) {
416
- // No value at all
417
- if (!value)
418
- return null;
419
- // A Date value
420
- if (value instanceof Date && value.getTime())
421
- return value;
422
- // Parse known formats using date-fns
423
- let d = parseISO(value);
424
- if (d && d.getTime() && d.getFullYear() > 1750)
425
- return d;
426
- d = parse(value, 'dd/MM/yyyy', new Date(), { locale: locale });
427
- if (d && d.getTime() && d.getFullYear() > 1750)
428
- return d;
429
- d = parse(value, 'yyyy-MM-dd', new Date(), { locale: locale });
430
- if (d && d.getTime() && d.getFullYear() > 1750)
431
- return d;
432
- // Parse values manually
433
- let parts = this.getDateParts(value);
434
- if (parts[0] < 100)
435
- parts[0] += 2000;
436
- if (isNaN(parts[0]) || parts[0] < 0 || parts[0] < 1750)
437
- return null;
438
- if (isNaN(parts[1]) || parts[1] < 0)
439
- return null;
440
- if (isNaN(parts[2]) || parts[2] < 0)
441
- return null;
442
- if (parts[1] > 11)
443
- return null;
444
- if (parts[1] === 1 && parts[2] > 29)
445
- return null;
446
- else if (parts[1] !== 1 && parts[2] > 31)
447
- return null;
448
- return new Date(parts[0], parts[1], parts[2], 2);
449
- }
450
- /**
451
- * Format a date
452
- * @param value : the date or string to format
453
- * @param fmt : the DateFormat to use or the string pattern
454
- * @param locale : the locale to use (default is IT)
455
- * @returns : the formatted string
456
- */
457
- static formatDate(value, fmt = DateFormat.Short, locale = it) {
458
- // No value at all
459
- if (!value)
460
- return null;
461
- // A string
462
- if (typeof value === 'string' || value instanceof String)
463
- value = this.parseDate(value);
464
- // Not a date
465
- if (!(value instanceof Date && value.getTime()))
466
- return null;
467
- // Format
468
- switch (fmt) {
469
- case DateFormat.Short: return format(value, "dd/MM/yyyy", { locale: locale });
470
- case DateFormat.Long: return format(value, "d MMMM yyyy", { locale: locale });
471
- case DateFormat.LongWithShortMonth: return format(value, "d MMM yyyy", { locale: locale });
472
- case DateFormat.LongWithWeekDay: return format(value, "EEEE, d MMMM yyyy", { locale: locale });
473
- case DateFormat.LongWithShortWeekDay: return format(value, "EEE, d MMMM yyyy", { locale: locale });
474
- case DateFormat.MonthAndYear: return format(value, "MMM yyyy", { locale: locale });
475
- case DateFormat.LongMonthAndYear: return format(value, "MMMM yyyy", { locale: locale });
476
- case DateFormat.WeekDay: return format(value, "EEE, d", { locale: locale });
477
- case DateFormat.LongWeekDay: return format(value, "EEEE, d", { locale: locale });
478
- case DateFormat.DayAndMonth: return format(value, "d MMMM", { locale: locale });
479
- case DateFormat.ShortUS: return format(value, "MM/dd/yyyy", { locale: locale });
480
- case DateFormat.ShortISO8601: return format(value, "yyyy-MM-dd", { locale: locale });
481
- default:
482
- return format(value, fmt, { locale: locale });
483
- }
484
- }
485
- /**
486
- * Return an italian local date
487
- * @param value : the date
488
- * @returns : the new date
489
- */
490
- static toLocalDate(value) {
491
- // No value at all
492
- if (!value)
493
- return null;
494
- // A string
495
- if (typeof value === 'string' || value instanceof String)
496
- value = this.parseDate(value);
497
- // Not a date
498
- if (!(value instanceof Date && value.getTime()))
499
- return null;
500
- // Update date
501
- return setHours(value, 2);
502
- }
503
- /**
504
- * Update a DateInterval object according to a string
505
- * @param value : string value
506
- * @param interval : DateInterval value to update
507
- * @param end : true if must be updated the first or the end value
508
- * @param copy : copy the same value (works only if not end element)
509
- */
510
- static changeDateInterval(value, interval, end = false, copy = false) {
511
- if (value) {
512
- let year = -1;
513
- if (value.length === 4 && (year = parseInt(value)) > 1750) {
514
- if (!end) {
515
- interval.from = fromZonedTime(new Date(year, 0, 1), 'UTC');
516
- interval.to = fromZonedTime(new Date(year, 11, 31), 'UTC');
517
- }
518
- else
519
- interval.to = new Date(year, 11, 31);
520
- }
521
- else {
522
- let parts = this.getDateParts(value);
523
- if (!parts || isNaN(parts[0]) || parts[0] < 0 || parts[0] < 1750)
524
- return;
525
- const d = fromZonedTime(new Date(parts[0], parts[1], parts[2]), 'UTC');
526
- if (end)
527
- interval.to = d;
528
- else if (copy) {
529
- interval.from = d;
530
- interval.to = d;
531
- }
532
- else
533
- interval.from = d;
534
- }
535
- }
536
- }
537
- /**
538
- * Encode url
539
- * @param value : the value to encode
540
- * @returns : the url encoded string
541
- */
542
- static urlEncode(value) {
543
- return encodeURIComponent(value);
544
- }
545
- /**
546
- * Decode url
547
- * @param value : the url to decode
548
- * @returns : the decode url string
549
- */
550
- static urlDecode(value) {
551
- const regex = /\+/g;
552
- return decodeURIComponent((value + "").replace(regex, "%20"));
553
- }
554
- /**
555
- * Get a querystring parameter value
556
- * @param name : the parameter name
557
- * @returns : the string value
558
- */
559
- static getQueryStringValueByName(name) {
560
- if (!this.isBrowser())
561
- return null;
562
- const url = window.location.href;
563
- if (url.includes("?")) {
564
- const httpParams = new HttpParams({ fromString: url.split("?")[1] });
565
- const v = decodeURIComponent(httpParams.get(name));
566
- if (v !== "null")
567
- return v;
568
- else
569
- return null;
570
- }
571
- return null;
572
- }
573
- /**
574
- * Generate a password
575
- * @returns : the password string
576
- */
577
- static generatePassword() {
578
- const random = "$" + Math.random().toString(36).slice(-7);
579
- let password = "";
580
- let hasUpperCase = false;
581
- for (const rnd of random) {
582
- if (!hasUpperCase && "abcdefghjilmnopqrstuvywxz".includes(rnd)) {
583
- password += rnd.toUpperCase();
584
- hasUpperCase = true;
585
- }
586
- else {
587
- password += rnd;
588
- }
589
- }
590
- if (!hasUpperCase)
591
- password = password.substring(0, 7) + "M";
592
- return password;
593
- }
594
- /**
595
- * Check if current browser supports touch
596
- * @returns : true if the display is touchable
597
- */
598
- static isTouchable() {
599
- return (this.isBrowser() && ("ontouchstart" in window ||
600
- navigator.maxTouchPoints > 0));
601
- }
602
- /**
603
- * This check will prevent 'window' logic to be executed
604
- * while executing the server rendering
605
- * @returns : true if using the browser
606
- */
607
- static isBrowser() {
608
- return typeof (window) !== 'undefined';
609
- }
610
- /**
611
- * Convert folders in a tree of Node object.
612
- * @param folders : the subfolders group or null to root
613
- * @returns : a node list
614
- */
615
- static toNodes(folders) {
616
- return this._toNodes(folders, undefined);
617
- }
618
- /**
619
- * Convert folders in a tree of Node object.
620
- * @param folders : the children group or null to root
621
- * @param parent : the parent node
622
- * @returns : a node list
623
- */
624
- static _toNodes(folders, parent) {
625
- const nodes = [];
626
- folders.forEach((n) => {
627
- const node = {
628
- id: n.id,
629
- name: n.name,
630
- count: n.count,
631
- parent: parent,
632
- children: undefined,
633
- bag: n,
634
- };
635
- node.children =
636
- n.children && n.children.length > 0
637
- ? this._toNodes(n.children, node)
638
- : [];
639
- nodes.push(node);
640
- });
641
- return nodes;
642
- }
643
- /**
644
- * Return the flags array to be used in selections
645
- * @param value : the new value
646
- * @param max: the max number of flags
647
- */
648
- static getFlags(value, max = 30) {
649
- if (value) {
650
- let items = [];
651
- let v = 1;
652
- let m = 1 << max;
653
- while (v < m) {
654
- if ((value & v) === v)
655
- items.push(v);
656
- v = v << 1;
657
- }
658
- return items;
659
- }
660
- else
661
- return [];
662
- }
663
- }
664
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYXJzLXV0aWxzL2NvcmUvc3lzdGVtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVsRCxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzdELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBWTVDLE1BQU0sQ0FBTixJQUFZLFVBYVg7QUFiRCxXQUFZLFVBQVU7SUFDcEIsNkNBQVMsQ0FBQTtJQUNULDJDQUFRLENBQUE7SUFDUix1RUFBc0IsQ0FBQTtJQUN0QixpRUFBbUIsQ0FBQTtJQUNuQiwyRUFBd0IsQ0FBQTtJQUN4QiwyREFBZ0IsQ0FBQTtJQUNoQixtRUFBb0IsQ0FBQTtJQUNwQixpREFBVyxDQUFBO0lBQ1gseURBQWUsQ0FBQTtJQUNmLDBEQUFnQixDQUFBO0lBQ2hCLGtEQUFZLENBQUE7SUFDWiw0REFBaUIsQ0FBQSxDQUFTLGFBQWE7QUFDekMsQ0FBQyxFQWJXLFVBQVUsS0FBVixVQUFVLFFBYXJCO0FBRUQsTUFBTSxPQUFPLFdBQVc7SUFDdEI7Ozs7OztPQU1HO0lBQ0gsTUFBTSxDQUFDLGNBQWMsQ0FBSSxLQUE2QixFQUFFLEdBQVcsRUFBRSxLQUFVO1FBQzdFLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDeEIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN6QixJQUFLLElBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxLQUFLLEVBQUUsQ0FBQztnQkFDakMsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sSUFBSSxD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RixJQUFJLENBQUMsUUFBUTtnQkFDWCxDQUFDLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUM7b0JBQ2pDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDO29CQUNqQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ1QsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOzs7O0tBSUM7SUFDRCxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQWEsRUFBRSxNQUFjLEVBQUU7UUFDN0MsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLElBQUksS0FBSyxHQUFhLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDVixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDO1lBQ2pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNiLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQztvQkFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNyQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNiLENBQUM7WUFDRCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7O1lBQU0sT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cFBhcmFtcyB9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5pbXBvcnQgeyBEYXRlSW50ZXJ2YWwgfSBmcm9tICcuL2RlZmluaXRpb25zJztcclxuaW1wb3J0IHsgZm9ybWF0LCBwYXJzZSwgcGFyc2VJU08sIHNldEhvdXJzIH0gZnJvbSAnZGF0ZS1mbnMnO1xyXG5pbXBvcnQgeyBpdCB9IGZyb20gJ2RhdGUtZm5zL2xvY2FsZSc7XHJcbmltcG9ydCB7IGZyb21ab25lZFRpbWUgfSBmcm9tICdkYXRlLWZucy10eic7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElOb2RlIHtcclxuICBpZDogc3RyaW5nO1xyXG4gIG5hbWU/OiBzdHJpbmcgfCBudWxsO1xyXG4gIGNvdW50PzogbnVtYmVyIHwgbnVsbDtcclxuICBjaGlsZHJlbj86IElOb2RlW10gfCBudWxsO1xyXG4gIHBhcmVudD86IElOb2RlIHwgbnVsbDtcclxuICBiYWc/OiBhbnkgfCBudWxsXHJcbn1cclxuXHJcblxyXG5leHBvcnQgZW51bSBEYXRlRm9ybWF0IHtcclxuICBTaG9ydCA9IDEsICAgICAgICAgICAgICAgIC8vIGRkL21tL3l5eXlcclxuICBMb25nID0gMiwgICAgICAgICAgICAgICAgIC8vIGQgbW1tbSB5eXl5XHJcbiAgTG9uZ1dpdGhTaG9ydE1vbnRoID0gMywgICAvLyBkIG1tbSB5eXl5XHJcbiAgTG9uZ1dpdGhXZWVrRGF5ID0gNCwgICAgICAvLyB3d3d3LCBkIG1tbW0geXl5eVxyXG4gIExvbmdXaXRoU2hvcnRXZWVrRGF5ID0gNSwgLy8gd3d3LCBkIG1tbW0geXl5eVxyXG4gIE1vbnRoQW5kWWVhciA9IDYsICAgICAgICAgLy8gbW1tIHl5eXlcclxuICBMb25nTW9udGhBbmRZZWFyID0gNywgICAgIC8vIG1tbW0geXl5eVxyXG4gIFdlZWtEYXkgPSA4LCAgICAgICAgICAgICAgLy8gd3d3IGRcclxuICBMb25nV2Vla0RheSA9IDksICAgICAgICAgIC8vIHd3d3cgZFxyXG4gIERheUFuZE1vbnRoID0gMTAsICAgICAgICAgLy8gZCBtbW1tXHJcbiAgU2hvcnRVUyA9IDExLCAgICAgICAgICAgICAvLyBtbS9kZC95eXl5XHJcbiAgU2hvcnRJU084NjAxID0gMTIgICAgICAgICAvLyB5eXl5LW1tLWRkXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBTeXN0ZW1VdGlscyB7XHJcbiAgLyoqXHJcbiAgICogQXJyYXkgZmluZCBieSBrZXlcclxuICAgKiBAcGFyYW0gYXJyYXkgICAgIDogdGhlIGFycmF5IHRvIHNjYW5cclxuICAgKiBAcGFyYW0ga2V5ICAgICAgIDoga2V5IG5hbWVcclxuICAgKiBAcGFyYW0gdmFsdWUgICAgIDogdGhlIHZhbHVlIHRvIHNlYXJjaCBmb3JcclxuICAgKiBAcmV0dXJucyAgICAgICAgIDogdGhlIHByb3BlcnR5IHZhbHVlIG9yIG51bGxcclxuICAgKi9cclxuICBzdGF0aWMgYXJyYXlGaW5kQnlLZXk8VD4oYXJyYXk6IFRbXSB8IG51bGwgfCB1bmRlZmluZWQsIGtleTogc3RyaW5nLCB2YWx1ZTogYW55KTogVCB8IG51bGwge1xyXG4gICAgaWYgKCFhcnJheSkgcmV0dXJuIG51bGw7XHJcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXJyYXkpIHtcclxuICAgICAgaWYgKChpdGVtIGFzIGFueSlba2V5XSA9PT0gdmFsdWUpIHtcclxuICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBcnJheSBmaW5kIGluZGV4IGJ5IGtleVxyXG4gICAqIEBwYXJhbSBhcnJheSAgIDogdGhlIGFycmF5IHRvIHNjYW5cclxuICAgKiBAcGFyYW0ga2V5ICAgICA6IHRoZSBrZXkgbmFtZVxyXG4gICAqIEBwYXJhbSB2YWx1ZSAgIDogdGhlIHZhbHVlIHRvIHNlYXJjaCBmb3JcclxuICAgKiBAcmV0dXJucyAgICAgICA6IHRoZSBhcnJheSBpbmRleCBvciAtMSBpZiBub3QgZm91bmRcclxuICAgKi9cclxuICBzdGF0aWMgYXJyYXlGaW5kSW5kZXhCeUtleTxUPihhcnJheTogVFtdIHwgbnVsbCB8IHVuZGVmaW5lZCwga2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBudW1iZXIge1xyXG4gICAgaWYgKCFhcnJheSkgcmV0dXJuIC0xO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xyXG4gICAgICBpZiAoKGFycmF5W2ldIGFzIGFueSlba2V5XSA9PT0gdmFsdWUpIHtcclxuICAgICAgICByZXR1cm4gaTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIC0xO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGEgdmFsdWUgZnJvbSBhbmQgYXJyYXkgbWFkZSBvZiBuYW1lfHZhbHVlIGl0ZW1zXHJcbiAgICogQHBhcmFtIGFycmF5ICAgOiB0aGUgYXJyYXkgdG8gc2NhblxyXG4gICAqIEBwYXJhbSB2YWx1ZSAgIDogdGhlIHZhbHVlIHRvIHNlYXJjaCBmb3JcclxuICAgKiBAcmV0dXJucyAgICAgICA6IHRoZSBwcm9wZXJ0eSB2YWx1ZSBvciBudWxsIGlmIG5vdCBmb3VuZFxyXG4gICAqL1xyXG4gIHN0YXRpYyBhcnJheUdldFZhbHVlPFQ+KGFycmF5OiBUW10gfCBudWxsIHwgdW5kZWZpbmVkLCB2YWx1ZTogYW55KTogYW55IHtcclxuICAgIGlmICghYXJyYXkpIHJldHVybiBudWxsO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBpdGVtID0gKGFycmF5W2ldIGFzIGFueSk7XHJcbiAgICAgIGlmIChpdGVtLnZhbHVlID09PSB2YWx1ZSkge1xyXG4gICAgICAgIHJldHVybiBpdGVtLm5hbWUgfHwgaXRlbS5pZDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb252ZXJ0IGl0ZW1zIHRvIG5vZGVzIGludG8gYSB0cmVlIHN0cnVjdHVyZVxyXG4gICAqIEBwYXJhbSBpdGVtcyAgIDogbGlzdCBvZiBub2Rlc1xyXG4gICAqIEBwYXJhbSBwYXJlbnQgIDogcGFyZW50IG5vZGVcclxuICAgKiBAcmV0dXJucyAgICAgICA6IGFuIGFycmF5IG9mIElOb2RlIG9iamVjdHNcclxuICAgKi9cclxuICBzdGF0aWMgYXJyYXlUb05vZGVzKGl0ZW1zOiBJTm9kZVtdLCBwYXJlbnQ6IElOb2RlID0gbnVsbCk6IElOb2RlW10ge1xyXG4gICAgY29uc3Qgbm9kZXM6IElOb2RlW10gPSBbXTtcclxuICAgIGl0ZW1zLmZvckVhY2goKG4pID0+IHtcclxuICAgICAgY29uc3Qgbm9kZTogSU5vZGUgPSB7XHJcbiAgICAgICAgaWQ6IG4uaWQudG9TdHJpbmcoKSxcclxuICAgICAgICBuYW1lOiBuLm5hbWUsXHJcbiAgICAgICAgY291bnQ6IG4uY291bnQgPyBuLmNvdW50IDogMCxcclxuICAgICAgICBjaGlsZHJlbjogbnVsbCxcclxuICAgICAgICBwYXJlbnQsXHJcbiAgICAgICAgYmFnOiBuLFxyXG4gICAgICB9O1xyXG4gICAgICBub2Rlcy5wdXNoKG5vZGUpO1xyXG4gICAgICBub2RlLmNoaWxkcmVuID1cclxuICAgICAgICBuLmNoaWxkcmVuICYmIG4uY2hpbGRyZW4ubGVuZ3RoID4gMFxyXG4gICAgICAgICAgPyB0aGlzLmFycmF5VG9Ob2RlcyhuLmNoaWxkcmVuLCBub2RlKVxyXG4gICAgICAgICAgOiBbXTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIG5vZGVzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXNlZCB0byBjb3BhcmUgaXRlbXMgZHVyaW5nIGFuIGFycmF5IG9mIG9iamVjdHMgc29ydGluZ1xyXG4gICAqIEBwYXJhbSBrZXkgICAgIDogdGhlIHByb3BlcnR5IG5hbWUgdG8gc29ydCBmb3JcclxuICAgKiBAcGFyYW0gb3JkZXIgICA6IHRoZSBvcmRlciAnYXNjJyBvciAnZGVzYydcclxuICAgKiBAcmV0dXJucyAgICAgICA6IDAgaWYgZXF1YWxzLCAxIGlmIGJpZ2dlciwgLTEgaWYgbG93ZXJcclxuICAgKi9cclxuICBzdGF0aWMgYXJyYXlTb3J0Q29tcGFyZShrZXk6IHN0cmluZywgb3JkZXI6IHN0cmluZyA9IFwiYXNjXCIpIHtcclxuICAgIGNvbnN0IHJlc3VsdCA9IGZ1bmN0aW9uIGlubmVyU29ydChhOiBhbnksIGI6IGFueSkge1xyXG4gICAgICBpZiAoIWEuaGFzT3duUHJvcGVydHkoa2V5KSB8fCAhYi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgLy8gcHJvcGVydHkgZG9lc24ndCBleGlzdCBvbiBlaXRoZXIgb2JqZWN0XHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgdmFyQSA9IHR5cGVvZiBhW2tleV0gPT09IFwic3RyaW5nXCIgPyBhW2tleV0udG9VcHBlckNhc2UoKSA6IGFba2V5XTtcclxuICAgICAgY29uc3QgdmFyQiA9IHR5cGVvZiBiW2tleV0gPT09IFwic3RyaW5nXCIgPyBiW2tleV0udG9VcHBlckNhc2UoKSA6IGJba2V5XTtcclxuICAgICAgbGV0IGNvbXBhcmlzb24gPSAwO1xyXG4gICAgICBpZiAodmFyQSA+IHZhckIpIGNvbXBhcmlzb24gPSAxO1xyXG4gICAgICBlbHNlIGlmICh2YXJBIDwgdmFyQikgY29tcGFyaXNvbiA9IC0xO1xyXG4gICAgICByZXR1cm4gb3JkZXIgPT09IFwiZGVzY1wiID8gY29tcGFyaXNvbiAqIC0xIDogY29tcGFyaXNvbjtcclxuICAgIH07XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRm9ybWF0IHdlaWdodFxyXG4gICAqIEBwYXJhbSBnciAgICA6IGdyYW1zXHJcbiAgICogQHJldHVybnMgICAgIDogdGhlIGZvcm1hdHRlZCBzdHJpbmdcclxuICAgKi9cclxuICBzdGF0aWMgZm9ybWF0V2VpZ2h0KGdyOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKGdyID4gMTAwMDAwMCkgcmV0dXJuIChnciAvIDEwMDAwMDApLnRvRml4ZWQoMikgKyBcIiB0XCI7XHJcbiAgICBlbHNlIGlmIChnciA+IDEwMDAwMCkgcmV0dXJuIChnciAvIDEwMDAwMCkudG9GaXhlZCgyKSArIFwiIHFcIjtcclxuICAgIGVsc2UgaWYgKGdyID4gMTAwMCkgcmV0dXJuIChnciAvIDEwMDApLnRvRml4ZWQoMikgKyBcIiBrZ1wiO1xyXG4gICAgZWxzZSByZXR1cm4gZ3IgKyBcIiBnclwiO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRm9ybWF0IGZpbGUgc2l6ZVxyXG4gICAqIEBwYXJhbSBieXRlcyA6IG51bWJlciBvZiBieXRlc1xyXG4gICAqIEByZXR1cm5zICAgICA6IHRoZSBmb3JtYXR0ZWQgc3RyaW5nXHJcbiAgICovXHJcbiAgc3RhdGljIGZvcm1hdEZpbGVTaXplKGJ5dGVzOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKGJ5dGVzID4gMTAyNDAwMCkgcmV0dXJuIChieXRlcyAvIDEwMjQwMDApLnRvRml4ZWQoMSkgKyBcIiBNQlwiO1xyXG4gICAgaWYgKGJ5dGVzID4gMTAyNCkgcmV0dXJuIChieXRlcyAvIDEwMjQpLnRvRml4ZWQoMSkgKyBcIiBLYlwiO1xyXG4gICAgcmV0dXJuIGJ5dGVzICsgXCIgYnl0ZVwiO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29tcGFyZSB0d28gc3RyaW5nXHJcbiAgICogQHBhcmFtIGEgICA6IHN0cmluZyBhXHJcbiAgICogQHBhcmFtIGIgICA6IHN0cmluZyBiXHJcbiAgICogQHJldHVybnMgICA6IDAgaWYgZXF1YWxzLCAxIGlmIGJpZ2dlciwgLTEgaWYgbG93ZXJcclxuICAgKi9cclxuICBzdGF0aWMgY29tcGFyZVN0cmluZyhhOiBzdHJpbmcsIGI6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICBpZiAoKGEgPz8gXCJcIikudG9Mb3dlckNhc2UoKSA+IChiID8/IFwiXCIpLnRvTG93ZXJDYXNlKCkpIHJldHVybiAxO1xyXG4gICAgaWYgKChhID8/IFwiXCIpLnRvTG93ZXJDYXNlKCkgPCAoYiA/PyBcIlwiKS50b0xvd2VyQ2FzZSgpKSByZXR1cm4gLTE7XHJcbiAgICByZXR1cm4gMDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhcGl0YWxpemUgYSBzdHJpbmdcclxuICAgKiBAcGFyYW0gcyAgIDogdGhlIHN0cmluZyB0byBjYXBpdGFsaXplXHJcbiAgICogQHJldHVybnMgICA6IHRoZSBjYXBpdGFsaXplZCBzdHJpbmcgIFxyXG4gICAqL1xyXG4gIHN0YXRpYyBjYXBpdGFsaXplKHM6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBpZiAoIXMpIHJldHVybiBudWxsO1xyXG4gICAgbGV0IGIgPSBcIlwiO1xyXG4gICAgbGV0IGNhcCA9IHRydWU7XHJcbiAgICBmb3IgKGNvbnN0IGNoYXIgb2Ygcykge1xyXG4gICAgICBpZiAoY2hhciA9PT0gXCIgXCIpIHtcclxuICAgICAgICBiICs9IGNoYXI7XHJcbiAgICAgICAgY2FwID0gdHJ1ZTtcclxuICAgICAgfSBlbHNlIGlmIChjYXApIHtcclxuICAgICAgICBiICs9IGNoYXIudG9VcHBlckNhc2UoKTtcclxuICAgICAgICBjYXAgPSBmYWxzZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBiICs9IGNoYXIudG9Mb3dlckNhc2UoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGI7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUcnVuY2F0ZSBhIHN0cmluZ1xyXG4gICAqIEBwYXJhbSBzICAgICA6IHRoZSBzdHJpbmcgdG8gdHJ1bmNhdGVcclxuICAgKiBAcGFyYW0gbWF4ICAgOiB0aGUgbWF4IG51bWJlciBvZiBjaGFyc1xyXG4gICAqIEByZXR1cm5zICAgICA6IHRoZSB0cnVuY2F0ZWQgc3RyaW5nXHJcbiAgICovXHJcbiAgc3RhdGljIHRydW5jYXRlKHM6IHN0cmluZywgbWF4OiBudW1iZXIgPSA1MDApOiBzdHJpbmcge1xyXG4gICAgaWYgKCFzKSByZXR1cm4gbnVsbDtcclxuICAgIGlmIChzLmxlbmd0aCA8IG1heCkgcmV0dXJuIHM7XHJcbiAgICBsZXQgaSA9IG1heCAtIDE7XHJcbiAgICB3aGlsZSAoaSA+IDApIHtcclxuICAgICAgaWYgKHNbaV0gPT09ICcgJykgcmV0dXJuIHMuc2xpY2UoMCwgaSk7XHJcbiAgICAgIGktLTtcclxuICAgIH1cclxuICAgIHJldHVybiBzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSm9pbiBhIGxpc3Qgb2Ygc3RyaW5nc1xyXG4gICAqIEBwYXJhbSBpdGVtcyAgICAgOiB0aGUgbGlzdCBvZiBzdHJpbmdzXHJcbiAgICogQHBhcmFtIHNlcCAgICAgICA6IHRoZSBzZXBhcmF0b3Igc3RyaW5nXHJcbiAgICogQHBhcmFtIG1heCAgICAgICA6IHRoZSBtYXhpbXVtIHJlc3VsdGluZyBzdHJpbmdcclxuICAgKiBAcmV0dXJucyAgICAgICAgIDogdGhlIGpvaW5lZCBzdHJpbmdcclxuICAgKi9cclxuICBzdGF0aWMgam9pbihpdGVtczogc3RyaW5nW10sIHNlcDogc3RyaW5nID0gXCIgXCIsIG1heDogbnVtYmVyID0gMzUwKTogc3RyaW5nIHtcclxuICAgIGlmICghaXRlbXMgfHwgaXRlbXMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgIGlmIChpdGVtcy5sZW5ndGggPiAxKSB7XHJcbiAgICAgIGxldCBsID0gMDtcclxuICAgICAgbGV0IHMgPSBcIlwiXHJcbiAgICAgIHdoaWxlIChzLmxlbmd0aCA8IG1heCAmJiBpdGVtcy5sZW5ndGggPiBsKSB7XHJcbiAgICAgICAgaWYgKGwgPiAwKSB7XHJcbiAgICAgICAgICBzICs9IHNlcDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcyArPSBpdGVtc1tsKytdO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChpdGVtcy5sZW5ndGggPiBsKSB7XHJcbiAgICAgICAgcyArPSBcIi4uLlwiO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBzO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGl0ZW1zWzBdO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVwbGFjZSBzdHVmZiBpbiB0ZXh0IGh0bWxcclxuICAgKiBAcGFyYW0gcyAgIDogdGhlIHN0cmluZyB0byBwcm9jZXNzXHJcbiAgICogQHJldHVybnMgICA6IHRoZSByZXBsYWNlZCBzdHJpbmcgIFxyXG4gICAqL1xyXG4gIHN0YXRpYyByZXBsYWNlQXNIdG1sKHM6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCByZWdleCA9IC9odHRwcz86XFwvXFwvLipbXlxcc10vaWdcclxuICAgIGNvbnN0IG0gPSByZWdleC5leGVjKHMpO1xyXG4gICAgaWYgKG0gJiYgbS5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGxldCB2ID0gbnVsbDtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgdiA9IG1baV07XHJcbiAgICAgICAgcyA9IHMucmVwbGFjZSh2LCAnPGEgaHJlZj1cIicgKyB2ICsgJ1wiIHRhcmdldD1cIl9ibGFua1wiPicgKyB2ICsgJzwvYT4nKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb21wYXJlIHR3byBuYW1lc1xyXG4gICAqIEBwYXJhbSBhICAgOiBuYW1lIGFcclxuICAgKiBAcGFyYW0gYiAgIDogbmFtZSBiXHJcbiAgICogQHJldHVybnMgICA6IHRydWUgaWYgYSBlcXVhbHMgYlxyXG4gICAqL1xyXG4gIHN0YXRpYyBjb21wYXJlTmFtZXMoYTogc3RyaW5nLCBiOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIGlmIChhKSBhID0gYS50cmltKCk7XHJcbiAgICBpZiAoYikgYiA9IGIudHJpbSgpO1xyXG4gICAgaWYgKGEgJiYgYiAmJiBhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcclxuICAgIGlmICh0aGlzLmNvbXBhcmVTdHJpbmcoYSwgYikgPT09IDApIHJldHVybiB0cnVlO1xyXG4gICAgY29uc3QgcDEgPSBhLnNwbGl0KFwiIFwiKTtcclxuICAgIGNvbnN0IHAyID0gYi5zcGxpdChcIiBcIik7XHJcbiAgICBpZiAocDEubGVuZ3RoICE9PSBwMi5sZW5ndGgpIHJldHVybiBmYWxzZTtcclxuICAgIGxldCBtYXRjaGVzID0gcDEubGVuZ3RoO1xyXG4gICAgZm9yIChjb25zdCBzMSBvZiBwMSkge1xyXG4gICAgICBmb3IgKGNvbnN0IHMyIG9mIHAyKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY29tcGFyZVN0cmluZyhzMSwgczIpID09PSAwKSB7XHJcbiAgICAgICAgICBtYXRjaGVzLS07XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbWF0Y2hlcyA9PT0gMDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENpcGhlciBhIHRleHRcclxuICAgKiBAcGFyYW0gdGV4dCAgICA6IHRoZSB0ZXh0XHJcbiAgICogQHBhcmFtIGtleSAgICAgOiB0aGUga2V5XHJcbiAgICogQHBhcmFtIHJldmVyc2UgOiB0cnVlIHRvIGRlY29kZSwgZmFsc2UgdG8gZW5jb2RlXHJcbiAgICogQHJldHVybnMgICAgICAgOnRoZSBjaXBoZXJlZCB0ZXh0XHJcbiAgICovXHJcbiAgc3RhdGljIGNpcGhlcih0ZXh0OiBzdHJpbmcsIGtleTogc3RyaW5nLCByZXZlcnNlOiBib29sZWFuID0gZmFsc2UpOiBzdHJpbmcge1xyXG4gICAgLy8gU3Vycm9nYXRlIHBhaXIgbGltaXRcclxuICAgIHZhciBib3VuZCA9IDB4MTAwMDA7XHJcblxyXG4gICAgLy8gQ3JlYXRlIHN0cmluZyBmcm9tIGNoYXJhY3RlciBjb2Rlc1xyXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXHJcbiAgICAgIG51bGwsXHJcbiAgICAgIC8vIFR1cm4gc3RyaW5nIHRvIGNoYXJhY3RlciBjb2Rlc1xyXG4gICAgICB0ZXh0LnNwbGl0KFwiXCIpLm1hcChmdW5jdGlvbiAodjogYW55LCBpOiBudW1iZXIpIHtcclxuICAgICAgICAvLyBHZXQgcm90YXRpb24gZnJvbSBrZXlcclxuICAgICAgICB2YXIgcm90YXRpb24gPSBrZXkuY2hhckNvZGVBdChpICUga2V5Lmxlbmd0aCk7XHJcblxyXG4gICAgICAgIC8vIEFyZSB3ZSBkZWNyeXB0aW5nP1xyXG4gICAgICAgIGlmIChyZXZlcnNlKSByb3RhdGlvbiA9IC1yb3RhdGlvbjtcclxuXHJcbiAgICAgICAgLy8gUmV0dXJuIGN1cnJlbnQgY2hhcmFjdGVyIGNvZGUgKyByb3RhdGlvblxyXG4gICAgICAgIHJldHVybiAodi5jaGFyQ29kZUF0KCkgKyByb3RhdGlvbiArIGJvdW5kKSAlIGJvdW5kO1xyXG4gICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENsb25lIGFuIG9iamVjdCB1c2luZyBKU09OXHJcbiAgICogQHBhcmFtIG9iaiA6IHRoZSBvYmxlY3QgdG8gY2xvbmVcclxuICAgKiBAcmV0dXJucyAgIDogYSBuZXcgb2JqZWN0XHJcbiAgICovXHJcbiAgc3RhdGljIGNsb25lKG9iajogYW55KTogYW55IHtcclxuICAgIGlmICghb2JqKSByZXR1cm4gbnVsbDtcclxuICAgIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xvbmUgYW4gb2JqZWN0IHVzaW5nIGRlZXAgY2xvbmluZ1xyXG4gICAqIEBwYXJhbSBvYmogICA6IHRoZSBvYmxlY3QgdG8gY2xvbmVcclxuICAgKiBAcmV0dXJucyAgICAgOiBhIG5ldyBvYmplY3RcclxuICAgKi9cclxuICBzdGF0aWMgZGVlcENsb25lPFQ+KG9iajogYW55LCBkZXN0OiBUID0gbnVsbCk6IFQge1xyXG4gICAgY29uc3QgY2xvbmVPYmogPSBkZXN0ID8gZGVzdCA6IChvYmouY29uc3RydWN0b3IoKSBhcyBhbnkpO1xyXG4gICAgY29uc3QgYXR0cmlidXRlcyA9IE9iamVjdC5rZXlzKG9iaik7XHJcbiAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZSBvZiBhdHRyaWJ1dGVzKSB7XHJcbiAgICAgIGNvbnN0IHByb3BlcnR5ID0gb2JqW2F0dHJpYnV0ZV07XHJcbiAgICAgIGlmICh0eXBlb2YgcHJvcGVydHkgPT09IFwib2JqZWN0XCIgJiYgcHJvcGVydHkgIT0gbnVsbCkge1xyXG4gICAgICAgIGNsb25lT2JqW2F0dHJpYnV0ZV0gPSB0aGlzLmRlZXBDbG9uZShwcm9wZXJ0eSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY2xvbmVPYmpbYXR0cmlidXRlXSA9IHByb3BlcnR5O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY2xvbmVPYmo7XHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBVVUlEXHJcbiAgICogQHBhcmFtIHZhbHVlICAgOiB0aGUgdmFsdWUgdG8gcGFyc2VcclxuICAgKiBAcmV0dXJucyAgICAgICA6IHRydWUgaWYgaXMgYSB2YWxpZCBVVUlEXHJcbiAgICovXHJcbiAgc3RhdGljIHBhcnNlVVVJRCh2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCByZWdleCA9IC9eKHt8KCk/WzAtOWEtZkEtRl17OH0tKFswLTlhLWZBLUZdezR9LSl7M31bMC05YS1mQS1GXXsxMn0ofXwpKT8kLztcclxuICAgIHJldHVybiByZWdleC50ZXN0KHZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhcnNlIGFuZCBlbnN1cmUgdGhhdCBVVUlEIGlzIG5vdCBlbXB0eVxyXG4gICAqIEBwYXJhbSB2YWx1ZSAgIDogdGhlIHZhbHVlIHRvIHBhcnNlXHJcbiAgICogQHJldHVybnMgICAgICAgOiB0cnVlIGlmIHZhbGlkIGFuZCBub3QgZW1wdHlcclxuICAgKi9cclxuICBzdGF0aWMgcGFyc2VVVUlETm90RW1wdHkodmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgcmVnZXggPSAvXih7fCgpPzB7OH0tKDB7NH0tKXszfTB7MTJ9KH18KSk/JC87XHJcbiAgICByZXR1cm4gdGhpcy5wYXJzZVVVSUQodmFsdWUpICYmICFyZWdleC50ZXN0KHZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiBhbiBlbXB0eSBVVUlEXHJcbiAgICogQHJldHVybnMgOiB0aGUgZW1wdHkgVVVJRFxyXG4gICAqL1xyXG4gIHN0YXRpYyBlbXB0eVVVSUQoKTogc3RyaW5nIHsgcmV0dXJuIFwiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlIGEgbmV3IFVVSURcclxuICAgKiBAcmV0dXJucyA6IHRoZSBzdHJpbmcgVVVJRFxyXG4gICAqL1xyXG4gIHN0YXRpYyBnZW5lcmF0ZVVVSUQoKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHJlZ2V4ID0gL1t4eV0vZztcclxuICAgIHJldHVybiBcInh4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eFwiLnJlcGxhY2UocmVnZXgsIGZ1bmN0aW9uIChjKSB7XHJcbiAgICAgIHZhciByID0gKE1hdGgucmFuZG9tKCkgKiAxNikgfCAwLFxyXG4gICAgICAgIHYgPSBjID09PSBcInhcIiA/IHIgOiAociAmIDB4MykgfCAweDg7XHJcbiAgICAgIHJldHVybiB2LnRvU3RyaW5nKDE2KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUGFyc2UgYSB0ZXh0IGFuZCByZXR1cm4gdHJ1ZSBpZiBpcyBhIHZhbGlkIGVtYWlsIG9yIG51bGxcclxuICAgKiBAcGFyYW0gdmFsdWUgOiBlbWFpbFxyXG4gICAqIEByZXR1cm5zICAgICA6IHRydWUgaWYgdGhlIGVtYWlsIGlzIHZhbGlkIG9yIGVtcHR5XHJcbiAgICovXHJcbiAgc3RhdGljIHBhcnNlRW1haWwodmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKCF2YWx1ZSkgcmV0dXJuIHRydWU7XHJcbiAgICBjb25zdCByZWdleCA9IC8oPzpbYS16MC05KyEjJCUmJyorXFwvPT9eX2B7fH1+LV0rKD86XFwuW2EtejAtOSEjJCUmJyorXFwvPT9eX2B7fH1+LV0rKSp8XCIoPzpbXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHgyMVxceDIzLVxceDViXFx4NWQtXFx4N2ZdfFxcXFxbXFx4MDEtXFx4MDlcXHgwYlxceDBjXFx4MGUtXFx4N2ZdKSpcIilAKD86KD86W2EtejAtOV0oPzpbYS16MC05LV0qW2EtejAtOV0pP1xcLikrW2EtejAtOV0oPzpbYS16MC05LV0qW2EtejAtOV0pP3xcXFsoPzooPzoyNVswLTVdfDJbMC00XVswLTldfFswMV0/WzAtOV1bMC05XT8pXFwuKXszfSg/OjI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldP3xbYS16MC05LV0qW2EtejAtOV06KD86W1xceDAxLVxceDA4XFx4MGJcXHgwY1xceDBlLVxceDFmXFx4MjEtXFx4NWFcXHg1My1cXHg3Zl18XFxcXFtcXHgwMS1cXHgwOVxceDBiXFx4MGNcXHgwZS1cXHg3Zl0pKylcXF0pL2dpXHJcbiAgICByZXR1cm4gcmVnZXgudGVzdCh2YWx1ZS50cmltKCkudG9Mb3dlckNhc2UoKSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQYXJzZSBhIHRleHQgYW5kIHJldHVybiB0cnVlIGlmIGlzIGEgdmFsaWQgdXJsIG9yIG51bGxcclxuICAgKiBAcGFyYW0gdmFsdWUgOiB0aGUgdXJsIHRvIHBhcnNlXHJcbiAgICogQHJldHVybnMgICAgIDogdHJ1ZSBpZiB0aGUgdXJsIGlzIHZhbGlkIG9yIGVtcHR5XHJcbiAgICovXHJcbiAgc3RhdGljIHBhcnNlVXJsKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIGlmICghdmFsdWUpIHJldHVybiB0cnVlO1xyXG4gICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKFxyXG4gICAgICBcIihodHRwcz86Ly8pPyhbXFxcXGRhLXouLV0rKVxcXFwuKFthLXouXXsyLDZ9KVsvXFxcXHcgLi1dKi8/XCJcclxuICAgICk7XHJcbiAgICByZXR1cm4gcmVnZXgudGVzdCh2YWx1ZS50cmltKCkudG9Mb3dlckNhc2UoKSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgZGF0ZSBwYXJ0cyBmcm9tIGEgc3RyaW5nIHZhbHVlXHJcbiAgICogQHBhcmFtIHZhbHVlICAgOiB0aGUgc3RyaW5nIHRvIHBhcnNlXHJcbiAgICogQHJldHVybnMgICAgICAgOiBhbiBhcnJheSBvZiBudW1iZXJzIHdpdGggeWVhciwgbW9udGgsIGRheVxyXG4gICAqL1xyXG4gIHN0YXRpYyBnZXREYXRlUGFydHModmFsdWU6IHN0cmluZyk6IG51bWJlcltdIHtcclxuICAgIGlmICghdmFsdWUpIHJldHVybiBudWxsO1xyXG4gICAgbGV0IHBhcnRzOiBudW1iZXJbXSA9IFtdO1xyXG4gICAgaWYgKHZhbHVlLmluZGV4T2YoXCItXCIpICE9PSAtMSkge1xyXG4gICAgICBjb25zdCBwID0gdmFsdWUuc3BsaXQoXCItXCIpO1xyXG4gICAgICBpZiAocC5sZW5ndGggIT09IDMpIHJldHVybiBudWxsO1xyXG4gICAgICBwYXJ0cyA9IFtwYXJzZUludChwWzBdKSwgcGFyc2VJbnQocFsxXSkgLSAxLCBwYXJzZUludChwWzJdKV07XHJcbiAgICB9IGVsc2UgaWYgKHZhbHVlLmluZGV4T2YoXCIvXCIpICE9PSAtMSkge1xyXG4gICAgICBjb25zdCBwID0gdmFsdWUuc3BsaXQoXCIvXCIpO1xyXG4gICAgICBpZiAocC5sZW5ndGggIT09IDMpIHJldHVybiBudWxsO1xyXG4gICAgICBwYXJ0cyA9IFtwYXJzZUludChwWzJdKSwgcGFyc2VJbnQocFsxXSkgLSAxLCBwYXJzZUludChwWzBdKV07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGFydHM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQYXJzZSBhIGRhdGVcclxuICAgKiBAcGFyYW0gdmFsdWUgICA6IHRoZSB2YWx1ZSB0byBjaGVja1xyXG4gICAqIEBwYXJhbSBsb2NhbGUgIDogdGhlIGxvY2FsZSB0byB1c2VcclxuICAgKiBAcmV0dXJucyAgICAgICA6IGEgdmFsaWQgRGF0ZSBvYmplY3Qgb3IgbnVsbFxyXG4gICAqL1xyXG4gIHN0YXRpYyBwYXJzZURhdGUodmFsdWU6IHN0cmluZyB8IERhdGUsIGxvY2FsZTogYW55ID0gaXQpOiBEYXRlIHtcclxuICAgIC8vIE5vIHZhbHVlIGF0IGFsbFxyXG4gICAgaWYgKCF2YWx1ZSkgcmV0dXJuIG51bGw7XHJcbiAgICAvLyBBIERhdGUgdmFsdWVcclxuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUgJiYgdmFsdWUuZ2V0VGltZSgpKSByZXR1cm4gdmFsdWU7XHJcbiAgICAvLyBQYXJzZSBrbm93biBmb3JtYXRzIHVzaW5nIGRhdGUtZm5zXHJcbiAgICBsZXQgZCA9IHBhcnNlSVNPKHZhbHVlIGFzIHN0cmluZyk7XHJcbiAgICBpZiAoZCAmJiBkLmdldFRpbWUoKSAmJiBkLmdldEZ1bGxZZWFyKCkgPiAxNzUwKSByZXR1cm4gZDtcclxuICAgIGQgPSBwYXJzZSh2YWx1ZSBhcyBzdHJpbmcsICdkZC9NTS95eXl5JywgbmV3IERhdGUoKSwgeyBsb2NhbGU6IGxvY2FsZSB9KTtcclxuICAgIGlmIChkICYmIGQuZ2V0VGltZSgpICYmIGQuZ2V0RnVsbFllYXIoKSA+IDE3NTApIHJldHVybiBkO1xyXG4gICAgZCA9IHBhcnNlKHZhbHVlIGFzIHN0cmluZywgJ3l5eXktTU0tZGQnLCBuZXcgRGF0ZSgpLCB7IGxvY2FsZTogbG9jYWxlIH0pO1xyXG4gICAgaWYgKGQgJiYgZC5nZXRUaW1lKCkgJiYgZC5nZXRGdWxsWWVhcigpID4gMTc1MCkgcmV0dXJuIGQ7XHJcbiAgICAvLyBQYXJzZSB2YWx1ZXMgbWFudWFsbHlcclxuICAgIGxldCBwYXJ0cyA9IHRoaXMuZ2V0RGF0ZVBhcnRzKHZhbHVlIGFzIHN0cmluZyk7XHJcbiAgICBpZiAocGFydHNbMF0gPCAxMDApIHBhcnRzWzBdICs9IDIwMDA7XHJcbiAgICBpZiAoaXNOYU4ocGFydHNbMF0pIHx8IHBhcnRzWzBdIDwgMCB8fCBwYXJ0c1swXSA8IDE3NTApIHJldHVybiBudWxsO1xyXG4gICAgaWYgKGlzTmFOKHBhcnRzWzFdKSB8fCBwYXJ0c1sxXSA8IDApIHJldHVybiBudWxsO1xyXG4gICAgaWYgKGlzTmFOKHBhcnRzWzJdKSB8fCBwYXJ0c1syXSA8IDApIHJldHVybiBudWxsO1xyXG4gICAgaWYgKHBhcnRzWzFdID4gMTEpIHJldHVybiBudWxsO1xyXG4gICAgaWYgKHBhcnRzWzFdID09PSAxICYmIHBhcnRzWzJdID4gMjkpIHJldHVybiBudWxsO1xyXG4gICAgZWxzZSBpZiAocGFydHNbMV0gIT09IDEgJiYgcGFydHNbMl0gPiAzMSkgcmV0dXJuIG51bGw7XHJcbiAgICByZXR1cm4gbmV3IERhdGUocGFydHNbMF0sIHBhcnRzWzFdLCBwYXJ0c1syXSwgMik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGb3JtYXQgYSBkYXRlXHJcbiAgICogQHBhcmFtIHZhbHVlICAgICA6IHRoZSBkYXRlIG9yIHN0cmluZyB0byBmb3JtYXRcclxuICAgKiBAcGFyYW0gZm10ICAgICAgIDogdGhlIERhdGVGb3JtYXQgdG8gdXNlIG9yIHRoZSBzdHJpbmcgcGF0dGVyblxyXG4gICAqIEBwYXJhbSBsb2NhbGUgICAgOiB0aGUgbG9jYWxlIHRvIHVzZSAoZGVmYXVsdCBpcyBJVClcclxuICAgKiBAcmV0dXJucyAgICAgICAgIDogdGhlIGZvcm1hdHRlZCBzdHJpbmdcclxuICAgKi9cclxuICBzdGF0aWMgZm9ybWF0RGF0ZShcclxuICAgIHZhbHVlOiBEYXRlIHwgc3RyaW5nLFxyXG4gICAgZm10OiBEYXRlRm9ybWF0IHwgc3RyaW5nID0gRGF0ZUZvcm1hdC5TaG9ydCxcclxuICAgIGxvY2FsZTogYW55ID0gaXQpOiBzdHJpbmcge1xyXG4gICAgLy8gTm8gdmFsdWUgYXQgYWxsXHJcbiAgICBpZiAoIXZhbHVlKSByZXR1cm4gbnVsbDtcclxuICAgIC8vIEEgc3RyaW5nXHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fCB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZylcclxuICAgICAgdmFsdWUgPSB0aGlzLnBhcnNlRGF0ZSh2YWx1ZSBhcyBzdHJpbmcpO1xyXG4gICAgLy8gTm90IGEgZGF0ZSBcclxuICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSAmJiB2YWx1ZS5nZXRUaW1lKCkpKVxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIC8vIEZvcm1hdFxyXG4gICAgc3dpdGNoIChmbXQpIHtcclxuICAgICAgY2FzZSBEYXRlRm9ybWF0LlNob3J0OiByZXR1cm4gZm9ybWF0KHZhbHVlLCBcImRkL01NL3l5eXlcIiwgeyBsb2NhbGU6IGxvY2FsZSB9KTtcclxuICAgICAgY2FzZSBEYXRlRm9ybWF0Lkxvbmc6IHJldHVybiBmb3JtYXQodmFsdWUsIFwiZCBNTU1NIHl5eXlcIiwgeyBsb2NhbGU6IGxvY2FsZSB9KTtcclxuICAgICAgY2FzZSBEYXRlRm9ybWF0LkxvbmdXaXRoU2hvcnRNb250aDogcmV0dXJuIGZvcm1hdCh2YWx1ZSwgXCJkIE1NTSB5eXl5XCIsIHsgbG9jYWxlOiBsb2NhbGUgfSk7XHJcbiAgICAgIGNhc2UgRGF0ZUZvcm1hdC5Mb25nV2l0aFdlZWtEYXk6IHJldHVybiBmb3JtYXQodmFsdWUsIFwiRUVFRSwgZCBNTU1NIHl5eXlcIiwgeyBsb2NhbGU6IGxvY2FsZSB9KTtcclxuICAgICAgY2FzZSBEYXRlRm9ybWF0LkxvbmdXaXRoU2hvcnRXZWVrRGF5OiByZXR1cm4gZm9ybWF0KHZhbHVlLCBcIkVFRSwgZCBNTU1NIHl5eXlcIiwgeyBsb2NhbGU6IGxvY2FsZSB9KTtcclxuICAgICAgY2FzZSBEYXRlRm9ybWF0Lk1vbnRoQW5kWWVhcjogcmV0dXJuIGZvcm1hdCh2YWx1ZSwgXCJNTU0geXl5eVwiLCB7IGxvY2FsZTogbG9jYWxlIH0pO1xyXG4gICAgICBjYXNlIERhdGVGb3JtYXQuTG9uZ01vbnRoQW5kWWVhcjogcmV0dXJuIGZvcm1hdCh2YWx1ZSwgXCJNTU1NIHl5eXlcIiwgeyBsb2NhbGU6IGxvY2FsZSB9KTtcclxuICAgICAgY2FzZSBEYXRlRm9ybWF0LldlZWtEYXk6IHJldHVybiBmb3JtYXQodmFsdWUsIFwiRUVFLCBkXCIsIHsgbG9jYWxlOiBsb2NhbGUgfSk7XHJcbiAgICAgIGNhc2UgRGF0ZUZvcm1hdC5Mb25nV2Vla0RheTogcmV0dXJuIGZvcm1hdCh2YWx1ZSwgXCJFRUVFLCBkXCIsIHsgbG9jYWxlOiBsb2NhbGUgfSk7XHJcbiAgICAgIGNhc2UgRGF0ZUZvcm1hdC5EYXlBbmRNb250aDogcmV0dXJuIGZvcm1hdCh2YWx1ZSwgXCJkIE1NTU1cIiwgeyBsb2NhbGU6IGxvY2FsZSB9KTtcclxuICAgICAgY2FzZSBEYXRlRm9ybWF0LlNob3J0VVM6IHJldHVybiBmb3JtYXQodmFsdWUsIFwiTU0vZGQveXl5eVwiLCB7IGxvY2FsZTogbG9jYWxlIH0pO1xyXG4gICAgICBjYXNlIERhdGVGb3JtYXQuU2hvcnRJU084NjAxOiByZXR1cm4gZm9ybWF0KHZhbHVlLCBcInl5eXktTU0tZGRcIiwgeyBsb2NhbGU6IGxvY2FsZSB9KTtcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICByZXR1cm4gZm9ybWF0KHZhbHVlLCBmbXQsIHsgbG9jYWxlOiBsb2NhbGUgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gYW4gaXRhbGlhbiBsb2NhbCBkYXRlXHJcbiAgICogQHBhcmFtIHZhbHVlICA6IHRoZSBkYXRlXHJcbiAgICogQHJldHVybnMgICAgIDogdGhlIG5ldyBkYXRlXHJcbiAgICovXHJcbiAgc3RhdGljIHRvTG9jYWxEYXRlKHZhbHVlOiBEYXRlIHwgc3RyaW5nKTogRGF0ZSB7XHJcbiAgICAvLyBObyB2YWx1ZSBhdCBhbGxcclxuICAgIGlmICghdmFsdWUpIHJldHVybiBudWxsO1xyXG4gICAgLy8gQSBzdHJpbmdcclxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKVxyXG4gICAgICB2YWx1ZSA9IHRoaXMucGFyc2VEYXRlKHZhbHVlIGFzIHN0cmluZyk7XHJcbiAgICAvLyBOb3QgYSBkYXRlXHJcbiAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIERhdGUgJiYgdmFsdWUuZ2V0VGltZSgpKSkgcmV0dXJuIG51bGw7XHJcbiAgICAvLyBVcGRhdGUgZGF0ZVxyXG4gICAgcmV0dXJuIHNldEhvdXJzKHZhbHVlLCAyKTtcclxuXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGUgYSBEYXRlSW50ZXJ2YWwgb2JqZWN0IGFjY29yZGluZyB0byBhIHN0cmluZ1xyXG4gICAqIEBwYXJhbSB2YWx1ZSAgICAgICA6IHN0cmluZyB2YWx1ZVxyXG4gICAqIEBwYXJhbSBpbnRlcnZhbCAgICA6IERhdGVJbnRlcnZhbCB2YWx1ZSB0byB1cGRhdGVcclxuICAgKiBAcGFyYW0gZW5kICAgICAgICAgOiB0cnVlIGlmIG11c3QgYmUgdXBkYXRlZCB0aGUgZmlyc3Qgb3IgdGhlIGVuZCB2YWx1ZSBcclxuICAgKiBAcGFyYW0gY29weSAgICAgICAgOiBjb3B5IHRoZSBzYW1lIHZhbHVlICh3b3JrcyBvbmx5IGlmIG5vdCBlbmQgZWxlbWVudClcclxuICAgKi9cclxuICBzdGF0aWMgY2hhbmdlRGF0ZUludGVydmFsKHZhbHVlOiBzdHJpbmcsIGludGVydmFsOiBEYXRlSW50ZXJ2YWwsIGVuZDogYm9vbGVhbiA9IGZhbHNlLCBjb3B5OiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICBsZXQgeWVhciA9IC0xO1xyXG4gICAgICBpZiAodmFsdWUubGVuZ3RoID09PSA0ICYmICh5ZWFyID0gcGFyc2VJbnQodmFsdWUpKSA+IDE3NTApIHtcclxuICAgICAgICBpZiAoIWVuZCkge1xyXG4gICAgICAgICAgaW50ZXJ2YWwuZnJvbSA9IGZyb21ab25lZFRpbWUobmV3IERhdGUoeWVhciwgMCwgMSksICdVVEMnKTtcclxuICAgICAgICAgIGludGVydmFsLnRvID0gZnJvbVpvbmVkVGltZShuZXcgRGF0ZSh5ZWFyLCAxMSwgMzEpLCAnVVRDJyk7XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICBpbnRlcnZhbC50byA9IG5ldyBEYXRlKHllYXIsIDExLCAzMSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbGV0IHBhcnRzID0gdGhpcy5nZXREYXRlUGFydHModmFsdWUpO1xyXG4gICAgICAgIGlmICghcGFydHMgfHwgaXNOYU4ocGFydHNbMF0pIHx8IHBhcnRzWzBdIDwgMCB8fCBwYXJ0c1swXSA8IDE3NTApIHJldHVybjtcclxuICAgICAgICBjb25zdCBkID0gZnJvbVpvbmVkVGltZShuZXcgRGF0ZShwYXJ0c1swXSwgcGFydHNbMV0sIHBhcnRzWzJdKSwgJ1VUQycpO1xyXG4gICAgICAgIGlmIChlbmQpXHJcbiAgICAgICAgICBpbnRlcnZhbC50byA9IGQ7XHJcbiAgICAgICAgZWxzZSBpZiAoY29weSkge1xyXG4gICAgICAgICAgaW50ZXJ2YWwuZnJvbSA9IGQ7XHJcbiAgICAgICAgICBpbnRlcnZhbC50byA9IGQ7XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICBpbnRlcnZhbC5mcm9tID0gZDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRW5jb2RlIHVybFxyXG4gICAqIEBwYXJhbSB2YWx1ZSA6IHRoZSB2YWx1ZSB0byBlbmNvZGVcclxuICAgKiBAcmV0dXJucyAgICAgOiB0aGUgdXJsIGVuY29kZWQgc3RyaW5nXHJcbiAgICovXHJcbiAgc3RhdGljIHVybEVuY29kZSh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVjb2RlIHVybFxyXG4gICAqIEBwYXJhbSB2YWx1ZSA6IHRoZSB1cmwgdG8gZGVjb2RlXHJcbiAgICogQHJldHVybnMgICAgIDogdGhlIGRlY29kZSB1cmwgc3RyaW5nXHJcbiAgICovXHJcbiAgc3RhdGljIHVybERlY29kZSh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHJlZ2V4ID0gL1xcKy9nO1xyXG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCgodmFsdWUgKyBcIlwiKS5yZXBsYWNlKHJlZ2V4LCBcIiUyMFwiKSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYSBxdWVyeXN0cmluZyBwYXJhbWV0ZXIgdmFsdWVcclxuICAgKiBAcGFyYW0gbmFtZSAgOiB0aGUgcGFyYW1ldGVyIG5hbWVcclxuICAgKiBAcmV0dXJucyAgICAgOiB0aGUgc3RyaW5nIHZhbHVlXHJcbiAgICovXHJcbiAgc3RhdGljIGdldFF1ZXJ5U3RyaW5nVmFsdWVCeU5hbWUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5pc0Jyb3dzZXIoKSkgcmV0dXJuIG51bGw7XHJcbiAgICBjb25zdCB1cmwgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgIGlmICh1cmwuaW5jbHVkZXMoXCI/XCIpKSB7XHJcbiAgICAgIGNvbnN0IGh0dHBQYXJhbXMgPSBuZXcgSHR0cFBhcmFtcyh7IGZyb21TdHJpbmc6IHVybC5zcGxpdChcIj9cIilbMV0gfSk7XHJcbiAgICAgIGNvbnN0IHYgPSBkZWNvZGVVUklDb21wb25lbnQoaHR0cFBhcmFtcy5nZXQobmFtZSkpO1xyXG4gICAgICBpZiAodiAhPT0gXCJudWxsXCIpIHJldHVybiB2O1xyXG4gICAgICBlbHNlIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZW5lcmF0ZSBhIHBhc3N3b3JkXHJcbiAgICogQHJldHVybnMgOiB0aGUgcGFzc3dvcmQgc3RyaW5nXHJcbiAgICovXHJcbiAgc3RhdGljIGdlbmVyYXRlUGFzc3dvcmQoKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHJhbmRvbSA9IFwiJFwiICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoLTcpO1xyXG4gICAgbGV0IHBhc3N3b3JkID0gXCJcIjtcclxuICAgIGxldCBoYXNVcHBlckNhc2UgPSBmYWxzZTtcclxuICAgIGZvciAoY29uc3Qgcm5kIG9mIHJhbmRvbSkge1xyXG4gICAgICBpZiAoIWhhc1VwcGVyQ2FzZSAmJiBcImFiY2RlZmdoamlsbW5vcHFyc3R1dnl3eHpcIi5pbmNsdWRlcyhybmQpKSB7XHJcbiAgICAgICAgcGFzc3dvcmQgKz0gcm5kLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgaGFzVXBwZXJDYXNlID0gdHJ1ZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBwYXNzd29yZCArPSBybmQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICghaGFzVXBwZXJDYXNlKVxyXG4gICAgICBwYXNzd29yZCA9IHBhc3N3b3JkLnN1YnN0cmluZygwLCA3KSArIFwiTVwiO1xyXG4gICAgcmV0dXJuIHBhc3N3b3JkO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgY3VycmVudCBicm93c2VyIHN1cHBvcnRzIHRvdWNoXHJcbiAgICogQHJldHVybnMgOiB0cnVlIGlmIHRoZSBkaXNwbGF5IGlzIHRvdWNoYWJsZVxyXG4gICAqL1xyXG4gIHN0YXRpYyBpc1RvdWNoYWJsZSgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIHRoaXMuaXNCcm93c2VyKCkgJiYgKFxyXG4gICAgICAgIFwib250b3VjaHN0YXJ0XCIgaW4gd2luZG93IHx8XHJcbiAgICAgICAgbmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzID4gMClcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUaGlzIGNoZWNrIHdpbGwgcHJldmVudCAnd2luZG93JyBsb2dpYyB0byBiZSBleGVjdXRlZFxyXG4gICAqIHdoaWxlIGV4ZWN1dGluZyB0aGUgc2VydmVyIHJlbmRlcmluZ1xyXG4gICAqIEByZXR1cm5zIDogdHJ1ZSBpZiB1c2luZyB0aGUgYnJvd3NlclxyXG4gICAqL1xyXG4gIHN0YXRpYyBpc0Jyb3dzZXIoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdHlwZW9mICh3aW5kb3cpICE9PSAndW5kZWZpbmVkJztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gKiBDb252ZXJ0IGZvbGRlcnMgaW4gYSB0cmVlIG9mIE5vZGUgb2JqZWN0LlxyXG4gKiBAcGFyYW0gZm9sZGVycyA6IHRoZSBzdWJmb2xkZXJzIGdyb3VwIG9yIG51bGwgdG8gcm9vdFxyXG4gKiBAcmV0dXJucyAgICAgICA6IGEgbm9kZSBsaXN0XHJcbiAqL1xyXG4gIHN0YXRpYyB0b05vZGVzKGZvbGRlcnM6IElOb2RlW10pOiBJTm9kZVtdIHtcclxuICAgIHJldHVybiB0aGlzLl90b05vZGVzKGZvbGRlcnMsIHVuZGVmaW5lZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb252ZXJ0IGZvbGRlcnMgaW4gYSB0cmVlIG9mIE5vZGUgb2JqZWN0LlxyXG4gICAqIEBwYXJhbSBmb2xkZXJzIDogdGhlIGNoaWxkcmVuIGdyb3VwIG9yIG51bGwgdG8gcm9vdFxyXG4gICAqIEBwYXJhbSBwYXJlbnQgIDogdGhlIHBhcmVudCBub2RlXHJcbiAgICogQHJldHVybnMgICAgICAgOiBhIG5vZGUgbGlzdCBcclxuICAgKi9cclxuICBwcml2YXRlIHN0YXRpYyBfdG9Ob2Rlcyhmb2xkZXJzOiBJTm9kZVtdLCBwYXJlbnQ6IElOb2RlIHwgdW5kZWZpbmVkKTogSU5vZGVbXSB7XHJcbiAgICBjb25zdCBub2RlczogSU5vZGVbXSA9IFtdO1xyXG4gICAgZm9sZGVycy5mb3JFYWNoKChuOiBJTm9kZSkgPT4ge1xyXG4gICAgICBjb25zdCBub2RlOiBJTm9kZSA9IHtcclxuICAgICAgICBpZDogbi5pZCxcclxuICAgICAgICBuYW1lOiBuLm5hbWUsXHJcbiAgICAgICAgY291bnQ6IG4uY291bnQsXHJcbiAgICAgICAgcGFyZW50OiBwYXJlbnQsXHJcbiAgICAgICAgY2hpbGRyZW46IHVuZGVmaW5lZCxcclxuICAgICAgICBiYWc6IG4sXHJcbiAgICAgIH07XHJcbiAgICAgIG5vZGUuY2hpbGRyZW4gPVxyXG4gICAgICAgIG4uY2hpbGRyZW4gJiYgbi5jaGlsZHJlbi5sZW5ndGggPiAwXHJcbiAgICAgICAgICA/IHRoaXMuX3RvTm9kZXMobi5jaGlsZHJlbiwgbm9kZSlcclxuICAgICAgICAgIDogW107XHJcbiAgICAgIG5vZGVzLnB1c2gobm9kZSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBub2RlcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gKiBSZXR1cm4gdGhlIGZsYWdzIGFycmF5IHRvIGJlIHVzZWQgaW4gc2VsZWN0aW9uc1xyXG4gKiBAcGFyYW0gdmFsdWUgOiB0aGUgbmV3IHZhbHVlXHJcbiAqIEBwYXJhbSBtYXg6IHRoZSBtYXggbnVtYmVyIG9mIGZsYWdzXHJcbiAqL1xyXG4gIHN0YXRpYyBnZXRGbGFncyh2YWx1ZTogbnVtYmVyLCBtYXg6IG51bWJlciA9IDMwKTogbnVtYmVyW10ge1xyXG4gICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgIGxldCBpdGVtczogbnVtYmVyW10gPSBbXTtcclxuICAgICAgbGV0IHYgPSAxO1xyXG4gICAgICBsZXQgbSA9IDEgPDwgbWF4O1xyXG4gICAgICB3aGlsZSAodiA8IG0pIHtcclxuICAgICAgICBpZiAoKHZhbHVlICYgdikgPT09IHYpIGl0ZW1zLnB1c2godik7XHJcbiAgICAgICAgdiA9IHYgPDwgMTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gaXRlbXM7XHJcbiAgICB9IGVsc2UgcmV0dXJuIFtdO1xyXG4gIH1cclxufVxyXG4iXX0=