tnp-helpers 13.1.26 → 13.1.27

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 (178) hide show
  1. package/app.js +3 -3
  2. package/browser/README.md +24 -24
  3. package/browser/esm2020/lib/angular.helper.mjs +87 -87
  4. package/browser/esm2020/lib/base-component.mjs +49 -49
  5. package/browser/esm2020/lib/base-formly-component.mjs +112 -112
  6. package/browser/esm2020/lib/condition-wait.mjs +45 -45
  7. package/browser/esm2020/lib/constants.mjs +8 -8
  8. package/browser/esm2020/lib/dual-component-ctrl.mjs +118 -118
  9. package/browser/esm2020/lib/firedev-models.mjs +3 -3
  10. package/browser/esm2020/lib/helpers-array-obj.mjs +82 -82
  11. package/browser/esm2020/lib/helpers-browser.mjs +46 -46
  12. package/browser/esm2020/lib/helpers-console-gui.mjs +9 -9
  13. package/browser/esm2020/lib/helpers-environment.mjs +32 -32
  14. package/browser/esm2020/lib/helpers-numbers.mjs +7 -7
  15. package/browser/esm2020/lib/helpers-strings-regexes.mjs +50 -50
  16. package/browser/esm2020/lib/helpers-strings.mjs +252 -252
  17. package/browser/esm2020/lib/helpers.mjs +285 -285
  18. package/browser/esm2020/lib/index.mjs +15 -15
  19. package/browser/esm2020/lib/long-press.directive.mjs +112 -112
  20. package/browser/esm2020/lib/project.mjs +429 -429
  21. package/browser/esm2020/lib/resize-service.mjs +21 -21
  22. package/browser/esm2020/public-api.mjs +1 -1
  23. package/browser/esm2020/tnp-helpers.mjs +4 -4
  24. package/browser/fesm2015/tnp-helpers.mjs +1686 -1686
  25. package/browser/fesm2020/tnp-helpers.mjs +1676 -1676
  26. package/browser/lib/angular.helper.d.ts +35 -35
  27. package/browser/lib/base-component.d.ts +16 -16
  28. package/browser/lib/base-formly-component.d.ts +30 -30
  29. package/browser/lib/condition-wait.d.ts +7 -7
  30. package/browser/lib/constants.d.ts +6 -6
  31. package/browser/lib/dual-component-ctrl.d.ts +24 -24
  32. package/browser/lib/firedev-models.d.ts +12 -12
  33. package/browser/lib/helpers-array-obj.d.ts +14 -14
  34. package/browser/lib/helpers-browser.d.ts +10 -10
  35. package/browser/lib/helpers-console-gui.d.ts +5 -5
  36. package/browser/lib/helpers-environment.d.ts +4 -4
  37. package/browser/lib/helpers-numbers.d.ts +2 -2
  38. package/browser/lib/helpers-strings-regexes.d.ts +27 -27
  39. package/browser/lib/helpers-strings.d.ts +49 -49
  40. package/browser/lib/helpers.d.ts +33 -33
  41. package/browser/lib/index.d.ts +11 -11
  42. package/browser/lib/long-press.directive.d.ts +24 -24
  43. package/browser/lib/project.d.ts +93 -93
  44. package/browser/lib/resize-service.d.ts +8 -8
  45. package/browser/tnp-helpers.d.ts +4 -4
  46. package/client/README.md +24 -24
  47. package/client/esm2020/lib/angular.helper.mjs +87 -87
  48. package/client/esm2020/lib/base-component.mjs +49 -49
  49. package/client/esm2020/lib/base-formly-component.mjs +112 -112
  50. package/client/esm2020/lib/condition-wait.mjs +45 -45
  51. package/client/esm2020/lib/constants.mjs +8 -8
  52. package/client/esm2020/lib/dual-component-ctrl.mjs +118 -118
  53. package/client/esm2020/lib/firedev-models.mjs +3 -3
  54. package/client/esm2020/lib/helpers-array-obj.mjs +82 -82
  55. package/client/esm2020/lib/helpers-browser.mjs +46 -46
  56. package/client/esm2020/lib/helpers-console-gui.mjs +9 -9
  57. package/client/esm2020/lib/helpers-environment.mjs +32 -32
  58. package/client/esm2020/lib/helpers-numbers.mjs +7 -7
  59. package/client/esm2020/lib/helpers-strings-regexes.mjs +50 -50
  60. package/client/esm2020/lib/helpers-strings.mjs +252 -252
  61. package/client/esm2020/lib/helpers.mjs +285 -285
  62. package/client/esm2020/lib/index.mjs +15 -15
  63. package/client/esm2020/lib/long-press.directive.mjs +112 -112
  64. package/client/esm2020/lib/project.mjs +429 -429
  65. package/client/esm2020/lib/resize-service.mjs +21 -21
  66. package/client/esm2020/public-api.mjs +1 -1
  67. package/client/esm2020/tnp-helpers.mjs +4 -4
  68. package/client/fesm2015/tnp-helpers.mjs +1686 -1686
  69. package/client/fesm2020/tnp-helpers.mjs +1676 -1676
  70. package/client/lib/angular.helper.d.ts +35 -35
  71. package/client/lib/base-component.d.ts +16 -16
  72. package/client/lib/base-formly-component.d.ts +30 -30
  73. package/client/lib/condition-wait.d.ts +7 -7
  74. package/client/lib/constants.d.ts +6 -6
  75. package/client/lib/dual-component-ctrl.d.ts +24 -24
  76. package/client/lib/firedev-models.d.ts +12 -12
  77. package/client/lib/helpers-array-obj.d.ts +14 -14
  78. package/client/lib/helpers-browser.d.ts +10 -10
  79. package/client/lib/helpers-console-gui.d.ts +5 -5
  80. package/client/lib/helpers-environment.d.ts +4 -4
  81. package/client/lib/helpers-numbers.d.ts +2 -2
  82. package/client/lib/helpers-strings-regexes.d.ts +27 -27
  83. package/client/lib/helpers-strings.d.ts +49 -49
  84. package/client/lib/helpers.d.ts +33 -33
  85. package/client/lib/index.d.ts +11 -11
  86. package/client/lib/long-press.directive.d.ts +24 -24
  87. package/client/lib/project.d.ts +93 -93
  88. package/client/lib/resize-service.d.ts +8 -8
  89. package/client/tnp-helpers.d.ts +4 -4
  90. package/index.d.ts +1 -1
  91. package/lib/angular.helper.d.ts +35 -35
  92. package/lib/angular.helper.js +3 -3
  93. package/lib/base-component.d.ts +13 -13
  94. package/lib/base-component.js +3 -3
  95. package/lib/base-formly-component.d.ts +27 -27
  96. package/lib/base-formly-component.js +3 -3
  97. package/lib/condition-wait.d.ts +8 -8
  98. package/lib/constants.d.ts +7 -7
  99. package/lib/dual-component-ctrl.d.ts +24 -24
  100. package/lib/dual-component-ctrl.js +3 -3
  101. package/lib/firedev-models.d.ts +13 -13
  102. package/lib/git-project.d.ts +46 -46
  103. package/lib/helpers-array-obj.d.ts +15 -15
  104. package/lib/helpers-browser.d.ts +11 -11
  105. package/lib/helpers-cli-tool.backend.d.ts +55 -55
  106. package/lib/helpers-console-gui.d.ts +17 -17
  107. package/lib/helpers-dependencies.backend.d.ts +11 -11
  108. package/lib/helpers-environment.d.ts +5 -5
  109. package/lib/helpers-file-folders.backend.d.ts +84 -84
  110. package/lib/helpers-git.backend.d.ts +43 -43
  111. package/lib/helpers-json5.backend.d.ts +16 -16
  112. package/lib/helpers-morphi-framework.backend.d.ts +4 -4
  113. package/lib/helpers-network.backend.d.ts +8 -8
  114. package/lib/helpers-npm.backend.d.ts +3 -3
  115. package/lib/helpers-numbers.d.ts +3 -3
  116. package/lib/helpers-path.backend.d.ts +7 -7
  117. package/lib/helpers-process.backend.d.ts +58 -58
  118. package/lib/helpers-strings-regexes.d.ts +28 -28
  119. package/lib/helpers-strings.d.ts +50 -50
  120. package/lib/helpers-system-terminal.backend.d.ts +5 -5
  121. package/lib/helpers-vscode.backend.d.ts +5 -5
  122. package/lib/helpers.d.ts +74 -74
  123. package/lib/index.d.ts +12 -12
  124. package/lib/long-press.directive.d.ts +22 -22
  125. package/lib/merge-helpers.backend.d.ts +23 -23
  126. package/lib/project.d.ts +96 -96
  127. package/lib/resize-service.d.ts +6 -6
  128. package/lib/ts-code/index.d.ts +1 -1
  129. package/lib/ts-code/ts-code-extractor.d.ts +14 -14
  130. package/lib/ts-code/ts-code-modifier.backend.d.ts +12 -12
  131. package/package.json +5 -5
  132. package/package.json_devDependencies.json +222 -222
  133. package/package.json_tnp.json5 +44 -44
  134. package/tmp-environment.json +20 -20
  135. package/websql/README.md +24 -24
  136. package/websql/esm2020/lib/angular.helper.mjs +87 -87
  137. package/websql/esm2020/lib/base-component.mjs +49 -49
  138. package/websql/esm2020/lib/base-formly-component.mjs +112 -112
  139. package/websql/esm2020/lib/condition-wait.mjs +45 -45
  140. package/websql/esm2020/lib/constants.mjs +8 -8
  141. package/websql/esm2020/lib/dual-component-ctrl.mjs +118 -118
  142. package/websql/esm2020/lib/firedev-models.mjs +3 -3
  143. package/websql/esm2020/lib/helpers-array-obj.mjs +82 -82
  144. package/websql/esm2020/lib/helpers-browser.mjs +46 -46
  145. package/websql/esm2020/lib/helpers-console-gui.mjs +9 -9
  146. package/websql/esm2020/lib/helpers-environment.mjs +32 -32
  147. package/websql/esm2020/lib/helpers-numbers.mjs +7 -7
  148. package/websql/esm2020/lib/helpers-strings-regexes.mjs +50 -50
  149. package/websql/esm2020/lib/helpers-strings.mjs +252 -252
  150. package/websql/esm2020/lib/helpers.mjs +285 -285
  151. package/websql/esm2020/lib/index.mjs +15 -15
  152. package/websql/esm2020/lib/long-press.directive.mjs +112 -112
  153. package/websql/esm2020/lib/project.mjs +429 -429
  154. package/websql/esm2020/lib/resize-service.mjs +21 -21
  155. package/websql/esm2020/public-api.mjs +1 -1
  156. package/websql/esm2020/tnp-helpers.mjs +4 -4
  157. package/websql/fesm2015/tnp-helpers.mjs +1686 -1686
  158. package/websql/fesm2020/tnp-helpers.mjs +1676 -1676
  159. package/websql/lib/angular.helper.d.ts +35 -35
  160. package/websql/lib/base-component.d.ts +16 -16
  161. package/websql/lib/base-formly-component.d.ts +30 -30
  162. package/websql/lib/condition-wait.d.ts +7 -7
  163. package/websql/lib/constants.d.ts +6 -6
  164. package/websql/lib/dual-component-ctrl.d.ts +24 -24
  165. package/websql/lib/firedev-models.d.ts +12 -12
  166. package/websql/lib/helpers-array-obj.d.ts +14 -14
  167. package/websql/lib/helpers-browser.d.ts +10 -10
  168. package/websql/lib/helpers-console-gui.d.ts +5 -5
  169. package/websql/lib/helpers-environment.d.ts +4 -4
  170. package/websql/lib/helpers-numbers.d.ts +2 -2
  171. package/websql/lib/helpers-strings-regexes.d.ts +27 -27
  172. package/websql/lib/helpers-strings.d.ts +49 -49
  173. package/websql/lib/helpers.d.ts +33 -33
  174. package/websql/lib/index.d.ts +11 -11
  175. package/websql/lib/long-press.directive.d.ts +24 -24
  176. package/websql/lib/project.d.ts +93 -93
  177. package/websql/lib/resize-service.d.ts +8 -8
  178. package/websql/tnp-helpers.d.ts +4 -4
@@ -1,253 +1,253 @@
1
- import { _ } from 'tnp-core/websql';
2
- import { Helpers } from './index';
3
- export class HelpersStrings {
4
- /**
5
- * Example:
6
- *
7
- * const result = interpolateString("I'm {age} years old!")
8
- * .withParameters({ age: 29 });
9
- *
10
- * const result = interpolateString("The {a} says {n}, {n}, {n}!")
11
- * .withParameters({ a: 'cow', n: 'moo' });
12
- *
13
- *
14
- * @param value string to interpolate
15
- * @param parameters object with parametes
16
- */
17
- interpolateString(value) {
18
- if (typeof value !== 'string') {
19
- Helpers.warn('[ss-logic][helper] Value for interpolation is not string: ', value);
20
- return value;
21
- }
22
- return {
23
- withParameters(parameters) {
24
- if (typeof parameters !== 'object') {
25
- Helpers.log(parameters);
26
- Helpers.warn('[ss-logic][helper] Parameters are not a object: ');
27
- return value;
28
- }
29
- return value.replace(/{([^{}]*)}/g, function (a, b) {
30
- var r = parameters[b];
31
- return typeof r === 'string' || typeof r === 'number' ? r : a;
32
- });
33
- }
34
- };
35
- }
36
- numValue(pixelsCss) {
37
- return parseInt(pixelsCss.replace('px', ''));
38
- }
39
- /**
40
- * examples:
41
- * 'aa bb bb' => ['aa','bb','cc'],
42
- * 'aa' => ['aa']
43
- * ['aa'] => ['aa']
44
- */
45
- splitIfNeed(stringOrArr) {
46
- let res = [];
47
- if (_.isArray(stringOrArr)) {
48
- res = stringOrArr.map(s => {
49
- return s.trim();
50
- });
51
- }
52
- if (_.isString(stringOrArr)) {
53
- res = stringOrArr.split(/\s*[\s,]\s*/);
54
- }
55
- return res.filter(f => !!f && (f.trim() !== ''));
56
- }
57
- removeDoubleOrMoreEmptyLines(s) {
58
- s = s?.split('\n').map(f => f.trimRight()).join('\n');
59
- return s?.replace(/(\r\n|\r|\n){2,}/g, '$1\n');
60
- }
61
- /**
62
- *
63
- * https://stackoverflow.com/a/57129703/1345101
64
- *
65
- * Returns the plural of an English word.
66
- *
67
- * @export
68
- * @param {string} word
69
- * @param {number} [amount]
70
- * @returns {string}
71
- */
72
- plural(word, amount) {
73
- if (amount !== undefined && amount === 1) {
74
- return word;
75
- }
76
- const plural = {
77
- '(quiz)$': "$1zes",
78
- '^(ox)$': "$1en",
79
- '([m|l])ouse$': "$1ice",
80
- '(matr|vert|ind)ix|ex$': "$1ices",
81
- '(x|ch|ss|sh)$': "$1es",
82
- '([^aeiouy]|qu)y$': "$1ies",
83
- '(hive)$': "$1s",
84
- '(?:([^f])fe|([lr])f)$': "$1$2ves",
85
- '(shea|lea|loa|thie)f$': "$1ves",
86
- 'sis$': "ses",
87
- '([ti])um$': "$1a",
88
- '(tomat|potat|ech|her|vet)o$': "$1oes",
89
- '(bu)s$': "$1ses",
90
- '(alias)$': "$1es",
91
- '(octop)us$': "$1i",
92
- '(ax|test)is$': "$1es",
93
- '(us)$': "$1es",
94
- '([^s]+)$': "$1s"
95
- };
96
- const irregular = {
97
- 'move': 'moves',
98
- 'foot': 'feet',
99
- 'goose': 'geese',
100
- 'sex': 'sexes',
101
- 'child': 'children',
102
- 'man': 'men',
103
- 'tooth': 'teeth',
104
- 'person': 'people'
105
- };
106
- const uncountable = [
107
- 'sheep',
108
- 'fish',
109
- 'deer',
110
- 'moose',
111
- 'series',
112
- 'species',
113
- 'money',
114
- 'rice',
115
- 'information',
116
- 'equipment',
117
- 'bison',
118
- 'cod',
119
- 'offspring',
120
- 'pike',
121
- 'salmon',
122
- 'shrimp',
123
- 'swine',
124
- 'trout',
125
- 'aircraft',
126
- 'hovercraft',
127
- 'spacecraft',
128
- 'sugar',
129
- 'tuna',
130
- 'you',
131
- 'wood'
132
- ];
133
- if (uncountable.indexOf(word.toLowerCase()) >= 0) {
134
- return word;
135
- }
136
- for (const w in irregular) {
137
- const pattern = new RegExp(`${w}$`, 'i');
138
- const replace = irregular[w];
139
- if (pattern.test(word)) {
140
- return word.replace(pattern, replace);
141
- }
142
- }
143
- for (const reg in plural) {
144
- const pattern = new RegExp(reg, 'i');
145
- if (pattern.test(word)) {
146
- return word.replace(pattern, plural[reg]);
147
- }
148
- }
149
- return word;
150
- }
151
- /**
152
- * https://stackoverflow.com/a/57129703/1345101
153
- *
154
- * Returns the singular of an English word.
155
- *
156
- * @export
157
- * @param {string} word
158
- * @param {number} [amount]
159
- * @returns {string}
160
- */
161
- singular(word, amount) {
162
- if (amount !== undefined && amount !== 1) {
163
- return word;
164
- }
165
- const singular = {
166
- '(quiz)zes$': "$1",
167
- '(matr)ices$': "$1ix",
168
- '(vert|ind)ices$': "$1ex",
169
- '^(ox)en$': "$1",
170
- '(alias)es$': "$1",
171
- '(octop|vir)i$': "$1us",
172
- '(cris|ax|test)es$': "$1is",
173
- '(shoe)s$': "$1",
174
- '(o)es$': "$1",
175
- '(bus)es$': "$1",
176
- '([m|l])ice$': "$1ouse",
177
- '(x|ch|ss|sh)es$': "$1",
178
- '(m)ovies$': "$1ovie",
179
- '(s)eries$': "$1eries",
180
- '([^aeiouy]|qu)ies$': "$1y",
181
- '([lr])ves$': "$1f",
182
- '(tive)s$': "$1",
183
- '(hive)s$': "$1",
184
- '(li|wi|kni)ves$': "$1fe",
185
- '(shea|loa|lea|thie)ves$': "$1f",
186
- '(^analy)ses$': "$1sis",
187
- '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$': "$1$2sis",
188
- '([ti])a$': "$1um",
189
- '(n)ews$': "$1ews",
190
- '(h|bl)ouses$': "$1ouse",
191
- '(corpse)s$': "$1",
192
- '(us)es$': "$1",
193
- 's$': ""
194
- };
195
- const irregular = {
196
- 'move': 'moves',
197
- 'foot': 'feet',
198
- 'goose': 'geese',
199
- 'sex': 'sexes',
200
- 'child': 'children',
201
- 'man': 'men',
202
- 'tooth': 'teeth',
203
- 'person': 'people'
204
- };
205
- const uncountable = [
206
- 'sheep',
207
- 'fish',
208
- 'deer',
209
- 'moose',
210
- 'series',
211
- 'species',
212
- 'money',
213
- 'rice',
214
- 'information',
215
- 'equipment',
216
- 'bison',
217
- 'cod',
218
- 'offspring',
219
- 'pike',
220
- 'salmon',
221
- 'shrimp',
222
- 'swine',
223
- 'trout',
224
- 'aircraft',
225
- 'hovercraft',
226
- 'spacecraft',
227
- 'sugar',
228
- 'tuna',
229
- 'you',
230
- 'wood'
231
- ];
232
- if (uncountable.indexOf(word.toLowerCase()) >= 0) {
233
- return word;
234
- }
235
- for (const w in irregular) {
236
- const pattern = new RegExp(`${irregular[w]}$`, 'i');
237
- const replace = w;
238
- if (pattern.test(word)) {
239
- return word.replace(pattern, replace);
240
- }
241
- }
242
- for (const reg in singular) {
243
- const pattern = new RegExp(reg, 'i');
244
- if (pattern.test(word)) {
245
- return word.replace(pattern, singular[reg]);
246
- }
247
- }
248
- return word;
249
- }
250
- }
251
- ;
252
- ({}); // @--end-of-file-for-module=tnp-helpers lib/helpers-strings.ts
1
+ import { _ } from 'tnp-core/websql';
2
+ import { Helpers } from './index';
3
+ export class HelpersStrings {
4
+ /**
5
+ * Example:
6
+ *
7
+ * const result = interpolateString("I'm {age} years old!")
8
+ * .withParameters({ age: 29 });
9
+ *
10
+ * const result = interpolateString("The {a} says {n}, {n}, {n}!")
11
+ * .withParameters({ a: 'cow', n: 'moo' });
12
+ *
13
+ *
14
+ * @param value string to interpolate
15
+ * @param parameters object with parametes
16
+ */
17
+ interpolateString(value) {
18
+ if (typeof value !== 'string') {
19
+ Helpers.warn('[ss-logic][helper] Value for interpolation is not string: ', value);
20
+ return value;
21
+ }
22
+ return {
23
+ withParameters(parameters) {
24
+ if (typeof parameters !== 'object') {
25
+ Helpers.log(parameters);
26
+ Helpers.warn('[ss-logic][helper] Parameters are not a object: ');
27
+ return value;
28
+ }
29
+ return value.replace(/{([^{}]*)}/g, function (a, b) {
30
+ var r = parameters[b];
31
+ return typeof r === 'string' || typeof r === 'number' ? r : a;
32
+ });
33
+ }
34
+ };
35
+ }
36
+ numValue(pixelsCss) {
37
+ return parseInt(pixelsCss.replace('px', ''));
38
+ }
39
+ /**
40
+ * examples:
41
+ * 'aa bb bb' => ['aa','bb','cc'],
42
+ * 'aa' => ['aa']
43
+ * ['aa'] => ['aa']
44
+ */
45
+ splitIfNeed(stringOrArr) {
46
+ let res = [];
47
+ if (_.isArray(stringOrArr)) {
48
+ res = stringOrArr.map(s => {
49
+ return s.trim();
50
+ });
51
+ }
52
+ if (_.isString(stringOrArr)) {
53
+ res = stringOrArr.split(/\s*[\s,]\s*/);
54
+ }
55
+ return res.filter(f => !!f && (f.trim() !== ''));
56
+ }
57
+ removeDoubleOrMoreEmptyLines(s) {
58
+ s = s?.split('\n').map(f => f.trimRight()).join('\n');
59
+ return s?.replace(/(\r\n|\r|\n){2,}/g, '$1\n');
60
+ }
61
+ /**
62
+ *
63
+ * https://stackoverflow.com/a/57129703/1345101
64
+ *
65
+ * Returns the plural of an English word.
66
+ *
67
+ * @export
68
+ * @param {string} word
69
+ * @param {number} [amount]
70
+ * @returns {string}
71
+ */
72
+ plural(word, amount) {
73
+ if (amount !== undefined && amount === 1) {
74
+ return word;
75
+ }
76
+ const plural = {
77
+ '(quiz)$': "$1zes",
78
+ '^(ox)$': "$1en",
79
+ '([m|l])ouse$': "$1ice",
80
+ '(matr|vert|ind)ix|ex$': "$1ices",
81
+ '(x|ch|ss|sh)$': "$1es",
82
+ '([^aeiouy]|qu)y$': "$1ies",
83
+ '(hive)$': "$1s",
84
+ '(?:([^f])fe|([lr])f)$': "$1$2ves",
85
+ '(shea|lea|loa|thie)f$': "$1ves",
86
+ 'sis$': "ses",
87
+ '([ti])um$': "$1a",
88
+ '(tomat|potat|ech|her|vet)o$': "$1oes",
89
+ '(bu)s$': "$1ses",
90
+ '(alias)$': "$1es",
91
+ '(octop)us$': "$1i",
92
+ '(ax|test)is$': "$1es",
93
+ '(us)$': "$1es",
94
+ '([^s]+)$': "$1s"
95
+ };
96
+ const irregular = {
97
+ 'move': 'moves',
98
+ 'foot': 'feet',
99
+ 'goose': 'geese',
100
+ 'sex': 'sexes',
101
+ 'child': 'children',
102
+ 'man': 'men',
103
+ 'tooth': 'teeth',
104
+ 'person': 'people'
105
+ };
106
+ const uncountable = [
107
+ 'sheep',
108
+ 'fish',
109
+ 'deer',
110
+ 'moose',
111
+ 'series',
112
+ 'species',
113
+ 'money',
114
+ 'rice',
115
+ 'information',
116
+ 'equipment',
117
+ 'bison',
118
+ 'cod',
119
+ 'offspring',
120
+ 'pike',
121
+ 'salmon',
122
+ 'shrimp',
123
+ 'swine',
124
+ 'trout',
125
+ 'aircraft',
126
+ 'hovercraft',
127
+ 'spacecraft',
128
+ 'sugar',
129
+ 'tuna',
130
+ 'you',
131
+ 'wood'
132
+ ];
133
+ if (uncountable.indexOf(word.toLowerCase()) >= 0) {
134
+ return word;
135
+ }
136
+ for (const w in irregular) {
137
+ const pattern = new RegExp(`${w}$`, 'i');
138
+ const replace = irregular[w];
139
+ if (pattern.test(word)) {
140
+ return word.replace(pattern, replace);
141
+ }
142
+ }
143
+ for (const reg in plural) {
144
+ const pattern = new RegExp(reg, 'i');
145
+ if (pattern.test(word)) {
146
+ return word.replace(pattern, plural[reg]);
147
+ }
148
+ }
149
+ return word;
150
+ }
151
+ /**
152
+ * https://stackoverflow.com/a/57129703/1345101
153
+ *
154
+ * Returns the singular of an English word.
155
+ *
156
+ * @export
157
+ * @param {string} word
158
+ * @param {number} [amount]
159
+ * @returns {string}
160
+ */
161
+ singular(word, amount) {
162
+ if (amount !== undefined && amount !== 1) {
163
+ return word;
164
+ }
165
+ const singular = {
166
+ '(quiz)zes$': "$1",
167
+ '(matr)ices$': "$1ix",
168
+ '(vert|ind)ices$': "$1ex",
169
+ '^(ox)en$': "$1",
170
+ '(alias)es$': "$1",
171
+ '(octop|vir)i$': "$1us",
172
+ '(cris|ax|test)es$': "$1is",
173
+ '(shoe)s$': "$1",
174
+ '(o)es$': "$1",
175
+ '(bus)es$': "$1",
176
+ '([m|l])ice$': "$1ouse",
177
+ '(x|ch|ss|sh)es$': "$1",
178
+ '(m)ovies$': "$1ovie",
179
+ '(s)eries$': "$1eries",
180
+ '([^aeiouy]|qu)ies$': "$1y",
181
+ '([lr])ves$': "$1f",
182
+ '(tive)s$': "$1",
183
+ '(hive)s$': "$1",
184
+ '(li|wi|kni)ves$': "$1fe",
185
+ '(shea|loa|lea|thie)ves$': "$1f",
186
+ '(^analy)ses$': "$1sis",
187
+ '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$': "$1$2sis",
188
+ '([ti])a$': "$1um",
189
+ '(n)ews$': "$1ews",
190
+ '(h|bl)ouses$': "$1ouse",
191
+ '(corpse)s$': "$1",
192
+ '(us)es$': "$1",
193
+ 's$': ""
194
+ };
195
+ const irregular = {
196
+ 'move': 'moves',
197
+ 'foot': 'feet',
198
+ 'goose': 'geese',
199
+ 'sex': 'sexes',
200
+ 'child': 'children',
201
+ 'man': 'men',
202
+ 'tooth': 'teeth',
203
+ 'person': 'people'
204
+ };
205
+ const uncountable = [
206
+ 'sheep',
207
+ 'fish',
208
+ 'deer',
209
+ 'moose',
210
+ 'series',
211
+ 'species',
212
+ 'money',
213
+ 'rice',
214
+ 'information',
215
+ 'equipment',
216
+ 'bison',
217
+ 'cod',
218
+ 'offspring',
219
+ 'pike',
220
+ 'salmon',
221
+ 'shrimp',
222
+ 'swine',
223
+ 'trout',
224
+ 'aircraft',
225
+ 'hovercraft',
226
+ 'spacecraft',
227
+ 'sugar',
228
+ 'tuna',
229
+ 'you',
230
+ 'wood'
231
+ ];
232
+ if (uncountable.indexOf(word.toLowerCase()) >= 0) {
233
+ return word;
234
+ }
235
+ for (const w in irregular) {
236
+ const pattern = new RegExp(`${irregular[w]}$`, 'i');
237
+ const replace = w;
238
+ if (pattern.test(word)) {
239
+ return word.replace(pattern, replace);
240
+ }
241
+ }
242
+ for (const reg in singular) {
243
+ const pattern = new RegExp(reg, 'i');
244
+ if (pattern.test(word)) {
245
+ return word.replace(pattern, singular[reg]);
246
+ }
247
+ }
248
+ return word;
249
+ }
250
+ }
251
+ ;
252
+ ({}); // @--end-of-file-for-module=tnp-helpers lib/helpers-strings.ts
253
253
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy1zdHJpbmdzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdG1wLWxpYnMtZm9yLWJ1bmRsZS13ZWJzcWwvdG5wLWhlbHBlcnMvcHJvamVjdHMvdG5wLWhlbHBlcnMvc3JjL2xpYi9oZWxwZXJzLXN0cmluZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3BDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFbEMsTUFBTSxPQUFPLGNBQWM7SUFFekI7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsaUJBQWlCLENBQVUsS0FBYTtRQUN0QyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtZQUM3QixPQUFPLENBQUMsSUFBSSxDQUFDLDREQUE0RCxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2xGLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFFRCxPQUFPO1lBQ0wsY0FBYyxDQUFDLFVBQWE7Z0JBQzFCLElBQUksT0FBTyxVQUFVLEtBQUssUUFBUSxFQUFFO29CQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQWlCLENBQUMsQ0FBQztvQkFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO29CQUNqRSxPQUFPLEtBQUssQ0FBQztpQkFDZDtnQkFDRCxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUM7b0JBQ2hELElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDdEIsT0FBTyxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEUsQ0FBUSxDQUFDLENBQUM7WUFDWixDQUFDO1NBQ0YsQ0FBQTtJQUVILENBQUM7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QUNaLFlBQVk7WUFDWixPQUFPO1lBQ1AsTUFBTTtZQUNOLEtBQUs7WUFDTCxNQUFNO1NBQ1AsQ0FBQTtRQUVELElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDaEQsT0FBTyxJQUFJLENBQUE7U0FDWjtRQUVELEtBQUssTUFBTSxDQUFDLElBQUksU0FBUyxFQUFFO1lBQ3pCLE1BQU0sT0FBTyxHQUFHLElBQUksTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUE7WUFDbkQsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFBO1lBQ2pCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDdEIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQTthQUN0QztTQUNGO1FBRUQsS0FBSyxNQUFNLEdBQUcsSUFBSSxRQUFRLEVBQUU7WUFDMUIsTUFBTSxPQUFPLEdBQUcsSUFBSSxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFBO1lBQ3BDLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDdEIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTthQUM1QztTQUNGO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0NBRUY7QUFHQSxDQUFDO0FBQUEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLCtEQUErRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IF8gfSBmcm9tICd0bnAtY29yZS93ZWJzcWwnO1xuaW1wb3J0IHsgSGVscGVycyB9IGZyb20gJy4vaW5kZXgnO1xuXG5leHBvcnQgY2xhc3MgSGVscGVyc1N0cmluZ3Mge1xuXG4gIC8qKlxuICAgKiBFeGFtcGxlOlxuICAgKlxuICAgKiBjb25zdCByZXN1bHQgPSBpbnRlcnBvbGF0ZVN0cmluZyhcIkknbSB7YWdlfSB5ZWFycyBvbGQhXCIpXG4gICAqIC53aXRoUGFyYW1ldGVycyh7IGFnZTogMjkgfSk7XG4gICAqXG4gICAqIGNvbnN0IHJlc3VsdCA9IGludGVycG9sYXRlU3RyaW5nKFwiVGhlIHthfSBzYXlzIHtufSwge259LCB7bn0hXCIpXG4gICAqIC53aXRoUGFyYW1ldGVycyh7IGE6ICdjb3cnLCBuOiAnbW9vJyB9KTtcbiAgICpcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIHN0cmluZyB0byBpbnRlcnBvbGF0ZVxuICAgKiBAcGFyYW0gcGFyYW1ldGVycyBvYmplY3Qgd2l0aCBwYXJhbWV0ZXNcbiAgICovXG4gIGludGVycG9sYXRlU3RyaW5nPFQgPSBhbnk+KHZhbHVlOiBzdHJpbmcpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgSGVscGVycy53YXJuKCdbc3MtbG9naWNdW2hlbHBlcl0gVmFsdWUgZm9yIGludGVycG9sYXRpb24gaXMgbm90IHN0cmluZzogJywgdmFsdWUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB3aXRoUGFyYW1ldGVycyhwYXJhbWV0ZXJzOiBUKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFyYW1ldGVycyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBIZWxwZXJzLmxvZyhwYXJhbWV0ZXJzIGFzIGFueSk7XG4gICAgICAgICAgSGVscGVycy53YXJuKCdbc3MtbG9naWNdW2hlbHBlcl0gUGFyYW1ldGVycyBhcmUgbm90IGEgb2JqZWN0OiAnKTtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL3soW157fV0qKX0vZywgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICB2YXIgciA9IHBhcmFtZXRlcnNbYl07XG4gICAgICAgICAgcmV0dXJuIHR5cGVvZiByID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgciA9PT0gJ251bWJlcicgPyByIDogYTtcbiAgICAgICAgfSBhcyBhbnkpO1xuICAgICAgfVxuICAgIH1cblxuICB9XG5cbiAgbnVtVmFsdWUocGl4ZWxzQ3NzOiBzdHJpbmcpIHtcblxuICAgIHJldHVybiBwYXJzZUludChwaXhlbHNDc3MucmVwbGFjZSgncHgnLCAnJykpO1xuICB9XG5cbiAgLyoqXG4gICAqIGV4YW1wbGVzOlxuICAgKiAnYWEgYmIgYmInID0+IFsnYWEnLCdiYicsJ2NjJ10sXG4gICAqICdhYScgPT4gWydhYSddXG4gICAqIFsnYWEnXSA9PiBbJ2FhJ11cbiAgICovXG4gIHNwbGl0SWZOZWVkKHN0cmluZ09yQXJyOiBzdHJpbmcgfCBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgICBsZXQgcmVzID0gW107XG4gICAgaWYgKF8uaXNBcnJheShzdHJpbmdPckFycikpIHtcbiAgICAgIHJlcyA9IHN0cmluZ09yQXJyLm1hcChzID0+IHtcbiAgICAgICAgcmV0dXJuIHMudHJpbSgpO1xuICAgICAgfSlcbiAgICB9XG4gICAgaWYgKF8uaXNTdHJpbmcoc3RyaW5nT3JBcnIpKSB7XG4gICAgICByZXMgPSBzdHJpbmdPckFyci5zcGxpdCgvXFxzKltcXHMsXVxccyovKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcy5maWx0ZXIoZiA9PiAhIWYgJiYgKGYudHJpbSgpICE9PSAnJykpO1xuICB9XG5cbiAgcmVtb3ZlRG91YmxlT3JNb3JlRW1wdHlMaW5lcyhzOiBzdHJpbmcpIHtcbiAgICBzID0gcz8uc3BsaXQoJ1xcbicpLm1hcChmID0+IGYudHJpbVJpZ2h0KCkpLmpvaW4oJ1xcbicpO1xuICAgIHJldHVybiBzPy5yZXBsYWNlKC8oXFxyXFxufFxccnxcXG4pezIsfS9nLCAnJDFcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNTcxMjk3MDMvMTM0NTEwMVxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSBwbHVyYWwgb2YgYW4gRW5nbGlzaCB3b3JkLlxuICAgKlxuICAgKiBAZXhwb3J0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSB3b3JkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbYW1vdW50XVxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgcGx1cmFsKHdvcmQ6IHN0cmluZywgYW1vdW50PzogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoYW1vdW50ICE9PSB1bmRlZmluZWQgJiYgYW1vdW50ID09PSAxKSB7XG4gICAgICByZXR1cm4gd29yZFxuICAgIH1cbiAgICBjb25zdCBwbHVyYWw6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAnKHF1aXopJCc6IFwiJDF6ZXNcIixcbiAgICAgICdeKG94KSQnOiBcIiQxZW5cIixcbiAgICAgICcoW218bF0pb3VzZSQnOiBcIiQxaWNlXCIsXG4gICAgICAnKG1hdHJ8dmVydHxpbmQpaXh8ZXgkJzogXCIkMWljZXNcIixcbiAgICAgICcoeHxjaHxzc3xzaCkkJzogXCIkMWVzXCIsXG4gICAgICAnKFteYWVpb3V5XXxxdSl5JCc6IFwiJDFpZXNcIixcbiAgICAgICcoaGl2ZSkkJzogXCIkMXNcIixcbiAgICAgICcoPzooW15mXSlmZXwoW2xyXSlmKSQnOiBcIiQxJDJ2ZXNcIixcbiAgICAgICcoc2hlYXxsZWF8bG9hfHRoaWUpZiQnOiBcIiQxdmVzXCIsXG4gICAgICAnc2lzJCc6IFwic2VzXCIsXG4gICAgICAnKFt0aV0pdW0kJzogXCIkMWFcIixcbiAgICAgICcodG9tYXR8cG90YXR8ZWNofGhlcnx2ZXQpbyQnOiBcIiQxb2VzXCIsXG4gICAgICAnKGJ1KXMkJzogXCIkMXNlc1wiLFxuICAgICAgJyhhbGlhcykkJzogXCIkMWVzXCIsXG4gICAgICAnKG9jdG9wKXVzJCc6IFwiJDFpXCIsXG4gICAgICAnKGF4fHRlc3QpaXMkJzogXCIkMWVzXCIsXG4gICAgICAnKHVzKSQnOiBcIiQxZXNcIixcbiAgICAgICcoW15zXSspJCc6IFwiJDFzXCJcbiAgICB9XG4gICAgY29uc3QgaXJyZWd1bGFyOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgJ21vdmUnOiAnbW92ZXMnLFxuICAgICAgJ2Zvb3QnOiAnZmVldCcsXG4gICAgICAnZ29vc2UnOiAnZ2Vlc2UnLFxuICAgICAgJ3NleCc6ICdzZXhlcycsXG4gICAgICAnY2hpbGQnOiAnY2hpbGRyZW4nLFxuICAgICAgJ21hbic6ICdtZW4nLFxuICAgICAgJ3Rvb3RoJzogJ3RlZXRoJyxcbiAgICAgICdwZXJzb24nOiAncGVvcGxlJ1xuICAgIH1cbiAgICBjb25zdCB1bmNvdW50YWJsZTogc3RyaW5nW10gPSBbXG4gICAgICAnc2hlZXAnLFxuICAgICAgJ2Zpc2gnLFxuICAgICAgJ2RlZXInLFxuICAgICAgJ21vb3NlJyxcbiAgICAgICdzZXJpZXMnLFxuICAgICAgJ3NwZWNpZXMnLFxuICAgICAgJ21vbmV5JyxcbiAgICAgICdyaWNlJyxcbiAgICAgICdpbmZvcm1hdGlvbicsXG4gICAgICAnZXF1aXBtZW50JyxcbiAgICAgICdiaXNvbicsXG4gICAgICAnY29kJyxcbiAgICAgICdvZmZzcHJpbmcnLFxuICAgICAgJ3Bpa2UnLFxuICAgICAgJ3NhbG1vbicsXG4gICAgICAnc2hyaW1wJyxcbiAgICAgICdzd2luZScsXG4gICAgICAndHJvdXQnLFxuICAgICAgJ2FpcmNyYWZ0JyxcbiAgICAgICdob3ZlcmNyYWZ0JyxcbiAgICAgICdzcGFjZWNyYWZ0JyxcbiAgICAgICdzdWdhcicsXG4gICAgICAndHVuYScsXG4gICAgICAneW91JyxcbiAgICAgICd3b29kJ1xuICAgIF1cblxuICAgIGlmICh1bmNvdW50YWJsZS5pbmRleE9mKHdvcmQudG9Mb3dlckNhc2UoKSkgPj0gMCkge1xuICAgICAgcmV0dXJuIHdvcmRcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHcgaW4gaXJyZWd1bGFyKSB7XG4gICAgICBjb25zdCBwYXR0ZXJuID0gbmV3IFJlZ0V4cChgJHt3fSRgLCAnaScpXG4gICAgICBjb25zdCByZXBsYWNlID0gaXJyZWd1bGFyW3ddXG4gICAgICBpZiAocGF0dGVybi50ZXN0KHdvcmQpKSB7XG4gICAgICAgIHJldHVybiB3b3JkLnJlcGxhY2UocGF0dGVybiwgcmVwbGFjZSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlZyBpbiBwbHVyYWwpIHtcbiAgICAgIGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKHJlZywgJ2knKVxuICAgICAgaWYgKHBhdHRlcm4udGVzdCh3b3JkKSkge1xuICAgICAgICByZXR1cm4gd29yZC5yZXBsYWNlKHBhdHRlcm4sIHBsdXJhbFtyZWddKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gd29yZFxuICB9XG5cblxuICAvKipcbiAgICogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzU3MTI5NzAzLzEzNDUxMDFcbiAgICpcbiAgKiBSZXR1cm5zIHRoZSBzaW5ndWxhciBvZiBhbiBFbmdsaXNoIHdvcmQuXG4gICpcbiAgKiBAZXhwb3J0XG4gICogQHBhcmFtIHtzdHJpbmd9IHdvcmRcbiAgKiBAcGFyYW0ge251bWJlcn0gW2Ftb3VudF1cbiAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAqL1xuICBzaW5ndWxhcih3b3JkOiBzdHJpbmcsIGFtb3VudD86IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKGFtb3VudCAhPT0gdW5kZWZpbmVkICYmIGFtb3VudCAhPT0gMSkge1xuICAgICAgcmV0dXJuIHdvcmRcbiAgICB9XG4gICAgY29uc3Qgc2luZ3VsYXI6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAnKHF1aXopemVzJCc6IFwiJDFcIixcbiAgICAgICcobWF0cilpY2VzJCc6IFwiJDFpeFwiLFxuICAgICAgJyh2ZXJ0fGluZClpY2VzJCc6IFwiJDFleFwiLFxuICAgICAgJ14ob3gpZW4kJzogXCIkMVwiLFxuICAgICAgJyhhbGlhcyllcyQnOiBcIiQxXCIsXG4gICAgICAnKG9jdG9wfHZpcilpJCc6IFwiJDF1c1wiLFxuICAgICAgJyhjcmlzfGF4fHRlc3QpZXMkJzogXCIkMWlzXCIsXG4gICAgICAnKHNob2UpcyQnOiBcIiQxXCIsXG4gICAgICAnKG8pZXMkJzogXCIkMVwiLFxuICAgICAgJyhidXMpZXMkJzogXCIkMVwiLFxuICAgICAgJyhbbXxsXSlpY2UkJzogXCIkMW91c2VcIixcbiAgICAgICcoeHxjaHxzc3xzaCllcyQnOiBcIiQxXCIsXG4gICAgICAnKG0pb3ZpZXMkJzogXCIkMW92aWVcIixcbiAgICAgICcocyllcmllcyQnOiBcIiQxZXJpZXNcIixcbiAgICAgICcoW15hZWlvdXldfHF1KWllcyQnOiBcIiQxeVwiLFxuICAgICAgJyhbbHJdKXZlcyQnOiBcIiQxZlwiLFxuICAgICAgJyh0aXZlKXMkJzogXCIkMVwiLFxuICAgICAgJyhoaXZlKXMkJzogXCIkMVwiLFxuICAgICAgJyhsaXx3aXxrbmkpdmVzJCc6IFwiJDFmZVwiLFxuICAgICAgJyhzaGVhfGxvYXxsZWF8dGhpZSl2ZXMkJzogXCIkMWZcIixcbiAgICAgICcoXmFuYWx5KXNlcyQnOiBcIiQxc2lzXCIsXG4gICAgICAnKChhKW5hbHl8KGIpYXwoZClpYWdub3wocClhcmVudGhlfChwKXJvZ25vfChzKXlub3B8KHQpaGUpc2VzJCc6IFwiJDEkMnNpc1wiLFxuICAgICAgJyhbdGldKWEkJzogXCIkMXVtXCIsXG4gICAgICAnKG4pZXdzJCc6IFwiJDFld3NcIixcbiAgICAgICcoaHxibClvdXNlcyQnOiBcIiQxb3VzZVwiLFxuICAgICAgJyhjb3Jwc2UpcyQnOiBcIiQxXCIsXG4gICAgICAnKHVzKWVzJCc6IFwiJDFcIixcbiAgICAgICdzJCc6IFwiXCJcbiAgICB9XG4gICAgY29uc3QgaXJyZWd1bGFyOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgJ21vdmUnOiAnbW92ZXMnLFxuICAgICAgJ2Zvb3QnOiAnZmVldCcsXG4gICAgICAnZ29vc2UnOiAnZ2Vlc2UnLFxuICAgICAgJ3NleCc6ICdzZXhlcycsXG4gICAgICAnY2hpbGQnOiAnY2hpbGRyZW4nLFxuICAgICAgJ21hbic6ICdtZW4nLFxuICAgICAgJ3Rvb3RoJzogJ3RlZXRoJyxcbiAgICAgICdwZXJzb24nOiAncGVvcGxlJ1xuICAgIH1cbiAgICBjb25zdCB1bmNvdW50YWJsZTogc3RyaW5nW10gPSBbXG4gICAgICAnc2hlZXAnLFxuICAgICAgJ2Zpc2gnLFxuICAgICAgJ2RlZXInLFxuICAgICAgJ21vb3NlJyxcbiAgICAgICdzZXJpZXMnLFxuICAgICAgJ3NwZWNpZXMnLFxuICAgICAgJ21vbmV5JyxcbiAgICAgICdyaWNlJyxcbiAgICAgICdpbmZvcm1hdGlvbicsXG4gICAgICAnZXF1aXBtZW50JyxcbiAgICAgICdiaXNvbicsXG4gICAgICAnY29kJyxcbiAgICAgICdvZmZzcHJpbmcnLFxuICAgICAgJ3Bpa2UnLFxuICAgICAgJ3NhbG1vbicsXG4gICAgICAnc2hyaW1wJyxcbiAgICAgICdzd2luZScsXG4gICAgICAndHJvdXQnLFxuICAgICAgJ2FpcmNyYWZ0JyxcbiAgICAgICdob3ZlcmNyYWZ0JyxcbiAgICAgICdzcGFjZWNyYWZ0JyxcbiAgICAgICdzdWdhcicsXG4gICAgICAndHVuYScsXG4gICAgICAneW91JyxcbiAgICAgICd3b29kJ1xuICAgIF1cblxuICAgIGlmICh1bmNvdW50YWJsZS5pbmRleE9mKHdvcmQudG9Mb3dlckNhc2UoKSkgPj0gMCkge1xuICAgICAgcmV0dXJuIHdvcmRcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHcgaW4gaXJyZWd1bGFyKSB7XG4gICAgICBjb25zdCBwYXR0ZXJuID0gbmV3IFJlZ0V4cChgJHtpcnJlZ3VsYXJbd119JGAsICdpJylcbiAgICAgIGNvbnN0IHJlcGxhY2UgPSB3XG4gICAgICBpZiAocGF0dGVybi50ZXN0KHdvcmQpKSB7XG4gICAgICAgIHJldHVybiB3b3JkLnJlcGxhY2UocGF0dGVybiwgcmVwbGFjZSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlZyBpbiBzaW5ndWxhcikge1xuICAgICAgY29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAocmVnLCAnaScpXG4gICAgICBpZiAocGF0dGVybi50ZXN0KHdvcmQpKSB7XG4gICAgICAgIHJldHVybiB3b3JkLnJlcGxhY2UocGF0dGVybiwgc2luZ3VsYXJbcmVnXSlcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHdvcmRcbiAgfVxuXG59XG5cblxuIDsoe30pOyAvLyBALS1lbmQtb2YtZmlsZS1mb3ItbW9kdWxlPXRucC1oZWxwZXJzIGxpYi9oZWxwZXJzLXN0cmluZ3MudHMiXX0=