namefully 1.1.0 → 1.2.0
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.
- package/dist/example/index.js +2734 -0
- package/dist/lib/config.d.ts +121 -0
- package/dist/lib/config.js +189 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +4 -0
- package/dist/lib/constants.js +31 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/error.d.ts +172 -0
- package/dist/lib/error.js +210 -0
- package/dist/lib/error.js.map +1 -0
- package/dist/lib/example/example.d.ts +1 -0
- package/dist/lib/full-name.d.ts +71 -0
- package/dist/lib/full-name.js +147 -0
- package/dist/lib/full-name.js.map +1 -0
- package/dist/lib/index.d.ts +16 -6
- package/dist/lib/index.js +29 -8
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/name.d.ts +177 -0
- package/dist/lib/name.js +322 -0
- package/dist/lib/name.js.map +1 -0
- package/dist/lib/namefully.d.ts +285 -208
- package/dist/lib/namefully.js +576 -576
- package/dist/lib/namefully.js.map +1 -1
- package/dist/lib/parser.d.ts +46 -0
- package/dist/lib/parser.js +173 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/src/config.d.ts +121 -0
- package/dist/lib/src/constants.d.ts +4 -0
- package/dist/lib/src/error.d.ts +172 -0
- package/dist/lib/src/full-name.d.ts +71 -0
- package/dist/lib/src/index.d.ts +20 -0
- package/dist/lib/src/name.d.ts +177 -0
- package/dist/lib/src/namefully.d.ts +379 -0
- package/dist/lib/src/parser.d.ts +46 -0
- package/dist/lib/src/types.d.ts +127 -0
- package/dist/lib/src/utils.d.ts +63 -0
- package/dist/lib/src/validator.d.ts +66 -0
- package/dist/lib/types.d.ts +127 -0
- package/dist/lib/types.js +181 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utils.d.ts +63 -0
- package/dist/lib/utils.js +138 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/validator.d.ts +66 -0
- package/dist/lib/validator.js +332 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/umd/namefully.js +2118 -2700
- package/dist/umd/namefully.js.map +1 -1
- package/dist/umd/namefully.min.js +1 -1
- package/dist/umd/namefully.min.js.LICENSE.txt +1 -18
- package/dist/umd/namefully.min.js.map +1 -1
- package/package.json +50 -54
- package/readme.md +132 -162
- package/changelog.md +0 -134
- package/dist/lib/core/constants.d.ts +0 -48
- package/dist/lib/core/constants.js +0 -101
- package/dist/lib/core/constants.js.map +0 -1
- package/dist/lib/core/core.d.ts +0 -17
- package/dist/lib/core/core.js +0 -24
- package/dist/lib/core/core.js.map +0 -1
- package/dist/lib/core/index.d.ts +0 -9
- package/dist/lib/core/index.js +0 -13
- package/dist/lib/core/index.js.map +0 -1
- package/dist/lib/core/parsers/array-name.parser.d.ts +0 -41
- package/dist/lib/core/parsers/array-name.parser.js +0 -86
- package/dist/lib/core/parsers/array-name.parser.js.map +0 -1
- package/dist/lib/core/parsers/array-string.parser.d.ts +0 -47
- package/dist/lib/core/parsers/array-string.parser.js +0 -95
- package/dist/lib/core/parsers/array-string.parser.js.map +0 -1
- package/dist/lib/core/parsers/index.d.ts +0 -11
- package/dist/lib/core/parsers/index.js +0 -11
- package/dist/lib/core/parsers/index.js.map +0 -1
- package/dist/lib/core/parsers/nama.parser.d.ts +0 -33
- package/dist/lib/core/parsers/nama.parser.js +0 -74
- package/dist/lib/core/parsers/nama.parser.js.map +0 -1
- package/dist/lib/core/parsers/parser.d.ts +0 -28
- package/dist/lib/core/parsers/parser.js +0 -3
- package/dist/lib/core/parsers/parser.js.map +0 -1
- package/dist/lib/core/parsers/string.parser.d.ts +0 -60
- package/dist/lib/core/parsers/string.parser.js +0 -62
- package/dist/lib/core/parsers/string.parser.js.map +0 -1
- package/dist/lib/core/utils.d.ts +0 -52
- package/dist/lib/core/utils.js +0 -178
- package/dist/lib/core/utils.js.map +0 -1
- package/dist/lib/models/enums.d.ts +0 -106
- package/dist/lib/models/enums.js +0 -114
- package/dist/lib/models/enums.js.map +0 -1
- package/dist/lib/models/firstname.d.ts +0 -77
- package/dist/lib/models/firstname.js +0 -131
- package/dist/lib/models/firstname.js.map +0 -1
- package/dist/lib/models/fullname.d.ts +0 -73
- package/dist/lib/models/fullname.js +0 -99
- package/dist/lib/models/fullname.js.map +0 -1
- package/dist/lib/models/index.d.ts +0 -13
- package/dist/lib/models/index.js +0 -16
- package/dist/lib/models/index.js.map +0 -1
- package/dist/lib/models/lastname.d.ts +0 -80
- package/dist/lib/models/lastname.js +0 -157
- package/dist/lib/models/lastname.js.map +0 -1
- package/dist/lib/models/misc.d.ts +0 -108
- package/dist/lib/models/misc.js +0 -3
- package/dist/lib/models/misc.js.map +0 -1
- package/dist/lib/models/name.d.ts +0 -76
- package/dist/lib/models/name.js +0 -115
- package/dist/lib/models/name.js.map +0 -1
- package/dist/lib/models/summary.d.ts +0 -26
- package/dist/lib/models/summary.js +0 -61
- package/dist/lib/models/summary.js.map +0 -1
- package/dist/lib/validators/array-name.validator.d.ts +0 -25
- package/dist/lib/validators/array-name.validator.js +0 -75
- package/dist/lib/validators/array-name.validator.js.map +0 -1
- package/dist/lib/validators/array-string.validator.d.ts +0 -43
- package/dist/lib/validators/array-string.validator.js +0 -76
- package/dist/lib/validators/array-string.validator.js.map +0 -1
- package/dist/lib/validators/common/validation-error.d.ts +0 -19
- package/dist/lib/validators/common/validation-error.js +0 -26
- package/dist/lib/validators/common/validation-error.js.map +0 -1
- package/dist/lib/validators/common/validation-rule.d.ts +0 -72
- package/dist/lib/validators/common/validation-rule.js +0 -76
- package/dist/lib/validators/common/validation-rule.js.map +0 -1
- package/dist/lib/validators/common/validation-type.d.ts +0 -24
- package/dist/lib/validators/common/validation-type.js +0 -28
- package/dist/lib/validators/common/validation-type.js.map +0 -1
- package/dist/lib/validators/firstname.validator.d.ts +0 -20
- package/dist/lib/validators/firstname.validator.js +0 -29
- package/dist/lib/validators/firstname.validator.js.map +0 -1
- package/dist/lib/validators/fullname.validator.d.ts +0 -21
- package/dist/lib/validators/fullname.validator.js +0 -38
- package/dist/lib/validators/fullname.validator.js.map +0 -1
- package/dist/lib/validators/index.d.ts +0 -21
- package/dist/lib/validators/index.js +0 -35
- package/dist/lib/validators/index.js.map +0 -1
- package/dist/lib/validators/lastname.validator.d.ts +0 -20
- package/dist/lib/validators/lastname.validator.js +0 -29
- package/dist/lib/validators/lastname.validator.js.map +0 -1
- package/dist/lib/validators/middlename.validator.d.ts +0 -20
- package/dist/lib/validators/middlename.validator.js +0 -38
- package/dist/lib/validators/middlename.validator.js.map +0 -1
- package/dist/lib/validators/nama.validator.d.ts +0 -21
- package/dist/lib/validators/nama.validator.js +0 -44
- package/dist/lib/validators/nama.validator.js.map +0 -1
- package/dist/lib/validators/namon.validator.d.ts +0 -20
- package/dist/lib/validators/namon.validator.js +0 -29
- package/dist/lib/validators/namon.validator.js.map +0 -1
- package/dist/lib/validators/prefix.validator.d.ts +0 -14
- package/dist/lib/validators/prefix.validator.js +0 -31
- package/dist/lib/validators/prefix.validator.js.map +0 -1
- package/dist/lib/validators/string-name.validator.d.ts +0 -20
- package/dist/lib/validators/string-name.validator.js +0 -29
- package/dist/lib/validators/string-name.validator.js.map +0 -1
- package/dist/lib/validators/suffix.validator.d.ts +0 -14
- package/dist/lib/validators/suffix.validator.js +0 -31
- package/dist/lib/validators/suffix.validator.js.map +0 -1
- package/dist/lib/validators/validator.d.ts +0 -13
- package/dist/lib/validators/validator.js +0 -9
- package/dist/lib/validators/validator.js.map +0 -1
|
@@ -0,0 +1,2734 @@
|
|
|
1
|
+
/******/ (function(modules) { // webpackBootstrap
|
|
2
|
+
/******/ // The module cache
|
|
3
|
+
/******/ var installedModules = {};
|
|
4
|
+
/******/
|
|
5
|
+
/******/ // The require function
|
|
6
|
+
/******/ function __webpack_require__(moduleId) {
|
|
7
|
+
/******/
|
|
8
|
+
/******/ // Check if module is in cache
|
|
9
|
+
/******/ if(installedModules[moduleId]) {
|
|
10
|
+
/******/ return installedModules[moduleId].exports;
|
|
11
|
+
/******/ }
|
|
12
|
+
/******/ // Create a new module (and put it into the cache)
|
|
13
|
+
/******/ var module = installedModules[moduleId] = {
|
|
14
|
+
/******/ i: moduleId,
|
|
15
|
+
/******/ l: false,
|
|
16
|
+
/******/ exports: {}
|
|
17
|
+
/******/ };
|
|
18
|
+
/******/
|
|
19
|
+
/******/ // Execute the module function
|
|
20
|
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
21
|
+
/******/
|
|
22
|
+
/******/ // Flag the module as loaded
|
|
23
|
+
/******/ module.l = true;
|
|
24
|
+
/******/
|
|
25
|
+
/******/ // Return the exports of the module
|
|
26
|
+
/******/ return module.exports;
|
|
27
|
+
/******/ }
|
|
28
|
+
/******/
|
|
29
|
+
/******/
|
|
30
|
+
/******/ // expose the modules object (__webpack_modules__)
|
|
31
|
+
/******/ __webpack_require__.m = modules;
|
|
32
|
+
/******/
|
|
33
|
+
/******/ // expose the module cache
|
|
34
|
+
/******/ __webpack_require__.c = installedModules;
|
|
35
|
+
/******/
|
|
36
|
+
/******/ // define getter function for harmony exports
|
|
37
|
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
|
38
|
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
|
39
|
+
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
|
40
|
+
/******/ }
|
|
41
|
+
/******/ };
|
|
42
|
+
/******/
|
|
43
|
+
/******/ // define __esModule on exports
|
|
44
|
+
/******/ __webpack_require__.r = function(exports) {
|
|
45
|
+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
46
|
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
47
|
+
/******/ }
|
|
48
|
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
49
|
+
/******/ };
|
|
50
|
+
/******/
|
|
51
|
+
/******/ // create a fake namespace object
|
|
52
|
+
/******/ // mode & 1: value is a module id, require it
|
|
53
|
+
/******/ // mode & 2: merge all properties of value into the ns
|
|
54
|
+
/******/ // mode & 4: return value when already ns object
|
|
55
|
+
/******/ // mode & 8|1: behave like require
|
|
56
|
+
/******/ __webpack_require__.t = function(value, mode) {
|
|
57
|
+
/******/ if(mode & 1) value = __webpack_require__(value);
|
|
58
|
+
/******/ if(mode & 8) return value;
|
|
59
|
+
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
|
60
|
+
/******/ var ns = Object.create(null);
|
|
61
|
+
/******/ __webpack_require__.r(ns);
|
|
62
|
+
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
|
63
|
+
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
|
64
|
+
/******/ return ns;
|
|
65
|
+
/******/ };
|
|
66
|
+
/******/
|
|
67
|
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
68
|
+
/******/ __webpack_require__.n = function(module) {
|
|
69
|
+
/******/ var getter = module && module.__esModule ?
|
|
70
|
+
/******/ function getDefault() { return module['default']; } :
|
|
71
|
+
/******/ function getModuleExports() { return module; };
|
|
72
|
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
|
73
|
+
/******/ return getter;
|
|
74
|
+
/******/ };
|
|
75
|
+
/******/
|
|
76
|
+
/******/ // Object.prototype.hasOwnProperty.call
|
|
77
|
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
|
78
|
+
/******/
|
|
79
|
+
/******/ // __webpack_public_path__
|
|
80
|
+
/******/ __webpack_require__.p = "";
|
|
81
|
+
/******/
|
|
82
|
+
/******/
|
|
83
|
+
/******/ // Load entry module and return exports
|
|
84
|
+
/******/ return __webpack_require__(__webpack_require__.s = "./example/example.ts");
|
|
85
|
+
/******/ })
|
|
86
|
+
/************************************************************************/
|
|
87
|
+
/******/ ({
|
|
88
|
+
|
|
89
|
+
/***/ "./example/example.ts":
|
|
90
|
+
/*!****************************!*\
|
|
91
|
+
!*** ./example/example.ts ***!
|
|
92
|
+
\****************************/
|
|
93
|
+
/*! no static exports found */
|
|
94
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
95
|
+
|
|
96
|
+
"use strict";
|
|
97
|
+
|
|
98
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
99
|
+
const index_1 = __webpack_require__(/*! ../src/index */ "./src/index.ts");
|
|
100
|
+
function example() {
|
|
101
|
+
// Gives a simple name some super power.
|
|
102
|
+
const name = new index_1.Namefully('Thomas Alva Edison', { orderedBy: index_1.NameOrder.LAST_NAME });
|
|
103
|
+
// Gets the count of characters, including space.
|
|
104
|
+
console.log(name.length); // 18
|
|
105
|
+
// Gets the first name.
|
|
106
|
+
console.log(name.first); // Thomas
|
|
107
|
+
// Gets the first middle name.
|
|
108
|
+
console.log(name.middle); // Alva
|
|
109
|
+
// Gets the last name.
|
|
110
|
+
console.log(name.last); // Edison
|
|
111
|
+
// Controls what the public sees.
|
|
112
|
+
console.log(name.public); // Thomas E
|
|
113
|
+
// Gets all the initials.
|
|
114
|
+
console.log(name.initials()); // ['T', 'A', 'E']
|
|
115
|
+
// Formats it as desired.
|
|
116
|
+
console.log(name.format('L, f m')); // EDISON, Thomas Alva
|
|
117
|
+
// Makes it short.
|
|
118
|
+
console.log(name.shorten()); // Thomas Edison
|
|
119
|
+
// Makes it flat.
|
|
120
|
+
console.log(name.zip()); // Thomas A. E.
|
|
121
|
+
// Makes it uppercase.
|
|
122
|
+
console.log(name.toUpperCase()); // THOMAS ALVA EDISON
|
|
123
|
+
// Transforms it into dot.case.
|
|
124
|
+
console.log(name.toDotCase()); // thomas.alva.edison
|
|
125
|
+
}
|
|
126
|
+
example();
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
/***/ }),
|
|
130
|
+
|
|
131
|
+
/***/ "./src/config.ts":
|
|
132
|
+
/*!***********************!*\
|
|
133
|
+
!*** ./src/config.ts ***!
|
|
134
|
+
\***********************/
|
|
135
|
+
/*! no static exports found */
|
|
136
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
137
|
+
|
|
138
|
+
"use strict";
|
|
139
|
+
|
|
140
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
141
|
+
exports.Config = void 0;
|
|
142
|
+
const types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
|
|
143
|
+
const defaultName = 'default';
|
|
144
|
+
const copyAlias = '_copy';
|
|
145
|
+
/**
|
|
146
|
+
* The Configuration to use across the other components.
|
|
147
|
+
*
|
|
148
|
+
* The multiton pattern is used to handle configurations across the `namefully`
|
|
149
|
+
* setup. This adds consistency when building other components such as `FirstName`,
|
|
150
|
+
* `LastName`, or `Name` of distinct types that may be of particular shapes.
|
|
151
|
+
*
|
|
152
|
+
* For example, a person's `FullName` may appear by:
|
|
153
|
+
* - NameOrder.FIRST_NAME: `Jon Snow` or
|
|
154
|
+
* - NameOrder.LAST_NAME: `Snow Jon`.
|
|
155
|
+
*
|
|
156
|
+
* `Config` makes it easy to set up a specific configuration for `Namefully`
|
|
157
|
+
* and reuse it through other instances or components along the way. If a new
|
|
158
|
+
* `Config` is needed, a named configuration may be created. It is actually
|
|
159
|
+
* advised to use named `Config.create(name)` instead as it may help mitigate issues
|
|
160
|
+
* and avoid confusion and ambiguity in the future. Plus, a named configuration
|
|
161
|
+
* explains its purpose.
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* const defaultConfig = Config.create();
|
|
165
|
+
* const mergedConfig = Config.merge({ name: 'other', title: Title.US });
|
|
166
|
+
* const copyConfig = mergedConfig.copyWith({ ending: true });
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* Additionally, a configuration may be merged with or copied from an existing
|
|
170
|
+
* configuration, prioritizing the new one's values, as shown in the example
|
|
171
|
+
* above.
|
|
172
|
+
*/
|
|
173
|
+
class Config {
|
|
174
|
+
constructor(name, orderedBy = types_1.NameOrder.FIRST_NAME, separator = types_1.Separator.SPACE, title = types_1.Title.UK, ending = false, bypass = true, surname = types_1.Surname.FATHER) {
|
|
175
|
+
this._name = name;
|
|
176
|
+
this._orderedBy = orderedBy;
|
|
177
|
+
this._separator = separator;
|
|
178
|
+
this._title = title;
|
|
179
|
+
this._ending = ending;
|
|
180
|
+
this._bypass = bypass;
|
|
181
|
+
this._surname = surname;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* The order of appearance of a full name.
|
|
185
|
+
*/
|
|
186
|
+
get orderedBy() {
|
|
187
|
+
return this._orderedBy;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The token used to indicate how to split string values.
|
|
191
|
+
*/
|
|
192
|
+
get separator() {
|
|
193
|
+
return this._separator;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The abbreviation type to indicate whether or not to add period to a prefix
|
|
197
|
+
* using the American or British way.
|
|
198
|
+
*/
|
|
199
|
+
get title() {
|
|
200
|
+
return this._title;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* The option indicating if an ending suffix is used in a formal way.
|
|
204
|
+
*/
|
|
205
|
+
get ending() {
|
|
206
|
+
return this._ending;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* A bypass of the validation rules with this option. This option is ideal
|
|
210
|
+
* to avoid checking their validity.
|
|
211
|
+
*/
|
|
212
|
+
get bypass() {
|
|
213
|
+
return this._bypass;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* An option indicating how to format a surname.
|
|
217
|
+
*
|
|
218
|
+
* The supported formats are:
|
|
219
|
+
* - `FATHER` name only
|
|
220
|
+
* - `MOTHER` name only
|
|
221
|
+
* - `HYPHENATED`, joining both father and mother names with a hyphen
|
|
222
|
+
* - `ALL`, joining both father and mother names with a space.
|
|
223
|
+
*
|
|
224
|
+
* Note that this option can be set when creating a `LastName`. As this can
|
|
225
|
+
* become ambiguous at the time of handling it, the value set in this is
|
|
226
|
+
* prioritized and viewed as the source of truth for future considerations.
|
|
227
|
+
*/
|
|
228
|
+
get surname() {
|
|
229
|
+
return this._surname;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* The name of the cached configuration.
|
|
233
|
+
*/
|
|
234
|
+
get name() {
|
|
235
|
+
return this._name;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Returns a named configuration with default values.
|
|
239
|
+
* @param name describing its purpose.
|
|
240
|
+
*/
|
|
241
|
+
static create(name = defaultName) {
|
|
242
|
+
if (!Config.cache.has(name)) {
|
|
243
|
+
Config.cache.set(name, new this(name));
|
|
244
|
+
}
|
|
245
|
+
return Config.cache.get(name);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Returns a combined version of the existing values of the default configuration
|
|
249
|
+
* and the provided optional values of another configuration.
|
|
250
|
+
* @param other partial config to be combined with.
|
|
251
|
+
*/
|
|
252
|
+
static merge(other) {
|
|
253
|
+
var _a, _b, _c, _d, _e, _f;
|
|
254
|
+
if (!other) {
|
|
255
|
+
return Config.create();
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
const config = Config.create(other.name);
|
|
259
|
+
config._orderedBy = (_a = other.orderedBy) !== null && _a !== void 0 ? _a : config.orderedBy;
|
|
260
|
+
config._separator = (_b = other.separator) !== null && _b !== void 0 ? _b : config.separator;
|
|
261
|
+
config._title = (_c = other.title) !== null && _c !== void 0 ? _c : config.title;
|
|
262
|
+
config._ending = (_d = other.ending) !== null && _d !== void 0 ? _d : config.ending;
|
|
263
|
+
config._bypass = (_e = other.bypass) !== null && _e !== void 0 ? _e : config.bypass;
|
|
264
|
+
config._surname = (_f = other.surname) !== null && _f !== void 0 ? _f : config.surname;
|
|
265
|
+
return config;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Returns a copy of this configuration merged with the provided values.
|
|
270
|
+
*
|
|
271
|
+
* The word `_copy` is added to the existing config's name to create the new
|
|
272
|
+
* config's name if the name already exists for previous configurations. This
|
|
273
|
+
* is useful to maintain the uniqueness of each configuration. For example,
|
|
274
|
+
* if the new copy is made from the default configuration, this new copy will
|
|
275
|
+
* be named `default_copy`.
|
|
276
|
+
*/
|
|
277
|
+
copyWith(options = {}) {
|
|
278
|
+
const { name, orderedBy, separator, title, ending, bypass, surname } = options;
|
|
279
|
+
const config = Config.create(this.genNewName(name !== null && name !== void 0 ? name : this.name + copyAlias));
|
|
280
|
+
config._orderedBy = orderedBy !== null && orderedBy !== void 0 ? orderedBy : this.orderedBy;
|
|
281
|
+
config._separator = separator !== null && separator !== void 0 ? separator : this.separator;
|
|
282
|
+
config._title = title !== null && title !== void 0 ? title : this.title;
|
|
283
|
+
config._ending = ending !== null && ending !== void 0 ? ending : this.ending;
|
|
284
|
+
config._bypass = bypass !== null && bypass !== void 0 ? bypass : this.bypass;
|
|
285
|
+
config._surname = surname !== null && surname !== void 0 ? surname : this.surname;
|
|
286
|
+
return config;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Makes an exact copy of the current configuration.
|
|
290
|
+
*/
|
|
291
|
+
clone() {
|
|
292
|
+
return this.copyWith();
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Resets the configuration by setting it back to its default values.
|
|
296
|
+
*/
|
|
297
|
+
reset() {
|
|
298
|
+
this._orderedBy = types_1.NameOrder.FIRST_NAME;
|
|
299
|
+
this._separator = types_1.Separator.SPACE;
|
|
300
|
+
this._title = types_1.Title.UK;
|
|
301
|
+
this._ending = false;
|
|
302
|
+
this._bypass = true;
|
|
303
|
+
this._surname = types_1.Surname.FATHER;
|
|
304
|
+
Config.cache.set(this.name, this);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Alters the name order between the first and last name, and rearrange the
|
|
308
|
+
* order of appearance of a name set.
|
|
309
|
+
*/
|
|
310
|
+
updateOrder(order) {
|
|
311
|
+
if (order && order !== this._orderedBy) {
|
|
312
|
+
Config.cache.get(this.name)._orderedBy = order;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Generates a unique new name.
|
|
317
|
+
*/
|
|
318
|
+
genNewName(name) {
|
|
319
|
+
return name === this.name || Config.cache.has(name) ? this.genNewName(name + copyAlias) : name;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
exports.Config = Config;
|
|
323
|
+
/**
|
|
324
|
+
* Cache for multiple instances.
|
|
325
|
+
*/
|
|
326
|
+
Config.cache = new Map();
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
/***/ }),
|
|
330
|
+
|
|
331
|
+
/***/ "./src/constants.ts":
|
|
332
|
+
/*!**************************!*\
|
|
333
|
+
!*** ./src/constants.ts ***!
|
|
334
|
+
\**************************/
|
|
335
|
+
/*! no static exports found */
|
|
336
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
337
|
+
|
|
338
|
+
"use strict";
|
|
339
|
+
|
|
340
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
341
|
+
exports.ALLOWED_TOKENS = exports.MAX_NUMBER_OF_NAME_PARTS = exports.MIN_NUMBER_OF_NAME_PARTS = exports.version = void 0;
|
|
342
|
+
exports.version = '1.2.0';
|
|
343
|
+
exports.MIN_NUMBER_OF_NAME_PARTS = 2;
|
|
344
|
+
exports.MAX_NUMBER_OF_NAME_PARTS = 5;
|
|
345
|
+
exports.ALLOWED_TOKENS = [
|
|
346
|
+
'.',
|
|
347
|
+
',',
|
|
348
|
+
' ',
|
|
349
|
+
'-',
|
|
350
|
+
'_',
|
|
351
|
+
'b',
|
|
352
|
+
'B',
|
|
353
|
+
'f',
|
|
354
|
+
'F',
|
|
355
|
+
'l',
|
|
356
|
+
'L',
|
|
357
|
+
'm',
|
|
358
|
+
'M',
|
|
359
|
+
'n',
|
|
360
|
+
'N',
|
|
361
|
+
'o',
|
|
362
|
+
'O',
|
|
363
|
+
'p',
|
|
364
|
+
'P',
|
|
365
|
+
's',
|
|
366
|
+
'S',
|
|
367
|
+
'$',
|
|
368
|
+
];
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
/***/ }),
|
|
372
|
+
|
|
373
|
+
/***/ "./src/error.ts":
|
|
374
|
+
/*!**********************!*\
|
|
375
|
+
!*** ./src/error.ts ***!
|
|
376
|
+
\**********************/
|
|
377
|
+
/*! no static exports found */
|
|
378
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
379
|
+
|
|
380
|
+
"use strict";
|
|
381
|
+
|
|
382
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
383
|
+
exports.UnknownError = exports.NotAllowedError = exports.ValidationError = exports.InputError = exports.NameError = exports.NameErrorType = void 0;
|
|
384
|
+
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
|
|
385
|
+
/**
|
|
386
|
+
* The error types supported by `Namefully`.
|
|
387
|
+
*/
|
|
388
|
+
var NameErrorType;
|
|
389
|
+
(function (NameErrorType) {
|
|
390
|
+
/**
|
|
391
|
+
* Thrown when a name entry/argument is incorrect.
|
|
392
|
+
*
|
|
393
|
+
* For example, a name should have a minimum of 2 characters, so an empty
|
|
394
|
+
* string or a string of one character would cause this kind of error.
|
|
395
|
+
*/
|
|
396
|
+
NameErrorType[NameErrorType["INPUT"] = 0] = "INPUT";
|
|
397
|
+
/**
|
|
398
|
+
* Thrown when the name components do not match the validation rules if the
|
|
399
|
+
* `Config.bypass` is not flagged up. This bypass option skips the validation
|
|
400
|
+
* rules.
|
|
401
|
+
*
|
|
402
|
+
* See also: `ValidationError`
|
|
403
|
+
*/
|
|
404
|
+
NameErrorType[NameErrorType["VALIDATION"] = 1] = "VALIDATION";
|
|
405
|
+
/**
|
|
406
|
+
* Thrown by not allowed operations such as in NameBuilder or name formatting.
|
|
407
|
+
*
|
|
408
|
+
* See also: `NotAllowedError`, `Namefully.format`.
|
|
409
|
+
*/
|
|
410
|
+
NameErrorType[NameErrorType["NOT_ALLOWED"] = 2] = "NOT_ALLOWED";
|
|
411
|
+
/**
|
|
412
|
+
* Thrown by any other unknown sources or unexpected situation.
|
|
413
|
+
*/
|
|
414
|
+
NameErrorType[NameErrorType["UNKNOWN"] = 3] = "UNKNOWN";
|
|
415
|
+
})(NameErrorType = exports.NameErrorType || (exports.NameErrorType = {}));
|
|
416
|
+
/**
|
|
417
|
+
* Base class for all name-related errors.
|
|
418
|
+
*
|
|
419
|
+
* A custom error is intended to convey information to the user about a failure,
|
|
420
|
+
* so that it can be addressed programmatically.
|
|
421
|
+
*
|
|
422
|
+
* A name handling failure is not considered a native error that should cause a
|
|
423
|
+
* program failure. Au contraire, it is expected that a programmer using this utility
|
|
424
|
+
* would consider validating a name using its own business rules. That is not
|
|
425
|
+
* this utility's job to guess those rules. So, the predefined `ValidationRules`
|
|
426
|
+
* obey some common validation techniques when it comes to sanitizing a person
|
|
427
|
+
* name. For this reason, the [Config.bypass] is set to `true` by default,
|
|
428
|
+
* indicating that those predefined rules should be skipped for the sake of the
|
|
429
|
+
* program.
|
|
430
|
+
*
|
|
431
|
+
* A programmer may leverage `Parser` to indicate business-tailored rules if he
|
|
432
|
+
* or she wants this utility to perform those safety checks behind the scenes.
|
|
433
|
+
*
|
|
434
|
+
* A name error intends to provide useful information about what causes the error
|
|
435
|
+
* and let the user take initiative on what happens next to the given name:
|
|
436
|
+
* reconstructing it or skipping it.
|
|
437
|
+
*/
|
|
438
|
+
class NameError extends Error {
|
|
439
|
+
/**
|
|
440
|
+
* Creates an error with a message describing the issue for a name source.
|
|
441
|
+
* @param source name input that caused the error
|
|
442
|
+
* @param message a message describing the failure.
|
|
443
|
+
* @param type of `NameErrorType`
|
|
444
|
+
*/
|
|
445
|
+
constructor(source, message, type = NameErrorType.UNKNOWN) {
|
|
446
|
+
super(message);
|
|
447
|
+
this.source = source;
|
|
448
|
+
this.type = type;
|
|
449
|
+
this.name = 'NameError';
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* The actual source input which caused the error.
|
|
453
|
+
*/
|
|
454
|
+
get sourceAsString() {
|
|
455
|
+
let input = '';
|
|
456
|
+
if (!this.source)
|
|
457
|
+
input = '<undefined>';
|
|
458
|
+
if (typeof this.source === 'string')
|
|
459
|
+
input = this.source;
|
|
460
|
+
if (utils_1.isNameArray(this.source))
|
|
461
|
+
input = this.source.map((n) => n.toString()).join(' ');
|
|
462
|
+
if (utils_1.isStringArray(this.source))
|
|
463
|
+
input = this.source.join(' ');
|
|
464
|
+
return input;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Whether a message describing the failure exists.
|
|
468
|
+
*/
|
|
469
|
+
get hasMessage() {
|
|
470
|
+
return this.message && this.message.trim().length > 0;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Returns a string representation of the error.
|
|
474
|
+
*/
|
|
475
|
+
toString() {
|
|
476
|
+
let report = `${this.name} (${this.sourceAsString})`;
|
|
477
|
+
if (this.hasMessage)
|
|
478
|
+
report = `${report}: ${this.message}`;
|
|
479
|
+
return report;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
exports.NameError = NameError;
|
|
483
|
+
/**
|
|
484
|
+
* An error thrown when a name source input is incorrect.
|
|
485
|
+
*
|
|
486
|
+
* A `Name` is a name for this utility under certain criteria (i.e., 2+ chars),
|
|
487
|
+
* hence, a wrong input will cause this kind of error. Another common reason
|
|
488
|
+
* may be a wrong key in a Json name parsing mechanism.
|
|
489
|
+
*
|
|
490
|
+
* Keep in mind that this error is different from a `ValidationError`.
|
|
491
|
+
*/
|
|
492
|
+
class InputError extends NameError {
|
|
493
|
+
/**
|
|
494
|
+
* Creates a new `InputError` with an optional error `message`.
|
|
495
|
+
*
|
|
496
|
+
* The name source is by nature a string content, maybe wrapped up in a different
|
|
497
|
+
* type. This string value may be extracted to form the following output:
|
|
498
|
+
* "InputError (stringName)",
|
|
499
|
+
* "InputError (stringName): message".
|
|
500
|
+
*/
|
|
501
|
+
constructor(error) {
|
|
502
|
+
super(error.source, error.message, NameErrorType.INPUT);
|
|
503
|
+
this.name = 'InputError';
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
exports.InputError = InputError;
|
|
507
|
+
/**
|
|
508
|
+
* An error thrown to indicate that a name fails the validation rules.
|
|
509
|
+
*/
|
|
510
|
+
class ValidationError extends NameError {
|
|
511
|
+
/**
|
|
512
|
+
* Creates error containing the invalid `nameType` and a `message` that
|
|
513
|
+
* briefly describes the problem if provided.
|
|
514
|
+
*
|
|
515
|
+
* For example, a validation error can be interpreted as:
|
|
516
|
+
* "ValidationError (nameType='stringName')",
|
|
517
|
+
* "ValidationError (nameType='stringName'): message"
|
|
518
|
+
*/
|
|
519
|
+
constructor(error) {
|
|
520
|
+
super(error.source, error.message, NameErrorType.VALIDATION);
|
|
521
|
+
this.nameType = error.nameType;
|
|
522
|
+
this.name = 'ValidationError';
|
|
523
|
+
}
|
|
524
|
+
toString() {
|
|
525
|
+
let report = `${this.name} (${this.nameType}='${this.sourceAsString}')`;
|
|
526
|
+
if (this.hasMessage)
|
|
527
|
+
report = `${report}: ${this.message}`;
|
|
528
|
+
return report;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
exports.ValidationError = ValidationError;
|
|
532
|
+
/**
|
|
533
|
+
* Thrown by not allowed operations such as in name formatting.
|
|
534
|
+
*
|
|
535
|
+
* For example, this will occur when trying to format a name accordingly using
|
|
536
|
+
* a non-supported key.
|
|
537
|
+
*/
|
|
538
|
+
class NotAllowedError extends NameError {
|
|
539
|
+
/**
|
|
540
|
+
* Creates a new `NotAllowedError` with an optional error `message` and the
|
|
541
|
+
* `operation` name.
|
|
542
|
+
*
|
|
543
|
+
* For example, an error of this kind can be interpreted as:
|
|
544
|
+
* "NotAllowedError (stringName)",
|
|
545
|
+
* "NotAllowedError (stringName) - operationName",
|
|
546
|
+
* "NotAllowedError (stringName) - operationName: message"
|
|
547
|
+
*/
|
|
548
|
+
constructor(error) {
|
|
549
|
+
super(error.source, error.message, NameErrorType.NOT_ALLOWED);
|
|
550
|
+
this.operation = error.operation;
|
|
551
|
+
this.name = 'NotAllowedError';
|
|
552
|
+
}
|
|
553
|
+
toString() {
|
|
554
|
+
let report = `${this.name} (${this.sourceAsString})`;
|
|
555
|
+
if (this.operation && this.operation.trim().length > 0)
|
|
556
|
+
report = `${report} - ${this.operation}`;
|
|
557
|
+
if (this.hasMessage)
|
|
558
|
+
report = `${report}: ${this.message}`;
|
|
559
|
+
return report;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
exports.NotAllowedError = NotAllowedError;
|
|
563
|
+
/**
|
|
564
|
+
* A fallback error thrown by any unknown sources or unexpected failure that are
|
|
565
|
+
* not of `NameError`.
|
|
566
|
+
*
|
|
567
|
+
* In this particular case, an `origin` remains useful as it provides details
|
|
568
|
+
* on the sources and the true nature of the unexpected error.
|
|
569
|
+
* At this point, deciding whether to exit the program or not depends on the
|
|
570
|
+
* programmer.
|
|
571
|
+
*/
|
|
572
|
+
class UnknownError extends NameError {
|
|
573
|
+
/**
|
|
574
|
+
* Creates a new `UnknownError` with an optional error `message`.
|
|
575
|
+
* Optionally, the original error revealing the true nature of the failure.
|
|
576
|
+
*/
|
|
577
|
+
constructor(error) {
|
|
578
|
+
super(error.source, error.message, NameErrorType.UNKNOWN);
|
|
579
|
+
this.origin = error.error;
|
|
580
|
+
this.name = 'UnknownError';
|
|
581
|
+
}
|
|
582
|
+
toString() {
|
|
583
|
+
let report = super.toString();
|
|
584
|
+
if (this.origin)
|
|
585
|
+
report += `\n${this.origin.toString()}`;
|
|
586
|
+
return report;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
exports.UnknownError = UnknownError;
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
/***/ }),
|
|
593
|
+
|
|
594
|
+
/***/ "./src/full-name.ts":
|
|
595
|
+
/*!**************************!*\
|
|
596
|
+
!*** ./src/full-name.ts ***!
|
|
597
|
+
\**************************/
|
|
598
|
+
/*! no static exports found */
|
|
599
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
600
|
+
|
|
601
|
+
"use strict";
|
|
602
|
+
|
|
603
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
604
|
+
exports.FullName = void 0;
|
|
605
|
+
const config_1 = __webpack_require__(/*! ./config */ "./src/config.ts");
|
|
606
|
+
const error_1 = __webpack_require__(/*! ./error */ "./src/error.ts");
|
|
607
|
+
const name_1 = __webpack_require__(/*! ./name */ "./src/name.ts");
|
|
608
|
+
const types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
|
|
609
|
+
const validator_1 = __webpack_require__(/*! ./validator */ "./src/validator.ts");
|
|
610
|
+
/**
|
|
611
|
+
* The core component of this utility.
|
|
612
|
+
*
|
|
613
|
+
* This component is comprised of five entities that make it easy to handle a
|
|
614
|
+
* full name set: prefix, first name, middle name, last name, and suffix.
|
|
615
|
+
* This class is intended for internal processes. However, it is understandable
|
|
616
|
+
* that it might be needed at some point for additional purposes. For this reason,
|
|
617
|
+
* it's made available.
|
|
618
|
+
*
|
|
619
|
+
* It is recommended to avoid using this class unless it is highly necessary or
|
|
620
|
+
* a custom parser is used for uncommon use cases. This utility tries to cover
|
|
621
|
+
* as many use cases as possible.
|
|
622
|
+
*
|
|
623
|
+
* Additionally, an optional configuration can be used to indicate some specific
|
|
624
|
+
* behaviors related to that name handling.
|
|
625
|
+
*/
|
|
626
|
+
class FullName {
|
|
627
|
+
/**
|
|
628
|
+
* Creates a full name as it goes
|
|
629
|
+
* @param options optional configuration for additional features.
|
|
630
|
+
*/
|
|
631
|
+
constructor(options) {
|
|
632
|
+
this._middleName = [];
|
|
633
|
+
this._config = config_1.Config.merge(options);
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* A snapshot of the configuration used to set up this full name.
|
|
637
|
+
*/
|
|
638
|
+
get config() {
|
|
639
|
+
return this._config;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* The prefix part of the full name.
|
|
643
|
+
*/
|
|
644
|
+
get prefix() {
|
|
645
|
+
return this._prefix;
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* The first name part of the full name.
|
|
649
|
+
*/
|
|
650
|
+
get firstName() {
|
|
651
|
+
return this._firstName;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* The last name part of the full name.
|
|
655
|
+
*/
|
|
656
|
+
get lastName() {
|
|
657
|
+
return this._lastName;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* The middle name part of the full name.
|
|
661
|
+
*/
|
|
662
|
+
get middleName() {
|
|
663
|
+
return this._middleName;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* The suffix part of the full name.
|
|
667
|
+
*/
|
|
668
|
+
get suffix() {
|
|
669
|
+
return this._suffix;
|
|
670
|
+
}
|
|
671
|
+
setPrefix(name) {
|
|
672
|
+
if (!name)
|
|
673
|
+
return this;
|
|
674
|
+
if (!this._config.bypass)
|
|
675
|
+
validator_1.Validators.prefix.validate(name);
|
|
676
|
+
const prefix = name instanceof name_1.Name ? name.value : name;
|
|
677
|
+
this._prefix = name_1.Name.prefix(this._config.title === types_1.Title.US ? `${prefix}.` : prefix);
|
|
678
|
+
return this;
|
|
679
|
+
}
|
|
680
|
+
setFirstName(name) {
|
|
681
|
+
if (!this._config.bypass)
|
|
682
|
+
validator_1.Validators.firstName.validate(name);
|
|
683
|
+
this._firstName = name instanceof name_1.FirstName ? name : new name_1.FirstName(name);
|
|
684
|
+
return this;
|
|
685
|
+
}
|
|
686
|
+
setLastName(name) {
|
|
687
|
+
if (!this._config.bypass)
|
|
688
|
+
validator_1.Validators.lastName.validate(name);
|
|
689
|
+
this._lastName = name instanceof name_1.LastName ? name : new name_1.LastName(name);
|
|
690
|
+
return this;
|
|
691
|
+
}
|
|
692
|
+
setMiddleName(names) {
|
|
693
|
+
if (!Array.isArray(names))
|
|
694
|
+
return;
|
|
695
|
+
if (!this._config.bypass)
|
|
696
|
+
validator_1.Validators.middleName.validate(names);
|
|
697
|
+
this._middleName = names.map((name) => name instanceof name_1.Name ? name : name_1.Name.middle(name));
|
|
698
|
+
return this;
|
|
699
|
+
}
|
|
700
|
+
setSuffix(name) {
|
|
701
|
+
if (!name)
|
|
702
|
+
return this;
|
|
703
|
+
if (!this._config.bypass)
|
|
704
|
+
validator_1.Validators.suffix.validate(name);
|
|
705
|
+
this._suffix = name_1.Name.suffix(name instanceof name_1.Name ? name.value : name);
|
|
706
|
+
return this;
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Returns true if a namon has been set.
|
|
710
|
+
*/
|
|
711
|
+
has(namon) {
|
|
712
|
+
if (namon.equal(types_1.Namon.PREFIX))
|
|
713
|
+
return !!this._prefix;
|
|
714
|
+
if (namon.equal(types_1.Namon.SUFFIX))
|
|
715
|
+
return !!this._suffix;
|
|
716
|
+
return namon.equal(types_1.Namon.MIDDLE_NAME) ? this._middleName.length > 0 : true;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Parses a json name into a full name.
|
|
720
|
+
* @param json parsable name element
|
|
721
|
+
* @param config optional configuration for additional features.
|
|
722
|
+
*/
|
|
723
|
+
static parse(json, config) {
|
|
724
|
+
try {
|
|
725
|
+
const fullName = new FullName(config);
|
|
726
|
+
fullName.setPrefix(json.prefix);
|
|
727
|
+
fullName.setFirstName(json.firstName);
|
|
728
|
+
fullName.setMiddleName(json.middleName);
|
|
729
|
+
fullName.setLastName(json.lastName);
|
|
730
|
+
fullName.setSuffix(json.suffix);
|
|
731
|
+
return fullName;
|
|
732
|
+
}
|
|
733
|
+
catch (error) {
|
|
734
|
+
if (error instanceof error_1.NameError) {
|
|
735
|
+
throw error;
|
|
736
|
+
}
|
|
737
|
+
else {
|
|
738
|
+
throw new error_1.UnknownError({
|
|
739
|
+
source: Object.values(json).join(' '),
|
|
740
|
+
message: 'could not parse JSON content',
|
|
741
|
+
error,
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
exports.FullName = FullName;
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
/***/ }),
|
|
751
|
+
|
|
752
|
+
/***/ "./src/index.ts":
|
|
753
|
+
/*!**********************!*\
|
|
754
|
+
!*** ./src/index.ts ***!
|
|
755
|
+
\**********************/
|
|
756
|
+
/*! no static exports found */
|
|
757
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
758
|
+
|
|
759
|
+
"use strict";
|
|
760
|
+
|
|
761
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
762
|
+
if (k2 === undefined) k2 = k;
|
|
763
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
764
|
+
}) : (function(o, m, k, k2) {
|
|
765
|
+
if (k2 === undefined) k2 = k;
|
|
766
|
+
o[k2] = m[k];
|
|
767
|
+
}));
|
|
768
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
769
|
+
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
|
|
770
|
+
};
|
|
771
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
772
|
+
/**
|
|
773
|
+
* Welcome to namefully!
|
|
774
|
+
*
|
|
775
|
+
* `namefully` is a JavaScript utility for handing person names.
|
|
776
|
+
*
|
|
777
|
+
* Sources
|
|
778
|
+
* - repo: https://github.com/ralflorent/namefully
|
|
779
|
+
* - docs: https://namefully.netlify.app
|
|
780
|
+
* - npm: https://npmjs.com/package/namefully
|
|
781
|
+
*
|
|
782
|
+
* @license MIT
|
|
783
|
+
*/
|
|
784
|
+
__exportStar(__webpack_require__(/*! ./config */ "./src/config.ts"), exports);
|
|
785
|
+
__exportStar(__webpack_require__(/*! ./error */ "./src/error.ts"), exports);
|
|
786
|
+
__exportStar(__webpack_require__(/*! ./full-name */ "./src/full-name.ts"), exports);
|
|
787
|
+
__exportStar(__webpack_require__(/*! ./name */ "./src/name.ts"), exports);
|
|
788
|
+
__exportStar(__webpack_require__(/*! ./namefully */ "./src/namefully.ts"), exports);
|
|
789
|
+
var parser_1 = __webpack_require__(/*! ./parser */ "./src/parser.ts");
|
|
790
|
+
Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return parser_1.Parser; } });
|
|
791
|
+
__exportStar(__webpack_require__(/*! ./types */ "./src/types.ts"), exports);
|
|
792
|
+
var utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
|
|
793
|
+
Object.defineProperty(exports, "NameIndex", { enumerable: true, get: function () { return utils_1.NameIndex; } });
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
/***/ }),
|
|
797
|
+
|
|
798
|
+
/***/ "./src/name.ts":
|
|
799
|
+
/*!*********************!*\
|
|
800
|
+
!*** ./src/name.ts ***!
|
|
801
|
+
\*********************/
|
|
802
|
+
/*! no static exports found */
|
|
803
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
804
|
+
|
|
805
|
+
"use strict";
|
|
806
|
+
|
|
807
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
808
|
+
exports.LastName = exports.FirstName = exports.Name = void 0;
|
|
809
|
+
const error_1 = __webpack_require__(/*! ./error */ "./src/error.ts");
|
|
810
|
+
const types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
|
|
811
|
+
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
|
|
812
|
+
/**
|
|
813
|
+
* Representation of a string type name with some extra capabilities.
|
|
814
|
+
*/
|
|
815
|
+
class Name {
|
|
816
|
+
/**
|
|
817
|
+
* Creates augmented names by adding extra functionality to a string name.
|
|
818
|
+
* @param type must be indicated to categorize the name so it can be
|
|
819
|
+
* treated accordingly.
|
|
820
|
+
* @param capsRange determines how the name should be capitalized initially.
|
|
821
|
+
*/
|
|
822
|
+
constructor(value, type, capsRange) {
|
|
823
|
+
this.type = type;
|
|
824
|
+
this.capsRange = capsRange !== null && capsRange !== void 0 ? capsRange : types_1.CapsRange.INITIAL;
|
|
825
|
+
this.value = value;
|
|
826
|
+
if (capsRange)
|
|
827
|
+
this.caps(capsRange);
|
|
828
|
+
}
|
|
829
|
+
set value(newValue) {
|
|
830
|
+
if (newValue.trim().length < 2) {
|
|
831
|
+
throw new error_1.InputError({ source: newValue, message: 'must be 2+ characters' });
|
|
832
|
+
}
|
|
833
|
+
this.namon = newValue;
|
|
834
|
+
this.initial = newValue[0];
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* The piece of string treated as a name.
|
|
838
|
+
*/
|
|
839
|
+
get value() {
|
|
840
|
+
return this.namon;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* The length of the name.
|
|
844
|
+
*/
|
|
845
|
+
get length() {
|
|
846
|
+
return this.namon.length;
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Whether the name is a prefix.
|
|
850
|
+
*/
|
|
851
|
+
get isPrefix() {
|
|
852
|
+
return this.type === types_1.Namon.PREFIX;
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Whether the name is a first name.
|
|
856
|
+
*/
|
|
857
|
+
get isFirstName() {
|
|
858
|
+
return this.type === types_1.Namon.FIRST_NAME;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Whether the name is a middle name.
|
|
862
|
+
*/
|
|
863
|
+
get isMiddleName() {
|
|
864
|
+
return this.type === types_1.Namon.MIDDLE_NAME;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Whether the name is a last name.
|
|
868
|
+
*/
|
|
869
|
+
get isLastName() {
|
|
870
|
+
return this.type === types_1.Namon.LAST_NAME;
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Whether the name is a suffix.
|
|
874
|
+
*/
|
|
875
|
+
get isSuffix() {
|
|
876
|
+
return this.type === types_1.Namon.SUFFIX;
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Creates a prefix.
|
|
880
|
+
*/
|
|
881
|
+
static prefix(value) {
|
|
882
|
+
return new this(value, types_1.Namon.PREFIX);
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Creates a first name.
|
|
886
|
+
*/
|
|
887
|
+
static first(value) {
|
|
888
|
+
return new this(value, types_1.Namon.FIRST_NAME);
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Creates a middle name.
|
|
892
|
+
*/
|
|
893
|
+
static middle(value) {
|
|
894
|
+
return new this(value, types_1.Namon.MIDDLE_NAME);
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Creates a last name.
|
|
898
|
+
*/
|
|
899
|
+
static last(value) {
|
|
900
|
+
return new this(value, types_1.Namon.LAST_NAME);
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* Creates a suffix.
|
|
904
|
+
*/
|
|
905
|
+
static suffix(value) {
|
|
906
|
+
return new this(value, types_1.Namon.SUFFIX);
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Gets the initials (first character) of this name.
|
|
910
|
+
*/
|
|
911
|
+
initials() {
|
|
912
|
+
return [this.initial];
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* String representation of this object.
|
|
916
|
+
*/
|
|
917
|
+
toString() {
|
|
918
|
+
return this.namon;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Returns true if the other is equal to this name.
|
|
922
|
+
*/
|
|
923
|
+
equal(other) {
|
|
924
|
+
return other instanceof Name && other.value === this.value && other.type === this.type;
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Capitalizes the name.
|
|
928
|
+
*/
|
|
929
|
+
caps(range) {
|
|
930
|
+
this.value = utils_1.capitalize(this.namon, range !== null && range !== void 0 ? range : this.capsRange);
|
|
931
|
+
return this;
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* De-capitalizes the name.
|
|
935
|
+
*/
|
|
936
|
+
decaps(range) {
|
|
937
|
+
this.value = utils_1.decapitalize(this.namon, range !== null && range !== void 0 ? range : this.capsRange);
|
|
938
|
+
return this;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
exports.Name = Name;
|
|
942
|
+
/**
|
|
943
|
+
* Representation of a first name with some extra functionality.
|
|
944
|
+
*/
|
|
945
|
+
class FirstName extends Name {
|
|
946
|
+
/**
|
|
947
|
+
* Creates an extended version of `Name` and flags it as a first name `type`.
|
|
948
|
+
*
|
|
949
|
+
* Some may consider `more` additional name parts of a given name as their
|
|
950
|
+
* first names, but not as their middle names. Though, it may mean the same,
|
|
951
|
+
* `more` provides the freedom to do it as it pleases.
|
|
952
|
+
*/
|
|
953
|
+
constructor(value, ...more) {
|
|
954
|
+
super(value, types_1.Namon.FIRST_NAME);
|
|
955
|
+
for (const name of more) {
|
|
956
|
+
if (name.trim().length < 2) {
|
|
957
|
+
throw new error_1.InputError({ source: name, message: 'must be 2+ characters' });
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
this._more = more;
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Determines whether a first name has `more` name parts.
|
|
964
|
+
*/
|
|
965
|
+
get hasMore() {
|
|
966
|
+
return this._more.length > 0;
|
|
967
|
+
}
|
|
968
|
+
get length() {
|
|
969
|
+
return super.length + (this.hasMore ? this._more.reduce((acc, n) => acc + n).length : 0);
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Returns a combined version of the `value` and `more` if any.
|
|
973
|
+
*/
|
|
974
|
+
get asNames() {
|
|
975
|
+
const names = [Name.first(this.value)];
|
|
976
|
+
if (this.hasMore) {
|
|
977
|
+
names.push(...this._more.map((n) => Name.first(n)));
|
|
978
|
+
}
|
|
979
|
+
return names;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* The additional name parts of the first name.
|
|
983
|
+
*/
|
|
984
|
+
get more() {
|
|
985
|
+
return this._more;
|
|
986
|
+
}
|
|
987
|
+
toString(withMore = false) {
|
|
988
|
+
return withMore && this.hasMore ? `${this.value} ${this._more.join(' ')}`.trim() : this.value;
|
|
989
|
+
}
|
|
990
|
+
initials(withMore = false) {
|
|
991
|
+
const inits = [this.initial];
|
|
992
|
+
if (withMore && this.hasMore) {
|
|
993
|
+
inits.push(...this._more.map((n) => n[0]));
|
|
994
|
+
}
|
|
995
|
+
return inits;
|
|
996
|
+
}
|
|
997
|
+
caps(range) {
|
|
998
|
+
range = range || this.capsRange;
|
|
999
|
+
this.value = utils_1.capitalize(this.value, range);
|
|
1000
|
+
if (this.hasMore)
|
|
1001
|
+
this._more = this._more.map((n) => utils_1.capitalize(n, range));
|
|
1002
|
+
return this;
|
|
1003
|
+
}
|
|
1004
|
+
decaps(range) {
|
|
1005
|
+
range = range || this.capsRange;
|
|
1006
|
+
this.value = utils_1.decapitalize(this.value, range);
|
|
1007
|
+
if (this.hasMore)
|
|
1008
|
+
this._more = this._more.map((n) => utils_1.decapitalize(n, range));
|
|
1009
|
+
return this;
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Makes a copy of the current name.
|
|
1013
|
+
*/
|
|
1014
|
+
copyWith(values) {
|
|
1015
|
+
var _a, _b;
|
|
1016
|
+
return new FirstName((_a = values.first) !== null && _a !== void 0 ? _a : this.value, ...((_b = values.more) !== null && _b !== void 0 ? _b : this._more));
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
exports.FirstName = FirstName;
|
|
1020
|
+
/**
|
|
1021
|
+
* Representation of a last name with some extra functionality.
|
|
1022
|
+
*/
|
|
1023
|
+
class LastName extends Name {
|
|
1024
|
+
/**
|
|
1025
|
+
* Creates an extended version of `Name` and flags it as a last name `type`.
|
|
1026
|
+
*
|
|
1027
|
+
* Some people may keep their `mother`'s surname and want to keep a clear cut
|
|
1028
|
+
* from their `father`'s surname. However, there are no clear rules about it.
|
|
1029
|
+
*/
|
|
1030
|
+
constructor(father, mother, format = types_1.Surname.FATHER) {
|
|
1031
|
+
super(father, types_1.Namon.LAST_NAME);
|
|
1032
|
+
this.format = format;
|
|
1033
|
+
if (mother && mother.trim().length < 2) {
|
|
1034
|
+
throw new error_1.InputError({ source: mother, message: 'must be 2+ characters' });
|
|
1035
|
+
}
|
|
1036
|
+
this._mother = mother;
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* The surname inherited from a father side.
|
|
1040
|
+
*/
|
|
1041
|
+
get father() {
|
|
1042
|
+
return this.value;
|
|
1043
|
+
}
|
|
1044
|
+
/**
|
|
1045
|
+
* The surname inherited from a mother side.
|
|
1046
|
+
*/
|
|
1047
|
+
get mother() {
|
|
1048
|
+
return this._mother;
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Returns `true` if the mother's surname is defined.
|
|
1052
|
+
*/
|
|
1053
|
+
get hasMother() {
|
|
1054
|
+
return !!this._mother;
|
|
1055
|
+
}
|
|
1056
|
+
get length() {
|
|
1057
|
+
var _a, _b;
|
|
1058
|
+
return super.length + ((_b = (_a = this._mother) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0);
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Returns a combined version of the `father` and `mother` if any.
|
|
1062
|
+
*/
|
|
1063
|
+
get asNames() {
|
|
1064
|
+
const names = [Name.last(this.value)];
|
|
1065
|
+
if (this.hasMother) {
|
|
1066
|
+
names.push(Name.last(this._mother));
|
|
1067
|
+
}
|
|
1068
|
+
return names;
|
|
1069
|
+
}
|
|
1070
|
+
toString(format) {
|
|
1071
|
+
var _a;
|
|
1072
|
+
format = format !== null && format !== void 0 ? format : this.format;
|
|
1073
|
+
switch (format) {
|
|
1074
|
+
case types_1.Surname.FATHER:
|
|
1075
|
+
return this.value;
|
|
1076
|
+
case types_1.Surname.MOTHER:
|
|
1077
|
+
return (_a = this.mother) !== null && _a !== void 0 ? _a : '';
|
|
1078
|
+
case types_1.Surname.HYPHENATED:
|
|
1079
|
+
return this.hasMother ? `${this.value}-${this._mother}` : this.value;
|
|
1080
|
+
case types_1.Surname.ALL:
|
|
1081
|
+
return this.hasMother ? `${this.value} ${this._mother}` : this.value;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
initials(format) {
|
|
1085
|
+
format = format || this.format;
|
|
1086
|
+
const inits = [];
|
|
1087
|
+
switch (format) {
|
|
1088
|
+
case types_1.Surname.MOTHER:
|
|
1089
|
+
if (this.hasMother)
|
|
1090
|
+
inits.push(this._mother[0]);
|
|
1091
|
+
break;
|
|
1092
|
+
case types_1.Surname.HYPHENATED:
|
|
1093
|
+
case types_1.Surname.ALL:
|
|
1094
|
+
inits.push(this.initial);
|
|
1095
|
+
if (this.hasMother)
|
|
1096
|
+
inits.push(this._mother[0]);
|
|
1097
|
+
break;
|
|
1098
|
+
case types_1.Surname.FATHER:
|
|
1099
|
+
default:
|
|
1100
|
+
inits.push(this.initial);
|
|
1101
|
+
}
|
|
1102
|
+
return inits;
|
|
1103
|
+
}
|
|
1104
|
+
caps(range) {
|
|
1105
|
+
range = range || this.capsRange;
|
|
1106
|
+
this.value = utils_1.capitalize(this.value, range);
|
|
1107
|
+
if (this.hasMother)
|
|
1108
|
+
this._mother = utils_1.capitalize(this._mother, range);
|
|
1109
|
+
return this;
|
|
1110
|
+
}
|
|
1111
|
+
decaps(range) {
|
|
1112
|
+
range = range || this.capsRange;
|
|
1113
|
+
this.value = utils_1.decapitalize(this.value, range);
|
|
1114
|
+
if (this.hasMother)
|
|
1115
|
+
this._mother = utils_1.decapitalize(this._mother, range);
|
|
1116
|
+
return this;
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Makes a copy of the current name.
|
|
1120
|
+
*/
|
|
1121
|
+
copyWith(values) {
|
|
1122
|
+
var _a, _b, _c;
|
|
1123
|
+
return new LastName((_a = values.father) !== null && _a !== void 0 ? _a : this.value, (_b = values.mother) !== null && _b !== void 0 ? _b : this.mother, (_c = values.format) !== null && _c !== void 0 ? _c : this.format);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
exports.LastName = LastName;
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
/***/ }),
|
|
1130
|
+
|
|
1131
|
+
/***/ "./src/namefully.ts":
|
|
1132
|
+
/*!**************************!*\
|
|
1133
|
+
!*** ./src/namefully.ts ***!
|
|
1134
|
+
\**************************/
|
|
1135
|
+
/*! no static exports found */
|
|
1136
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
1137
|
+
|
|
1138
|
+
"use strict";
|
|
1139
|
+
|
|
1140
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1141
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1142
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1143
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1144
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1145
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1146
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1147
|
+
});
|
|
1148
|
+
};
|
|
1149
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1150
|
+
exports.Namefully = void 0;
|
|
1151
|
+
const config_1 = __webpack_require__(/*! ./config */ "./src/config.ts");
|
|
1152
|
+
const constants_1 = __webpack_require__(/*! ./constants */ "./src/constants.ts");
|
|
1153
|
+
const error_1 = __webpack_require__(/*! ./error */ "./src/error.ts");
|
|
1154
|
+
const parser_1 = __webpack_require__(/*! ./parser */ "./src/parser.ts");
|
|
1155
|
+
const types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
|
|
1156
|
+
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
|
|
1157
|
+
/**
|
|
1158
|
+
* A helper for organizing person names in a particular order, way, or shape.
|
|
1159
|
+
*
|
|
1160
|
+
* Though `namefully` is easy to use, it does not magically guess which part of
|
|
1161
|
+
* the name is what (prefix, suffix, first, last, or middle names). It relies
|
|
1162
|
+
* actually on how the name parts are indicated (i.e., their roles) so that
|
|
1163
|
+
* it can perform internally certain operations and saves us some extra
|
|
1164
|
+
* calculations/processing. In addition, `Namefully` can be created using
|
|
1165
|
+
* distinct raw data shapes. This is intended to give some flexibility to the
|
|
1166
|
+
* developer so that he or she is not bound to a particular data format.
|
|
1167
|
+
* By following closely the API reference to know how to harness its usability,
|
|
1168
|
+
* this utility aims to save time in formatting names.
|
|
1169
|
+
*
|
|
1170
|
+
* `namefully` also works like a trapdoor. Once a raw data is provided and
|
|
1171
|
+
* validated, a developer can only *access* in a vast amount of, yet effective
|
|
1172
|
+
* ways the name info. *No editing* is possible. If the name is mistaken, a new
|
|
1173
|
+
* instance of `Namefully` must be created. In other words, it's immutable.
|
|
1174
|
+
* Remember, this utility's primary objective is to help manipulate a person name.
|
|
1175
|
+
*
|
|
1176
|
+
* Note that the name standards used for the current version of this library
|
|
1177
|
+
* are as follows:
|
|
1178
|
+
* `[prefix] firstName [middleName] lastName [suffix]`
|
|
1179
|
+
* The opening `[` and closing `]` symbols mean that these parts are optional.
|
|
1180
|
+
* In other words, the most basic and typical case is a name that looks like
|
|
1181
|
+
* this: `John Smith`, where `John` is the first name piece and `Smith`, the last
|
|
1182
|
+
* name piece.
|
|
1183
|
+
*
|
|
1184
|
+
* @see https://departments.weber.edu/qsupport&training/Data_Standards/Name.htm
|
|
1185
|
+
* for more info on name standards.
|
|
1186
|
+
*
|
|
1187
|
+
* **IMPORTANT**: Keep in mind that the order of appearance (or name order) matters
|
|
1188
|
+
* and may be altered through configured parameters, which will be seen later.
|
|
1189
|
+
* By default, the order of appearance is as shown above and will be used as a
|
|
1190
|
+
* basis for future examples and use cases.
|
|
1191
|
+
*
|
|
1192
|
+
* Once imported, all that is required to do is to create an instance of
|
|
1193
|
+
* `Namefully` and the rest will follow.
|
|
1194
|
+
*
|
|
1195
|
+
* Some terminologies used across the library are:
|
|
1196
|
+
* - namon: 1 piece of name (e.g., first name)
|
|
1197
|
+
* - nama: 2+ pieces of name (e.g., first name + last name)
|
|
1198
|
+
*
|
|
1199
|
+
* Happy name handling 😊!
|
|
1200
|
+
*/
|
|
1201
|
+
class Namefully {
|
|
1202
|
+
/**
|
|
1203
|
+
* Creates a name with distinguishable parts from a raw string content.
|
|
1204
|
+
* @param names element to parse.
|
|
1205
|
+
* @param options additional settings.
|
|
1206
|
+
*
|
|
1207
|
+
* An optional configuration may be provided with specifics on how to treat
|
|
1208
|
+
* a full name during its course. By default, all name parts are validated
|
|
1209
|
+
* against some basic validation rules to avoid common runtime exceptions.
|
|
1210
|
+
*/
|
|
1211
|
+
constructor(names, options) {
|
|
1212
|
+
this.build(this.toParser(names), options);
|
|
1213
|
+
}
|
|
1214
|
+
/**
|
|
1215
|
+
* Constructs a `Namefully` instance from a text.
|
|
1216
|
+
*
|
|
1217
|
+
* It works like `parse` except that this function returns `null` where `parse`
|
|
1218
|
+
* would throw a `NameError`.
|
|
1219
|
+
*/
|
|
1220
|
+
static tryParse(text) {
|
|
1221
|
+
try {
|
|
1222
|
+
return new this(parser_1.Parser.build(text));
|
|
1223
|
+
}
|
|
1224
|
+
catch (error) {
|
|
1225
|
+
return undefined;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* Constructs a `Namefully` instance from a text.
|
|
1230
|
+
*
|
|
1231
|
+
* It throws a `NameError` if the text cannot be parsed. Use `tryParse`
|
|
1232
|
+
* instead if a `null` return is preferred over a throwable error.
|
|
1233
|
+
*
|
|
1234
|
+
* This operation is computed asynchronously, which gives more flexibility at
|
|
1235
|
+
* the time of catching the error (and stack trace if any). The acceptable
|
|
1236
|
+
* text format is a string composed of two or more name pieces. For instance,
|
|
1237
|
+
* `John Lennon`, or `John Winston Ono Lennon` are parsable names and follow
|
|
1238
|
+
* the basic name standard rules (i.e., first-middle-last).
|
|
1239
|
+
*
|
|
1240
|
+
* Keep in mind that prefix and suffix are not considered during the parsing
|
|
1241
|
+
* process.
|
|
1242
|
+
*/
|
|
1243
|
+
static parse(text) {
|
|
1244
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1245
|
+
return parser_1.Parser.buildAsync(text).then((parser) => new Namefully(parser));
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* The current configuration.
|
|
1250
|
+
*/
|
|
1251
|
+
get config() {
|
|
1252
|
+
return this._config;
|
|
1253
|
+
}
|
|
1254
|
+
/**
|
|
1255
|
+
* The number of characters of the `birthName`, including spaces.
|
|
1256
|
+
*/
|
|
1257
|
+
get length() {
|
|
1258
|
+
return this.birth.length;
|
|
1259
|
+
}
|
|
1260
|
+
/**
|
|
1261
|
+
* The prefix part.
|
|
1262
|
+
*/
|
|
1263
|
+
get prefix() {
|
|
1264
|
+
var _a;
|
|
1265
|
+
return (_a = this._fullName.prefix) === null || _a === void 0 ? void 0 : _a.toString();
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* The firt name.
|
|
1269
|
+
*/
|
|
1270
|
+
get first() {
|
|
1271
|
+
return this.firstName();
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* The first middle name if any.
|
|
1275
|
+
*/
|
|
1276
|
+
get middle() {
|
|
1277
|
+
return this.hasMiddle ? this.middleName()[0] : undefined;
|
|
1278
|
+
}
|
|
1279
|
+
/**
|
|
1280
|
+
* Returns true if any middle name has been set.
|
|
1281
|
+
*/
|
|
1282
|
+
get hasMiddle() {
|
|
1283
|
+
return this._fullName.has(types_1.Namon.MIDDLE_NAME);
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* The last name.
|
|
1287
|
+
*/
|
|
1288
|
+
get last() {
|
|
1289
|
+
return this.lastName();
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* The suffix part.
|
|
1293
|
+
*/
|
|
1294
|
+
get suffix() {
|
|
1295
|
+
var _a;
|
|
1296
|
+
return (_a = this._fullName.suffix) === null || _a === void 0 ? void 0 : _a.toString();
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* The birth name.
|
|
1300
|
+
*/
|
|
1301
|
+
get birth() {
|
|
1302
|
+
return this.birthName();
|
|
1303
|
+
}
|
|
1304
|
+
/**
|
|
1305
|
+
* The shortest version of a person name.
|
|
1306
|
+
*/
|
|
1307
|
+
get short() {
|
|
1308
|
+
return this.shorten();
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* The longest version of a person name.
|
|
1312
|
+
*/
|
|
1313
|
+
get long() {
|
|
1314
|
+
return this.birth;
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* The entire name set.
|
|
1318
|
+
*/
|
|
1319
|
+
get full() {
|
|
1320
|
+
return this.fullName();
|
|
1321
|
+
}
|
|
1322
|
+
/**
|
|
1323
|
+
* The first name combined with the last name's initial.
|
|
1324
|
+
*/
|
|
1325
|
+
get public() {
|
|
1326
|
+
return this.format('f $l');
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Returns the full name as set.
|
|
1330
|
+
*/
|
|
1331
|
+
toString() {
|
|
1332
|
+
return this.full;
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Fetches the raw form of a name piece.
|
|
1336
|
+
*/
|
|
1337
|
+
get(namon) {
|
|
1338
|
+
if (namon.equal(types_1.Namon.PREFIX))
|
|
1339
|
+
return this._fullName.prefix;
|
|
1340
|
+
if (namon.equal(types_1.Namon.FIRST_NAME))
|
|
1341
|
+
return this._fullName.firstName;
|
|
1342
|
+
if (namon.equal(types_1.Namon.MIDDLE_NAME))
|
|
1343
|
+
return this._fullName.middleName;
|
|
1344
|
+
if (namon.equal(types_1.Namon.LAST_NAME))
|
|
1345
|
+
return this._fullName.lastName;
|
|
1346
|
+
if (namon.equal(types_1.Namon.SUFFIX))
|
|
1347
|
+
return this._fullName.suffix;
|
|
1348
|
+
return undefined;
|
|
1349
|
+
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Whether this name is equal to another one from a raw-string perspective.
|
|
1352
|
+
*/
|
|
1353
|
+
equal(other) {
|
|
1354
|
+
return this.toString() === other.toString();
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Gets a JSON representation of the full name.
|
|
1358
|
+
*/
|
|
1359
|
+
toJson() {
|
|
1360
|
+
return {
|
|
1361
|
+
prefix: this.prefix,
|
|
1362
|
+
firstName: this.first,
|
|
1363
|
+
middleName: this.middleName(),
|
|
1364
|
+
lastName: this.last,
|
|
1365
|
+
suffix: this.suffix,
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Confirms that a name part has been set.
|
|
1370
|
+
*/
|
|
1371
|
+
has(namon) {
|
|
1372
|
+
return this._fullName.has(namon);
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Gets the full name ordered as configured.
|
|
1376
|
+
*
|
|
1377
|
+
* The name order `orderedBy` forces to order by first or last name by
|
|
1378
|
+
* overriding the preset configuration.
|
|
1379
|
+
*
|
|
1380
|
+
* `Namefully.format` may also be used to alter manually the order of appearance
|
|
1381
|
+
* of full name.
|
|
1382
|
+
*
|
|
1383
|
+
* For example:
|
|
1384
|
+
* ```typescript
|
|
1385
|
+
* const name = new Namefully('Jon Stark Snow');
|
|
1386
|
+
* console.log(name.fullName(NameOrder.LAST_NAME)); // "Snow Jon Stark"
|
|
1387
|
+
* console.log(name.format('l f m')); // "Snow Jon Stark"
|
|
1388
|
+
* ```
|
|
1389
|
+
*/
|
|
1390
|
+
fullName(orderedBy) {
|
|
1391
|
+
const sep = this._config.ending ? ',' : '';
|
|
1392
|
+
const names = [];
|
|
1393
|
+
orderedBy = orderedBy || this._config.orderedBy;
|
|
1394
|
+
if (this.prefix)
|
|
1395
|
+
names.push(this.prefix);
|
|
1396
|
+
if (orderedBy === types_1.NameOrder.FIRST_NAME) {
|
|
1397
|
+
names.push(this.first, ...this.middleName(), this.last + sep);
|
|
1398
|
+
}
|
|
1399
|
+
else {
|
|
1400
|
+
names.push(this.last, this.first, this.middleName().join(' ') + sep);
|
|
1401
|
+
}
|
|
1402
|
+
if (this.suffix)
|
|
1403
|
+
names.push(this.suffix);
|
|
1404
|
+
return names.join(' ').trim();
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Gets the birth name ordered as configured, no `prefix` or `suffix`.
|
|
1408
|
+
*
|
|
1409
|
+
* @param orderedBy forces to order by first or last name by overriding the
|
|
1410
|
+
* preset configuration.
|
|
1411
|
+
*/
|
|
1412
|
+
birthName(orderedBy) {
|
|
1413
|
+
orderedBy = orderedBy || this._config.orderedBy;
|
|
1414
|
+
return orderedBy === types_1.NameOrder.FIRST_NAME
|
|
1415
|
+
? [this.first, ...this.middleName(), this.last].join(' ')
|
|
1416
|
+
: [this.last, this.first, ...this.middleName()].join(' ');
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Gets the first name part of the `FullName`.
|
|
1420
|
+
*
|
|
1421
|
+
* @param withMore determines whether to include other pieces of the first
|
|
1422
|
+
* name.
|
|
1423
|
+
*/
|
|
1424
|
+
firstName(withMore = true) {
|
|
1425
|
+
return this._fullName.firstName.toString(withMore);
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Gets the middle name part of the `FullName`.
|
|
1429
|
+
*/
|
|
1430
|
+
middleName() {
|
|
1431
|
+
return this._fullName.middleName.map((n) => n.value);
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Gets the last name part of the `FullName`.
|
|
1435
|
+
*
|
|
1436
|
+
* @param format overrides the how-to formatting of a surname output,
|
|
1437
|
+
* considering its sub-parts.
|
|
1438
|
+
*/
|
|
1439
|
+
lastName(format) {
|
|
1440
|
+
return this._fullName.lastName.toString(format);
|
|
1441
|
+
}
|
|
1442
|
+
/**
|
|
1443
|
+
* Gets the initials of the `FullName`.
|
|
1444
|
+
*
|
|
1445
|
+
* @param {options.orderedBy} forces to order by first or last name by
|
|
1446
|
+
* overriding the preset configuration.
|
|
1447
|
+
* @param
|
|
1448
|
+
*
|
|
1449
|
+
* For example, given the names:
|
|
1450
|
+
* - `John Smith` => `['J', 'S']`
|
|
1451
|
+
* - `John Ben Smith` => `['J', 'B', 'S']`.
|
|
1452
|
+
*/
|
|
1453
|
+
initials(options) {
|
|
1454
|
+
const initials = [];
|
|
1455
|
+
const firstInits = this._fullName.firstName.initials();
|
|
1456
|
+
const midInits = this._fullName.middleName.map((n) => n.initials()[0]);
|
|
1457
|
+
const lastInits = this._fullName.lastName.initials();
|
|
1458
|
+
const mergedOptions = Object.assign({ orderedBy: this._config.orderedBy, only: types_1.NameType.BIRTH_NAME }, options);
|
|
1459
|
+
const { orderedBy, only } = mergedOptions;
|
|
1460
|
+
if (only != types_1.NameType.BIRTH_NAME) {
|
|
1461
|
+
if (only == types_1.NameType.FIRST_NAME) {
|
|
1462
|
+
initials.push(...firstInits);
|
|
1463
|
+
}
|
|
1464
|
+
else if (only == types_1.NameType.MIDDLE_NAME) {
|
|
1465
|
+
initials.push(...midInits);
|
|
1466
|
+
}
|
|
1467
|
+
else {
|
|
1468
|
+
initials.push(...lastInits);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
else if (orderedBy == types_1.NameOrder.FIRST_NAME) {
|
|
1472
|
+
initials.push(...firstInits, ...midInits, ...lastInits);
|
|
1473
|
+
}
|
|
1474
|
+
else {
|
|
1475
|
+
initials.push(...lastInits, ...firstInits, ...midInits);
|
|
1476
|
+
}
|
|
1477
|
+
return initials;
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* Shortens a complex full name to a simple typical name, a combination of
|
|
1481
|
+
* first and last name.
|
|
1482
|
+
*
|
|
1483
|
+
* @param orderedBy forces to order by first or last name by overriding the
|
|
1484
|
+
* preset configuration.
|
|
1485
|
+
*
|
|
1486
|
+
* For a given name such as `Mr Keanu Charles Reeves`, shortening this name
|
|
1487
|
+
* is equivalent to making it `Keanu Reeves`.
|
|
1488
|
+
*
|
|
1489
|
+
* As a shortened name, the namon of the first name is favored over the other
|
|
1490
|
+
* names forming part of the entire first names, if any. Meanwhile, for
|
|
1491
|
+
* the last name, the configured `surname` is prioritized.
|
|
1492
|
+
*
|
|
1493
|
+
* For a given `FirstName FatherName MotherName`, shortening this name when
|
|
1494
|
+
* the surname is set as `mother` is equivalent to making it:
|
|
1495
|
+
* `FirstName MotherName`.
|
|
1496
|
+
*/
|
|
1497
|
+
shorten(orderedBy) {
|
|
1498
|
+
orderedBy = orderedBy || this._config.orderedBy;
|
|
1499
|
+
return orderedBy == types_1.NameOrder.FIRST_NAME
|
|
1500
|
+
? [this._fullName.firstName.value, this._fullName.lastName.toString()].join(' ')
|
|
1501
|
+
: [this._fullName.lastName.toString(), this._fullName.firstName.value].join(' ');
|
|
1502
|
+
}
|
|
1503
|
+
/**
|
|
1504
|
+
* Flattens a long name using the name types as variants.
|
|
1505
|
+
*
|
|
1506
|
+
* While @param limit sets a threshold as a limited number of characters
|
|
1507
|
+
* supported to flatten a `FullName`, @param by indicates which variant
|
|
1508
|
+
* to use when doing so. By default, a full name gets flattened by
|
|
1509
|
+
* `Flat.MIDDLE_NAME`.
|
|
1510
|
+
*
|
|
1511
|
+
* The flattening operation is only executed iff there is a valid entry and
|
|
1512
|
+
* it surpasses the limit set. In the examples below, let us assume that the
|
|
1513
|
+
* name goes beyond the limit value.
|
|
1514
|
+
*
|
|
1515
|
+
* Flattening a long name refers to reducing the name to the following forms.
|
|
1516
|
+
* For example, `John Winston Ono Lennon` flattened by:
|
|
1517
|
+
* * Flat.FIRST_NAME: => 'J. Winston Ono Lennon'
|
|
1518
|
+
* * Flat.MIDDLE_NAME: => 'John W. O. Lennon'
|
|
1519
|
+
* * Flat.LAST_NAME: => 'John Winston Ono L.'
|
|
1520
|
+
* * Flat.FIRST_MID: => 'J. W. O. Lennon'
|
|
1521
|
+
* * Flat.MID_LAST: => 'John W. O. L.'
|
|
1522
|
+
* * Flat.ALL: => 'J. W. O. L.'
|
|
1523
|
+
*
|
|
1524
|
+
* With the help of the @param recursive flag, the above operation can happen
|
|
1525
|
+
* recursively in the same order if the name is still too long. For example,
|
|
1526
|
+
* flattening `John Winston Ono Lennon` using the following params:
|
|
1527
|
+
* `flatten({ limit: 18, by: Flat.FIRST_NAME, recursive: true })`
|
|
1528
|
+
* will result in `John W. O. Lennon` and not `J. Winston Ono Lennon`.
|
|
1529
|
+
*
|
|
1530
|
+
* A shorter version of this method is `zip()`.
|
|
1531
|
+
*/
|
|
1532
|
+
flatten(options) {
|
|
1533
|
+
if (this.length <= options.limit)
|
|
1534
|
+
return this.full;
|
|
1535
|
+
const mergedOptions = Object.assign({ limit: 20, by: types_1.Flat.MIDDLE_NAME, withPeriod: true, recursive: false, withMore: false }, options);
|
|
1536
|
+
const { by, limit, recursive, withMore, withPeriod, surname } = mergedOptions;
|
|
1537
|
+
const sep = withPeriod ? '.' : '';
|
|
1538
|
+
const fn = this._fullName.firstName.toString();
|
|
1539
|
+
const mn = this.middleName().join(' ');
|
|
1540
|
+
const ln = this._fullName.lastName.toString();
|
|
1541
|
+
const hasMid = this.hasMiddle;
|
|
1542
|
+
const f = this._fullName.firstName.initials(withMore).join(sep + ' ') + sep;
|
|
1543
|
+
const l = this._fullName.lastName.initials(surname).join(sep + ' ') + sep;
|
|
1544
|
+
const m = hasMid ? this._fullName.middleName.map((n) => n.initials()[0]).join(sep + ' ') + sep : '';
|
|
1545
|
+
let name = [];
|
|
1546
|
+
if (this._config.orderedBy == types_1.NameOrder.FIRST_NAME) {
|
|
1547
|
+
switch (by) {
|
|
1548
|
+
case types_1.Flat.FIRST_NAME:
|
|
1549
|
+
name = hasMid ? [f, mn, ln] : [f, ln];
|
|
1550
|
+
break;
|
|
1551
|
+
case types_1.Flat.LAST_NAME:
|
|
1552
|
+
name = hasMid ? [fn, mn, l] : [fn, l];
|
|
1553
|
+
break;
|
|
1554
|
+
case types_1.Flat.MIDDLE_NAME:
|
|
1555
|
+
name = hasMid ? [fn, m, ln] : [fn, ln];
|
|
1556
|
+
break;
|
|
1557
|
+
case types_1.Flat.FIRST_MID:
|
|
1558
|
+
name = hasMid ? [f, m, ln] : [f, ln];
|
|
1559
|
+
break;
|
|
1560
|
+
case types_1.Flat.MID_LAST:
|
|
1561
|
+
name = hasMid ? [fn, m, l] : [fn, l];
|
|
1562
|
+
break;
|
|
1563
|
+
case types_1.Flat.ALL:
|
|
1564
|
+
name = hasMid ? [f, m, l] : [f, l];
|
|
1565
|
+
break;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
else {
|
|
1569
|
+
switch (by) {
|
|
1570
|
+
case types_1.Flat.FIRST_NAME:
|
|
1571
|
+
name = hasMid ? [ln, f, mn] : [ln, f];
|
|
1572
|
+
break;
|
|
1573
|
+
case types_1.Flat.LAST_NAME:
|
|
1574
|
+
name = hasMid ? [l, fn, mn] : [l, fn];
|
|
1575
|
+
break;
|
|
1576
|
+
case types_1.Flat.MIDDLE_NAME:
|
|
1577
|
+
name = hasMid ? [ln, fn, m] : [ln, fn];
|
|
1578
|
+
break;
|
|
1579
|
+
case types_1.Flat.FIRST_MID:
|
|
1580
|
+
name = hasMid ? [ln, f, m] : [ln, f];
|
|
1581
|
+
break;
|
|
1582
|
+
case types_1.Flat.MID_LAST:
|
|
1583
|
+
name = hasMid ? [l, fn, m] : [l, fn];
|
|
1584
|
+
break;
|
|
1585
|
+
case types_1.Flat.ALL:
|
|
1586
|
+
name = hasMid ? [l, f, m] : [l, f];
|
|
1587
|
+
break;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
const flat = name.join(' ');
|
|
1591
|
+
if (recursive && flat.length > limit) {
|
|
1592
|
+
const next = by == types_1.Flat.FIRST_NAME
|
|
1593
|
+
? types_1.Flat.MIDDLE_NAME
|
|
1594
|
+
: by == types_1.Flat.MIDDLE_NAME
|
|
1595
|
+
? types_1.Flat.LAST_NAME
|
|
1596
|
+
: by == types_1.Flat.LAST_NAME
|
|
1597
|
+
? types_1.Flat.FIRST_MID
|
|
1598
|
+
: by == types_1.Flat.FIRST_MID
|
|
1599
|
+
? types_1.Flat.MID_LAST
|
|
1600
|
+
: by == types_1.Flat.MID_LAST
|
|
1601
|
+
? types_1.Flat.ALL
|
|
1602
|
+
: by == types_1.Flat.ALL
|
|
1603
|
+
? types_1.Flat.ALL
|
|
1604
|
+
: by;
|
|
1605
|
+
if (next == by)
|
|
1606
|
+
return flat;
|
|
1607
|
+
return this.flatten(Object.assign(Object.assign({}, options), { by: next }));
|
|
1608
|
+
}
|
|
1609
|
+
return flat;
|
|
1610
|
+
}
|
|
1611
|
+
/**
|
|
1612
|
+
* Zips or compacts a name using different forms of variants.
|
|
1613
|
+
*
|
|
1614
|
+
* @see `flatten()` for more details.
|
|
1615
|
+
*/
|
|
1616
|
+
zip(by = types_1.Flat.MID_LAST, withPeriod = true) {
|
|
1617
|
+
return this.flatten({ limit: 0, by, withPeriod });
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Formats the full name as desired.
|
|
1621
|
+
* @param pattern character used to format it.
|
|
1622
|
+
*
|
|
1623
|
+
* string format
|
|
1624
|
+
* -------------
|
|
1625
|
+
* - 'short': typical first + last name
|
|
1626
|
+
* - 'long': birth name (without prefix and suffix)
|
|
1627
|
+
* - 'public': first name combined with the last name's initial.
|
|
1628
|
+
* - 'official': official document format
|
|
1629
|
+
*
|
|
1630
|
+
* char format
|
|
1631
|
+
* -----------
|
|
1632
|
+
* - 'b': birth name
|
|
1633
|
+
* - 'B': capitalized birth name
|
|
1634
|
+
* - 'f': first name
|
|
1635
|
+
* - 'F': capitalized first name
|
|
1636
|
+
* - 'l': last name
|
|
1637
|
+
* - 'L': capitalized last name
|
|
1638
|
+
* - 'm': middle names
|
|
1639
|
+
* - 'M': capitalized middle names
|
|
1640
|
+
* - 'o': official document format
|
|
1641
|
+
* - 'O': official document format in capital letters
|
|
1642
|
+
* - 'p': prefix
|
|
1643
|
+
* - 'P': capitalized prefix
|
|
1644
|
+
* - 's': suffix
|
|
1645
|
+
* - 'S': capitalized suffix
|
|
1646
|
+
*
|
|
1647
|
+
* punctuations
|
|
1648
|
+
* ------------
|
|
1649
|
+
* - '.': period
|
|
1650
|
+
* - ',': comma
|
|
1651
|
+
* - ' ': space
|
|
1652
|
+
* - '-': hyphen
|
|
1653
|
+
* - '_': underscore
|
|
1654
|
+
* - '$': an escape character to select only the initial of the next char.
|
|
1655
|
+
*
|
|
1656
|
+
* Given the name `Joe Jim Smith`, use `format` with the `pattern` string.
|
|
1657
|
+
* - format('l f') => 'Smith Joe'
|
|
1658
|
+
* - format('L, f') => 'SMITH, Joe'
|
|
1659
|
+
* - format('short') => 'Joe Smith'
|
|
1660
|
+
* - format() => 'SMITH, Joe Jim'
|
|
1661
|
+
* - format(r'f $l.') => 'Joe S.'.
|
|
1662
|
+
*
|
|
1663
|
+
* Do note that the escape character is only valid for the birth name parts:
|
|
1664
|
+
* first, middle, and last names.
|
|
1665
|
+
*/
|
|
1666
|
+
format(pattern) {
|
|
1667
|
+
var _a;
|
|
1668
|
+
if (pattern == 'short')
|
|
1669
|
+
return this.short;
|
|
1670
|
+
if (pattern == 'long')
|
|
1671
|
+
return this.long;
|
|
1672
|
+
if (pattern == 'public')
|
|
1673
|
+
return this.public;
|
|
1674
|
+
if (pattern == 'official')
|
|
1675
|
+
pattern = 'o';
|
|
1676
|
+
let group = '';
|
|
1677
|
+
const formatted = [];
|
|
1678
|
+
for (const char of pattern.split('')) {
|
|
1679
|
+
if (constants_1.ALLOWED_TOKENS.indexOf(char) === -1) {
|
|
1680
|
+
throw new error_1.NotAllowedError({
|
|
1681
|
+
source: this.full,
|
|
1682
|
+
operation: 'format',
|
|
1683
|
+
message: `unsupported character <${char}> from ${pattern}.`,
|
|
1684
|
+
});
|
|
1685
|
+
}
|
|
1686
|
+
group += char;
|
|
1687
|
+
if (char === '$')
|
|
1688
|
+
continue;
|
|
1689
|
+
formatted.push((_a = this.map(group)) !== null && _a !== void 0 ? _a : '');
|
|
1690
|
+
group = '';
|
|
1691
|
+
}
|
|
1692
|
+
return formatted.join('').trim();
|
|
1693
|
+
}
|
|
1694
|
+
/**
|
|
1695
|
+
* Flips definitely the name order from the preset/current config.
|
|
1696
|
+
*/
|
|
1697
|
+
flip() {
|
|
1698
|
+
if (this._config.orderedBy === types_1.NameOrder.FIRST_NAME) {
|
|
1699
|
+
this._config.updateOrder(types_1.NameOrder.LAST_NAME);
|
|
1700
|
+
console.log(`The name order is now changed to: ${types_1.NameOrder.LAST_NAME}`);
|
|
1701
|
+
}
|
|
1702
|
+
else {
|
|
1703
|
+
this._config.updateOrder(types_1.NameOrder.FIRST_NAME);
|
|
1704
|
+
console.log(`The name order is now changed to: ${types_1.NameOrder.FIRST_NAME}`);
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
/**
|
|
1708
|
+
* Splits the name parts of a birth name.
|
|
1709
|
+
* @param separator token for the split.
|
|
1710
|
+
*/
|
|
1711
|
+
split(separator = /[' -]/g) {
|
|
1712
|
+
return this.birth.replace(separator, ' ').split(' ');
|
|
1713
|
+
}
|
|
1714
|
+
/**
|
|
1715
|
+
* Joins the name parts of a birth name.
|
|
1716
|
+
* @param separator token for the junction.
|
|
1717
|
+
*/
|
|
1718
|
+
join(separator = '') {
|
|
1719
|
+
return this.split().join(separator);
|
|
1720
|
+
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Transforms a birth name into UPPERCASE
|
|
1723
|
+
*/
|
|
1724
|
+
toUpperCase() {
|
|
1725
|
+
return this.birth.toUpperCase();
|
|
1726
|
+
}
|
|
1727
|
+
/**
|
|
1728
|
+
* Transforms a birth name into lowercase
|
|
1729
|
+
*/
|
|
1730
|
+
toLowerCase() {
|
|
1731
|
+
return this.birth.toLowerCase();
|
|
1732
|
+
}
|
|
1733
|
+
/**
|
|
1734
|
+
* Transforms a birth name into camelCase
|
|
1735
|
+
*/
|
|
1736
|
+
toCamelCase() {
|
|
1737
|
+
return utils_1.decapitalize(this.toPascalCase());
|
|
1738
|
+
}
|
|
1739
|
+
/**
|
|
1740
|
+
* Transforms a birth name into PascalCase
|
|
1741
|
+
*/
|
|
1742
|
+
toPascalCase() {
|
|
1743
|
+
return this.split()
|
|
1744
|
+
.map((n) => utils_1.capitalize(n))
|
|
1745
|
+
.join('');
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* Transforms a birth name into snake_case
|
|
1749
|
+
*/
|
|
1750
|
+
toSnakeCase() {
|
|
1751
|
+
return this.split()
|
|
1752
|
+
.map((n) => n.toLowerCase())
|
|
1753
|
+
.join('_');
|
|
1754
|
+
}
|
|
1755
|
+
/**
|
|
1756
|
+
* Transforms a birth name into hyphen-case
|
|
1757
|
+
*/
|
|
1758
|
+
toHyphenCase() {
|
|
1759
|
+
return this.split()
|
|
1760
|
+
.map((n) => n.toLowerCase())
|
|
1761
|
+
.join('-');
|
|
1762
|
+
}
|
|
1763
|
+
/**
|
|
1764
|
+
* Transforms a birth name into dot.case
|
|
1765
|
+
*/
|
|
1766
|
+
toDotCase() {
|
|
1767
|
+
return this.split()
|
|
1768
|
+
.map((n) => n.toLowerCase())
|
|
1769
|
+
.join('.');
|
|
1770
|
+
}
|
|
1771
|
+
/**
|
|
1772
|
+
* Transforms a birth name into ToGgLeCaSe
|
|
1773
|
+
*/
|
|
1774
|
+
toToggleCase() {
|
|
1775
|
+
return utils_1.toggleCase(this.birth);
|
|
1776
|
+
}
|
|
1777
|
+
build(parser, options) {
|
|
1778
|
+
this._config = config_1.Config.merge(options);
|
|
1779
|
+
this._fullName = parser.parse(this._config);
|
|
1780
|
+
}
|
|
1781
|
+
toParser(raw) {
|
|
1782
|
+
if (raw instanceof parser_1.Parser)
|
|
1783
|
+
return raw;
|
|
1784
|
+
if (typeof raw === 'string')
|
|
1785
|
+
return new parser_1.StringParser(raw);
|
|
1786
|
+
if (utils_1.isStringArray(raw))
|
|
1787
|
+
return new parser_1.ArrayStringParser(raw);
|
|
1788
|
+
if (utils_1.isNameArray(raw))
|
|
1789
|
+
return new parser_1.ArrayNameParser(raw);
|
|
1790
|
+
if (typeof raw === 'object')
|
|
1791
|
+
return new parser_1.NamaParser(raw);
|
|
1792
|
+
throw new error_1.InputError({
|
|
1793
|
+
source: raw,
|
|
1794
|
+
message: 'Cannot parse raw data. Review expected data types.',
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
map(char) {
|
|
1798
|
+
var _a, _b;
|
|
1799
|
+
switch (char) {
|
|
1800
|
+
case '.':
|
|
1801
|
+
case ',':
|
|
1802
|
+
case ' ':
|
|
1803
|
+
case '-':
|
|
1804
|
+
case '_':
|
|
1805
|
+
return char;
|
|
1806
|
+
case 'b':
|
|
1807
|
+
return this.birth;
|
|
1808
|
+
case 'B':
|
|
1809
|
+
return this.birth.toUpperCase();
|
|
1810
|
+
case 'f':
|
|
1811
|
+
return this.first;
|
|
1812
|
+
case 'F':
|
|
1813
|
+
return this.first.toUpperCase();
|
|
1814
|
+
case 'l':
|
|
1815
|
+
return this.last;
|
|
1816
|
+
case 'L':
|
|
1817
|
+
return this.last.toUpperCase();
|
|
1818
|
+
case 'm':
|
|
1819
|
+
case 'M':
|
|
1820
|
+
return char == 'm' ? this.middleName().join(' ') : this.middleName().join(' ').toUpperCase();
|
|
1821
|
+
case 'o':
|
|
1822
|
+
case 'O':
|
|
1823
|
+
const sep = this._config.ending ? ',' : '';
|
|
1824
|
+
const names = [];
|
|
1825
|
+
if (this.prefix)
|
|
1826
|
+
names.push(this.prefix);
|
|
1827
|
+
names.push(`${this.last},`.toUpperCase());
|
|
1828
|
+
if (this.hasMiddle) {
|
|
1829
|
+
names.push(this.first, this.middleName().join(' ') + sep);
|
|
1830
|
+
}
|
|
1831
|
+
else {
|
|
1832
|
+
names.push(this.first + sep);
|
|
1833
|
+
}
|
|
1834
|
+
if (this.suffix)
|
|
1835
|
+
names.push(this.suffix);
|
|
1836
|
+
const nama = names.join(' ').trim();
|
|
1837
|
+
return char === 'o' ? nama : nama.toUpperCase();
|
|
1838
|
+
case 'p':
|
|
1839
|
+
return this.prefix;
|
|
1840
|
+
case 'P':
|
|
1841
|
+
return (_a = this.prefix) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
1842
|
+
case 's':
|
|
1843
|
+
return this.suffix;
|
|
1844
|
+
case 'S':
|
|
1845
|
+
return (_b = this.suffix) === null || _b === void 0 ? void 0 : _b.toUpperCase();
|
|
1846
|
+
case '$f':
|
|
1847
|
+
case '$F':
|
|
1848
|
+
return this._fullName.firstName.initials()[0];
|
|
1849
|
+
case '$l':
|
|
1850
|
+
case '$L':
|
|
1851
|
+
return this._fullName.lastName.initials()[0];
|
|
1852
|
+
case '$m':
|
|
1853
|
+
case '$M':
|
|
1854
|
+
return this._fullName.middleName.map((n) => n.initials()[0])[0];
|
|
1855
|
+
default:
|
|
1856
|
+
return undefined;
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
exports.Namefully = Namefully;
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
/***/ }),
|
|
1864
|
+
|
|
1865
|
+
/***/ "./src/parser.ts":
|
|
1866
|
+
/*!***********************!*\
|
|
1867
|
+
!*** ./src/parser.ts ***!
|
|
1868
|
+
\***********************/
|
|
1869
|
+
/*! no static exports found */
|
|
1870
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
1871
|
+
|
|
1872
|
+
"use strict";
|
|
1873
|
+
|
|
1874
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1875
|
+
exports.ArrayNameParser = exports.NamaParser = exports.ArrayStringParser = exports.StringParser = exports.Parser = void 0;
|
|
1876
|
+
const full_name_1 = __webpack_require__(/*! ./full-name */ "./src/full-name.ts");
|
|
1877
|
+
const config_1 = __webpack_require__(/*! ./config */ "./src/config.ts");
|
|
1878
|
+
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
|
|
1879
|
+
const validator_1 = __webpack_require__(/*! ./validator */ "./src/validator.ts");
|
|
1880
|
+
const name_1 = __webpack_require__(/*! ./name */ "./src/name.ts");
|
|
1881
|
+
const types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
|
|
1882
|
+
const error_1 = __webpack_require__(/*! ./error */ "./src/error.ts");
|
|
1883
|
+
/**
|
|
1884
|
+
* A parser signature that helps to organize the names accordingly.
|
|
1885
|
+
*/
|
|
1886
|
+
class Parser {
|
|
1887
|
+
/**
|
|
1888
|
+
* Constructs a custom parser accordingly.
|
|
1889
|
+
* @param raw data to be parsed
|
|
1890
|
+
*/
|
|
1891
|
+
constructor(raw) {
|
|
1892
|
+
this.raw = raw;
|
|
1893
|
+
}
|
|
1894
|
+
/**
|
|
1895
|
+
* Builds a dynamic `Parser` on the fly and throws a `NameError` when unable
|
|
1896
|
+
* to do so. The built parser only knows how to operate birth names.
|
|
1897
|
+
*/
|
|
1898
|
+
static build(text) {
|
|
1899
|
+
const parts = text.trim().split(types_1.Separator.SPACE.token);
|
|
1900
|
+
const length = parts.length;
|
|
1901
|
+
if (length == 0 || length == 1) {
|
|
1902
|
+
throw new error_1.InputError({
|
|
1903
|
+
source: text,
|
|
1904
|
+
message: 'cannot build from invalid input',
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
else if (length == 2 || length == 3) {
|
|
1908
|
+
return new StringParser(text);
|
|
1909
|
+
}
|
|
1910
|
+
else {
|
|
1911
|
+
const last = parts.pop();
|
|
1912
|
+
const [first, ...middles] = parts;
|
|
1913
|
+
return new ArrayStringParser([first, middles.join(' '), last]);
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
/**
|
|
1917
|
+
* Builds asynchronously a dynamic `Parser`.
|
|
1918
|
+
*/
|
|
1919
|
+
static buildAsync(text) {
|
|
1920
|
+
try {
|
|
1921
|
+
return Promise.resolve(Parser.build(text));
|
|
1922
|
+
}
|
|
1923
|
+
catch (error) {
|
|
1924
|
+
return Promise.reject(error);
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
exports.Parser = Parser;
|
|
1929
|
+
class StringParser extends Parser {
|
|
1930
|
+
constructor(raw) {
|
|
1931
|
+
super(raw);
|
|
1932
|
+
}
|
|
1933
|
+
parse(options) {
|
|
1934
|
+
const config = config_1.Config.merge(options);
|
|
1935
|
+
const names = this.raw.split(config.separator.token);
|
|
1936
|
+
return new ArrayStringParser(names).parse(options);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
exports.StringParser = StringParser;
|
|
1940
|
+
class ArrayStringParser extends Parser {
|
|
1941
|
+
constructor(raw) {
|
|
1942
|
+
super(raw);
|
|
1943
|
+
}
|
|
1944
|
+
parse(options) {
|
|
1945
|
+
const config = config_1.Config.merge(options);
|
|
1946
|
+
const fullName = new full_name_1.FullName(config);
|
|
1947
|
+
const raw = this.raw.map((n) => n.trim());
|
|
1948
|
+
const index = utils_1.NameIndex.when(config.orderedBy, raw.length);
|
|
1949
|
+
const validator = new validator_1.ArrayStringValidator(index);
|
|
1950
|
+
if (config.bypass) {
|
|
1951
|
+
validator.validateIndex(raw);
|
|
1952
|
+
}
|
|
1953
|
+
else {
|
|
1954
|
+
validator.validate(raw);
|
|
1955
|
+
}
|
|
1956
|
+
switch (raw.length) {
|
|
1957
|
+
case 2:
|
|
1958
|
+
fullName.setFirstName(new name_1.FirstName(raw[index.firstName]));
|
|
1959
|
+
fullName.setLastName(new name_1.LastName(raw[index.lastName]));
|
|
1960
|
+
break;
|
|
1961
|
+
case 3:
|
|
1962
|
+
fullName.setFirstName(new name_1.FirstName(raw[index.firstName]));
|
|
1963
|
+
fullName.setMiddleName(this.split(raw[index.middleName], config));
|
|
1964
|
+
fullName.setLastName(new name_1.LastName(raw[index.lastName]));
|
|
1965
|
+
break;
|
|
1966
|
+
case 4:
|
|
1967
|
+
fullName.setPrefix(name_1.Name.prefix(raw[index.prefix]));
|
|
1968
|
+
fullName.setFirstName(new name_1.FirstName(raw[index.firstName]));
|
|
1969
|
+
fullName.setMiddleName(this.split(raw[index.middleName], config));
|
|
1970
|
+
fullName.setLastName(new name_1.LastName(raw[index.lastName]));
|
|
1971
|
+
break;
|
|
1972
|
+
case 5:
|
|
1973
|
+
fullName.setPrefix(name_1.Name.prefix(raw[index.prefix]));
|
|
1974
|
+
fullName.setFirstName(new name_1.FirstName(raw[index.firstName]));
|
|
1975
|
+
fullName.setMiddleName(this.split(raw[index.middleName], config));
|
|
1976
|
+
fullName.setLastName(new name_1.LastName(raw[index.lastName]));
|
|
1977
|
+
fullName.setSuffix(name_1.Name.suffix(raw[index.suffix]));
|
|
1978
|
+
break;
|
|
1979
|
+
}
|
|
1980
|
+
return fullName;
|
|
1981
|
+
}
|
|
1982
|
+
split(raw, config) {
|
|
1983
|
+
return raw.split(config.separator.token).map((name) => name_1.Name.middle(name));
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
exports.ArrayStringParser = ArrayStringParser;
|
|
1987
|
+
class NamaParser extends Parser {
|
|
1988
|
+
constructor(raw) {
|
|
1989
|
+
super(raw);
|
|
1990
|
+
}
|
|
1991
|
+
parse(options) {
|
|
1992
|
+
const config = config_1.Config.merge(options);
|
|
1993
|
+
if (config.bypass) {
|
|
1994
|
+
validator_1.NamaValidator.create().validateKeys(this.asNama());
|
|
1995
|
+
}
|
|
1996
|
+
else {
|
|
1997
|
+
validator_1.NamaValidator.create().validate(this.asNama());
|
|
1998
|
+
}
|
|
1999
|
+
return full_name_1.FullName.parse(this.raw, config);
|
|
2000
|
+
}
|
|
2001
|
+
asNama() {
|
|
2002
|
+
return new Map(Object.entries(this.raw).map(([key, value]) => {
|
|
2003
|
+
const namon = types_1.Namon.cast(key);
|
|
2004
|
+
if (!namon) {
|
|
2005
|
+
throw new error_1.InputError({
|
|
2006
|
+
source: Object.values(this.raw).join(' '),
|
|
2007
|
+
message: `unsupported key "${key}"`,
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
return [namon, value];
|
|
2011
|
+
}));
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
exports.NamaParser = NamaParser;
|
|
2015
|
+
class ArrayNameParser extends Parser {
|
|
2016
|
+
constructor(raw) {
|
|
2017
|
+
super(raw);
|
|
2018
|
+
}
|
|
2019
|
+
parse(options) {
|
|
2020
|
+
const config = config_1.Config.merge(options);
|
|
2021
|
+
const fullName = new full_name_1.FullName(config);
|
|
2022
|
+
validator_1.ArrayNameValidator.create().validate(this.raw);
|
|
2023
|
+
for (let name of this.raw) {
|
|
2024
|
+
if (name.isPrefix) {
|
|
2025
|
+
fullName.setPrefix(name);
|
|
2026
|
+
}
|
|
2027
|
+
else if (name.isSuffix) {
|
|
2028
|
+
fullName.setSuffix(name);
|
|
2029
|
+
}
|
|
2030
|
+
else if (name.isFirstName) {
|
|
2031
|
+
fullName.setFirstName(name instanceof name_1.FirstName ? name : new name_1.FirstName(name.value));
|
|
2032
|
+
}
|
|
2033
|
+
else if (name.isMiddleName) {
|
|
2034
|
+
fullName.middleName.push(name);
|
|
2035
|
+
}
|
|
2036
|
+
else if (name.isLastName) {
|
|
2037
|
+
const lastName = new name_1.LastName(name.value, name instanceof name_1.LastName ? name.mother : undefined, config.surname);
|
|
2038
|
+
fullName.setLastName(lastName);
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
return fullName;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
exports.ArrayNameParser = ArrayNameParser;
|
|
2045
|
+
|
|
2046
|
+
|
|
2047
|
+
/***/ }),
|
|
2048
|
+
|
|
2049
|
+
/***/ "./src/types.ts":
|
|
2050
|
+
/*!**********************!*\
|
|
2051
|
+
!*** ./src/types.ts ***!
|
|
2052
|
+
\**********************/
|
|
2053
|
+
/*! no static exports found */
|
|
2054
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
2055
|
+
|
|
2056
|
+
"use strict";
|
|
2057
|
+
|
|
2058
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2059
|
+
exports.Separator = exports.Namon = exports.CapsRange = exports.Flat = exports.NameType = exports.NameOrder = exports.Surname = exports.Title = void 0;
|
|
2060
|
+
/**
|
|
2061
|
+
* The abbreviation type to indicate whether or not to add period to a prefix
|
|
2062
|
+
* using the American or British way.
|
|
2063
|
+
*/
|
|
2064
|
+
var Title;
|
|
2065
|
+
(function (Title) {
|
|
2066
|
+
// A period after the prefix.
|
|
2067
|
+
Title["US"] = "US";
|
|
2068
|
+
// No period after the prefix.
|
|
2069
|
+
Title["UK"] = "UK";
|
|
2070
|
+
})(Title = exports.Title || (exports.Title = {}));
|
|
2071
|
+
/**
|
|
2072
|
+
* An option indicating how to format a surname.
|
|
2073
|
+
*
|
|
2074
|
+
* This enum can be set via `Config` or when creating a `LastName`. As this can
|
|
2075
|
+
* become ambiguous at the time of handling it, the value set in `Config` is
|
|
2076
|
+
* prioritized and viewed as the source of truth for future considerations.
|
|
2077
|
+
*/
|
|
2078
|
+
var Surname;
|
|
2079
|
+
(function (Surname) {
|
|
2080
|
+
// The fatherly surname only.
|
|
2081
|
+
Surname["FATHER"] = "father";
|
|
2082
|
+
// The motherly surname only.
|
|
2083
|
+
Surname["MOTHER"] = "mother";
|
|
2084
|
+
// The junction of both the fatherly and motherly surnames with a hyphen.
|
|
2085
|
+
Surname["HYPHENATED"] = "hyphenated";
|
|
2086
|
+
// The junction of both the fatherly and motherly surnames with a space.
|
|
2087
|
+
Surname["ALL"] = "all";
|
|
2088
|
+
})(Surname = exports.Surname || (exports.Surname = {}));
|
|
2089
|
+
/**
|
|
2090
|
+
* The order of appearance of a `FullName`.
|
|
2091
|
+
*/
|
|
2092
|
+
var NameOrder;
|
|
2093
|
+
(function (NameOrder) {
|
|
2094
|
+
// The first part of a full name, usually the first piece of a person name.
|
|
2095
|
+
NameOrder["FIRST_NAME"] = "firstName";
|
|
2096
|
+
// The last part of a full name, usually the last piece of a person name.
|
|
2097
|
+
NameOrder["LAST_NAME"] = "lastName";
|
|
2098
|
+
})(NameOrder = exports.NameOrder || (exports.NameOrder = {}));
|
|
2099
|
+
/**
|
|
2100
|
+
* The types of name handled in this according the name standards.
|
|
2101
|
+
*/
|
|
2102
|
+
var NameType;
|
|
2103
|
+
(function (NameType) {
|
|
2104
|
+
NameType["FIRST_NAME"] = "firstName";
|
|
2105
|
+
NameType["MIDDLE_NAME"] = "middleName";
|
|
2106
|
+
NameType["LAST_NAME"] = "lastName";
|
|
2107
|
+
NameType["BIRTH_NAME"] = "birthName";
|
|
2108
|
+
})(NameType = exports.NameType || (exports.NameType = {}));
|
|
2109
|
+
/**
|
|
2110
|
+
* The possible variants to indicate how to flatten a `FullName`.
|
|
2111
|
+
*/
|
|
2112
|
+
var Flat;
|
|
2113
|
+
(function (Flat) {
|
|
2114
|
+
// Use the first name's initial combined with the remaining parts.
|
|
2115
|
+
Flat["FIRST_NAME"] = "firstName";
|
|
2116
|
+
// Use the middle name's initial combined with the remaining parts.
|
|
2117
|
+
Flat["MIDDLE_NAME"] = "middleName";
|
|
2118
|
+
// Use the last name's initial combined with the remaining parts.
|
|
2119
|
+
Flat["LAST_NAME"] = "lastName";
|
|
2120
|
+
// Use both the first and middle names' initials combined with the remaining parts.
|
|
2121
|
+
Flat["FIRST_MID"] = "firstMid";
|
|
2122
|
+
// Use both the last and middle names' initials combined with the remaining parts.
|
|
2123
|
+
Flat["MID_LAST"] = "midLast";
|
|
2124
|
+
// Use the first, middle and last names' initials combined with the remaining parts.
|
|
2125
|
+
Flat["ALL"] = "all";
|
|
2126
|
+
})(Flat = exports.Flat || (exports.Flat = {}));
|
|
2127
|
+
/**
|
|
2128
|
+
* The range to use when capitalizing a string content.
|
|
2129
|
+
*/
|
|
2130
|
+
var CapsRange;
|
|
2131
|
+
(function (CapsRange) {
|
|
2132
|
+
// No capitalization.
|
|
2133
|
+
CapsRange[CapsRange["NONE"] = 0] = "NONE";
|
|
2134
|
+
// Apply capitalization to the first letter.
|
|
2135
|
+
CapsRange[CapsRange["INITIAL"] = 1] = "INITIAL";
|
|
2136
|
+
// Apply capitalization to all the letters.
|
|
2137
|
+
CapsRange[CapsRange["ALL"] = 2] = "ALL";
|
|
2138
|
+
})(CapsRange = exports.CapsRange || (exports.CapsRange = {}));
|
|
2139
|
+
/**
|
|
2140
|
+
* The types of name handled in this utility according the name standards.
|
|
2141
|
+
*/
|
|
2142
|
+
class Namon {
|
|
2143
|
+
constructor(index, key) {
|
|
2144
|
+
this.index = index;
|
|
2145
|
+
this.key = key;
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Whether this string key is part of the predefined keys.
|
|
2149
|
+
*/
|
|
2150
|
+
static has(key) {
|
|
2151
|
+
return Namon.all.has(key);
|
|
2152
|
+
}
|
|
2153
|
+
/**
|
|
2154
|
+
* Makes a string key a namon type.
|
|
2155
|
+
*/
|
|
2156
|
+
static cast(key) {
|
|
2157
|
+
return Namon.has(key) ? Namon.all.get(key) : undefined;
|
|
2158
|
+
}
|
|
2159
|
+
/**
|
|
2160
|
+
* String representation of this object.
|
|
2161
|
+
*/
|
|
2162
|
+
toString() {
|
|
2163
|
+
return `Namon.${this.key}`;
|
|
2164
|
+
}
|
|
2165
|
+
/**
|
|
2166
|
+
* Whether this and the other value are equal.
|
|
2167
|
+
*/
|
|
2168
|
+
equal(other) {
|
|
2169
|
+
return other instanceof Namon && other.index == this.index && other.key == this.key;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
exports.Namon = Namon;
|
|
2173
|
+
Namon.PREFIX = new Namon(0, 'prefix');
|
|
2174
|
+
Namon.FIRST_NAME = new Namon(1, 'firstName');
|
|
2175
|
+
Namon.MIDDLE_NAME = new Namon(2, 'middleName');
|
|
2176
|
+
Namon.LAST_NAME = new Namon(3, 'lastName');
|
|
2177
|
+
Namon.SUFFIX = new Namon(4, 'suffix');
|
|
2178
|
+
/**
|
|
2179
|
+
* The list of supported name types.
|
|
2180
|
+
*/
|
|
2181
|
+
Namon.values = [Namon.PREFIX, Namon.FIRST_NAME, Namon.MIDDLE_NAME, Namon.LAST_NAME, Namon.SUFFIX];
|
|
2182
|
+
/**
|
|
2183
|
+
* All the predefined name types.
|
|
2184
|
+
*/
|
|
2185
|
+
Namon.all = new Map([
|
|
2186
|
+
[Namon.PREFIX.key, Namon.PREFIX],
|
|
2187
|
+
[Namon.FIRST_NAME.key, Namon.FIRST_NAME],
|
|
2188
|
+
[Namon.MIDDLE_NAME.key, Namon.MIDDLE_NAME],
|
|
2189
|
+
[Namon.LAST_NAME.key, Namon.LAST_NAME],
|
|
2190
|
+
[Namon.SUFFIX.key, Namon.SUFFIX],
|
|
2191
|
+
]);
|
|
2192
|
+
/**
|
|
2193
|
+
* The token used to indicate how to split string values.
|
|
2194
|
+
*/
|
|
2195
|
+
class Separator {
|
|
2196
|
+
constructor(name, token) {
|
|
2197
|
+
this.name = name;
|
|
2198
|
+
this.token = token;
|
|
2199
|
+
}
|
|
2200
|
+
/**
|
|
2201
|
+
* String representation of this object.
|
|
2202
|
+
*/
|
|
2203
|
+
toString() {
|
|
2204
|
+
return `Separator.${this.name}`;
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
exports.Separator = Separator;
|
|
2208
|
+
Separator.COMMA = new Separator('comma', ',');
|
|
2209
|
+
Separator.COLON = new Separator('colon', ':');
|
|
2210
|
+
Separator.DOUBLE_QUOTE = new Separator('doubleQuote', '"');
|
|
2211
|
+
Separator.EMPTY = new Separator('empty', '');
|
|
2212
|
+
Separator.HYPHEN = new Separator('hyphen', '-');
|
|
2213
|
+
Separator.PERIOD = new Separator('period', '.');
|
|
2214
|
+
Separator.SEMI_COLON = new Separator('semiColon', ';');
|
|
2215
|
+
Separator.SINGLE_QUOTE = new Separator('singleQuote', "'");
|
|
2216
|
+
Separator.SPACE = new Separator('space', ' ');
|
|
2217
|
+
Separator.UNDERSCORE = new Separator('underscore', '_');
|
|
2218
|
+
/**
|
|
2219
|
+
* All the available separators.
|
|
2220
|
+
*/
|
|
2221
|
+
Separator.all = new Map([
|
|
2222
|
+
[Separator.COMMA.name, Separator.COMMA],
|
|
2223
|
+
[Separator.COLON.name, Separator.COLON],
|
|
2224
|
+
[Separator.DOUBLE_QUOTE.name, Separator.DOUBLE_QUOTE],
|
|
2225
|
+
[Separator.EMPTY.name, Separator.EMPTY],
|
|
2226
|
+
[Separator.HYPHEN.name, Separator.HYPHEN],
|
|
2227
|
+
[Separator.PERIOD.name, Separator.PERIOD],
|
|
2228
|
+
[Separator.SEMI_COLON.name, Separator.SEMI_COLON],
|
|
2229
|
+
[Separator.SINGLE_QUOTE.name, Separator.SINGLE_QUOTE],
|
|
2230
|
+
[Separator.SPACE.name, Separator.SPACE],
|
|
2231
|
+
[Separator.UNDERSCORE.name, Separator.UNDERSCORE],
|
|
2232
|
+
]);
|
|
2233
|
+
/**
|
|
2234
|
+
* All the available tokens.
|
|
2235
|
+
*/
|
|
2236
|
+
Separator.tokens = [...Separator.all.values()].map((s) => s.token);
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
/***/ }),
|
|
2240
|
+
|
|
2241
|
+
/***/ "./src/utils.ts":
|
|
2242
|
+
/*!**********************!*\
|
|
2243
|
+
!*** ./src/utils.ts ***!
|
|
2244
|
+
\**********************/
|
|
2245
|
+
/*! no static exports found */
|
|
2246
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
2247
|
+
|
|
2248
|
+
"use strict";
|
|
2249
|
+
|
|
2250
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2251
|
+
exports.isNameArray = exports.isStringArray = exports.toggleCase = exports.decapitalize = exports.capitalize = exports.NameIndex = void 0;
|
|
2252
|
+
const constants_1 = __webpack_require__(/*! ./constants */ "./src/constants.ts");
|
|
2253
|
+
const name_1 = __webpack_require__(/*! ./name */ "./src/name.ts");
|
|
2254
|
+
const types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
|
|
2255
|
+
/**
|
|
2256
|
+
* A fixed set of values to handle specific positions for list of names.
|
|
2257
|
+
*
|
|
2258
|
+
* As for list of names, this helps to follow a specific order based on the
|
|
2259
|
+
* count of elements. It is expected that the list has to be between two and
|
|
2260
|
+
* five elements. Also, the order of appearance set in the configuration
|
|
2261
|
+
* influences how the parsing is carried out.
|
|
2262
|
+
*
|
|
2263
|
+
* Ordered by first name, the parser works as follows:
|
|
2264
|
+
* - 2 elements: firstName lastName
|
|
2265
|
+
* - 3 elements: firstName middleName lastName
|
|
2266
|
+
* - 4 elements: prefix firstName middleName lastName
|
|
2267
|
+
* - 5 elements: prefix firstName middleName lastName suffix
|
|
2268
|
+
*
|
|
2269
|
+
* Ordered by last name, the parser works as follows:
|
|
2270
|
+
* - 2 elements: lastName firstName
|
|
2271
|
+
* - 3 elements: lastName firstName middleName
|
|
2272
|
+
* - 4 elements: prefix lastName firstName middleName
|
|
2273
|
+
* - 5 elements: prefix lastName firstName middleName suffix
|
|
2274
|
+
*
|
|
2275
|
+
* For example, `Jane Smith` (ordered by first name) is expected to be indexed:
|
|
2276
|
+
* `['Jane', 'Smith']`.
|
|
2277
|
+
*/
|
|
2278
|
+
class NameIndex {
|
|
2279
|
+
constructor(prefix, firstName, middleName, lastName, suffix) {
|
|
2280
|
+
this.prefix = prefix;
|
|
2281
|
+
this.firstName = firstName;
|
|
2282
|
+
this.middleName = middleName;
|
|
2283
|
+
this.lastName = lastName;
|
|
2284
|
+
this.suffix = suffix;
|
|
2285
|
+
}
|
|
2286
|
+
/**
|
|
2287
|
+
* The minimum number of parts in a list of names.
|
|
2288
|
+
*/
|
|
2289
|
+
static get min() {
|
|
2290
|
+
return constants_1.MIN_NUMBER_OF_NAME_PARTS;
|
|
2291
|
+
}
|
|
2292
|
+
/**
|
|
2293
|
+
* The maximum number of parts in a list of names.
|
|
2294
|
+
*/
|
|
2295
|
+
static get max() {
|
|
2296
|
+
return constants_1.MAX_NUMBER_OF_NAME_PARTS;
|
|
2297
|
+
}
|
|
2298
|
+
/**
|
|
2299
|
+
* The default or base indexing: firstName lastName.
|
|
2300
|
+
*/
|
|
2301
|
+
static base() {
|
|
2302
|
+
return new this(-1, 0, -1, 1, -1);
|
|
2303
|
+
}
|
|
2304
|
+
/**
|
|
2305
|
+
* Gets the name index for a list of names based on the `count` of elements
|
|
2306
|
+
* and their `order` of appearance.
|
|
2307
|
+
*/
|
|
2308
|
+
static when(order, count = 2) {
|
|
2309
|
+
if (order == types_1.NameOrder.FIRST_NAME) {
|
|
2310
|
+
switch (count) {
|
|
2311
|
+
case 2: // first name + last name
|
|
2312
|
+
return new this(-1, 0, -1, 1, -1);
|
|
2313
|
+
case 3: // first name + middle name + last name
|
|
2314
|
+
return new this(-1, 0, 1, 2, -1);
|
|
2315
|
+
case 4: // prefix + first name + middle name + last name
|
|
2316
|
+
return new this(0, 1, 2, 3, -1);
|
|
2317
|
+
case 5: // prefix + first name + middle name + last name + suffix
|
|
2318
|
+
return new this(0, 1, 2, 3, 4);
|
|
2319
|
+
default:
|
|
2320
|
+
return NameIndex.base();
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
else {
|
|
2324
|
+
switch (count) {
|
|
2325
|
+
case 2: // last name + first name
|
|
2326
|
+
return new this(-1, 1, -1, 0, -1);
|
|
2327
|
+
case 3: // last name + first name + middle name
|
|
2328
|
+
return new this(-1, 1, 2, 0, -1);
|
|
2329
|
+
case 4: // prefix + last name + first name + middle name
|
|
2330
|
+
return new this(0, 2, 3, 1, -1);
|
|
2331
|
+
case 5: // prefix + last name + first name + middle name + suffix
|
|
2332
|
+
return new this(0, 2, 3, 1, 4);
|
|
2333
|
+
default:
|
|
2334
|
+
return NameIndex.base();
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
exports.NameIndex = NameIndex;
|
|
2340
|
+
/**
|
|
2341
|
+
* Capitalizes a string via a `CapsRange` option.
|
|
2342
|
+
*/
|
|
2343
|
+
function capitalize(str, range = types_1.CapsRange.INITIAL) {
|
|
2344
|
+
if (!str || range === types_1.CapsRange.NONE)
|
|
2345
|
+
return str;
|
|
2346
|
+
const initial = str[0].toUpperCase();
|
|
2347
|
+
const rest = str.slice(1).toLowerCase();
|
|
2348
|
+
return range === types_1.CapsRange.INITIAL ? initial.concat(rest) : str.toUpperCase();
|
|
2349
|
+
}
|
|
2350
|
+
exports.capitalize = capitalize;
|
|
2351
|
+
/**
|
|
2352
|
+
* Decapitalizes a string via a `CapsRange` option.
|
|
2353
|
+
*/
|
|
2354
|
+
function decapitalize(str, range = types_1.CapsRange.INITIAL) {
|
|
2355
|
+
if (!str || range === types_1.CapsRange.NONE)
|
|
2356
|
+
return str;
|
|
2357
|
+
const initial = str[0].toLowerCase();
|
|
2358
|
+
const rest = str.slice(1);
|
|
2359
|
+
return range === types_1.CapsRange.INITIAL ? initial.concat(rest) : str.toLowerCase();
|
|
2360
|
+
}
|
|
2361
|
+
exports.decapitalize = decapitalize;
|
|
2362
|
+
/**
|
|
2363
|
+
* Toggles a string representation.
|
|
2364
|
+
*/
|
|
2365
|
+
function toggleCase(str) {
|
|
2366
|
+
const chars = [];
|
|
2367
|
+
for (const c of str) {
|
|
2368
|
+
if (c === c.toUpperCase()) {
|
|
2369
|
+
chars.push(c.toLowerCase());
|
|
2370
|
+
}
|
|
2371
|
+
else {
|
|
2372
|
+
chars.push(c.toUpperCase());
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
return chars.join('');
|
|
2376
|
+
}
|
|
2377
|
+
exports.toggleCase = toggleCase;
|
|
2378
|
+
function isStringArray(value) {
|
|
2379
|
+
return Array.isArray(value) && value.length > 0 && value.every((e) => typeof e === 'string');
|
|
2380
|
+
}
|
|
2381
|
+
exports.isStringArray = isStringArray;
|
|
2382
|
+
function isNameArray(value) {
|
|
2383
|
+
return Array.isArray(value) && value.length > 0 && value.every((e) => e instanceof name_1.Name);
|
|
2384
|
+
}
|
|
2385
|
+
exports.isNameArray = isNameArray;
|
|
2386
|
+
|
|
2387
|
+
|
|
2388
|
+
/***/ }),
|
|
2389
|
+
|
|
2390
|
+
/***/ "./src/validator.ts":
|
|
2391
|
+
/*!**************************!*\
|
|
2392
|
+
!*** ./src/validator.ts ***!
|
|
2393
|
+
\**************************/
|
|
2394
|
+
/*! no static exports found */
|
|
2395
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
2396
|
+
|
|
2397
|
+
"use strict";
|
|
2398
|
+
|
|
2399
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2400
|
+
exports.Validators = exports.ArrayNameValidator = exports.ArrayStringValidator = exports.NamaValidator = void 0;
|
|
2401
|
+
const constants_1 = __webpack_require__(/*! ./constants */ "./src/constants.ts");
|
|
2402
|
+
const error_1 = __webpack_require__(/*! ./error */ "./src/error.ts");
|
|
2403
|
+
const name_1 = __webpack_require__(/*! ./name */ "./src/name.ts");
|
|
2404
|
+
const types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
|
|
2405
|
+
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
|
|
2406
|
+
/**
|
|
2407
|
+
* Represents a set of validation rules (regex)
|
|
2408
|
+
*
|
|
2409
|
+
* This regex is intented to match specific alphabets only as a person name does
|
|
2410
|
+
* not contain special characters. `\w` does not cover non-Latin characters. So,
|
|
2411
|
+
* it is extended using unicode chars to cover more cases (e.g., Icelandic).
|
|
2412
|
+
* It matches as follows:
|
|
2413
|
+
* [a-z]: Latin alphabet from a (index 97) to z (index 122)
|
|
2414
|
+
* [A-Z]: Latin alphabet from A (index 65) to Z (index 90)
|
|
2415
|
+
* [\u00C0-\u00D6]: Latin/German chars from À (index 192) to Ö (index 214)
|
|
2416
|
+
* [\u00D8-\u00f6]: German/Icelandic chars from Ø (index 216) to ö (index 246)
|
|
2417
|
+
* [\u00f8-\u00ff]: German/Icelandic chars from ø (index 248) to ÿ (index 255)
|
|
2418
|
+
* [\u0400-\u04FF]: Cyrillic alphabet from Ѐ (index 1024) to ӿ (index 1279)
|
|
2419
|
+
* [Ά-ωΑ-ώ]: Greek alphabet from Ά (index 902) to ω (index 969)
|
|
2420
|
+
*/
|
|
2421
|
+
class ValidationRule {
|
|
2422
|
+
}
|
|
2423
|
+
ValidationRule.base = /[a-zA-Z\u00C0-\u00D6\u00D8-\u00f6\u00f8-\u00ff\u0400-\u04FFΆ-ωΑ-ώ]/;
|
|
2424
|
+
/**
|
|
2425
|
+
* Matches one name part (namon) that is of nature:
|
|
2426
|
+
* - Latin (English, Spanish, French, etc.)
|
|
2427
|
+
* - European (Greek, Cyrillic, Icelandic, German)
|
|
2428
|
+
* - hyphenated
|
|
2429
|
+
* - with apostrophe
|
|
2430
|
+
* - with space
|
|
2431
|
+
*/
|
|
2432
|
+
ValidationRule.namon = new RegExp(`^${ValidationRule.base.source}+(([' -]${ValidationRule.base.source})?${ValidationRule.base.source}*)*$`);
|
|
2433
|
+
/**
|
|
2434
|
+
* Matches one name part (namon) that is of nature:
|
|
2435
|
+
* - Latin (English, Spanish, French, etc.)
|
|
2436
|
+
* - European (Greek, Cyrillic, Icelandic, German)
|
|
2437
|
+
* - hyphenated
|
|
2438
|
+
* - with apostrophe
|
|
2439
|
+
*/
|
|
2440
|
+
ValidationRule.firstName = ValidationRule.namon;
|
|
2441
|
+
/**
|
|
2442
|
+
* Matches 1+ names part (namon) that are of nature:
|
|
2443
|
+
* - Latin (English, Spanish, French, etc.)
|
|
2444
|
+
* - European (Greek, Cyrillic, Icelandic, German)
|
|
2445
|
+
* - hyphenated
|
|
2446
|
+
* - with apostrophe
|
|
2447
|
+
* - with space
|
|
2448
|
+
*/
|
|
2449
|
+
ValidationRule.middleName = new RegExp(`^${ValidationRule.base.source}+(([' -]${ValidationRule.base.source})?${ValidationRule.base.source}*)*$`);
|
|
2450
|
+
/**
|
|
2451
|
+
* Matches one name part (namon) that is of nature:
|
|
2452
|
+
* - Latin (English, Spanish, French, etc.)
|
|
2453
|
+
* - European (Greek, Cyrillic, Icelandic, German)
|
|
2454
|
+
* - hyphenated
|
|
2455
|
+
* - with apostrophe
|
|
2456
|
+
* - with space
|
|
2457
|
+
*/
|
|
2458
|
+
ValidationRule.lastName = ValidationRule.namon;
|
|
2459
|
+
class ArrayValidator {
|
|
2460
|
+
validate(values) {
|
|
2461
|
+
if (values.length == 0 ||
|
|
2462
|
+
values.length < constants_1.MIN_NUMBER_OF_NAME_PARTS ||
|
|
2463
|
+
values.length > constants_1.MAX_NUMBER_OF_NAME_PARTS) {
|
|
2464
|
+
throw new error_1.InputError({
|
|
2465
|
+
source: values.map((n) => n.toString()),
|
|
2466
|
+
message: `expecting a list of ${constants_1.MIN_NUMBER_OF_NAME_PARTS}-${constants_1.MIN_NUMBER_OF_NAME_PARTS} elements`,
|
|
2467
|
+
});
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
class NamonValidator {
|
|
2472
|
+
constructor() { }
|
|
2473
|
+
static create() {
|
|
2474
|
+
return this.validator || (this.validator = new this());
|
|
2475
|
+
}
|
|
2476
|
+
validate(value, type) {
|
|
2477
|
+
if (value instanceof name_1.Name) {
|
|
2478
|
+
NameValidator.create().validate(value, type);
|
|
2479
|
+
}
|
|
2480
|
+
else if (typeof value === 'string') {
|
|
2481
|
+
if (!ValidationRule.namon.test(value)) {
|
|
2482
|
+
throw new error_1.ValidationError({
|
|
2483
|
+
source: value,
|
|
2484
|
+
nameType: 'namon',
|
|
2485
|
+
message: 'invalid content',
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
else {
|
|
2490
|
+
throw new error_1.InputError({
|
|
2491
|
+
source: typeof value,
|
|
2492
|
+
message: 'expecting types of string | Name',
|
|
2493
|
+
});
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
class FirstNameValidator {
|
|
2498
|
+
constructor() { }
|
|
2499
|
+
static create() {
|
|
2500
|
+
return this.validator || (this.validator = new this());
|
|
2501
|
+
}
|
|
2502
|
+
validate(value) {
|
|
2503
|
+
if (value instanceof name_1.FirstName) {
|
|
2504
|
+
value.asNames.forEach((name) => this.validate(name.value));
|
|
2505
|
+
}
|
|
2506
|
+
else if (typeof value === 'string') {
|
|
2507
|
+
if (!ValidationRule.firstName.test(value)) {
|
|
2508
|
+
throw new error_1.ValidationError({
|
|
2509
|
+
source: value,
|
|
2510
|
+
nameType: 'firstName',
|
|
2511
|
+
message: 'invalid content',
|
|
2512
|
+
});
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
else {
|
|
2516
|
+
throw new error_1.InputError({
|
|
2517
|
+
source: typeof value,
|
|
2518
|
+
message: 'expecting types string | FirstName',
|
|
2519
|
+
});
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
class MiddleNameValidator {
|
|
2524
|
+
constructor() { }
|
|
2525
|
+
static create() {
|
|
2526
|
+
return this.validator || (this.validator = new this());
|
|
2527
|
+
}
|
|
2528
|
+
validate(value) {
|
|
2529
|
+
if (typeof value === 'string') {
|
|
2530
|
+
if (!ValidationRule.middleName.test(value)) {
|
|
2531
|
+
throw new error_1.ValidationError({
|
|
2532
|
+
source: value,
|
|
2533
|
+
nameType: 'middleName',
|
|
2534
|
+
message: 'invalid content',
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
else if (Array.isArray(value)) {
|
|
2539
|
+
try {
|
|
2540
|
+
const validator = NamonValidator.create();
|
|
2541
|
+
for (let name of value)
|
|
2542
|
+
validator.validate(name, types_1.Namon.MIDDLE_NAME);
|
|
2543
|
+
}
|
|
2544
|
+
catch (error) {
|
|
2545
|
+
throw new error_1.ValidationError({
|
|
2546
|
+
source: value,
|
|
2547
|
+
nameType: 'middleName',
|
|
2548
|
+
message: error === null || error === void 0 ? void 0 : error.message,
|
|
2549
|
+
});
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
else {
|
|
2553
|
+
throw new error_1.InputError({
|
|
2554
|
+
source: typeof value,
|
|
2555
|
+
message: 'expecting types of string | string[] | Name[]',
|
|
2556
|
+
});
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
class LastNameValidator {
|
|
2561
|
+
constructor() { }
|
|
2562
|
+
static create() {
|
|
2563
|
+
return this.validator || (this.validator = new this());
|
|
2564
|
+
}
|
|
2565
|
+
validate(value) {
|
|
2566
|
+
if (value instanceof name_1.LastName) {
|
|
2567
|
+
value.asNames.forEach((name) => this.validate(name.value));
|
|
2568
|
+
}
|
|
2569
|
+
else if (typeof value === 'string') {
|
|
2570
|
+
if (!ValidationRule.lastName.test(value)) {
|
|
2571
|
+
throw new error_1.ValidationError({
|
|
2572
|
+
source: value,
|
|
2573
|
+
nameType: 'lastName',
|
|
2574
|
+
message: 'invalid content',
|
|
2575
|
+
});
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
else {
|
|
2579
|
+
throw new error_1.InputError({
|
|
2580
|
+
source: typeof value,
|
|
2581
|
+
message: 'expecting types string | LastName',
|
|
2582
|
+
});
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
class NameValidator {
|
|
2587
|
+
constructor() { }
|
|
2588
|
+
static create() {
|
|
2589
|
+
return this.validator || (this.validator = new this());
|
|
2590
|
+
}
|
|
2591
|
+
validate(name, type) {
|
|
2592
|
+
if (type && name.type !== type) {
|
|
2593
|
+
throw new error_1.ValidationError({
|
|
2594
|
+
source: [name],
|
|
2595
|
+
nameType: name.type.toString(),
|
|
2596
|
+
message: 'wrong type',
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2599
|
+
if (!ValidationRule.namon.test(name.value)) {
|
|
2600
|
+
throw new error_1.ValidationError({
|
|
2601
|
+
source: [name],
|
|
2602
|
+
nameType: name.type.toString(),
|
|
2603
|
+
message: 'invalid content',
|
|
2604
|
+
});
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
class NamaValidator {
|
|
2609
|
+
constructor() { }
|
|
2610
|
+
static create() {
|
|
2611
|
+
return this.validator || (this.validator = new this());
|
|
2612
|
+
}
|
|
2613
|
+
validate(value) {
|
|
2614
|
+
this.validateKeys(value);
|
|
2615
|
+
Validators.firstName.validate(value.get(types_1.Namon.FIRST_NAME));
|
|
2616
|
+
Validators.lastName.validate(value.get(types_1.Namon.LAST_NAME));
|
|
2617
|
+
if (value.has(types_1.Namon.PREFIX)) {
|
|
2618
|
+
Validators.namon.validate(value.get(types_1.Namon.PREFIX));
|
|
2619
|
+
}
|
|
2620
|
+
if (value.has(types_1.Namon.SUFFIX)) {
|
|
2621
|
+
Validators.namon.validate(value.get(types_1.Namon.SUFFIX));
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
validateKeys(nama) {
|
|
2625
|
+
if (!nama.size) {
|
|
2626
|
+
throw new error_1.InputError({ source: undefined, message: 'Map<k,v> must not be empty' });
|
|
2627
|
+
}
|
|
2628
|
+
else if (nama.size < constants_1.MIN_NUMBER_OF_NAME_PARTS || nama.size > constants_1.MAX_NUMBER_OF_NAME_PARTS) {
|
|
2629
|
+
throw new error_1.InputError({
|
|
2630
|
+
source: [...nama.values()],
|
|
2631
|
+
message: `expecting ${constants_1.MIN_NUMBER_OF_NAME_PARTS}-${constants_1.MIN_NUMBER_OF_NAME_PARTS} fields`,
|
|
2632
|
+
});
|
|
2633
|
+
}
|
|
2634
|
+
if (!nama.has(types_1.Namon.FIRST_NAME)) {
|
|
2635
|
+
throw new error_1.InputError({
|
|
2636
|
+
source: [...nama.values()],
|
|
2637
|
+
message: '"firstName" is a required key',
|
|
2638
|
+
});
|
|
2639
|
+
}
|
|
2640
|
+
if (!nama.has(types_1.Namon.LAST_NAME)) {
|
|
2641
|
+
throw new error_1.InputError({
|
|
2642
|
+
source: [...nama.values()],
|
|
2643
|
+
message: '"lastName" is a required key',
|
|
2644
|
+
});
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
exports.NamaValidator = NamaValidator;
|
|
2649
|
+
class ArrayStringValidator extends ArrayValidator {
|
|
2650
|
+
constructor(index = utils_1.NameIndex.base()) {
|
|
2651
|
+
super();
|
|
2652
|
+
this.index = index;
|
|
2653
|
+
}
|
|
2654
|
+
validate(values) {
|
|
2655
|
+
this.validateIndex(values);
|
|
2656
|
+
switch (values.length) {
|
|
2657
|
+
case 2:
|
|
2658
|
+
Validators.firstName.validate(values[this.index.firstName]);
|
|
2659
|
+
Validators.lastName.validate(values[this.index.lastName]);
|
|
2660
|
+
break;
|
|
2661
|
+
case 3:
|
|
2662
|
+
Validators.firstName.validate(values[this.index.firstName]);
|
|
2663
|
+
Validators.middleName.validate(values[this.index.middleName]);
|
|
2664
|
+
Validators.lastName.validate(values[this.index.lastName]);
|
|
2665
|
+
break;
|
|
2666
|
+
case 4:
|
|
2667
|
+
Validators.namon.validate(values[this.index.prefix]);
|
|
2668
|
+
Validators.firstName.validate(values[this.index.firstName]);
|
|
2669
|
+
Validators.middleName.validate(values[this.index.middleName]);
|
|
2670
|
+
Validators.lastName.validate(values[this.index.lastName]);
|
|
2671
|
+
break;
|
|
2672
|
+
case 5:
|
|
2673
|
+
Validators.namon.validate(values[this.index.prefix]);
|
|
2674
|
+
Validators.firstName.validate(values[this.index.firstName]);
|
|
2675
|
+
Validators.middleName.validate(values[this.index.middleName]);
|
|
2676
|
+
Validators.lastName.validate(values[this.index.lastName]);
|
|
2677
|
+
Validators.namon.validate(values[this.index.suffix]);
|
|
2678
|
+
break;
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
validateIndex(values) {
|
|
2682
|
+
super.validate(values);
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
exports.ArrayStringValidator = ArrayStringValidator;
|
|
2686
|
+
class ArrayNameValidator {
|
|
2687
|
+
constructor() { }
|
|
2688
|
+
static create() {
|
|
2689
|
+
return this.validator || (this.validator = new this());
|
|
2690
|
+
}
|
|
2691
|
+
validate(value) {
|
|
2692
|
+
if (value.length < constants_1.MIN_NUMBER_OF_NAME_PARTS) {
|
|
2693
|
+
throw new error_1.InputError({
|
|
2694
|
+
source: value,
|
|
2695
|
+
message: `expecting at least ${constants_1.MIN_NUMBER_OF_NAME_PARTS} elements`,
|
|
2696
|
+
});
|
|
2697
|
+
}
|
|
2698
|
+
if (!this.hasBasicNames(value)) {
|
|
2699
|
+
throw new error_1.InputError({
|
|
2700
|
+
source: value,
|
|
2701
|
+
message: 'both first and last names are required',
|
|
2702
|
+
});
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
hasBasicNames(names) {
|
|
2706
|
+
const accumulator = {};
|
|
2707
|
+
for (const name of names) {
|
|
2708
|
+
if (name.isFirstName || name.isLastName) {
|
|
2709
|
+
accumulator[name.type.key] = name.toString();
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
return Object.keys(accumulator).length == constants_1.MIN_NUMBER_OF_NAME_PARTS;
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
exports.ArrayNameValidator = ArrayNameValidator;
|
|
2716
|
+
/**
|
|
2717
|
+
* A list of validators for a specific namon.
|
|
2718
|
+
*/
|
|
2719
|
+
class Validators {
|
|
2720
|
+
}
|
|
2721
|
+
exports.Validators = Validators;
|
|
2722
|
+
Validators.namon = NamonValidator.create();
|
|
2723
|
+
Validators.nama = NamaValidator.create();
|
|
2724
|
+
Validators.prefix = NamonValidator.create();
|
|
2725
|
+
Validators.firstName = FirstNameValidator.create();
|
|
2726
|
+
Validators.middleName = MiddleNameValidator.create();
|
|
2727
|
+
Validators.lastName = LastNameValidator.create();
|
|
2728
|
+
Validators.suffix = NamonValidator.create();
|
|
2729
|
+
|
|
2730
|
+
|
|
2731
|
+
/***/ })
|
|
2732
|
+
|
|
2733
|
+
/******/ });
|
|
2734
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vZXhhbXBsZS9leGFtcGxlLnRzIiwid2VicGFjazovLy8uL3NyYy9jb25maWcudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbnN0YW50cy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvZXJyb3IudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Z1bGwtbmFtZS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL25hbWUudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL25hbWVmdWxseS50cyIsIndlYnBhY2s6Ly8vLi9zcmMvcGFyc2VyLnRzIiwid2VicGFjazovLy8uL3NyYy90eXBlcy50cyIsIndlYnBhY2s6Ly8vLi9zcmMvdXRpbHMudHMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3ZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO1FBQUE7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7OztRQUdBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSwwQ0FBMEMsZ0NBQWdDO1FBQzFFO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0Esd0RBQXdELGtCQUFrQjtRQUMxRTtRQUNBLGlEQUFpRCxjQUFjO1FBQy9EOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQSx5Q0FBeUMsaUNBQWlDO1FBQzFFLGdIQUFnSCxtQkFBbUIsRUFBRTtRQUNySTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBLDJCQUEyQiwwQkFBMEIsRUFBRTtRQUN2RCxpQ0FBaUMsZUFBZTtRQUNoRDtRQUNBO1FBQ0E7O1FBRUE7UUFDQSxzREFBc0QsK0RBQStEOztRQUVySDtR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QUFDLENBQUMsQ0FBQztnQkFDMUQsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLGVBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZELE1BQUs7WUFDVCxLQUFLLENBQUM7Z0JBQ0YsUUFBUSxDQUFDLFlBQVksQ0FBQyxJQUFJLGdCQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUMxRCxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDakUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLGVBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZELE1BQUs7WUFDVCxLQUFLLENBQUM7Z0JBQ0YsUUFBUSxDQUFDLFNBQVMsQ0FBQyxXQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDbEQsUUFBUSxDQUFDLFlBQVksQ0FBQyxJQUFJLGdCQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUMxRCxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDakUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLGVBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZELE1BQUs7WUFDVCxLQUFLLENBQUM7Z0JBQ0YsUUFBUSxDQUFDLFNBQVMsQ0FBQyxXQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDbEQsUUFBUSxDQUFDLFlBQVksQ0FBQyxJ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Z0JBQ0YsVUFBVSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQzNELFVBQVUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN6RCxNQUFLO1lBQ1QsS0FBSyxDQUFDO2dCQUNGLFVBQVUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUMzRCxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDN0QsVUFBVSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3pELE1BQUs7WUFDVCxLQUFLLENBQUM7Z0JBQ0YsVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3BELFVBQVUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUMzRCxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDN0QsVUFBVSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3pELE1BQUs7WUFDVCxLQUFLLENBQUM7Z0JBQ0YsVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3BELFVBQVUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUMzRCxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDN0QsVUFBVSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3pELFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNwRCxNQUFLO1NBQ1o7SUFDTCxDQUFDO0lBRUQsYUFBYSxDQUFDLE1BQWdCO1FBQzFCLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO0lBQzFCLENBQUM7Q0FDSjtBQXJDRCxvREFxQ0M7QUFFRCxNQUFhLGtCQUFrQjtJQUUzQixnQkFBdUIsQ0FBQztJQUN4QixNQUFNLENBQUMsTUFBTTtRQUNULE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUMxRCxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQWE7UUFDbEIsSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLG9DQUF3QixFQUFFO1lBQ3pDLE1BQU0sSUFBSSxrQkFBVSxDQUFDO2dCQUNqQixNQUFNLEVBQUUsS0FBSztnQkFDYixPQUFPLEVBQUUsc0JBQXNCLG9DQUF3QixXQUFXO2FBQ3JFLENBQUM7U0FDTDtRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQzVCLE1BQU0sSUFBSSxrQkFBVSxDQUFDO2dCQUNqQixNQUFNLEVBQUUsS0FBSztnQkFDYixPQUFPLEVBQUUsd0NBQXdDO2FBQ3BELENBQUM7U0FDTDtJQUNMLENBQUM7SUFFTyxhQUFhLENBQUMsS0FBYTtRQUMvQixNQUFNLFdBQVcsR0FBOEIsRUFBRTtRQUNqRCxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtZQUN0QixJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDckMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRTthQUMvQztTQUNKO1FBQ0QsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sSUFBSSxvQ0FBd0I7SUFDdEUsQ0FBQztDQUNKO0FBaENELGdEQWdDQztBQUVEOztHQUVHO0FBQ0gsTUFBc0IsVUFBVTs7QUFBaEMsZ0NBUUM7QUFQVSxnQkFBSyxHQUFHLGNBQWMsQ0FBQyxNQUFNLEVBQUU7QUFDL0IsZUFBSSxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUU7QUFDN0IsaUJBQU0sR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFO0FBQ2hDLG9CQUFTLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxFQUFFO0FBQ3ZDLHFCQUFVLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxFQUFFO0FBQ3pDLG1CQUFRLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxFQUFFO0FBQ3JDLGlCQUFNLEdBQUcsY0FBYyxDQUFDLE1BQU0sRUFBRSIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGdldHRlciB9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuIFx0XHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcbiBcdFx0fVxuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuIFx0fTtcblxuIFx0Ly8gY3JlYXRlIGEgZmFrZSBuYW1lc3BhY2Ugb2JqZWN0XG4gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcbiBcdC8vIG1vZGUgJiAyOiBtZXJnZSBhbGwgcHJvcGVydGllcyBvZiB2YWx1ZSBpbnRvIHRoZSBuc1xuIFx0Ly8gbW9kZSAmIDQ6IHJldHVybiB2YWx1ZSB3aGVuIGFscmVhZHkgbnMgb2JqZWN0XG4gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnQgPSBmdW5jdGlvbih2YWx1ZSwgbW9kZSkge1xuIFx0XHRpZihtb2RlICYgMSkgdmFsdWUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKHZhbHVlKTtcbiBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcbiBcdFx0aWYoKG1vZGUgJiA0KSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcbiBcdFx0dmFyIG5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG5zLCAnZGVmYXVsdCcsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuIFx0XHRpZihtb2RlICYgMiAmJiB0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIGZvcih2YXIga2V5IGluIHZhbHVlKSBfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGtleSwgZnVuY3Rpb24oa2V5KSB7IHJldHVybiB2YWx1ZVtrZXldOyB9LmJpbmQobnVsbCwga2V5KSk7XG4gXHRcdHJldHVybiBucztcbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSBcIi4vZXhhbXBsZS9leGFtcGxlLnRzXCIpO1xuIiwiaW1wb3J0IHsgTmFtZWZ1bGx5LCBOYW1lT3JkZXIgfSBmcm9tICcuLi9zcmMvaW5kZXgnXG5cbmZ1bmN0aW9uIGV4YW1wbGUoKSB7XG4gICAgLy8gR2l2ZXMgYSBzaW1wbGUgbmFtZSBzb21lIHN1cGVyIHBvd2VyLlxuICAgIGNvbnN0IG5hbWUgPSBuZXcgTmFtZWZ1bGx5KCdUaG9tYXMgQWx2YSBFZGlzb24nLCB7IG9yZGVyZWRCeTogTmFtZU9yZGVyLkxBU1RfTkFNRSB9KVxuXG4gICAgLy8gR2V0cyB0aGUgY291bnQgb2YgY2hhcmFjdGVycywgaW5jbHVkaW5nIHNwYWNlLlxuICAgIGNvbnNvbGUubG9nKG5hbWUubGVuZ3RoKSAvLyAxOFxuXG4gICAgLy8gR2V0cyB0aGUgZmlyc3QgbmFtZS5cbiAgICBjb25zb2xlLmxvZyhuYW1lLmZpcnN0KSAvLyBUaG9tYXNcblxuICAgIC8vIEdldHMgdGhlIGZpcnN0IG1pZGRsZSBuYW1lLlxuICAgIGNvbnNvbGUubG9nKG5hbWUubWlkZGxlKSAvLyBBbHZhXG5cbiAgICAvLyBHZXRzIHRoZSBsYXN0IG5hbWUuXG4gICAgY29uc29sZS5sb2cobmFtZS5sYXN0KSAvLyBFZGlzb25cblxuICAgIC8vIENvbnRyb2xzIHdoYXQgdGhlIHB1YmxpYyBzZWVzLlxuICAgIGNvbnNvbGUubG9nKG5hbWUucHVibGljKSAvLyBUaG9tYXMgRVxuXG4gICAgLy8gR2V0cyBhbGwgdGhlIGluaXRpYWxzLlxuICAgIGNvbnNvbGUubG9nKG5hbWUuaW5pdGlhbHMoKSkgLy8gWydUJywgJ0EnLCAnRSddXG5cbiAgICAvLyBGb3JtYXRzIGl0IGFzIGRlc2lyZWQuXG4gICAgY29uc29sZS5sb2cobmFtZS5mb3JtYXQoJ0wsIGYgbScpKSAvLyBFRElTT04sIFRob21hcyBBbHZhXG5cbiAgICAvLyBNYWtlcyBpdCBzaG9ydC5cbiAgICBjb25zb2xlLmxvZyhuYW1lLnNob3J0ZW4oKSkgLy8gVGhvbWFzIEVkaXNvblxuXG4gICAgLy8gTWFrZXMgaXQgZmxhdC5cbiAgICBjb25zb2xlLmxvZyhuYW1lLnppcCgpKSAvLyBUaG9tYXMgQS4gRS5cblxuICAgIC8vIE1ha2VzIGl0IHVwcGVyY2FzZS5cbiAgICBjb25zb2xlLmxvZyhuYW1lLnRvVXBwZXJDYXNlKCkpIC8vIFRIT01BUyBBTFZBIEVESVNPTlxuXG4gICAgLy8gVHJhbnNmb3JtcyBpdCBpbnRvIGRvdC5jYXNlLlxuICAgIGNvbnNvbGUubG9nKG5hbWUudG9Eb3RDYXNlKCkpIC8vIHRob21hcy5hbHZhLmVkaXNvblxufVxuXG5leGFtcGxlKClcbiIsImltcG9ydCB7IE5hbWVPcmRlciwgU2VwYXJhdG9yLCBUaXRsZSwgU3VybmFtZSB9IGZyb20gJy4vdHlwZXMnXG5cbmNvbnN0IGRlZmF1bHROYW1lID0gJ2RlZmF1bHQnXG5jb25zdCBjb3B5QWxpYXMgPSAnX2NvcHknXG5cbi8qKlxuICogVGhlIENvbmZpZ3VyYXRpb24gdG8gdXNlIGFjcm9zcyB0aGUgb3RoZXIgY29tcG9uZW50cy5cbiAqXG4gKiBUaGUgbXVsdGl0b24gcGF0dGVybiBpcyB1c2VkIHRvIGhhbmRsZSBjb25maWd1cmF0aW9ucyBhY3Jvc3MgdGhlIGBuYW1lZnVsbHlgXG4gKiBzZXR1cC4gVGhpcyBhZGRzIGNvbnNpc3RlbmN5IHdoZW4gYnVpbGRpbmcgb3RoZXIgY29tcG9uZW50cyBzdWNoIGFzIGBGaXJzdE5hbWVgLFxuICogYExhc3ROYW1lYCwgb3IgYE5hbWVgIG9mIGRpc3RpbmN0IHR5cGVzIHRoYXQgbWF5IGJlIG9mIHBhcnRpY3VsYXIgc2hhcGVzLlxuICpcbiAqIEZvciBleGFtcGxlLCBhIHBlcnNvbidzIGBGdWxsTmFtZWAgbWF5IGFwcGVhciBieTpcbiAqIC0gTmFtZU9yZGVyLkZJUlNUX05BTUU6IGBKb24gU25vd2Agb3JcbiAqIC0gTmFtZU9yZGVyLkxBU1RfTkFNRTogYFNub3cgSm9uYC5cbiAqXG4gKiBgQ29uZmlnYCBtYWtlcyBpdCBlYXN5IHRvIHNldCB1cCBhIHNwZWNpZmljIGNvbmZpZ3VyYXRpb24gZm9yIGBOYW1lZnVsbHlgXG4gKiBhbmQgcmV1c2UgaXQgdGhyb3VnaCBvdGhlciBpbnN0YW5jZXMgb3IgY29tcG9uZW50cyBhbG9uZyB0aGUgd2F5LiBJZiBhIG5ld1xuICogYENvbmZpZ2AgaXMgbmVlZGVkLCBhIG5hbWVkIGNvbmZpZ3VyYXRpb24gbWF5IGJlIGNyZWF0ZWQuIEl0IGlzIGFjdHVhbGx5XG4gKiBhZHZpc2VkIHRvIHVzZSBuYW1lZCBgQ29uZmlnLmNyZWF0ZShuYW1lKWAgaW5zdGVhZCBhcyBpdCBtYXkgaGVscCBtaXRpZ2F0ZSBpc3N1ZXNcbiAqIGFuZCBhdm9pZCBjb25mdXNpb24gYW5kIGFtYmlndWl0eSBpbiB0aGUgZnV0dXJlLiBQbHVzLCBhIG5hbWVkIGNvbmZpZ3VyYXRpb25cbiAqIGV4cGxhaW5zIGl0cyBwdXJwb3NlLlxuICpcbiAqIGBgYHRzXG4gKiBjb25zdCBkZWZhdWx0Q29uZmlnID0gQ29uZmlnLmNyZWF0ZSgpO1xuICogY29uc3QgbWVyZ2VkQ29uZmlnID0gQ29uZmlnLm1lcmdlKHsgbmFtZTogJ290aGVyJywgdGl0bGU6IFRpdGxlLlVTIH0pO1xuICogY29uc3QgY29weUNvbmZpZyA9IG1lcmdlZENvbmZpZy5jb3B5V2l0aCh7IGVuZGluZzogdHJ1ZSB9KTtcbiAqIGBgYFxuICpcbiAqIEFkZGl0aW9uYWxseSwgYSBjb25maWd1cmF0aW9uIG1heSBiZSBtZXJnZWQgd2l0aCBvciBjb3BpZWQgZnJvbSBhbiBleGlzdGluZ1xuICogY29uZmlndXJhdGlvbiwgcHJpb3JpdGl6aW5nIHRoZSBuZXcgb25lJ3MgdmFsdWVzLCBhcyBzaG93biBpbiB0aGUgZXhhbXBsZVxuICogYWJvdmUuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25maWcge1xuICAgIHByaXZhdGUgX25hbWU6IHN0cmluZ1xuICAgIHByaXZhdGUgX29yZGVyZWRCeTogTmFtZU9yZGVyXG4gICAgcHJpdmF0ZSBfc2VwYXJhdG9yOiBTZXBhcmF0b3JcbiAgICBwcml2YXRlIF90aXRsZTogVGl0bGVcbiAgICBwcml2YXRlIF9lbmRpbmc6IGJvb2xlYW5cbiAgICBwcml2YXRlIF9ieXBhc3M6IGJvb2xlYW5cbiAgICBwcml2YXRlIF9zdXJuYW1lOiBTdXJuYW1lXG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3JkZXIgb2YgYXBwZWFyYW5jZSBvZiBhIGZ1bGwgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgb3JkZXJlZEJ5KCk6IE5hbWVPcmRlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vcmRlcmVkQnlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdG9rZW4gdXNlZCB0byBpbmRpY2F0ZSBob3cgdG8gc3BsaXQgc3RyaW5nIHZhbHVlcy5cbiAgICAgKi9cbiAgICBnZXQgc2VwYXJhdG9yKCk6IFNlcGFyYXRvciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXBhcmF0b3JcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYWJicmV2aWF0aW9uIHR5cGUgdG8gaW5kaWNhdGUgd2hldGhlciBvciBub3QgdG8gYWRkIHBlcmlvZCB0byBhIHByZWZpeFxuICAgICAqIHVzaW5nIHRoZSBBbWVyaWNhbiBvciBCcml0aXNoIHdheS5cbiAgICAgKi9cbiAgICBnZXQgdGl0bGUoKTogVGl0bGUge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGl0bGVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3B0aW9uIGluZGljYXRpbmcgaWYgYW4gZW5kaW5nIHN1ZmZpeCBpcyB1c2VkIGluIGEgZm9ybWFsIHdheS5cbiAgICAgKi9cbiAgICBnZXQgZW5kaW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5kaW5nXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBieXBhc3Mgb2YgdGhlIHZhbGlkYXRpb24gcnVsZXMgd2l0aCB0aGlzIG9wdGlvbi4gVGhpcyBvcHRpb24gaXMgaWRlYWxcbiAgICAgKiB0byBhdm9pZCBjaGVja2luZyB0aGVpciB2YWxpZGl0eS5cbiAgICAgKi9cbiAgICBnZXQgYnlwYXNzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnlwYXNzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQW4gb3B0aW9uIGluZGljYXRpbmcgaG93IHRvIGZvcm1hdCBhIHN1cm5hbWUuXG4gICAgICpcbiAgICAgKiBUaGUgc3VwcG9ydGVkIGZvcm1hdHMgYXJlOlxuICAgICAqIC0gYEZBVEhFUmAgbmFtZSBvbmx5XG4gICAgICogLSBgTU9USEVSYCBuYW1lIG9ubHlcbiAgICAgKiAtIGBIWVBIRU5BVEVEYCwgam9pbmluZyBib3RoIGZhdGhlciBhbmQgbW90aGVyIG5hbWVzIHdpdGggYSBoeXBoZW5cbiAgICAgKiAtIGBBTExgLCBqb2luaW5nIGJvdGggZmF0aGVyIGFuZCBtb3RoZXIgbmFtZXMgd2l0aCBhIHNwYWNlLlxuICAgICAqXG4gICAgICogTm90ZSB0aGF0IHRoaXMgb3B0aW9uIGNhbiBiZSBzZXQgd2hlbiBjcmVhdGluZyBhIGBMYXN0TmFtZWAuIEFzIHRoaXMgY2FuXG4gICAgICogYmVjb21lIGFtYmlndW91cyBhdCB0aGUgdGltZSBvZiBoYW5kbGluZyBpdCwgdGhlIHZhbHVlIHNldCBpbiB0aGlzIGlzXG4gICAgICogcHJpb3JpdGl6ZWQgYW5kIHZpZXdlZCBhcyB0aGUgc291cmNlIG9mIHRydXRoIGZvciBmdXR1cmUgY29uc2lkZXJhdGlvbnMuXG4gICAgICovXG4gICAgZ2V0IHN1cm5hbWUoKTogU3VybmFtZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdXJuYW1lXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGNhY2hlZCBjb25maWd1cmF0aW9uLlxuICAgICAqL1xuICAgIGdldCBuYW1lKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9uYW1lXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FjaGUgZm9yIG11bHRpcGxlIGluc3RhbmNlcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHN0YXRpYyBjYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBDb25maWc+KClcblxuICAgIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgICAgIG5hbWU6IHN0cmluZyxcbiAgICAgICAgb3JkZXJlZEJ5ID0gTmFtZU9yZGVyLkZJUlNUX05BTUUsXG4gICAgICAgIHNlcGFyYXRvciA9IFNlcGFyYXRvci5TUEFDRSxcbiAgICAgICAgdGl0bGUgPSBUaXRsZS5VSyxcbiAgICAgICAgZW5kaW5nID0gZmFsc2UsXG4gICAgICAgIGJ5cGFzcyA9IHRydWUsXG4gICAgICAgIHN1cm5hbWUgPSBTdXJuYW1lLkZBVEhFUixcbiAgICApIHtcbiAgICAgICAgdGhpcy5fbmFtZSA9IG5hbWVcbiAgICAgICAgdGhpcy5fb3JkZXJlZEJ5ID0gb3JkZXJlZEJ5XG4gICAgICAgIHRoaXMuX3NlcGFyYXRvciA9IHNlcGFyYXRvclxuICAgICAgICB0aGlzLl90aXRsZSA9IHRpdGxlXG4gICAgICAgIHRoaXMuX2VuZGluZyA9IGVuZGluZ1xuICAgICAgICB0aGlzLl9ieXBhc3MgPSBieXBhc3NcbiAgICAgICAgdGhpcy5fc3VybmFtZSA9IHN1cm5hbWVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgbmFtZWQgY29uZmlndXJhdGlvbiB3aXRoIGRlZmF1bHQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSBuYW1lIGRlc2NyaWJpbmcgaXRzIHB1cnBvc2UuXG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZShuYW1lID0gZGVmYXVsdE5hbWUpOiBDb25maWcge1xuICAgICAgICBpZiAoIUNvbmZpZy5jYWNoZS5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIENvbmZpZy5jYWNoZS5zZXQobmFtZSwgbmV3IHRoaXMobmFtZSkpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIENvbmZpZy5jYWNoZS5nZXQobmFtZSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgY29tYmluZWQgdmVyc2lvbiBvZiB0aGUgZXhpc3RpbmcgdmFsdWVzIG9mIHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb25cbiAgICAgKiBhbmQgdGhlIHByb3ZpZGVkIG9wdGlvbmFsIHZhbHVlcyBvZiBhbm90aGVyIGNvbmZpZ3VyYXRpb24uXG4gICAgICogQHBhcmFtIG90aGVyIHBhcnRpYWwgY29uZmlnIHRvIGJlIGNvbWJpbmVkIHdpdGguXG4gICAgICovXG4gICAgc3RhdGljIG1lcmdlKG90aGVyPzogUGFydGlhbDxDb25maWc+KTogQ29uZmlnIHtcbiAgICAgICAgaWYgKCFvdGhlcikge1xuICAgICAgICAgICAgcmV0dXJuIENvbmZpZy5jcmVhdGUoKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmNyZWF0ZShvdGhlci5uYW1lKVxuICAgICAgICAgICAgY29uZmlnLl9vcmRlcmVkQnkgPSBvdGhlci5vcmRlcmVkQnkgPz8gY29uZmlnLm9yZGVyZWRCeVxuICAgICAgICAgICAgY29uZmlnLl9zZXBhcmF0b3IgPSBvdGhlci5zZXBhcmF0b3IgPz8gY29uZmlnLnNlcGFyYXRvclxuICAgICAgICAgICAgY29uZmlnLl90aXRsZSA9IG90aGVyLnRpdGxlID8/IGNvbmZpZy50aXRsZVxuICAgICAgICAgICAgY29uZmlnLl9lbmRpbmcgPSBvdGhlci5lbmRpbmcgPz8gY29uZmlnLmVuZGluZ1xuICAgICAgICAgICAgY29uZmlnLl9ieXBhc3MgPSBvdGhlci5ieXBhc3MgPz8gY29uZmlnLmJ5cGFzc1xuICAgICAgICAgICAgY29uZmlnLl9zdXJuYW1lID0gb3RoZXIuc3VybmFtZSA/PyBjb25maWcuc3VybmFtZVxuICAgICAgICAgICAgcmV0dXJuIGNvbmZpZ1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhpcyBjb25maWd1cmF0aW9uIG1lcmdlZCB3aXRoIHRoZSBwcm92aWRlZCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBUaGUgd29yZCBgX2NvcHlgIGlzIGFkZGVkIHRvIHRoZSBleGlzdGluZyBjb25maWcncyBuYW1lIHRvIGNyZWF0ZSB0aGUgbmV3XG4gICAgICogY29uZmlnJ3MgbmFtZSBpZiB0aGUgbmFtZSBhbHJlYWR5IGV4aXN0cyBmb3IgcHJldmlvdXMgY29uZmlndXJhdGlvbnMuIFRoaXNcbiAgICAgKiBpcyB1c2VmdWwgdG8gbWFpbnRhaW4gdGhlIHVuaXF1ZW5lc3Mgb2YgZWFjaCBjb25maWd1cmF0aW9uLiBGb3IgZXhhbXBsZSxcbiAgICAgKiBpZiB0aGUgbmV3IGNvcHkgaXMgbWFkZSBmcm9tIHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24sIHRoaXMgbmV3IGNvcHkgd2lsbFxuICAgICAqIGJlIG5hbWVkIGBkZWZhdWx0X2NvcHlgLlxuICAgICAqL1xuICAgIGNvcHlXaXRoKG9wdGlvbnM6IFBhcnRpYWw8Q29uZmlnPiA9IHt9KTogQ29uZmlnIHtcbiAgICAgICAgY29uc3QgeyBuYW1lLCBvcmRlcmVkQnksIHNlcGFyYXRvciwgdGl0bGUsIGVuZGluZywgYnlwYXNzLCBzdXJuYW1lIH0gPSBvcHRpb25zXG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5jcmVhdGUodGhpcy5nZW5OZXdOYW1lKG5hbWUgPz8gdGhpcy5uYW1lICsgY29weUFsaWFzKSlcbiAgICAgICAgY29uZmlnLl9vcmRlcmVkQnkgPSBvcmRlcmVkQnkgPz8gdGhpcy5vcmRlcmVkQnlcbiAgICAgICAgY29uZmlnLl9zZXBhcmF0b3IgPSBzZXBhcmF0b3IgPz8gdGhpcy5zZXBhcmF0b3JcbiAgICAgICAgY29uZmlnLl90aXRsZSA9IHRpdGxlID8/IHRoaXMudGl0bGVcbiAgICAgICAgY29uZmlnLl9lbmRpbmcgPSBlbmRpbmcgPz8gdGhpcy5lbmRpbmdcbiAgICAgICAgY29uZmlnLl9ieXBhc3MgPSBieXBhc3MgPz8gdGhpcy5ieXBhc3NcbiAgICAgICAgY29uZmlnLl9zdXJuYW1lID0gc3VybmFtZSA/PyB0aGlzLnN1cm5hbWVcbiAgICAgICAgcmV0dXJuIGNvbmZpZ1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2VzIGFuIGV4YWN0IGNvcHkgb2YgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbi5cbiAgICAgKi9cbiAgICBjbG9uZSgpOiBDb25maWcge1xuICAgICAgICByZXR1cm4gdGhpcy5jb3B5V2l0aCgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzZXRzIHRoZSBjb25maWd1cmF0aW9uIGJ5IHNldHRpbmcgaXQgYmFjayB0byBpdHMgZGVmYXVsdCB2YWx1ZXMuXG4gICAgICovXG4gICAgcmVzZXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX29yZGVyZWRCeSA9IE5hbWVPcmRlci5GSVJTVF9OQU1FXG4gICAgICAgIHRoaXMuX3NlcGFyYXRvciA9IFNlcGFyYXRvci5TUEFDRVxuICAgICAgICB0aGlzLl90aXRsZSA9IFRpdGxlLlVLXG4gICAgICAgIHRoaXMuX2VuZGluZyA9IGZhbHNlXG4gICAgICAgIHRoaXMuX2J5cGFzcyA9IHRydWVcbiAgICAgICAgdGhpcy5fc3VybmFtZSA9IFN1cm5hbWUuRkFUSEVSXG4gICAgICAgIENvbmZpZy5jYWNoZS5zZXQodGhpcy5uYW1lLCB0aGlzKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsdGVycyB0aGUgbmFtZSBvcmRlciBiZXR3ZWVuIHRoZSBmaXJzdCBhbmQgbGFzdCBuYW1lLCBhbmQgcmVhcnJhbmdlIHRoZVxuICAgICAqIG9yZGVyIG9mIGFwcGVhcmFuY2Ugb2YgYSBuYW1lIHNldC5cbiAgICAgKi9cbiAgICB1cGRhdGVPcmRlcihvcmRlcjogTmFtZU9yZGVyKTogdm9pZCB7XG4gICAgICAgIGlmIChvcmRlciAmJiBvcmRlciAhPT0gdGhpcy5fb3JkZXJlZEJ5KSB7XG4gICAgICAgICAgICBDb25maWcuY2FjaGUuZ2V0KHRoaXMubmFtZSkuX29yZGVyZWRCeSA9IG9yZGVyXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZXMgYSB1bmlxdWUgbmV3IG5hbWUuXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZW5OZXdOYW1lKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBuYW1lID09PSB0aGlzLm5hbWUgfHwgQ29uZmlnLmNhY2hlLmhhcyhuYW1lKSA/IHRoaXMuZ2VuTmV3TmFtZShuYW1lICsgY29weUFsaWFzKSA6IG5hbWVcbiAgICB9XG59XG4iLCJleHBvcnQgY29uc3QgdmVyc2lvbiA9ICcxLjIuMCdcbmV4cG9ydCBjb25zdCBNSU5fTlVNQkVSX09GX05BTUVfUEFSVFMgPSAyXG5leHBvcnQgY29uc3QgTUFYX05VTUJFUl9PRl9OQU1FX1BBUlRTID0gNVxuZXhwb3J0IGNvbnN0IEFMTE9XRURfVE9LRU5TID0gW1xuICAgICcuJyxcbiAgICAnLCcsXG4gICAgJyAnLFxuICAgICctJyxcbiAgICAnXycsXG4gICAgJ2InLFxuICAgICdCJyxcbiAgICAnZicsXG4gICAgJ0YnLFxuICAgICdsJyxcbiAgICAnTCcsXG4gICAgJ20nLFxuICAgICdNJyxcbiAgICAnbicsXG4gICAgJ04nLFxuICAgICdvJyxcbiAgICAnTycsXG4gICAgJ3AnLFxuICAgICdQJyxcbiAgICAncycsXG4gICAgJ1MnLFxuICAgICckJyxcbl1cbiIsImltcG9ydCB7IE5hbWUgfSBmcm9tICcuL25hbWUnXG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJy4vdHlwZXMnXG5pbXBvcnQgeyBpc05hbWVBcnJheSwgaXNTdHJpbmdBcnJheSB9IGZyb20gJy4vdXRpbHMnXG5cbnR5cGUgTmFtZVNvdXJjZSA9IE51bGxhYmxlPHN0cmluZyB8IHN0cmluZ1tdIHwgTmFtZVtdPlxuXG5pbnRlcmZhY2UgRXJyb3JNZXNzYWdlIHtcbiAgICBzb3VyY2U6IE5hbWVTb3VyY2VcbiAgICBtZXNzYWdlPzogc3RyaW5nXG59XG5cbi8qKlxuICogVGhlIGVycm9yIHR5cGVzIHN1cHBvcnRlZCBieSBgTmFtZWZ1bGx5YC5cbiAqL1xuZXhwb3J0IGVudW0gTmFtZUVycm9yVHlwZSB7XG4gICAgLyoqXG4gICAgICogVGhyb3duIHdoZW4gYSBuYW1lIGVudHJ5L2FyZ3VtZW50IGlzIGluY29ycmVjdC5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlLCBhIG5hbWUgc2hvdWxkIGhhdmUgYSBtaW5pbXVtIG9mIDIgY2hhcmFjdGVycywgc28gYW4gZW1wdHlcbiAgICAgKiBzdHJpbmcgb3IgYSBzdHJpbmcgb2Ygb25lIGNoYXJhY3RlciB3b3VsZCBjYXVzZSB0aGlzIGtpbmQgb2YgZXJyb3IuXG4gICAgICovXG4gICAgSU5QVVQsXG5cbiAgICAvKipcbiAgICAgKiBUaHJvd24gd2hlbiB0aGUgbmFtZSBjb21wb25lbnRzIGRvIG5vdCBtYXRjaCB0aGUgdmFsaWRhdGlvbiBydWxlcyBpZiB0aGVcbiAgICAgKiBgQ29uZmlnLmJ5cGFzc2AgaXMgbm90IGZsYWdnZWQgdXAuIFRoaXMgYnlwYXNzIG9wdGlvbiBza2lwcyB0aGUgdmFsaWRhdGlvblxuICAgICAqIHJ1bGVzLlxuICAgICAqXG4gICAgICogU2VlIGFsc286IGBWYWxpZGF0aW9uRXJyb3JgXG4gICAgICovXG4gICAgVkFMSURBVElPTixcblxuICAgIC8qKlxuICAgICAqIFRocm93biBieSBub3QgYWxsb3dlZCBvcGVyYXRpb25zIHN1Y2ggYXMgaW4gTmFtZUJ1aWxkZXIgb3IgbmFtZSBmb3JtYXR0aW5nLlxuICAgICAqXG4gICAgICogU2VlIGFsc286IGBOb3RBbGxvd2VkRXJyb3JgLCBgTmFtZWZ1bGx5LmZvcm1hdGAuXG4gICAgICovXG4gICAgTk9UX0FMTE9XRUQsXG5cbiAgICAvKipcbiAgICAgKiBUaHJvd24gYnkgYW55IG90aGVyIHVua25vd24gc291cmNlcyBvciB1bmV4cGVjdGVkIHNpdHVhdGlvbi5cbiAgICAgKi9cbiAgICBVTktOT1dOLFxufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGFsbCBuYW1lLXJlbGF0ZWQgZXJyb3JzLlxuICpcbiAqIEEgY3VzdG9tIGVycm9yIGlzIGludGVuZGVkIHRvIGNvbnZleSBpbmZvcm1hdGlvbiB0byB0aGUgdXNlciBhYm91dCBhIGZhaWx1cmUsXG4gKiBzbyB0aGF0IGl0IGNhbiBiZSBhZGRyZXNzZWQgcHJvZ3JhbW1hdGljYWxseS5cbiAqXG4gKiBBIG5hbWUgaGFuZGxpbmcgZmFpbHVyZSBpcyBub3QgY29uc2lkZXJlZCBhIG5hdGl2ZSBlcnJvciB0aGF0IHNob3VsZCBjYXVzZSBhXG4gKiBwcm9ncmFtIGZhaWx1cmUuIEF1IGNvbnRyYWlyZSwgaXQgaXMgZXhwZWN0ZWQgdGhhdCBhIHByb2dyYW1tZXIgdXNpbmcgdGhpcyB1dGlsaXR5XG4gKiB3b3VsZCBjb25zaWRlciB2YWxpZGF0aW5nIGEgbmFtZSB1c2luZyBpdHMgb3duIGJ1c2luZXNzIHJ1bGVzLiBUaGF0IGlzIG5vdFxuICogdGhpcyB1dGlsaXR5J3Mgam9iIHRvIGd1ZXNzIHRob3NlIHJ1bGVzLiBTbywgdGhlIHByZWRlZmluZWQgYFZhbGlkYXRpb25SdWxlc2BcbiAqIG9iZXkgc29tZSBjb21tb24gdmFsaWRhdGlvbiB0ZWNobmlxdWVzIHdoZW4gaXQgY29tZXMgdG8gc2FuaXRpemluZyBhIHBlcnNvblxuICogbmFtZS4gRm9yIHRoaXMgcmVhc29uLCB0aGUgW0NvbmZpZy5ieXBhc3NdIGlzIHNldCB0byBgdHJ1ZWAgYnkgZGVmYXVsdCxcbiAqIGluZGljYXRpbmcgdGhhdCB0aG9zZSBwcmVkZWZpbmVkIHJ1bGVzIHNob3VsZCBiZSBza2lwcGVkIGZvciB0aGUgc2FrZSBvZiB0aGVcbiAqIHByb2dyYW0uXG4gKlxuICogQSBwcm9ncmFtbWVyIG1heSBsZXZlcmFnZSBgUGFyc2VyYCB0byBpbmRpY2F0ZSBidXNpbmVzcy10YWlsb3JlZCBydWxlcyBpZiBoZVxuICogb3Igc2hlIHdhbnRzIHRoaXMgdXRpbGl0eSB0byBwZXJmb3JtIHRob3NlIHNhZmV0eSBjaGVja3MgYmVoaW5kIHRoZSBzY2VuZXMuXG4gKlxuICogQSBuYW1lIGVycm9yIGludGVuZHMgdG8gcHJvdmlkZSB1c2VmdWwgaW5mb3JtYXRpb24gYWJvdXQgd2hhdCBjYXVzZXMgdGhlIGVycm9yXG4gKiBhbmQgbGV0IHRoZSB1c2VyIHRha2UgaW5pdGlhdGl2ZSBvbiB3aGF0IGhhcHBlbnMgbmV4dCB0byB0aGUgZ2l2ZW4gbmFtZTpcbiAqIHJlY29uc3RydWN0aW5nIGl0IG9yIHNraXBwaW5nIGl0LlxuICovXG5leHBvcnQgY2xhc3MgTmFtZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gZXJyb3Igd2l0aCBhIG1lc3NhZ2UgZGVzY3JpYmluZyB0aGUgaXNzdWUgZm9yIGEgbmFtZSBzb3VyY2UuXG4gICAgICogQHBhcmFtIHNvdXJjZSBuYW1lIGlucHV0IHRoYXQgY2F1c2VkIHRoZSBlcnJvclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIGEgbWVzc2FnZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlLlxuICAgICAqIEBwYXJhbSB0eXBlIG9mIGBOYW1lRXJyb3JUeXBlYFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHJlYWRvbmx5IHNvdXJjZTogTmFtZVNvdXJjZSwgbWVzc2FnZT86IHN0cmluZywgcmVhZG9ubHkgdHlwZTogTmFtZUVycm9yVHlwZSA9IE5hbWVFcnJvclR5cGUuVU5LTk9XTikge1xuICAgICAgICBzdXBlcihtZXNzYWdlKVxuICAgICAgICB0aGlzLm5hbWUgPSAnTmFtZUVycm9yJ1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBhY3R1YWwgc291cmNlIGlucHV0IHdoaWNoIGNhdXNlZCB0aGUgZXJyb3IuXG4gICAgICovXG4gICAgZ2V0IHNvdXJjZUFzU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIGxldCBpbnB1dCA9ICcnXG4gICAgICAgIGlmICghdGhpcy5zb3VyY2UpIGlucHV0ID0gJzx1bmRlZmluZWQ+J1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuc291cmNlID09PSAnc3RyaW5nJykgaW5wdXQgPSB0aGlzLnNvdXJjZVxuICAgICAgICBpZiAoaXNOYW1lQXJyYXkodGhpcy5zb3VyY2UpKSBpbnB1dCA9ICg8TmFtZVtdPnRoaXMuc291cmNlKS5tYXAoKG4pID0+IG4udG9TdHJpbmcoKSkuam9pbignICcpXG4gICAgICAgIGlmIChpc1N0cmluZ0FycmF5KHRoaXMuc291cmNlKSkgaW5wdXQgPSAoPHN0cmluZ1tdPnRoaXMuc291cmNlKS5qb2luKCcgJylcbiAgICAgICAgcmV0dXJuIGlucHV0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBhIG1lc3NhZ2UgZGVzY3JpYmluZyB0aGUgZmFpbHVyZSBleGlzdHMuXG4gICAgICovXG4gICAgZ2V0IGhhc01lc3NhZ2UoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2UgJiYgdGhpcy5tZXNzYWdlLnRyaW0oKS5sZW5ndGggPiAwXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZXJyb3IuXG4gICAgICovXG4gICAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHJlcG9ydCA9IGAke3RoaXMubmFtZX0gKCR7dGhpcy5zb3VyY2VBc1N0cmluZ30pYFxuICAgICAgICBpZiAodGhpcy5oYXNNZXNzYWdlKSByZXBvcnQgPSBgJHtyZXBvcnR9OiAke3RoaXMubWVzc2FnZX1gXG4gICAgICAgIHJldHVybiByZXBvcnRcbiAgICB9XG59XG5cbi8qKlxuICogQW4gZXJyb3IgdGhyb3duIHdoZW4gYSBuYW1lIHNvdXJjZSBpbnB1dCBpcyBpbmNvcnJlY3QuXG4gKlxuICogQSBgTmFtZWAgaXMgYSBuYW1lIGZvciB0aGlzIHV0aWxpdHkgdW5kZXIgY2VydGFpbiBjcml0ZXJpYSAoaS5lLiwgMisgY2hhcnMpLFxuICogaGVuY2UsIGEgd3JvbmcgaW5wdXQgd2lsbCBjYXVzZSB0aGlzIGtpbmQgb2YgZXJyb3IuIEFub3RoZXIgY29tbW9uIHJlYXNvblxuICogbWF5IGJlIGEgd3Jvbmcga2V5IGluIGEgSnNvbiBuYW1lIHBhcnNpbmcgbWVjaGFuaXNtLlxuICpcbiAqIEtlZXAgaW4gbWluZCB0aGF0IHRoaXMgZXJyb3IgaXMgZGlmZmVyZW50IGZyb20gYSBgVmFsaWRhdGlvbkVycm9yYC5cbiAqL1xuZXhwb3J0IGNsYXNzIElucHV0RXJyb3IgZXh0ZW5kcyBOYW1lRXJyb3Ige1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgYElucHV0RXJyb3JgIHdpdGggYW4gb3B0aW9uYWwgZXJyb3IgYG1lc3NhZ2VgLlxuICAgICAqXG4gICAgICogVGhlIG5hbWUgc291cmNlIGlzIGJ5IG5hdHVyZSBhIHN0cmluZyBjb250ZW50LCBtYXliZSB3cmFwcGVkIHVwIGluIGEgZGlmZmVyZW50XG4gICAgICogdHlwZS4gVGhpcyBzdHJpbmcgdmFsdWUgbWF5IGJlIGV4dHJhY3RlZCB0byBmb3JtIHRoZSBmb2xsb3dpbmcgb3V0cHV0OlxuICAgICAqICAgXCJJbnB1dEVycm9yIChzdHJpbmdOYW1lKVwiLFxuICAgICAqICAgXCJJbnB1dEVycm9yIChzdHJpbmdOYW1lKTogbWVzc2FnZVwiLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGVycm9yOiBFcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgc3VwZXIoZXJyb3Iuc291cmNlLCBlcnJvci5tZXNzYWdlLCBOYW1lRXJyb3JUeXBlLklOUFVUKVxuICAgICAgICB0aGlzLm5hbWUgPSAnSW5wdXRFcnJvcidcbiAgICB9XG59XG5cbi8qKlxuICogQW4gZXJyb3IgdGhyb3duIHRvIGluZGljYXRlIHRoYXQgYSBuYW1lIGZhaWxzIHRoZSB2YWxpZGF0aW9uIHJ1bGVzLlxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgTmFtZUVycm9yIHtcbiAgICAvKipcbiAgICAgKiBOYW1lIG9mIHRoZSBpbnZhbGlkIGBuYW1lVHlwZWAgaWYgYXZhaWxhYmxlLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWVUeXBlOiBzdHJpbmdcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgZXJyb3IgY29udGFpbmluZyB0aGUgaW52YWxpZCBgbmFtZVR5cGVgIGFuZCBhIGBtZXNzYWdlYCB0aGF0XG4gICAgICogYnJpZWZseSBkZXNjcmliZXMgdGhlIHByb2JsZW0gaWYgcHJvdmlkZWQuXG4gICAgICpcbiAgICAgKiBGb3IgZXhhbXBsZSwgYSB2YWxpZGF0aW9uIGVycm9yIGNhbiBiZSBpbnRlcnByZXRlZCBhczpcbiAgICAgKiAgICAgXCJWYWxpZGF0aW9uRXJyb3IgKG5hbWVUeXBlPSdzdHJpbmdOYW1lJylcIixcbiAgICAgKiAgICAgXCJWYWxpZGF0aW9uRXJyb3IgKG5hbWVUeXBlPSdzdHJpbmdOYW1lJyk6IG1lc3NhZ2VcIlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGVycm9yOiBFcnJvck1lc3NhZ2UgJiB7IG5hbWVUeXBlOiBzdHJpbmcgfSkge1xuICAgICAgICBzdXBlcihlcnJvci5zb3VyY2UsIGVycm9yLm1lc3NhZ2UsIE5hbWVFcnJvclR5cGUuVkFMSURBVElPTilcbiAgICAgICAgdGhpcy5uYW1lVHlwZSA9IGVycm9yLm5hbWVUeXBlXG4gICAgICAgIHRoaXMubmFtZSA9ICdWYWxpZGF0aW9uRXJyb3InXG4gICAgfVxuXG4gICAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHJlcG9ydCA9IGAke3RoaXMubmFtZX0gKCR7dGhpcy5uYW1lVHlwZX09JyR7dGhpcy5zb3VyY2VBc1N0cmluZ30nKWBcbiAgICAgICAgaWYgKHRoaXMuaGFzTWVzc2FnZSkgcmVwb3J0ID0gYCR7cmVwb3J0fTogJHt0aGlzLm1lc3NhZ2V9YFxuICAgICAgICByZXR1cm4gcmVwb3J0XG4gICAgfVxufVxuXG4vKipcbiAqIFRocm93biBieSBub3QgYWxsb3dlZCBvcGVyYXRpb25zIHN1Y2ggYXMgaW4gbmFtZSBmb3JtYXR0aW5nLlxuICpcbiAqIEZvciBleGFtcGxlLCB0aGlzIHdpbGwgb2NjdXIgd2hlbiB0cnlpbmcgdG8gZm9ybWF0IGEgbmFtZSBhY2NvcmRpbmdseSB1c2luZ1xuICogYSBub24tc3VwcG9ydGVkIGtleS5cbiAqL1xuZXhwb3J0IGNsYXNzIE5vdEFsbG93ZWRFcnJvciBleHRlbmRzIE5hbWVFcnJvciB7XG4gICAgLyoqXG4gICAgICogVGhlIHJldm9rZWQgb3BlcmF0aW9uIG5hbWUuXG4gICAgICovXG4gICAgcmVhZG9ubHkgb3BlcmF0aW9uOiBzdHJpbmdcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgYE5vdEFsbG93ZWRFcnJvcmAgd2l0aCBhbiBvcHRpb25hbCBlcnJvciBgbWVzc2FnZWAgYW5kIHRoZVxuICAgICAqIGBvcGVyYXRpb25gIG5hbWUuXG4gICAgICpcbiAgICAgKiBGb3IgZXhhbXBsZSwgYW4gZXJyb3Igb2YgdGhpcyBraW5kIGNhbiBiZSBpbnRlcnByZXRlZCBhczpcbiAgICAgKiAgICAgXCJOb3RBbGxvd2VkRXJyb3IgKHN0cmluZ05hbWUpXCIsXG4gICAgICogICAgIFwiTm90QWxsb3dlZEVycm9yIChzdHJpbmdOYW1lKSAtIG9wZXJhdGlvbk5hbWVcIixcbiAgICAgKiAgICAgXCJOb3RBbGxvd2VkRXJyb3IgKHN0cmluZ05hbWUpIC0gb3BlcmF0aW9uTmFtZTogbWVzc2FnZVwiXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZXJyb3I6IEVycm9yTWVzc2FnZSAmIHsgb3BlcmF0aW9uOiBzdHJpbmcgfSkge1xuICAgICAgICBzdXBlcihlcnJvci5zb3VyY2UsIGVycm9yLm1lc3NhZ2UsIE5hbWVFcnJvclR5cGUuTk9UX0FMTE9XRUQpXG4gICAgICAgIHRoaXMub3BlcmF0aW9uID0gZXJyb3Iub3BlcmF0aW9uXG4gICAgICAgIHRoaXMubmFtZSA9ICdOb3RBbGxvd2VkRXJyb3InXG4gICAgfVxuXG4gICAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHJlcG9ydCA9IGAke3RoaXMubmFtZX0gKCR7dGhpcy5zb3VyY2VBc1N0cmluZ30pYFxuICAgICAgICBpZiAodGhpcy5vcGVyYXRpb24gJiYgdGhpcy5vcGVyYXRpb24udHJpbSgpLmxlbmd0aCA+IDApIHJlcG9ydCA9IGAke3JlcG9ydH0gLSAke3RoaXMub3BlcmF0aW9ufWBcbiAgICAgICAgaWYgKHRoaXMuaGFzTWVzc2FnZSkgcmVwb3J0ID0gYCR7cmVwb3J0fTogJHt0aGlzLm1lc3NhZ2V9YFxuICAgICAgICByZXR1cm4gcmVwb3J0XG4gICAgfVxufVxuXG4vKipcbiAqIEEgZmFsbGJhY2sgZXJyb3IgdGhyb3duIGJ5IGFueSB1bmtub3duIHNvdXJjZXMgb3IgdW5leHBlY3RlZCBmYWlsdXJlIHRoYXQgYXJlXG4gKiBub3Qgb2YgYE5hbWVFcnJvcmAuXG4gKlxuICogSW4gdGhpcyBwYXJ0aWN1bGFyIGNhc2UsIGFuIGBvcmlnaW5gIHJlbWFpbnMgdXNlZnVsIGFzIGl0IHByb3ZpZGVzIGRldGFpbHNcbiAqIG9uIHRoZSBzb3VyY2VzIGFuZCB0aGUgdHJ1ZSBuYXR1cmUgb2YgdGhlIHVuZXhwZWN0ZWQgZXJyb3IuXG4gKiBBdCB0aGlzIHBvaW50LCBkZWNpZGluZyB3aGV0aGVyIHRvIGV4aXQgdGhlIHByb2dyYW0gb3Igbm90IGRlcGVuZHMgb24gdGhlXG4gKiBwcm9ncmFtbWVyLlxuICovXG5leHBvcnQgY2xhc3MgVW5rbm93bkVycm9yIGV4dGVuZHMgTmFtZUVycm9yIHtcbiAgICAvKipcbiAgICAgKiBUaGUgcG9zc2libGUgdW5rbm93biBlcnJvciwgd2l0aCB0cmFjZSByZXZlYWxpbmcgaXRzIHNvdXJjZSBhbmQgcmVhc29uLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IG9yaWdpbj86IEVycm9yXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGBVbmtub3duRXJyb3JgIHdpdGggYW4gb3B0aW9uYWwgZXJyb3IgYG1lc3NhZ2VgLlxuICAgICAqIE9wdGlvbmFsbHksIHRoZSBvcmlnaW5hbCBlcnJvciByZXZlYWxpbmcgdGhlIHRydWUgbmF0dXJlIG9mIHRoZSBmYWlsdXJlLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGVycm9yOiBFcnJvck1lc3NhZ2UgJiB7IGVycm9yPzogRXJyb3IgfSkge1xuICAgICAgICBzdXBlcihlcnJvci5zb3VyY2UsIGVycm9yLm1lc3NhZ2UsIE5hbWVFcnJvclR5cGUuVU5LTk9XTilcbiAgICAgICAgdGhpcy5vcmlnaW4gPSBlcnJvci5lcnJvclxuICAgICAgICB0aGlzLm5hbWUgPSAnVW5rbm93bkVycm9yJ1xuICAgIH1cblxuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIGxldCByZXBvcnQgPSBzdXBlci50b1N0cmluZygpXG4gICAgICAgIGlmICh0aGlzLm9yaWdpbikgcmVwb3J0ICs9IGBcXG4ke3RoaXMub3JpZ2luLnRvU3RyaW5nKCl9YFxuICAgICAgICByZXR1cm4gcmVwb3J0XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgQ29uZmlnIH0gZnJvbSAnLi9jb25maWcnXG5pbXBvcnQgeyBOYW1lRXJyb3IsIFVua25vd25FcnJvciB9IGZyb20gJy4vZXJyb3InXG5pbXBvcnQgeyBGaXJzdE5hbWUsIExhc3ROYW1lLCBOYW1lLCBKc29uTmFtZSB9IGZyb20gJy4vbmFtZSdcbmltcG9ydCB7IE51bGxhYmxlLCBOYW1vbiwgVGl0bGUgfSBmcm9tICcuL3R5cGVzJ1xuaW1wb3J0IHsgVmFsaWRhdG9ycyB9IGZyb20gJy4vdmFsaWRhdG9yJ1xuXG4vKipcbiAqIFRoZSBjb3JlIGNvbXBvbmVudCBvZiB0aGlzIHV0aWxpdHkuXG4gKlxuICogVGhpcyBjb21wb25lbnQgaXMgY29tcHJpc2VkIG9mIGZpdmUgZW50aXRpZXMgdGhhdCBtYWtlIGl0IGVhc3kgdG8gaGFuZGxlIGFcbiAqIGZ1bGwgbmFtZSBzZXQ6IHByZWZpeCwgZmlyc3QgbmFtZSwgbWlkZGxlIG5hbWUsIGxhc3QgbmFtZSwgYW5kIHN1ZmZpeC5cbiAqIFRoaXMgY2xhc3MgaXMgaW50ZW5kZWQgZm9yIGludGVybmFsIHByb2Nlc3Nlcy4gSG93ZXZlciwgaXQgaXMgdW5kZXJzdGFuZGFibGVcbiAqIHRoYXQgaXQgbWlnaHQgYmUgbmVlZGVkIGF0IHNvbWUgcG9pbnQgZm9yIGFkZGl0aW9uYWwgcHVycG9zZXMuIEZvciB0aGlzIHJlYXNvbixcbiAqIGl0J3MgbWFkZSBhdmFpbGFibGUuXG4gKlxuICogSXQgaXMgcmVjb21tZW5kZWQgdG8gYXZvaWQgdXNpbmcgdGhpcyBjbGFzcyB1bmxlc3MgaXQgaXMgaGlnaGx5IG5lY2Vzc2FyeSBvclxuICogYSBjdXN0b20gcGFyc2VyIGlzIHVzZWQgZm9yIHVuY29tbW9uIHVzZSBjYXNlcy4gVGhpcyB1dGlsaXR5IHRyaWVzIHRvIGNvdmVyXG4gKiBhcyBtYW55IHVzZSBjYXNlcyBhcyBwb3NzaWJsZS5cbiAqXG4gKiBBZGRpdGlvbmFsbHksIGFuIG9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gY2FuIGJlIHVzZWQgdG8gaW5kaWNhdGUgc29tZSBzcGVjaWZpY1xuICogYmVoYXZpb3JzIHJlbGF0ZWQgdG8gdGhhdCBuYW1lIGhhbmRsaW5nLlxuICovXG5leHBvcnQgY2xhc3MgRnVsbE5hbWUge1xuICAgIHByaXZhdGUgX3ByZWZpeDogTnVsbGFibGU8TmFtZT5cbiAgICBwcml2YXRlIF9maXJzdE5hbWU6IEZpcnN0TmFtZVxuICAgIHByaXZhdGUgX21pZGRsZU5hbWU6IE5hbWVbXSA9IFtdXG4gICAgcHJpdmF0ZSBfbGFzdE5hbWU6IExhc3ROYW1lXG4gICAgcHJpdmF0ZSBfc3VmZml4OiBOdWxsYWJsZTxOYW1lPlxuICAgIHByaXZhdGUgX2NvbmZpZzogQ29uZmlnXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVsbCBuYW1lIGFzIGl0IGdvZXNcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBvcHRpb25hbCBjb25maWd1cmF0aW9uIGZvciBhZGRpdGlvbmFsIGZlYXR1cmVzLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM/OiBQYXJ0aWFsPENvbmZpZz4pIHtcbiAgICAgICAgdGhpcy5fY29uZmlnID0gQ29uZmlnLm1lcmdlKG9wdGlvbnMpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzbmFwc2hvdCBvZiB0aGUgY29uZmlndXJhdGlvbiB1c2VkIHRvIHNldCB1cCB0aGlzIGZ1bGwgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgY29uZmlnKCk6IENvbmZpZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb25maWdcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJlZml4IHBhcnQgb2YgdGhlIGZ1bGwgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgcHJlZml4KCk6IE51bGxhYmxlPE5hbWU+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ByZWZpeFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBmaXJzdCBuYW1lIHBhcnQgb2YgdGhlIGZ1bGwgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgZmlyc3ROYW1lKCk6IEZpcnN0TmFtZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maXJzdE5hbWVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbGFzdCBuYW1lIHBhcnQgb2YgdGhlIGZ1bGwgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgbGFzdE5hbWUoKTogTGFzdE5hbWUge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGFzdE5hbWVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWlkZGxlIG5hbWUgcGFydCBvZiB0aGUgZnVsbCBuYW1lLlxuICAgICAqL1xuICAgIGdldCBtaWRkbGVOYW1lKCk6IE5hbWVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9taWRkbGVOYW1lXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHN1ZmZpeCBwYXJ0IG9mIHRoZSBmdWxsIG5hbWUuXG4gICAgICovXG4gICAgZ2V0IHN1ZmZpeCgpOiBOdWxsYWJsZTxOYW1lPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdWZmaXhcbiAgICB9XG5cbiAgICBzZXRQcmVmaXgobmFtZTogTnVsbGFibGU8c3RyaW5nIHwgTmFtZT4pOiBGdWxsTmFtZSB7XG4gICAgICAgIGlmICghbmFtZSkgcmV0dXJuIHRoaXNcbiAgICAgICAgaWYgKCF0aGlzLl9jb25maWcuYnlwYXNzKSBWYWxpZGF0b3JzLnByZWZpeC52YWxpZGF0ZShuYW1lKVxuICAgICAgICBjb25zdCBwcmVmaXggPSBuYW1lIGluc3RhbmNlb2YgTmFtZSA/IG5hbWUudmFsdWUgOiBuYW1lXG4gICAgICAgIHRoaXMuX3ByZWZpeCA9IE5hbWUucHJlZml4KHRoaXMuX2NvbmZpZy50aXRsZSA9PT0gVGl0bGUuVVMgPyBgJHtwcmVmaXh9LmAgOiBwcmVmaXgpXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgc2V0Rmlyc3ROYW1lKG5hbWU6IHN0cmluZyB8IEZpcnN0TmFtZSk6IEZ1bGxOYW1lIHtcbiAgICAgICAgaWYgKCF0aGlzLl9jb25maWcuYnlwYXNzKSBWYWxpZGF0b3JzLmZpcnN0TmFtZS52YWxpZGF0ZShuYW1lKVxuICAgICAgICB0aGlzLl9maXJzdE5hbWUgPSBuYW1lIGluc3RhbmNlb2YgRmlyc3ROYW1lID8gbmFtZSA6IG5ldyBGaXJzdE5hbWUobmFtZSlcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICBzZXRMYXN0TmFtZShuYW1lOiBzdHJpbmcgfCBMYXN0TmFtZSk6IEZ1bGxOYW1lIHtcbiAgICAgICAgaWYgKCF0aGlzLl9jb25maWcuYnlwYXNzKSBWYWxpZGF0b3JzLmxhc3ROYW1lLnZhbGlkYXRlKG5hbWUpXG4gICAgICAgIHRoaXMuX2xhc3ROYW1lID0gbmFtZSBpbnN0YW5jZW9mIExhc3ROYW1lID8gbmFtZSA6IG5ldyBMYXN0TmFtZShuYW1lKVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIHNldE1pZGRsZU5hbWUobmFtZXM6IHN0cmluZ1tdIHwgTmFtZVtdKTogRnVsbE5hbWUge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobmFtZXMpKSByZXR1cm5cbiAgICAgICAgaWYgKCF0aGlzLl9jb25maWcuYnlwYXNzKSBWYWxpZGF0b3JzLm1pZGRsZU5hbWUudmFsaWRhdGUobmFtZXMpXG4gICAgICAgIHRoaXMuX21pZGRsZU5hbWUgPSAobmFtZXMgYXMgQXJyYXk8c3RyaW5nIHwgTmFtZT4pLm1hcCgobmFtZSkgPT5cbiAgICAgICAgICAgIG5hbWUgaW5zdGFuY2VvZiBOYW1lID8gbmFtZSA6IE5hbWUubWlkZGxlKG5hbWUpLFxuICAgICAgICApXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgc2V0U3VmZml4KG5hbWU6IE51bGxhYmxlPHN0cmluZyB8IE5hbWU+KTogRnVsbE5hbWUge1xuICAgICAgICBpZiAoIW5hbWUpIHJldHVybiB0aGlzXG4gICAgICAgIGlmICghdGhpcy5fY29uZmlnLmJ5cGFzcykgVmFsaWRhdG9ycy5zdWZmaXgudmFsaWRhdGUobmFtZSlcbiAgICAgICAgdGhpcy5fc3VmZml4ID0gTmFtZS5zdWZmaXgobmFtZSBpbnN0YW5jZW9mIE5hbWUgPyBuYW1lLnZhbHVlIDogbmFtZSlcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgYSBuYW1vbiBoYXMgYmVlbiBzZXQuXG4gICAgICovXG4gICAgaGFzKG5hbW9uOiBOYW1vbik6IGJvb2xlYW4ge1xuICAgICAgICBpZiAobmFtb24uZXF1YWwoTmFtb24uUFJFRklYKSkgcmV0dXJuICEhdGhpcy5fcHJlZml4XG4gICAgICAgIGlmIChuYW1vbi5lcXVhbChOYW1vbi5TVUZGSVgpKSByZXR1cm4gISF0aGlzLl9zdWZmaXhcbiAgICAgICAgcmV0dXJuIG5hbW9uLmVxdWFsKE5hbW9uLk1JRERMRV9OQU1FKSA/IHRoaXMuX21pZGRsZU5hbWUubGVuZ3RoID4gMCA6IHRydWVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgYSBqc29uIG5hbWUgaW50byBhIGZ1bGwgbmFtZS5cbiAgICAgKiBAcGFyYW0ganNvbiBwYXJzYWJsZSBuYW1lIGVsZW1lbnRcbiAgICAgKiBAcGFyYW0gY29uZmlnIG9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIGFkZGl0aW9uYWwgZmVhdHVyZXMuXG4gICAgICovXG4gICAgc3RhdGljIHBhcnNlKGpzb246IEpzb25OYW1lLCBjb25maWc/OiBDb25maWcpOiBGdWxsTmFtZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmdWxsTmFtZSA9IG5ldyBGdWxsTmFtZShjb25maWcpXG4gICAgICAgICAgICBmdWxsTmFtZS5zZXRQcmVmaXgoanNvbi5wcmVmaXgpXG4gICAgICAgICAgICBmdWxsTmFtZS5zZXRGaXJzdE5hbWUoanNvbi5maXJzdE5hbWUpXG4gICAgICAgICAgICBmdWxsTmFtZS5zZXRNaWRkbGVOYW1lKGpzb24ubWlkZGxlTmFtZSlcbiAgICAgICAgICAgIGZ1bGxOYW1lLnNldExhc3ROYW1lKGpzb24ubGFzdE5hbWUpXG4gICAgICAgICAgICBmdWxsTmFtZS5zZXRTdWZmaXgoanNvbi5zdWZmaXgpXG4gICAgICAgICAgICByZXR1cm4gZnVsbE5hbWVcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5hbWVFcnJvcikge1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9yXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbmtub3duRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IE9iamVjdC52YWx1ZXMoanNvbikuam9pbignICcpLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnY291bGQgbm90IHBhcnNlIEpTT04gY29udGVudCcsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIFdlbGNvbWUgdG8gbmFtZWZ1bGx5IVxuICpcbiAqIGBuYW1lZnVsbHlgIGlzIGEgSmF2YVNjcmlwdCB1dGlsaXR5IGZvciBoYW5kaW5nIHBlcnNvbiBuYW1lcy5cbiAqXG4gKiBTb3VyY2VzXG4gKiAtIHJlcG86IGh0dHBzOi8vZ2l0aHViLmNvbS9yYWxmbG9yZW50L25hbWVmdWxseVxuICogLSBkb2NzOiBodHRwczovL25hbWVmdWxseS5uZXRsaWZ5LmFwcFxuICogLSBucG06IGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvbmFtZWZ1bGx5XG4gKlxuICogQGxpY2Vuc2UgTUlUXG4gKi9cbmV4cG9ydCAqIGZyb20gJy4vY29uZmlnJ1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcidcbmV4cG9ydCAqIGZyb20gJy4vZnVsbC1uYW1lJ1xuZXhwb3J0ICogZnJvbSAnLi9uYW1lJ1xuZXhwb3J0ICogZnJvbSAnLi9uYW1lZnVsbHknXG5leHBvcnQgeyBQYXJzZXIgfSBmcm9tICcuL3BhcnNlcidcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMnXG5leHBvcnQgeyBOYW1lSW5kZXggfSBmcm9tICcuL3V0aWxzJ1xuIiwiaW1wb3J0IHsgSW5wdXRFcnJvciB9IGZyb20gJy4vZXJyb3InXG5pbXBvcnQgeyBDYXBzUmFuZ2UsIE5hbW9uLCBTdXJuYW1lIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCB7IGNhcGl0YWxpemUsIGRlY2FwaXRhbGl6ZSB9IGZyb20gJy4vdXRpbHMnXG5cbi8qKlxuICogUmVwcmVzZW50YXRpb24gb2YgYSBzdHJpbmcgdHlwZSBuYW1lIHdpdGggc29tZSBleHRyYSBjYXBhYmlsaXRpZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBOYW1lIHtcbiAgICBwcml2YXRlIG5hbW9uOiBzdHJpbmdcbiAgICBwcm90ZWN0ZWQgaW5pdGlhbDogc3RyaW5nXG4gICAgcHJvdGVjdGVkIGNhcHNSYW5nZTogQ2Fwc1JhbmdlXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGF1Z21lbnRlZCBuYW1lcyBieSBhZGRpbmcgZXh0cmEgZnVuY3Rpb25hbGl0eSB0byBhIHN0cmluZyBuYW1lLlxuICAgICAqIEBwYXJhbSB0eXBlIG11c3QgYmUgaW5kaWNhdGVkIHRvIGNhdGVnb3JpemUgdGhlIG5hbWUgc28gaXQgY2FuIGJlXG4gICAgICogdHJlYXRlZCBhY2NvcmRpbmdseS5cbiAgICAgKiBAcGFyYW0gY2Fwc1JhbmdlIGRldGVybWluZXMgaG93IHRoZSBuYW1lIHNob3VsZCBiZSBjYXBpdGFsaXplZCBpbml0aWFsbHkuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodmFsdWU6IHN0cmluZywgcmVhZG9ubHkgdHlwZTogTmFtb24sIGNhcHNSYW5nZT86IENhcHNSYW5nZSkge1xuICAgICAgICB0aGlzLmNhcHNSYW5nZSA9IGNhcHNSYW5nZSA/PyBDYXBzUmFuZ2UuSU5JVElBTFxuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWVcbiAgICAgICAgaWYgKGNhcHNSYW5nZSkgdGhpcy5jYXBzKGNhcHNSYW5nZSlcbiAgICB9XG5cbiAgICBzZXQgdmFsdWUobmV3VmFsdWU6IHN0cmluZykge1xuICAgICAgICBpZiAobmV3VmFsdWUudHJpbSgpLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHsgc291cmNlOiBuZXdWYWx1ZSwgbWVzc2FnZTogJ211c3QgYmUgMisgY2hhcmFjdGVycycgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubmFtb24gPSBuZXdWYWx1ZVxuICAgICAgICB0aGlzLmluaXRpYWwgPSBuZXdWYWx1ZVswXVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBwaWVjZSBvZiBzdHJpbmcgdHJlYXRlZCBhcyBhIG5hbWUuXG4gICAgICovXG4gICAgZ2V0IHZhbHVlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbW9uXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGxlbmd0aCBvZiB0aGUgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbW9uLmxlbmd0aFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIG5hbWUgaXMgYSBwcmVmaXguXG4gICAgICovXG4gICAgZ2V0IGlzUHJlZml4KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSBOYW1vbi5QUkVGSVhcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBuYW1lIGlzIGEgZmlyc3QgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgaXNGaXJzdE5hbWUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09IE5hbW9uLkZJUlNUX05BTUVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBuYW1lIGlzIGEgbWlkZGxlIG5hbWUuXG4gICAgICovXG4gICAgZ2V0IGlzTWlkZGxlTmFtZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gTmFtb24uTUlERExFX05BTUVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBuYW1lIGlzIGEgbGFzdCBuYW1lLlxuICAgICAqL1xuICAgIGdldCBpc0xhc3ROYW1lKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSBOYW1vbi5MQVNUX05BTUVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBuYW1lIGlzIGEgc3VmZml4LlxuICAgICAqL1xuICAgIGdldCBpc1N1ZmZpeCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gTmFtb24uU1VGRklYXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHByZWZpeC5cbiAgICAgKi9cbiAgICBzdGF0aWMgcHJlZml4KHZhbHVlOiBzdHJpbmcpOiBOYW1lIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHZhbHVlLCBOYW1vbi5QUkVGSVgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZpcnN0IG5hbWUuXG4gICAgICovXG4gICAgc3RhdGljIGZpcnN0KHZhbHVlOiBzdHJpbmcpOiBOYW1lIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHZhbHVlLCBOYW1vbi5GSVJTVF9OQU1FKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBtaWRkbGUgbmFtZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgbWlkZGxlKHZhbHVlOiBzdHJpbmcpOiBOYW1lIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHZhbHVlLCBOYW1vbi5NSURETEVfTkFNRSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbGFzdCBuYW1lLlxuICAgICAqL1xuICAgIHN0YXRpYyBsYXN0KHZhbHVlOiBzdHJpbmcpOiBOYW1lIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHZhbHVlLCBOYW1vbi5MQVNUX05BTUUpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHN1ZmZpeC5cbiAgICAgKi9cbiAgICBzdGF0aWMgc3VmZml4KHZhbHVlOiBzdHJpbmcpOiBOYW1lIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHZhbHVlLCBOYW1vbi5TVUZGSVgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgaW5pdGlhbHMgKGZpcnN0IGNoYXJhY3Rlcikgb2YgdGhpcyBuYW1lLlxuICAgICAqL1xuICAgIGluaXRpYWxzKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIFt0aGlzLmluaXRpYWxdXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbW9uXG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgb3RoZXIgaXMgZXF1YWwgdG8gdGhpcyBuYW1lLlxuICAgICAqL1xuICAgIGVxdWFsKG90aGVyOiBOYW1lIHwgdW5rbm93bik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiBOYW1lICYmIG90aGVyLnZhbHVlID09PSB0aGlzLnZhbHVlICYmIG90aGVyLnR5cGUgPT09IHRoaXMudHlwZVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhcGl0YWxpemVzIHRoZSBuYW1lLlxuICAgICAqL1xuICAgIGNhcHMocmFuZ2U/OiBDYXBzUmFuZ2UpOiBOYW1lIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IGNhcGl0YWxpemUodGhpcy5uYW1vbiwgcmFuZ2UgPz8gdGhpcy5jYXBzUmFuZ2UpXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGUtY2FwaXRhbGl6ZXMgdGhlIG5hbWUuXG4gICAgICovXG4gICAgZGVjYXBzKHJhbmdlPzogQ2Fwc1JhbmdlKTogTmFtZSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBkZWNhcGl0YWxpemUodGhpcy5uYW1vbiwgcmFuZ2UgPz8gdGhpcy5jYXBzUmFuZ2UpXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgZmlyc3QgbmFtZSB3aXRoIHNvbWUgZXh0cmEgZnVuY3Rpb25hbGl0eS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZpcnN0TmFtZSBleHRlbmRzIE5hbWUge1xuICAgIHByaXZhdGUgX21vcmU6IHN0cmluZ1tdXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGV4dGVuZGVkIHZlcnNpb24gb2YgYE5hbWVgIGFuZCBmbGFncyBpdCBhcyBhIGZpcnN0IG5hbWUgYHR5cGVgLlxuICAgICAqXG4gICAgICogU29tZSBtYXkgY29uc2lkZXIgYG1vcmVgIGFkZGl0aW9uYWwgbmFtZSBwYXJ0cyBvZiBhIGdpdmVuIG5hbWUgYXMgdGhlaXJcbiAgICAgKiBmaXJzdCBuYW1lcywgYnV0IG5vdCBhcyB0aGVpciBtaWRkbGUgbmFtZXMuIFRob3VnaCwgaXQgbWF5IG1lYW4gdGhlIHNhbWUsXG4gICAgICogYG1vcmVgIHByb3ZpZGVzIHRoZSBmcmVlZG9tIHRvIGRvIGl0IGFzIGl0IHBsZWFzZXMuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodmFsdWU6IHN0cmluZywgLi4ubW9yZTogc3RyaW5nW10pIHtcbiAgICAgICAgc3VwZXIodmFsdWUsIE5hbW9uLkZJUlNUX05BTUUpXG5cbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIG1vcmUpIHtcbiAgICAgICAgICAgIGlmIChuYW1lLnRyaW0oKS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IElucHV0RXJyb3IoeyBzb3VyY2U6IG5hbWUsIG1lc3NhZ2U6ICdtdXN0IGJlIDIrIGNoYXJhY3RlcnMnIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbW9yZSA9IG1vcmVcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBmaXJzdCBuYW1lIGhhcyBgbW9yZWAgbmFtZSBwYXJ0cy5cbiAgICAgKi9cbiAgICBnZXQgaGFzTW9yZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vcmUubGVuZ3RoID4gMFxuICAgIH1cblxuICAgIGdldCBsZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHN1cGVyLmxlbmd0aCArICh0aGlzLmhhc01vcmUgPyB0aGlzLl9tb3JlLnJlZHVjZSgoYWNjLCBuKSA9PiBhY2MgKyBuKS5sZW5ndGggOiAwKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBjb21iaW5lZCB2ZXJzaW9uIG9mIHRoZSBgdmFsdWVgIGFuZCBgbW9yZWAgaWYgYW55LlxuICAgICAqL1xuICAgIGdldCBhc05hbWVzKCk6IE5hbWVbXSB7XG4gICAgICAgIGNvbnN0IG5hbWVzOiBOYW1lW10gPSBbTmFtZS5maXJzdCh0aGlzLnZhbHVlKV1cbiAgICAgICAgaWYgKHRoaXMuaGFzTW9yZSkge1xuICAgICAgICAgICAgbmFtZXMucHVzaCguLi50aGlzLl9tb3JlLm1hcCgobikgPT4gTmFtZS5maXJzdChuKSkpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hbWVzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGFkZGl0aW9uYWwgbmFtZSBwYXJ0cyBvZiB0aGUgZmlyc3QgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgbW9yZSgpOiBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb3JlXG4gICAgfVxuXG4gICAgdG9TdHJpbmcod2l0aE1vcmUgPSBmYWxzZSk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB3aXRoTW9yZSAmJiB0aGlzLmhhc01vcmUgPyBgJHt0aGlzLnZhbHVlfSAke3RoaXMuX21vcmUuam9pbignICcpfWAudHJpbSgpIDogdGhpcy52YWx1ZVxuICAgIH1cblxuICAgIGluaXRpYWxzKHdpdGhNb3JlID0gZmFsc2UpOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IGluaXRzOiBzdHJpbmdbXSA9IFt0aGlzLmluaXRpYWxdXG4gICAgICAgIGlmICh3aXRoTW9yZSAmJiB0aGlzLmhhc01vcmUpIHtcbiAgICAgICAgICAgIGluaXRzLnB1c2goLi4udGhpcy5fbW9yZS5tYXAoKG4pID0+IG5bMF0pKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbml0c1xuICAgIH1cblxuICAgIGNhcHMocmFuZ2U/OiBDYXBzUmFuZ2UpOiBGaXJzdE5hbWUge1xuICAgICAgICByYW5nZSA9IHJhbmdlIHx8IHRoaXMuY2Fwc1JhbmdlXG4gICAgICAgIHRoaXMudmFsdWUgPSBjYXBpdGFsaXplKHRoaXMudmFsdWUsIHJhbmdlKVxuICAgICAgICBpZiAodGhpcy5oYXNNb3JlKSB0aGlzLl9tb3JlID0gdGhpcy5fbW9yZS5tYXAoKG4pID0+IGNhcGl0YWxpemUobiwgcmFuZ2UpKVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIGRlY2FwcyhyYW5nZT86IENhcHNSYW5nZSk6IEZpcnN0TmFtZSB7XG4gICAgICAgIHJhbmdlID0gcmFuZ2UgfHwgdGhpcy5jYXBzUmFuZ2VcbiAgICAgICAgdGhpcy52YWx1ZSA9IGRlY2FwaXRhbGl6ZSh0aGlzLnZhbHVlLCByYW5nZSlcbiAgICAgICAgaWYgKHRoaXMuaGFzTW9yZSkgdGhpcy5fbW9yZSA9IHRoaXMuX21vcmUubWFwKChuKSA9PiBkZWNhcGl0YWxpemUobiwgcmFuZ2UpKVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2VzIGEgY29weSBvZiB0aGUgY3VycmVudCBuYW1lLlxuICAgICAqL1xuICAgIGNvcHlXaXRoKHZhbHVlcz86IHsgZmlyc3Q/OiBzdHJpbmc7IG1vcmU/OiBzdHJpbmdbXSB9KTogRmlyc3ROYW1lIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGaXJzdE5hbWUodmFsdWVzLmZpcnN0ID8/IHRoaXMudmFsdWUsIC4uLih2YWx1ZXMubW9yZSA/PyB0aGlzLl9tb3JlKSlcbiAgICB9XG59XG5cbi8qKlxuICogUmVwcmVzZW50YXRpb24gb2YgYSBsYXN0IG5hbWUgd2l0aCBzb21lIGV4dHJhIGZ1bmN0aW9uYWxpdHkuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYXN0TmFtZSBleHRlbmRzIE5hbWUge1xuICAgIHByaXZhdGUgX21vdGhlcj86IHN0cmluZ1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBleHRlbmRlZCB2ZXJzaW9uIG9mIGBOYW1lYCBhbmQgZmxhZ3MgaXQgYXMgYSBsYXN0IG5hbWUgYHR5cGVgLlxuICAgICAqXG4gICAgICogU29tZSBwZW9wbGUgbWF5IGtlZXAgdGhlaXIgYG1vdGhlcmAncyBzdXJuYW1lIGFuZCB3YW50IHRvIGtlZXAgYSBjbGVhciBjdXRcbiAgICAgKiBmcm9tIHRoZWlyIGBmYXRoZXJgJ3Mgc3VybmFtZS4gSG93ZXZlciwgdGhlcmUgYXJlIG5vIGNsZWFyIHJ1bGVzIGFib3V0IGl0LlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGZhdGhlcjogc3RyaW5nLCBtb3RoZXI/OiBzdHJpbmcsIHJlYWRvbmx5IGZvcm1hdCA9IFN1cm5hbWUuRkFUSEVSKSB7XG4gICAgICAgIHN1cGVyKGZhdGhlciwgTmFtb24uTEFTVF9OQU1FKVxuXG4gICAgICAgIGlmIChtb3RoZXIgJiYgbW90aGVyLnRyaW0oKS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW5wdXRFcnJvcih7IHNvdXJjZTogbW90aGVyLCBtZXNzYWdlOiAnbXVzdCBiZSAyKyBjaGFyYWN0ZXJzJyB9KVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX21vdGhlciA9IG1vdGhlclxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzdXJuYW1lIGluaGVyaXRlZCBmcm9tIGEgZmF0aGVyIHNpZGUuXG4gICAgICovXG4gICAgZ2V0IGZhdGhlcigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzdXJuYW1lIGluaGVyaXRlZCBmcm9tIGEgbW90aGVyIHNpZGUuXG4gICAgICovXG4gICAgZ2V0IG1vdGhlcigpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW90aGVyXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG1vdGhlcidzIHN1cm5hbWUgaXMgZGVmaW5lZC5cbiAgICAgKi9cbiAgICBnZXQgaGFzTW90aGVyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9tb3RoZXJcbiAgICB9XG5cbiAgICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBzdXBlci5sZW5ndGggKyAodGhpcy5fbW90aGVyPy5sZW5ndGggPz8gMClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgY29tYmluZWQgdmVyc2lvbiBvZiB0aGUgYGZhdGhlcmAgYW5kIGBtb3RoZXJgIGlmIGFueS5cbiAgICAgKi9cbiAgICBnZXQgYXNOYW1lcygpOiBOYW1lW10ge1xuICAgICAgICBjb25zdCBuYW1lczogTmFtZVtdID0gW05hbWUubGFzdCh0aGlzLnZhbHVlKV1cbiAgICAgICAgaWYgKHRoaXMuaGFzTW90aGVyKSB7XG4gICAgICAgICAgICBuYW1lcy5wdXNoKE5hbWUubGFzdCh0aGlzLl9tb3RoZXIpKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYW1lc1xuICAgIH1cblxuICAgIHRvU3RyaW5nKGZvcm1hdD86IFN1cm5hbWUpOiBzdHJpbmcge1xuICAgICAgICBmb3JtYXQgPSBmb3JtYXQgPz8gdGhpcy5mb3JtYXRcbiAgICAgICAgc3dpdGNoIChmb3JtYXQpIHtcbiAgICAgICAgICAgIGNhc2UgU3VybmFtZS5GQVRIRVI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVcbiAgICAgICAgICAgIGNhc2UgU3VybmFtZS5NT1RIRVI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW90aGVyID8/ICcnXG4gICAgICAgICAgICBjYXNlIFN1cm5hbWUuSFlQSEVOQVRFRDpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYXNNb3RoZXIgPyBgJHt0aGlzLnZhbHVlfS0ke3RoaXMuX21vdGhlcn1gIDogdGhpcy52YWx1ZVxuICAgICAgICAgICAgY2FzZSBTdXJuYW1lLkFMTDpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYXNNb3RoZXIgPyBgJHt0aGlzLnZhbHVlfSAke3RoaXMuX21vdGhlcn1gIDogdGhpcy52YWx1ZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgaW5pdGlhbHMoZm9ybWF0PzogU3VybmFtZSk6IHN0cmluZ1tdIHtcbiAgICAgICAgZm9ybWF0ID0gZm9ybWF0IHx8IHRoaXMuZm9ybWF0XG4gICAgICAgIGNvbnN0IGluaXRzOiBzdHJpbmdbXSA9IFtdXG4gICAgICAgIHN3aXRjaCAoZm9ybWF0KSB7XG4gICAgICAgICAgICBjYXNlIFN1cm5hbWUuTU9USEVSOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhc01vdGhlcikgaW5pdHMucHVzaCh0aGlzLl9tb3RoZXJbMF0pXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgU3VybmFtZS5IWVBIRU5BVEVEOlxuICAgICAgICAgICAgY2FzZSBTdXJuYW1lLkFMTDpcbiAgICAgICAgICAgICAgICBpbml0cy5wdXNoKHRoaXMuaW5pdGlhbClcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNNb3RoZXIpIGluaXRzLnB1c2godGhpcy5fbW90aGVyWzBdKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIFN1cm5hbWUuRkFUSEVSOlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbml0cy5wdXNoKHRoaXMuaW5pdGlhbClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5pdHNcbiAgICB9XG5cbiAgICBjYXBzKHJhbmdlPzogQ2Fwc1JhbmdlKTogTGFzdE5hbWUge1xuICAgICAgICByYW5nZSA9IHJhbmdlIHx8IHRoaXMuY2Fwc1JhbmdlXG4gICAgICAgIHRoaXMudmFsdWUgPSBjYXBpdGFsaXplKHRoaXMudmFsdWUsIHJhbmdlKVxuICAgICAgICBpZiAodGhpcy5oYXNNb3RoZXIpIHRoaXMuX21vdGhlciA9IGNhcGl0YWxpemUodGhpcy5fbW90aGVyLCByYW5nZSlcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICBkZWNhcHMocmFuZ2U/OiBDYXBzUmFuZ2UpOiBMYXN0TmFtZSB7XG4gICAgICAgIHJhbmdlID0gcmFuZ2UgfHwgdGhpcy5jYXBzUmFuZ2VcbiAgICAgICAgdGhpcy52YWx1ZSA9IGRlY2FwaXRhbGl6ZSh0aGlzLnZhbHVlLCByYW5nZSlcbiAgICAgICAgaWYgKHRoaXMuaGFzTW90aGVyKSB0aGlzLl9tb3RoZXIgPSBkZWNhcGl0YWxpemUodGhpcy5fbW90aGVyLCByYW5nZSlcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgbmFtZS5cbiAgICAgKi9cbiAgICBjb3B5V2l0aCh2YWx1ZXM/OiB7IGZhdGhlcj86IHN0cmluZzsgbW90aGVyPzogc3RyaW5nOyBmb3JtYXQ/OiBTdXJuYW1lIH0pOiBMYXN0TmFtZSB7XG4gICAgICAgIHJldHVybiBuZXcgTGFzdE5hbWUodmFsdWVzLmZhdGhlciA/PyB0aGlzLnZhbHVlLCB2YWx1ZXMubW90aGVyID8/IHRoaXMubW90aGVyLCB2YWx1ZXMuZm9ybWF0ID8/IHRoaXMuZm9ybWF0KVxuICAgIH1cbn1cblxuLyoqXG4gKiBKU09OIHNpZ25hdHVyZSBmb3IgYEZ1bGxOYW1lYCBkYXRhLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEpzb25OYW1lIHtcbiAgICBwcmVmaXg/OiBzdHJpbmdcbiAgICBmaXJzdE5hbWU6IHN0cmluZ1xuICAgIG1pZGRsZU5hbWU/OiBzdHJpbmdbXVxuICAgIGxhc3ROYW1lOiBzdHJpbmdcbiAgICBzdWZmaXg/OiBzdHJpbmdcbn1cbiIsImltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4vY29uZmlnJ1xuaW1wb3J0IHsgQUxMT1dFRF9UT0tFTlMgfSBmcm9tICcuL2NvbnN0YW50cydcbmltcG9ydCB7IElucHV0RXJyb3IsIE5vdEFsbG93ZWRFcnJvciB9IGZyb20gJy4vZXJyb3InXG5pbXBvcnQgeyBGdWxsTmFtZSB9IGZyb20gJy4vZnVsbC1uYW1lJ1xuaW1wb3J0IHsgTmFtZSwgSnNvbk5hbWUgfSBmcm9tICcuL25hbWUnXG5pbXBvcnQgeyBBcnJheU5hbWVQYXJzZXIsIEFycmF5U3RyaW5nUGFyc2VyLCBOYW1hUGFyc2VyLCBQYXJzZXIsIFN0cmluZ1BhcnNlciB9IGZyb20gJy4vcGFyc2VyJ1xuaW1wb3J0IHsgRmxhdCwgTmFtZU9yZGVyLCBOYW1lVHlwZSwgTmFtb24sIE51bGxhYmxlLCBTdXJuYW1lIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCB7IGNhcGl0YWxpemUsIGRlY2FwaXRhbGl6ZSwgaXNOYW1lQXJyYXksIGlzU3RyaW5nQXJyYXksIHRvZ2dsZUNhc2UgfSBmcm9tICcuL3V0aWxzJ1xuXG4vKipcbiAqIEEgaGVscGVyIGZvciBvcmdhbml6aW5nIHBlcnNvbiBuYW1lcyBpbiBhIHBhcnRpY3VsYXIgb3JkZXIsIHdheSwgb3Igc2hhcGUuXG4gKlxuICogVGhvdWdoIGBuYW1lZnVsbHlgIGlzIGVhc3kgdG8gdXNlLCBpdCBkb2VzIG5vdCBtYWdpY2FsbHkgZ3Vlc3Mgd2hpY2ggcGFydCBvZlxuICogdGhlIG5hbWUgaXMgd2hhdCAocHJlZml4LCBzdWZmaXgsIGZpcnN0LCBsYXN0LCBvciBtaWRkbGUgbmFtZXMpLiBJdCByZWxpZXNcbiAqIGFjdHVhbGx5IG9uIGhvdyB0aGUgbmFtZSBwYXJ0cyBhcmUgaW5kaWNhdGVkIChpLmUuLCB0aGVpciByb2xlcykgc28gdGhhdFxuICogaXQgY2FuIHBlcmZvcm0gaW50ZXJuYWxseSBjZXJ0YWluIG9wZXJhdGlvbnMgYW5kIHNhdmVzIHVzIHNvbWUgZXh0cmFcbiAqIGNhbGN1bGF0aW9ucy9wcm9jZXNzaW5nLiBJbiBhZGRpdGlvbiwgYE5hbWVmdWxseWAgY2FuIGJlIGNyZWF0ZWQgdXNpbmdcbiAqIGRpc3RpbmN0IHJhdyBkYXRhIHNoYXBlcy4gVGhpcyBpcyBpbnRlbmRlZCB0byBnaXZlIHNvbWUgZmxleGliaWxpdHkgdG8gdGhlXG4gKiBkZXZlbG9wZXIgc28gdGhhdCBoZSBvciBzaGUgaXMgbm90IGJvdW5kIHRvIGEgcGFydGljdWxhciBkYXRhIGZvcm1hdC5cbiAqIEJ5IGZvbGxvd2luZyBjbG9zZWx5IHRoZSBBUEkgcmVmZXJlbmNlIHRvIGtub3cgaG93IHRvIGhhcm5lc3MgaXRzIHVzYWJpbGl0eSxcbiAqIHRoaXMgdXRpbGl0eSBhaW1zIHRvIHNhdmUgdGltZSBpbiBmb3JtYXR0aW5nIG5hbWVzLlxuICpcbiAqIGBuYW1lZnVsbHlgIGFsc28gd29ya3MgbGlrZSBhIHRyYXBkb29yLiBPbmNlIGEgcmF3IGRhdGEgaXMgcHJvdmlkZWQgYW5kXG4gKiB2YWxpZGF0ZWQsIGEgZGV2ZWxvcGVyIGNhbiBvbmx5ICphY2Nlc3MqIGluIGEgdmFzdCBhbW91bnQgb2YsIHlldCBlZmZlY3RpdmVcbiAqIHdheXMgdGhlIG5hbWUgaW5mby4gKk5vIGVkaXRpbmcqIGlzIHBvc3NpYmxlLiBJZiB0aGUgbmFtZSBpcyBtaXN0YWtlbiwgYSBuZXdcbiAqIGluc3RhbmNlIG9mIGBOYW1lZnVsbHlgIG11c3QgYmUgY3JlYXRlZC4gSW4gb3RoZXIgd29yZHMsIGl0J3MgaW1tdXRhYmxlLlxuICogUmVtZW1iZXIsIHRoaXMgdXRpbGl0eSdzIHByaW1hcnkgb2JqZWN0aXZlIGlzIHRvIGhlbHAgbWFuaXB1bGF0ZSBhIHBlcnNvbiBuYW1lLlxuICpcbiAqIE5vdGUgdGhhdCB0aGUgbmFtZSBzdGFuZGFyZHMgdXNlZCBmb3IgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGlzIGxpYnJhcnlcbiAqIGFyZSBhcyBmb2xsb3dzOlxuICogICAgICBgW3ByZWZpeF0gZmlyc3ROYW1lIFttaWRkbGVOYW1lXSBsYXN0TmFtZSBbc3VmZml4XWBcbiAqIFRoZSBvcGVuaW5nIGBbYCBhbmQgY2xvc2luZyBgXWAgc3ltYm9scyBtZWFuIHRoYXQgdGhlc2UgcGFydHMgYXJlIG9wdGlvbmFsLlxuICogSW4gb3RoZXIgd29yZHMsIHRoZSBtb3N0IGJhc2ljIGFuZCB0eXBpY2FsIGNhc2UgaXMgYSBuYW1lIHRoYXQgbG9va3MgbGlrZVxuICogdGhpczogYEpvaG4gU21pdGhgLCB3aGVyZSBgSm9obmAgaXMgdGhlIGZpcnN0IG5hbWUgcGllY2UgYW5kIGBTbWl0aGAsIHRoZSBsYXN0XG4gKiBuYW1lIHBpZWNlLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kZXBhcnRtZW50cy53ZWJlci5lZHUvcXN1cHBvcnQmdHJhaW5pbmcvRGF0YV9TdGFuZGFyZHMvTmFtZS5odG1cbiAqIGZvciBtb3JlIGluZm8gb24gbmFtZSBzdGFuZGFyZHMuXG4gKlxuICogKipJTVBPUlRBTlQqKjogS2VlcCBpbiBtaW5kIHRoYXQgdGhlIG9yZGVyIG9mIGFwcGVhcmFuY2UgKG9yIG5hbWUgb3JkZXIpIG1hdHRlcnNcbiAqIGFuZCBtYXkgYmUgYWx0ZXJlZCB0aHJvdWdoIGNvbmZpZ3VyZWQgcGFyYW1ldGVycywgd2hpY2ggd2lsbCBiZSBzZWVuIGxhdGVyLlxuICogQnkgZGVmYXVsdCwgdGhlIG9yZGVyIG9mIGFwcGVhcmFuY2UgaXMgYXMgc2hvd24gYWJvdmUgYW5kIHdpbGwgYmUgdXNlZCBhcyBhXG4gKiBiYXNpcyBmb3IgZnV0dXJlIGV4YW1wbGVzIGFuZCB1c2UgY2FzZXMuXG4gKlxuICogT25jZSBpbXBvcnRlZCwgYWxsIHRoYXQgaXMgcmVxdWlyZWQgdG8gZG8gaXMgdG8gY3JlYXRlIGFuIGluc3RhbmNlIG9mXG4gKiBgTmFtZWZ1bGx5YCBhbmQgdGhlIHJlc3Qgd2lsbCBmb2xsb3cuXG4gKlxuICogU29tZSB0ZXJtaW5vbG9naWVzIHVzZWQgYWNyb3NzIHRoZSBsaWJyYXJ5IGFyZTpcbiAqIC0gbmFtb246IDEgcGllY2Ugb2YgbmFtZSAoZS5nLiwgZmlyc3QgbmFtZSlcbiAqIC0gbmFtYTogMisgcGllY2VzIG9mIG5hbWUgKGUuZy4sIGZpcnN0IG5hbWUgKyBsYXN0IG5hbWUpXG4gKlxuICogSGFwcHkgbmFtZSBoYW5kbGluZyDwn5iKIVxuICovXG5leHBvcnQgY2xhc3MgTmFtZWZ1bGx5IHtcbiAgICAvKipcbiAgICAgKiBBIGNvcHkgb2YgaGlnaC1xdWFsaXR5IG5hbWUgZGF0YS5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9mdWxsTmFtZTogRnVsbE5hbWVcblxuICAgIC8qKlxuICAgICAqIEEgY29weSBvZiB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIChjb21iaW5lZCB3aXRoIGEgY3VzdG9tIG9uZSBpZiBhbnkpLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2NvbmZpZzogQ29uZmlnXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmFtZSB3aXRoIGRpc3Rpbmd1aXNoYWJsZSBwYXJ0cyBmcm9tIGEgcmF3IHN0cmluZyBjb250ZW50LlxuICAgICAqIEBwYXJhbSBuYW1lcyBlbGVtZW50IHRvIHBhcnNlLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIGFkZGl0aW9uYWwgc2V0dGluZ3MuXG4gICAgICpcbiAgICAgKiBBbiBvcHRpb25hbCBjb25maWd1cmF0aW9uIG1heSBiZSBwcm92aWRlZCB3aXRoIHNwZWNpZmljcyBvbiBob3cgdG8gdHJlYXRcbiAgICAgKiBhIGZ1bGwgbmFtZSBkdXJpbmcgaXRzIGNvdXJzZS4gQnkgZGVmYXVsdCwgYWxsIG5hbWUgcGFydHMgYXJlIHZhbGlkYXRlZFxuICAgICAqIGFnYWluc3Qgc29tZSBiYXNpYyB2YWxpZGF0aW9uIHJ1bGVzIHRvIGF2b2lkIGNvbW1vbiBydW50aW1lIGV4Y2VwdGlvbnMuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobmFtZXM6IHN0cmluZyB8IHN0cmluZ1tdIHwgTmFtZVtdIHwgSnNvbk5hbWUgfCBQYXJzZXIsIG9wdGlvbnM/OiBQYXJ0aWFsPENvbmZpZz4pIHtcbiAgICAgICAgdGhpcy5idWlsZCh0aGlzLnRvUGFyc2VyKG5hbWVzKSwgb3B0aW9ucylcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgYE5hbWVmdWxseWAgaW5zdGFuY2UgZnJvbSBhIHRleHQuXG4gICAgICpcbiAgICAgKiBJdCB3b3JrcyBsaWtlIGBwYXJzZWAgZXhjZXB0IHRoYXQgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGBudWxsYCB3aGVyZSBgcGFyc2VgXG4gICAgICogd291bGQgdGhyb3cgYSBgTmFtZUVycm9yYC5cbiAgICAgKi9cbiAgICBzdGF0aWMgdHJ5UGFyc2UodGV4dDogc3RyaW5nKTogTmFtZWZ1bGx5IHwgdW5kZWZpbmVkIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgdGhpcyhQYXJzZXIuYnVpbGQodGV4dCkpXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgYE5hbWVmdWxseWAgaW5zdGFuY2UgZnJvbSBhIHRleHQuXG4gICAgICpcbiAgICAgKiBJdCB0aHJvd3MgYSBgTmFtZUVycm9yYCBpZiB0aGUgdGV4dCBjYW5ub3QgYmUgcGFyc2VkLiBVc2UgYHRyeVBhcnNlYFxuICAgICAqIGluc3RlYWQgaWYgYSBgbnVsbGAgcmV0dXJuIGlzIHByZWZlcnJlZCBvdmVyIGEgdGhyb3dhYmxlIGVycm9yLlxuICAgICAqXG4gICAgICogVGhpcyBvcGVyYXRpb24gaXMgY29tcHV0ZWQgYXN5bmNocm9ub3VzbHksIHdoaWNoIGdpdmVzIG1vcmUgZmxleGliaWxpdHkgYXRcbiAgICAgKiB0aGUgdGltZSBvZiBjYXRjaGluZyB0aGUgZXJyb3IgKGFuZCBzdGFjayB0cmFjZSBpZiBhbnkpLiBUaGUgYWNjZXB0YWJsZVxuICAgICAqIHRleHQgZm9ybWF0IGlzIGEgc3RyaW5nIGNvbXBvc2VkIG9mIHR3byBvciBtb3JlIG5hbWUgcGllY2VzLiBGb3IgaW5zdGFuY2UsXG4gICAgICogYEpvaG4gTGVubm9uYCwgb3IgYEpvaG4gV2luc3RvbiBPbm8gTGVubm9uYCBhcmUgcGFyc2FibGUgbmFtZXMgYW5kIGZvbGxvd1xuICAgICAqIHRoZSBiYXNpYyBuYW1lIHN0YW5kYXJkIHJ1bGVzIChpLmUuLCBmaXJzdC1taWRkbGUtbGFzdCkuXG4gICAgICpcbiAgICAgKiBLZWVwIGluIG1pbmQgdGhhdCBwcmVmaXggYW5kIHN1ZmZpeCBhcmUgbm90IGNvbnNpZGVyZWQgZHVyaW5nIHRoZSBwYXJzaW5nXG4gICAgICogcHJvY2Vzcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgcGFyc2UodGV4dDogc3RyaW5nKTogUHJvbWlzZTxOYW1lZnVsbHk+IHtcbiAgICAgICAgcmV0dXJuIFBhcnNlci5idWlsZEFzeW5jKHRleHQpLnRoZW4oKHBhcnNlcikgPT4gbmV3IE5hbWVmdWxseShwYXJzZXIpKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24uXG4gICAgICovXG4gICAgZ2V0IGNvbmZpZygpOiBDb25maWcge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29uZmlnXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHRoZSBgYmlydGhOYW1lYCwgaW5jbHVkaW5nIHNwYWNlcy5cbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmJpcnRoLmxlbmd0aFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBwcmVmaXggcGFydC5cbiAgICAgKi9cbiAgICBnZXQgcHJlZml4KCk6IE51bGxhYmxlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZnVsbE5hbWUucHJlZml4Py50b1N0cmluZygpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGZpcnQgbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgZmlyc3QoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmlyc3ROYW1lKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmlyc3QgbWlkZGxlIG5hbWUgaWYgYW55LlxuICAgICAqL1xuICAgIGdldCBtaWRkbGUoKTogTnVsbGFibGU8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhc01pZGRsZSA/IHRoaXMubWlkZGxlTmFtZSgpWzBdIDogdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIGFueSBtaWRkbGUgbmFtZSBoYXMgYmVlbiBzZXQuXG4gICAgICovXG4gICAgZ2V0IGhhc01pZGRsZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bGxOYW1lLmhhcyhOYW1vbi5NSURETEVfTkFNRSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbGFzdCBuYW1lLlxuICAgICAqL1xuICAgIGdldCBsYXN0KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmxhc3ROYW1lKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc3VmZml4IHBhcnQuXG4gICAgICovXG4gICAgZ2V0IHN1ZmZpeCgpOiBOdWxsYWJsZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bGxOYW1lLnN1ZmZpeD8udG9TdHJpbmcoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiaXJ0aCBuYW1lLlxuICAgICAqL1xuICAgIGdldCBiaXJ0aCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5iaXJ0aE5hbWUoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzaG9ydGVzdCB2ZXJzaW9uIG9mIGEgcGVyc29uIG5hbWUuXG4gICAgICovXG4gICAgZ2V0IHNob3J0KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnNob3J0ZW4oKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBsb25nZXN0IHZlcnNpb24gb2YgYSBwZXJzb24gbmFtZS5cbiAgICAgKi9cbiAgICBnZXQgbG9uZygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5iaXJ0aFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBlbnRpcmUgbmFtZSBzZXQuXG4gICAgICovXG4gICAgZ2V0IGZ1bGwoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnVsbE5hbWUoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBmaXJzdCBuYW1lIGNvbWJpbmVkIHdpdGggdGhlIGxhc3QgbmFtZSdzIGluaXRpYWwuXG4gICAgICovXG4gICAgZ2V0IHB1YmxpYygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXQoJ2YgJGwnKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGZ1bGwgbmFtZSBhcyBzZXQuXG4gICAgICovXG4gICAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnVsbFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIHJhdyBmb3JtIG9mIGEgbmFtZSBwaWVjZS5cbiAgICAgKi9cbiAgICBnZXQobmFtb246IE5hbW9uKTogTnVsbGFibGU8TmFtZSB8IE5hbWVbXT4ge1xuICAgICAgICBpZiAobmFtb24uZXF1YWwoTmFtb24uUFJFRklYKSkgcmV0dXJuIHRoaXMuX2Z1bGxOYW1lLnByZWZpeFxuICAgICAgICBpZiAobmFtb24uZXF1YWwoTmFtb24uRklSU1RfTkFNRSkpIHJldHVybiB0aGlzLl9mdWxsTmFtZS5maXJzdE5hbWVcbiAgICAgICAgaWYgKG5hbW9uLmVxdWFsKE5hbW9uLk1JRERMRV9OQU1FKSkgcmV0dXJuIHRoaXMuX2Z1bGxOYW1lLm1pZGRsZU5hbWVcbiAgICAgICAgaWYgKG5hbW9uLmVxdWFsKE5hbW9uLkxBU1RfTkFNRSkpIHJldHVybiB0aGlzLl9mdWxsTmFtZS5sYXN0TmFtZVxuICAgICAgICBpZiAobmFtb24uZXF1YWwoTmFtb24uU1VGRklYKSkgcmV0dXJuIHRoaXMuX2Z1bGxOYW1lLnN1ZmZpeFxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGlzIG5hbWUgaXMgZXF1YWwgdG8gYW5vdGhlciBvbmUgZnJvbSBhIHJhdy1zdHJpbmcgcGVyc3BlY3RpdmUuXG4gICAgICovXG4gICAgZXF1YWwob3RoZXI6IE5hbWVmdWxseSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy50b1N0cmluZygpID09PSBvdGhlci50b1N0cmluZygpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhIEpTT04gcmVwcmVzZW50YXRpb24gb2YgdGhlIGZ1bGwgbmFtZS5cbiAgICAgKi9cbiAgICB0b0pzb24oKTogSnNvbk5hbWUge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJlZml4OiB0aGlzLnByZWZpeCxcbiAgICAgICAgICAgIGZpcnN0TmFtZTogdGhpcy5maXJzdCxcbiAgICAgICAgICAgIG1pZGRsZU5hbWU6IHRoaXMubWlkZGxlTmFtZSgpLFxuICAgICAgICAgICAgbGFzdE5hbWU6IHRoaXMubGFzdCxcbiAgICAgICAgICAgIHN1ZmZpeDogdGhpcy5zdWZmaXgsXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25maXJtcyB0aGF0IGEgbmFtZSBwYXJ0IGhhcyBiZWVuIHNldC5cbiAgICAgKi9cbiAgICBoYXMobmFtb246IE5hbW9uKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mdWxsTmFtZS5oYXMobmFtb24pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZnVsbCBuYW1lIG9yZGVyZWQgYXMgY29uZmlndXJlZC5cbiAgICAgKlxuICAgICAqIFRoZSBuYW1lIG9yZGVyIGBvcmRlcmVkQnlgIGZvcmNlcyB0byBvcmRlciBieSBmaXJzdCBvciBsYXN0IG5hbWUgYnlcbiAgICAgKiBvdmVycmlkaW5nIHRoZSBwcmVzZXQgY29uZmlndXJhdGlvbi5cbiAgICAgKlxuICAgICAqIGBOYW1lZnVsbHkuZm9ybWF0YCBtYXkgYWxzbyBiZSB1c2VkIHRvIGFsdGVyIG1hbnVhbGx5IHRoZSBvcmRlciBvZiBhcHBlYXJhbmNlXG4gICAgICogb2YgZnVsbCBuYW1lLlxuICAgICAqXG4gICAgICogRm9yIGV4YW1wbGU6XG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IG5hbWUgPSBuZXcgTmFtZWZ1bGx5KCdKb24gU3RhcmsgU25vdycpO1xuICAgICAqIGNvbnNvbGUubG9nKG5hbWUuZnVsbE5hbWUoTmFtZU9yZGVyLkxBU1RfTkFNRSkpOyAvLyBcIlNub3cgSm9uIFN0YXJrXCJcbiAgICAgKiBjb25zb2xlLmxvZyhuYW1lLmZvcm1hdCgnbCBmIG0nKSk7IC8vIFwiU25vdyBKb24gU3RhcmtcIlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGZ1bGxOYW1lKG9yZGVyZWRCeT86IE5hbWVPcmRlcik6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHNlcCA9IHRoaXMuX2NvbmZpZy5lbmRpbmcgPyAnLCcgOiAnJ1xuICAgICAgICBjb25zdCBuYW1lczogc3RyaW5nW10gPSBbXVxuICAgICAgICBvcmRlcmVkQnkgPSBvcmRlcmVkQnkgfHwgdGhpcy5fY29uZmlnLm9yZGVyZWRCeVxuXG4gICAgICAgIGlmICh0aGlzLnByZWZpeCkgbmFtZXMucHVzaCh0aGlzLnByZWZpeClcbiAgICAgICAgaWYgKG9yZGVyZWRCeSA9PT0gTmFtZU9yZGVyLkZJUlNUX05BTUUpIHtcbiAgICAgICAgICAgIG5hbWVzLnB1c2godGhpcy5maXJzdCwgLi4udGhpcy5taWRkbGVOYW1lKCksIHRoaXMubGFzdCArIHNlcClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5hbWVzLnB1c2godGhpcy5sYXN0LCB0aGlzLmZpcnN0LCB0aGlzLm1pZGRsZU5hbWUoKS5qb2luKCcgJykgKyBzZXApXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3VmZml4KSBuYW1lcy5wdXNoKHRoaXMuc3VmZml4KVxuXG4gICAgICAgIHJldHVybiBuYW1lcy5qb2luKCcgJykudHJpbSgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYmlydGggbmFtZSBvcmRlcmVkIGFzIGNvbmZpZ3VyZWQsIG5vIGBwcmVmaXhgIG9yIGBzdWZmaXhgLlxuICAgICAqXG4gICAgICogQHBhcmFtIG9yZGVyZWRCeSBmb3JjZXMgdG8gb3JkZXIgYnkgZmlyc3Qgb3IgbGFzdCBuYW1lIGJ5IG92ZXJyaWRpbmcgdGhlXG4gICAgICogcHJlc2V0IGNvbmZpZ3VyYXRpb24uXG4gICAgICovXG4gICAgYmlydGhOYW1lKG9yZGVyZWRCeT86IE5hbWVPcmRlcik6IHN0cmluZyB7XG4gICAgICAgIG9yZGVyZWRCeSA9IG9yZGVyZWRCeSB8fCB0aGlzLl9jb25maWcub3JkZXJlZEJ5XG4gICAgICAgIHJldHVybiBvcmRlcmVkQnkgPT09IE5hbWVPcmRlci5GSVJTVF9OQU1FXG4gICAgICAgICAgICA/IFt0aGlzLmZpcnN0LCAuLi50aGlzLm1pZGRsZU5hbWUoKSwgdGhpcy5sYXN0XS5qb2luKCcgJylcbiAgICAgICAgICAgIDogW3RoaXMubGFzdCwgdGhpcy5maXJzdCwgLi4udGhpcy5taWRkbGVOYW1lKCldLmpvaW4oJyAnKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGZpcnN0IG5hbWUgcGFydCBvZiB0aGUgYEZ1bGxOYW1lYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB3aXRoTW9yZSBkZXRlcm1pbmVzIHdoZXRoZXIgdG8gaW5jbHVkZSBvdGhlciBwaWVjZXMgb2YgdGhlIGZpcnN0XG4gICAgICogbmFtZS5cbiAgICAgKi9cbiAgICBmaXJzdE5hbWUod2l0aE1vcmUgPSB0cnVlKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bGxOYW1lLmZpcnN0TmFtZS50b1N0cmluZyh3aXRoTW9yZSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBtaWRkbGUgbmFtZSBwYXJ0IG9mIHRoZSBgRnVsbE5hbWVgLlxuICAgICAqL1xuICAgIG1pZGRsZU5hbWUoKTogc3RyaW5nW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZnVsbE5hbWUubWlkZGxlTmFtZS5tYXAoKG4pID0+IG4udmFsdWUpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbGFzdCBuYW1lIHBhcnQgb2YgdGhlIGBGdWxsTmFtZWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZm9ybWF0IG92ZXJyaWRlcyB0aGUgaG93LXRvIGZvcm1hdHRpbmcgb2YgYSBzdXJuYW1lIG91dHB1dCxcbiAgICAgKiBjb25zaWRlcmluZyBpdHMgc3ViLXBhcnRzLlxuICAgICAqL1xuICAgIGxhc3ROYW1lKGZvcm1hdD86IFN1cm5hbWUpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5fZnVsbE5hbWUubGFzdE5hbWUudG9TdHJpbmcoZm9ybWF0KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGluaXRpYWxzIG9mIHRoZSBgRnVsbE5hbWVgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtvcHRpb25zLm9yZGVyZWRCeX0gZm9yY2VzIHRvIG9yZGVyIGJ5IGZpcnN0IG9yIGxhc3QgbmFtZSBieVxuICAgICAqIG92ZXJyaWRpbmcgdGhlIHByZXNldCBjb25maWd1cmF0aW9uLlxuICAgICAqIEBwYXJhbVxuICAgICAqXG4gICAgICogRm9yIGV4YW1wbGUsIGdpdmVuIHRoZSBuYW1lczpcbiAgICAgKiAtIGBKb2huIFNtaXRoYCA9PiBgWydKJywgJ1MnXWBcbiAgICAgKiAtIGBKb2huIEJlbiBTbWl0aGAgPT4gYFsnSicsICdCJywgJ1MnXWAuXG4gICAgICovXG4gICAgaW5pdGlhbHMob3B0aW9ucz86IHsgb3JkZXJlZEJ5PzogTmFtZU9yZGVyOyBvbmx5PzogTmFtZVR5cGUgfSk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgaW5pdGlhbHM6IHN0cmluZ1tdID0gW11cbiAgICAgICAgY29uc3QgZmlyc3RJbml0cyA9IHRoaXMuX2Z1bGxOYW1lLmZpcnN0TmFtZS5pbml0aWFscygpXG4gICAgICAgIGNvbnN0IG1pZEluaXRzID0gdGhpcy5fZnVsbE5hbWUubWlkZGxlTmFtZS5tYXAoKG4pID0+IG4uaW5pdGlhbHMoKVswXSlcbiAgICAgICAgY29uc3QgbGFzdEluaXRzID0gdGhpcy5fZnVsbE5hbWUubGFzdE5hbWUuaW5pdGlhbHMoKVxuXG4gICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7XG4gICAgICAgICAgICBvcmRlcmVkQnk6IHRoaXMuX2NvbmZpZy5vcmRlcmVkQnksXG4gICAgICAgICAgICBvbmx5OiBOYW1lVHlwZS5CSVJUSF9OQU1FLFxuICAgICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IG9yZGVyZWRCeSwgb25seSB9ID0gbWVyZ2VkT3B0aW9uc1xuXG4gICAgICAgIGlmIChvbmx5ICE9IE5hbWVUeXBlLkJJUlRIX05BTUUpIHtcbiAgICAgICAgICAgIGlmIChvbmx5ID09IE5hbWVUeXBlLkZJUlNUX05BTUUpIHtcbiAgICAgICAgICAgICAgICBpbml0aWFscy5wdXNoKC4uLmZpcnN0SW5pdHMpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG9ubHkgPT0gTmFtZVR5cGUuTUlERExFX05BTUUpIHtcbiAgICAgICAgICAgICAgICBpbml0aWFscy5wdXNoKC4uLm1pZEluaXRzKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbml0aWFscy5wdXNoKC4uLmxhc3RJbml0cylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChvcmRlcmVkQnkgPT0gTmFtZU9yZGVyLkZJUlNUX05BTUUpIHtcbiAgICAgICAgICAgIGluaXRpYWxzLnB1c2goLi4uZmlyc3RJbml0cywgLi4ubWlkSW5pdHMsIC4uLmxhc3RJbml0cylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluaXRpYWxzLnB1c2goLi4ubGFzdEluaXRzLCAuLi5maXJzdEluaXRzLCAuLi5taWRJbml0cylcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5pdGlhbHNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG9ydGVucyBhIGNvbXBsZXggZnVsbCBuYW1lIHRvIGEgc2ltcGxlIHR5cGljYWwgbmFtZSwgYSBjb21iaW5hdGlvbiBvZlxuICAgICAqIGZpcnN0IGFuZCBsYXN0IG5hbWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb3JkZXJlZEJ5IGZvcmNlcyB0byBvcmRlciBieSBmaXJzdCBvciBsYXN0IG5hbWUgYnkgb3ZlcnJpZGluZyB0aGVcbiAgICAgKiBwcmVzZXQgY29uZmlndXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEZvciBhIGdpdmVuIG5hbWUgc3VjaCBhcyBgTXIgS2VhbnUgQ2hhcmxlcyBSZWV2ZXNgLCBzaG9ydGVuaW5nIHRoaXMgbmFtZVxuICAgICAqIGlzIGVxdWl2YWxlbnQgdG8gbWFraW5nIGl0IGBLZWFudSBSZWV2ZXNgLlxuICAgICAqXG4gICAgICogQXMgYSBzaG9ydGVuZWQgbmFtZSwgdGhlIG5hbW9uIG9mIHRoZSBmaXJzdCBuYW1lIGlzIGZhdm9yZWQgb3ZlciB0aGUgb3RoZXJcbiAgICAgKiBuYW1lcyBmb3JtaW5nIHBhcnQgb2YgdGhlIGVudGlyZSBmaXJzdCBuYW1lcywgaWYgYW55LiBNZWFud2hpbGUsIGZvclxuICAgICAqIHRoZSBsYXN0IG5hbWUsIHRoZSBjb25maWd1cmVkIGBzdXJuYW1lYCBpcyBwcmlvcml0aXplZC5cbiAgICAgKlxuICAgICAqIEZvciBhIGdpdmVuIGBGaXJzdE5hbWUgRmF0aGVyTmFtZSBNb3RoZXJOYW1lYCwgc2hvcnRlbmluZyB0aGlzIG5hbWUgd2hlblxuICAgICAqIHRoZSBzdXJuYW1lIGlzIHNldCBhcyBgbW90aGVyYCBpcyBlcXVpdmFsZW50IHRvIG1ha2luZyBpdDpcbiAgICAgKiBgRmlyc3ROYW1lIE1vdGhlck5hbWVgLlxuICAgICAqL1xuICAgIHNob3J0ZW4ob3JkZXJlZEJ5PzogTmFtZU9yZGVyKTogc3RyaW5nIHtcbiAgICAgICAgb3JkZXJlZEJ5ID0gb3JkZXJlZEJ5IHx8IHRoaXMuX2NvbmZpZy5vcmRlcmVkQnlcbiAgICAgICAgcmV0dXJuIG9yZGVyZWRCeSA9PSBOYW1lT3JkZXIuRklSU1RfTkFNRVxuICAgICAgICAgICAgPyBbdGhpcy5fZnVsbE5hbWUuZmlyc3ROYW1lLnZhbHVlLCB0aGlzLl9mdWxsTmFtZS5sYXN0TmFtZS50b1N0cmluZygpXS5qb2luKCcgJylcbiAgICAgICAgICAgIDogW3RoaXMuX2Z1bGxOYW1lLmxhc3ROYW1lLnRvU3RyaW5nKCksIHRoaXMuX2Z1bGxOYW1lLmZpcnN0TmFtZS52YWx1ZV0uam9pbignICcpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmxhdHRlbnMgYSBsb25nIG5hbWUgdXNpbmcgdGhlIG5hbWUgdHlwZXMgYXMgdmFyaWFudHMuXG4gICAgICpcbiAgICAgKiBXaGlsZSBAcGFyYW0gbGltaXQgc2V0cyBhIHRocmVzaG9sZCBhcyBhIGxpbWl0ZWQgbnVtYmVyIG9mIGNoYXJhY3RlcnNcbiAgICAgKiBzdXBwb3J0ZWQgdG8gZmxhdHRlbiBhIGBGdWxsTmFtZWAsIEBwYXJhbSBieSBpbmRpY2F0ZXMgd2hpY2ggdmFyaWFudFxuICAgICAqIHRvIHVzZSB3aGVuIGRvaW5nIHNvLiBCeSBkZWZhdWx0LCBhIGZ1bGwgbmFtZSBnZXRzIGZsYXR0ZW5lZCBieVxuICAgICAqIGBGbGF0Lk1JRERMRV9OQU1FYC5cbiAgICAgKlxuICAgICAqIFRoZSBmbGF0dGVuaW5nIG9wZXJhdGlvbiBpcyBvbmx5IGV4ZWN1dGVkIGlmZiB0aGVyZSBpcyBhIHZhbGlkIGVudHJ5IGFuZFxuICAgICAqIGl0IHN1cnBhc3NlcyB0aGUgbGltaXQgc2V0LiBJbiB0aGUgZXhhbXBsZXMgYmVsb3csIGxldCB1cyBhc3N1bWUgdGhhdCB0aGVcbiAgICAgKiBuYW1lIGdvZXMgYmV5b25kIHRoZSBsaW1pdCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEZsYXR0ZW5pbmcgYSBsb25nIG5hbWUgcmVmZXJzIHRvIHJlZHVjaW5nIHRoZSBuYW1lIHRvIHRoZSBmb2xsb3dpbmcgZm9ybXMuXG4gICAgICogRm9yIGV4YW1wbGUsIGBKb2huIFdpbnN0b24gT25vIExlbm5vbmAgZmxhdHRlbmVkIGJ5OlxuICAgICAqICogRmxhdC5GSVJTVF9OQU1FOiA9PiAnSi4gV2luc3RvbiBPbm8gTGVubm9uJ1xuICAgICAqICogRmxhdC5NSURETEVfTkFNRTogPT4gJ0pvaG4gVy4gTy4gTGVubm9uJ1xuICAgICAqICogRmxhdC5MQVNUX05BTUU6ID0+ICdKb2huIFdpbnN0b24gT25vIEwuJ1xuICAgICAqICogRmxhdC5GSVJTVF9NSUQ6ID0+ICdKLiBXLiBPLiBMZW5ub24nXG4gICAgICogKiBGbGF0Lk1JRF9MQVNUOiA9PiAnSm9obiBXLiBPLiBMLidcbiAgICAgKiAqIEZsYXQuQUxMOiA9PiAnSi4gVy4gTy4gTC4nXG4gICAgICpcbiAgICAgKiBXaXRoIHRoZSBoZWxwIG9mIHRoZSBAcGFyYW0gcmVjdXJzaXZlIGZsYWcsIHRoZSBhYm92ZSBvcGVyYXRpb24gY2FuIGhhcHBlblxuICAgICAqIHJlY3Vyc2l2ZWx5IGluIHRoZSBzYW1lIG9yZGVyIGlmIHRoZSBuYW1lIGlzIHN0aWxsIHRvbyBsb25nLiBGb3IgZXhhbXBsZSxcbiAgICAgKiBmbGF0dGVuaW5nIGBKb2huIFdpbnN0b24gT25vIExlbm5vbmAgdXNpbmcgdGhlIGZvbGxvd2luZyBwYXJhbXM6XG4gICAgICogYGZsYXR0ZW4oeyBsaW1pdDogMTgsIGJ5OiBGbGF0LkZJUlNUX05BTUUsIHJlY3Vyc2l2ZTogdHJ1ZSB9KWBcbiAgICAgKiB3aWxsIHJlc3VsdCBpbiBgSm9obiBXLiBPLiBMZW5ub25gIGFuZCBub3QgYEouIFdpbnN0b24gT25vIExlbm5vbmAuXG4gICAgICpcbiAgICAgKiBBIHNob3J0ZXIgdmVyc2lvbiBvZiB0aGlzIG1ldGhvZCBpcyBgemlwKClgLlxuICAgICAqL1xuICAgIGZsYXR0ZW4oXG4gICAgICAgIG9wdGlvbnM6IFBhcnRpYWw8e1xuICAgICAgICAgICAgbGltaXQ6IG51bWJlclxuICAgICAgICAgICAgYnk6IEZsYXRcbiAgICAgICAgICAgIHdpdGhQZXJpb2Q6IGJvb2xlYW5cbiAgICAgICAgICAgIHJlY3Vyc2l2ZTogYm9vbGVhblxuICAgICAgICAgICAgd2l0aE1vcmU6IGJvb2xlYW5cbiAgICAgICAgICAgIHN1cm5hbWU6IFN1cm5hbWVcbiAgICAgICAgfT4sXG4gICAgKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHRoaXMubGVuZ3RoIDw9IG9wdGlvbnMubGltaXQpIHJldHVybiB0aGlzLmZ1bGxcblxuICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0ge1xuICAgICAgICAgICAgbGltaXQ6IDIwLFxuICAgICAgICAgICAgYnk6IEZsYXQuTUlERExFX05BTUUsXG4gICAgICAgICAgICB3aXRoUGVyaW9kOiB0cnVlLFxuICAgICAgICAgICAgcmVjdXJzaXZlOiBmYWxzZSxcbiAgICAgICAgICAgIHdpdGhNb3JlOiBmYWxzZSxcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IGJ5LCBsaW1pdCwgcmVjdXJzaXZlLCB3aXRoTW9yZSwgd2l0aFBlcmlvZCwgc3VybmFtZSB9ID0gbWVyZ2VkT3B0aW9uc1xuICAgICAgICBjb25zdCBzZXAgPSB3aXRoUGVyaW9kID8gJy4nIDogJydcbiAgICAgICAgY29uc3QgZm4gPSB0aGlzLl9mdWxsTmFtZS5maXJzdE5hbWUudG9TdHJpbmcoKVxuICAgICAgICBjb25zdCBtbiA9IHRoaXMubWlkZGxlTmFtZSgpLmpvaW4oJyAnKVxuICAgICAgICBjb25zdCBsbiA9IHRoaXMuX2Z1bGxOYW1lLmxhc3ROYW1lLnRvU3RyaW5nKClcbiAgICAgICAgY29uc3QgaGFzTWlkID0gdGhpcy5oYXNNaWRkbGVcbiAgICAgICAgY29uc3QgZiA9IHRoaXMuX2Z1bGxOYW1lLmZpcnN0TmFtZS5pbml0aWFscyh3aXRoTW9yZSkuam9pbihzZXAgKyAnICcpICsgc2VwXG4gICAgICAgIGNvbnN0IGwgPSB0aGlzLl9mdWxsTmFtZS5sYXN0TmFtZS5pbml0aWFscyhzdXJuYW1lKS5qb2luKHNlcCArICcgJykgKyBzZXBcbiAgICAgICAgY29uc3QgbSA9IGhhc01pZCA/IHRoaXMuX2Z1bGxOYW1lLm1pZGRsZU5hbWUubWFwKChuKSA9PiBuLmluaXRpYWxzKClbMF0pLmpvaW4oc2VwICsgJyAnKSArIHNlcCA6ICcnXG4gICAgICAgIGxldCBuYW1lOiBzdHJpbmdbXSA9IFtdXG5cbiAgICAgICAgaWYgKHRoaXMuX2NvbmZpZy5vcmRlcmVkQnkgPT0gTmFtZU9yZGVyLkZJUlNUX05BTUUpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoYnkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIEZsYXQuRklSU1RfTkFNRTpcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGhhc01pZCA/IFtmLCBtbiwgbG5dIDogW2YsIGxuXVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGNhc2UgRmxhdC5MQVNUX05BTUU6XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBoYXNNaWQgPyBbZm4sIG1uLCBsXSA6IFtmbiwgbF1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIEZsYXQuTUlERExFX05BTUU6XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBoYXNNaWQgPyBbZm4sIG0sIGxuXSA6IFtmbiwgbG5dXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSBGbGF0LkZJUlNUX01JRDpcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGhhc01pZCA/IFtmLCBtLCBsbl0gOiBbZiwgbG5dXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSBGbGF0Lk1JRF9MQVNUOlxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gaGFzTWlkID8gW2ZuLCBtLCBsXSA6IFtmbiwgbF1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIEZsYXQuQUxMOlxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gaGFzTWlkID8gW2YsIG0sIGxdIDogW2YsIGxdXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGJ5KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBGbGF0LkZJUlNUX05BTUU6XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBoYXNNaWQgPyBbbG4sIGYsIG1uXSA6IFtsbiwgZl1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICBjYXNlIEZsYXQuTEFTVF9OQU1FOlxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gaGFzTWlkID8gW2wsIGZuLCBtbl0gOiBbbCwgZm5dXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSBGbGF0Lk1JRERMRV9OQU1FOlxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gaGFzTWlkID8gW2xuLCBmbiwgbV0gOiBbbG4sIGZuXVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGNhc2UgRmxhdC5GSVJTVF9NSUQ6XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBoYXNNaWQgPyBbbG4sIGYsIG1dIDogW2xuLCBmXVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGNhc2UgRmxhdC5NSURfTEFTVDpcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGhhc01pZCA/IFtsLCBmbiwgbV0gOiBbbCwgZm5dXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgY2FzZSBGbGF0LkFMTDpcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGhhc01pZCA/IFtsLCBmLCBtXSA6IFtsLCBmXVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmxhdCA9IG5hbWUuam9pbignICcpXG4gICAgICAgIGlmIChyZWN1cnNpdmUgJiYgZmxhdC5sZW5ndGggPiBsaW1pdCkge1xuICAgICAgICAgICAgY29uc3QgbmV4dCA9XG4gICAgICAgICAgICAgICAgYnkgPT0gRmxhdC5GSVJTVF9OQU1FXG4gICAgICAgICAgICAgICAgICAgID8gRmxhdC5NSURETEVfTkFNRVxuICAgICAgICAgICAgICAgICAgICA6IGJ5ID09IEZsYXQuTUlERExFX05BTUVcbiAgICAgICAgICAgICAgICAgICAgPyBGbGF0LkxBU1RfTkFNRVxuICAgICAgICAgICAgICAgICAgICA6IGJ5ID09IEZsYXQuTEFTVF9OQU1FXG4gICAgICAgICAgICAgICAgICAgID8gRmxhdC5GSVJTVF9NSURcbiAgICAgICAgICAgICAgICAgICAgOiBieSA9PSBGbGF0LkZJUlNUX01JRFxuICAgICAgICAgICAgICAgICAgICA/IEZsYXQuTUlEX0xBU1RcbiAgICAgICAgICAgICAgICAgICAgOiBieSA9PSBGbGF0Lk1JRF9MQVNUXG4gICAgICAgICAgICAgICAgICAgID8gRmxhdC5BTExcbiAgICAgICAgICAgICAgICAgICAgOiBieSA9PSBGbGF0LkFMTFxuICAgICAgICAgICAgICAgICAgICA/IEZsYXQuQUxMXG4gICAgICAgICAgICAgICAgICAgIDogYnlcbiAgICAgICAgICAgIGlmIChuZXh0ID09IGJ5KSByZXR1cm4gZmxhdFxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmxhdHRlbih7IC4uLm9wdGlvbnMsIGJ5OiBuZXh0IH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZsYXRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBaaXBzIG9yIGNvbXBhY3RzIGEgbmFtZSB1c2luZyBkaWZmZXJlbnQgZm9ybXMgb2YgdmFyaWFudHMuXG4gICAgICpcbiAgICAgKiBAc2VlIGBmbGF0dGVuKClgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICovXG4gICAgemlwKGJ5ID0gRmxhdC5NSURfTEFTVCwgd2l0aFBlcmlvZCA9IHRydWUpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5mbGF0dGVuKHsgbGltaXQ6IDAsIGJ5LCB3aXRoUGVyaW9kIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9ybWF0cyB0aGUgZnVsbCBuYW1lIGFzIGRlc2lyZWQuXG4gICAgICogQHBhcmFtIHBhdHRlcm4gY2hhcmFjdGVyIHVzZWQgdG8gZm9ybWF0IGl0LlxuICAgICAqXG4gICAgICogc3RyaW5nIGZvcm1hdFxuICAgICAqIC0tLS0tLS0tLS0tLS1cbiAgICAgKiAtICdzaG9ydCc6IHR5cGljYWwgZmlyc3QgKyBsYXN0IG5hbWVcbiAgICAgKiAtICdsb25nJzogYmlydGggbmFtZSAod2l0aG91dCBwcmVmaXggYW5kIHN1ZmZpeClcbiAgICAgKiAtICdwdWJsaWMnOiBmaXJzdCBuYW1lIGNvbWJpbmVkIHdpdGggdGhlIGxhc3QgbmFtZSdzIGluaXRpYWwuXG4gICAgICogLSAnb2ZmaWNpYWwnOiBvZmZpY2lhbCBkb2N1bWVudCBmb3JtYXRcbiAgICAgKlxuICAgICAqIGNoYXIgZm9ybWF0XG4gICAgICogLS0tLS0tLS0tLS1cbiAgICAgKiAtICdiJzogYmlydGggbmFtZVxuICAgICAqIC0gJ0InOiBjYXBpdGFsaXplZCBiaXJ0aCBuYW1lXG4gICAgICogLSAnZic6IGZpcnN0IG5hbWVcbiAgICAgKiAtICdGJzogY2FwaXRhbGl6ZWQgZmlyc3QgbmFtZVxuICAgICAqIC0gJ2wnOiBsYXN0IG5hbWVcbiAgICAgKiAtICdMJzogY2FwaXRhbGl6ZWQgbGFzdCBuYW1lXG4gICAgICogLSAnbSc6IG1pZGRsZSBuYW1lc1xuICAgICAqIC0gJ00nOiBjYXBpdGFsaXplZCBtaWRkbGUgbmFtZXNcbiAgICAgKiAtICdvJzogb2ZmaWNpYWwgZG9jdW1lbnQgZm9ybWF0XG4gICAgICogLSAnTyc6IG9mZmljaWFsIGRvY3VtZW50IGZvcm1hdCBpbiBjYXBpdGFsIGxldHRlcnNcbiAgICAgKiAtICdwJzogcHJlZml4XG4gICAgICogLSAnUCc6IGNhcGl0YWxpemVkIHByZWZpeFxuICAgICAqIC0gJ3MnOiBzdWZmaXhcbiAgICAgKiAtICdTJzogY2FwaXRhbGl6ZWQgc3VmZml4XG4gICAgICpcbiAgICAgKiBwdW5jdHVhdGlvbnNcbiAgICAgKiAtLS0tLS0tLS0tLS1cbiAgICAgKiAtICcuJzogcGVyaW9kXG4gICAgICogLSAnLCc6IGNvbW1hXG4gICAgICogLSAnICc6IHNwYWNlXG4gICAgICogLSAnLSc6IGh5cGhlblxuICAgICAqIC0gJ18nOiB1bmRlcnNjb3JlXG4gICAgICogLSAnJCc6IGFuIGVzY2FwZSBjaGFyYWN0ZXIgdG8gc2VsZWN0IG9ubHkgdGhlIGluaXRpYWwgb2YgdGhlIG5leHQgY2hhci5cbiAgICAgKlxuICAgICAqIEdpdmVuIHRoZSBuYW1lIGBKb2UgSmltIFNtaXRoYCwgdXNlIGBmb3JtYXRgIHdpdGggdGhlIGBwYXR0ZXJuYCBzdHJpbmcuXG4gICAgICogLSBmb3JtYXQoJ2wgZicpID0+ICdTbWl0aCBKb2UnXG4gICAgICogLSBmb3JtYXQoJ0wsIGYnKSA9PiAnU01JVEgsIEpvZSdcbiAgICAgKiAtIGZvcm1hdCgnc2hvcnQnKSA9PiAnSm9lIFNtaXRoJ1xuICAgICAqIC0gZm9ybWF0KCkgPT4gJ1NNSVRILCBKb2UgSmltJ1xuICAgICAqIC0gZm9ybWF0KHInZiAkbC4nKSA9PiAnSm9lIFMuJy5cbiAgICAgKlxuICAgICAqIERvIG5vdGUgdGhhdCB0aGUgZXNjYXBlIGNoYXJhY3RlciBpcyBvbmx5IHZhbGlkIGZvciB0aGUgYmlydGggbmFtZSBwYXJ0czpcbiAgICAgKiBmaXJzdCwgbWlkZGxlLCBhbmQgbGFzdCBuYW1lcy5cbiAgICAgKi9cbiAgICBmb3JtYXQocGF0dGVybjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHBhdHRlcm4gPT0gJ3Nob3J0JykgcmV0dXJuIHRoaXMuc2hvcnRcbiAgICAgICAgaWYgKHBhdHRlcm4gPT0gJ2xvbmcnKSByZXR1cm4gdGhpcy5sb25nXG4gICAgICAgIGlmIChwYXR0ZXJuID09ICdwdWJsaWMnKSByZXR1cm4gdGhpcy5wdWJsaWNcbiAgICAgICAgaWYgKHBhdHRlcm4gPT0gJ29mZmljaWFsJykgcGF0dGVybiA9ICdvJ1xuXG4gICAgICAgIGxldCBncm91cCA9ICcnXG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZDogc3RyaW5nW10gPSBbXVxuICAgICAgICBmb3IgKGNvbnN0IGNoYXIgb2YgcGF0dGVybi5zcGxpdCgnJykpIHtcbiAgICAgICAgICAgIGlmIChBTExPV0VEX1RPS0VOUy5pbmRleE9mKGNoYXIpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb3RBbGxvd2VkRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHRoaXMuZnVsbCxcbiAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uOiAnZm9ybWF0JyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYHVuc3VwcG9ydGVkIGNoYXJhY3RlciA8JHtjaGFyfT4gZnJvbSAke3BhdHRlcm59LmAsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGdyb3VwICs9IGNoYXJcbiAgICAgICAgICAgIGlmIChjaGFyID09PSAnJCcpIGNvbnRpbnVlXG4gICAgICAgICAgICBmb3JtYXR0ZWQucHVzaCh0aGlzLm1hcChncm91cCkgPz8gJycpXG4gICAgICAgICAgICBncm91cCA9ICcnXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdHRlZC5qb2luKCcnKS50cmltKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGbGlwcyBkZWZpbml0ZWx5IHRoZSBuYW1lIG9yZGVyIGZyb20gdGhlIHByZXNldC9jdXJyZW50IGNvbmZpZy5cbiAgICAgKi9cbiAgICBmbGlwKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5fY29uZmlnLm9yZGVyZWRCeSA9PT0gTmFtZU9yZGVyLkZJUlNUX05BTUUpIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbmZpZy51cGRhdGVPcmRlcihOYW1lT3JkZXIuTEFTVF9OQU1FKVxuICAgICAgICAgICAgY29uc29sZS5sb2coYFRoZSBuYW1lIG9yZGVyIGlzIG5vdyBjaGFuZ2VkIHRvOiAke05hbWVPcmRlci5MQVNUX05BTUV9YClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbmZpZy51cGRhdGVPcmRlcihOYW1lT3JkZXIuRklSU1RfTkFNRSlcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBUaGUgbmFtZSBvcmRlciBpcyBub3cgY2hhbmdlZCB0bzogJHtOYW1lT3JkZXIuRklSU1RfTkFNRX1gKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3BsaXRzIHRoZSBuYW1lIHBhcnRzIG9mIGEgYmlydGggbmFtZS5cbiAgICAgKiBAcGFyYW0gc2VwYXJhdG9yIHRva2VuIGZvciB0aGUgc3BsaXQuXG4gICAgICovXG4gICAgc3BsaXQoc2VwYXJhdG9yOiBzdHJpbmcgfCBSZWdFeHAgPSAvWycgLV0vZyk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmlydGgucmVwbGFjZShzZXBhcmF0b3IsICcgJykuc3BsaXQoJyAnKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEpvaW5zIHRoZSBuYW1lIHBhcnRzIG9mIGEgYmlydGggbmFtZS5cbiAgICAgKiBAcGFyYW0gc2VwYXJhdG9yIHRva2VuIGZvciB0aGUganVuY3Rpb24uXG4gICAgICovXG4gICAgam9pbihzZXBhcmF0b3IgPSAnJyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnNwbGl0KCkuam9pbihzZXBhcmF0b3IpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtcyBhIGJpcnRoIG5hbWUgaW50byBVUFBFUkNBU0VcbiAgICAgKi9cbiAgICB0b1VwcGVyQ2FzZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5iaXJ0aC50b1VwcGVyQ2FzZSgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtcyBhIGJpcnRoIG5hbWUgaW50byBsb3dlcmNhc2VcbiAgICAgKi9cbiAgICB0b0xvd2VyQ2FzZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5iaXJ0aC50b0xvd2VyQ2FzZSgpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtcyBhIGJpcnRoIG5hbWUgaW50byBjYW1lbENhc2VcbiAgICAgKi9cbiAgICB0b0NhbWVsQ2FzZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gZGVjYXBpdGFsaXplKHRoaXMudG9QYXNjYWxDYXNlKCkpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtcyBhIGJpcnRoIG5hbWUgaW50byBQYXNjYWxDYXNlXG4gICAgICovXG4gICAgdG9QYXNjYWxDYXNlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnNwbGl0KClcbiAgICAgICAgICAgIC5tYXAoKG4pID0+IGNhcGl0YWxpemUobikpXG4gICAgICAgICAgICAuam9pbignJylcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm1zIGEgYmlydGggbmFtZSBpbnRvIHNuYWtlX2Nhc2VcbiAgICAgKi9cbiAgICB0b1NuYWtlQ2FzZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5zcGxpdCgpXG4gICAgICAgICAgICAubWFwKChuKSA9PiBuLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgICAgICAuam9pbignXycpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtcyBhIGJpcnRoIG5hbWUgaW50byBoeXBoZW4tY2FzZVxuICAgICAqL1xuICAgIHRvSHlwaGVuQ2FzZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5zcGxpdCgpXG4gICAgICAgICAgICAubWFwKChuKSA9PiBuLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgICAgICAuam9pbignLScpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtcyBhIGJpcnRoIG5hbWUgaW50byBkb3QuY2FzZVxuICAgICAqL1xuICAgIHRvRG90Q2FzZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5zcGxpdCgpXG4gICAgICAgICAgICAubWFwKChuKSA9PiBuLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgICAgICAuam9pbignLicpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtcyBhIGJpcnRoIG5hbWUgaW50byBUb0dnTGVDYVNlXG4gICAgICovXG4gICAgdG9Ub2dnbGVDYXNlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0b2dnbGVDYXNlKHRoaXMuYmlydGgpXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBidWlsZDxUPihwYXJzZXI6IFBhcnNlcjxUPiwgb3B0aW9ucz86IFBhcnRpYWw8Q29uZmlnPik6IHZvaWQge1xuICAgICAgICB0aGlzLl9jb25maWcgPSBDb25maWcubWVyZ2Uob3B0aW9ucylcbiAgICAgICAgdGhpcy5fZnVsbE5hbWUgPSBwYXJzZXIucGFyc2UodGhpcy5fY29uZmlnKVxuICAgIH1cblxuICAgIHByaXZhdGUgdG9QYXJzZXIocmF3OiBzdHJpbmcgfCBzdHJpbmdbXSB8IE5hbWVbXSB8IEpzb25OYW1lIHwgUGFyc2VyKTogUGFyc2VyIHtcbiAgICAgICAgaWYgKHJhdyBpbnN0YW5jZW9mIFBhcnNlcikgcmV0dXJuIHJhd1xuICAgICAgICBpZiAodHlwZW9mIHJhdyA9PT0gJ3N0cmluZycpIHJldHVybiBuZXcgU3RyaW5nUGFyc2VyKHJhdylcbiAgICAgICAgaWYgKGlzU3RyaW5nQXJyYXkocmF3KSkgcmV0dXJuIG5ldyBBcnJheVN0cmluZ1BhcnNlcihyYXcgYXMgc3RyaW5nW10pXG4gICAgICAgIGlmIChpc05hbWVBcnJheShyYXcpKSByZXR1cm4gbmV3IEFycmF5TmFtZVBhcnNlcihyYXcgYXMgTmFtZVtdKVxuICAgICAgICBpZiAodHlwZW9mIHJhdyA9PT0gJ29iamVjdCcpIHJldHVybiBuZXcgTmFtYVBhcnNlcihyYXcgYXMgSnNvbk5hbWUpXG5cbiAgICAgICAgdGhyb3cgbmV3IElucHV0RXJyb3Ioe1xuICAgICAgICAgICAgc291cmNlOiByYXcsXG4gICAgICAgICAgICBtZXNzYWdlOiAnQ2Fubm90IHBhcnNlIHJhdyBkYXRhLiBSZXZpZXcgZXhwZWN0ZWQgZGF0YSB0eXBlcy4nLFxuICAgICAgICB9KVxuICAgIH1cblxuICAgIHByaXZhdGUgbWFwKGNoYXI6IHN0cmluZyk6IE51bGxhYmxlPHN0cmluZz4ge1xuICAgICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgICAgIGNhc2UgJy4nOlxuICAgICAgICAgICAgY2FzZSAnLCc6XG4gICAgICAgICAgICBjYXNlICcgJzpcbiAgICAgICAgICAgIGNhc2UgJy0nOlxuICAgICAgICAgICAgY2FzZSAnXyc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoYXJcbiAgICAgICAgICAgIGNhc2UgJ2InOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJpcnRoXG4gICAgICAgICAgICBjYXNlICdCJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5iaXJ0aC50b1VwcGVyQ2FzZSgpXG4gICAgICAgICAgICBjYXNlICdmJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5maXJzdFxuICAgICAgICAgICAgY2FzZSAnRic6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlyc3QudG9VcHBlckNhc2UoKVxuICAgICAgICAgICAgY2FzZSAnbCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGFzdFxuICAgICAgICAgICAgY2FzZSAnTCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGFzdC50b1VwcGVyQ2FzZSgpXG4gICAgICAgICAgICBjYXNlICdtJzpcbiAgICAgICAgICAgIGNhc2UgJ00nOlxuICAgICAgICAgICAgICAgIHJldHVybiBjaGFyID09ICdtJyA/IHRoaXMubWlkZGxlTmFtZSgpLmpvaW4oJyAnKSA6IHRoaXMubWlkZGxlTmFtZSgpLmpvaW4oJyAnKS50b1VwcGVyQ2FzZSgpXG4gICAgICAgICAgICBjYXNlICdvJzpcbiAgICAgICAgICAgIGNhc2UgJ08nOlxuICAgICAgICAgICAgICAgIGNvbnN0IHNlcCA9IHRoaXMuX2NvbmZpZy5lbmRpbmcgPyAnLCcgOiAnJ1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWVzOiBzdHJpbmdbXSA9IFtdXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJlZml4KSBuYW1lcy5wdXNoKHRoaXMucHJlZml4KVxuICAgICAgICAgICAgICAgIG5hbWVzLnB1c2goYCR7dGhpcy5sYXN0fSxgLnRvVXBwZXJDYXNlKCkpXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFzTWlkZGxlKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWVzLnB1c2godGhpcy5maXJzdCwgdGhpcy5taWRkbGVOYW1lKCkuam9pbignICcpICsgc2VwKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWVzLnB1c2godGhpcy5maXJzdCArIHNlcClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3VmZml4KSBuYW1lcy5wdXNoKHRoaXMuc3VmZml4KVxuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWEgPSBuYW1lcy5qb2luKCcgJykudHJpbSgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoYXIgPT09ICdvJyA/IG5hbWEgOiBuYW1hLnRvVXBwZXJDYXNlKClcbiAgICAgICAgICAgIGNhc2UgJ3AnOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnByZWZpeFxuICAgICAgICAgICAgY2FzZSAnUCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJlZml4Py50b1VwcGVyQ2FzZSgpXG4gICAgICAgICAgICBjYXNlICdzJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zdWZmaXhcbiAgICAgICAgICAgIGNhc2UgJ1MnOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnN1ZmZpeD8udG9VcHBlckNhc2UoKVxuICAgICAgICAgICAgY2FzZSAnJGYnOlxuICAgICAgICAgICAgY2FzZSAnJEYnOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9mdWxsTmFtZS5maXJzdE5hbWUuaW5pdGlhbHMoKVswXVxuICAgICAgICAgICAgY2FzZSAnJGwnOlxuICAgICAgICAgICAgY2FzZSAnJEwnOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9mdWxsTmFtZS5sYXN0TmFtZS5pbml0aWFscygpWzBdXG4gICAgICAgICAgICBjYXNlICckbSc6XG4gICAgICAgICAgICBjYXNlICckTSc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Z1bGxOYW1lLm1pZGRsZU5hbWUubWFwKChuKSA9PiBuLmluaXRpYWxzKClbMF0pWzBdXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImltcG9ydCB7IEZ1bGxOYW1lIH0gZnJvbSAnLi9mdWxsLW5hbWUnXG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuL2NvbmZpZydcbmltcG9ydCB7IE5hbWVJbmRleCB9IGZyb20gJy4vdXRpbHMnXG5pbXBvcnQgeyBBcnJheVN0cmluZ1ZhbGlkYXRvciwgQXJyYXlOYW1lVmFsaWRhdG9yLCBOYW1hVmFsaWRhdG9yIH0gZnJvbSAnLi92YWxpZGF0b3InXG5pbXBvcnQgeyBGaXJzdE5hbWUsIExhc3ROYW1lLCBOYW1lLCBKc29uTmFtZSB9IGZyb20gJy4vbmFtZSdcbmltcG9ydCB7IE5hbW9uLCBOdWxsYWJsZSwgU2VwYXJhdG9yIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCB7IElucHV0RXJyb3IgfSBmcm9tICcuL2Vycm9yJ1xuXG4vKipcbiAqIEEgcGFyc2VyIHNpZ25hdHVyZSB0aGF0IGhlbHBzIHRvIG9yZ2FuaXplIHRoZSBuYW1lcyBhY2NvcmRpbmdseS5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFBhcnNlcjxUID0gYW55PiB7XG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIGN1c3RvbSBwYXJzZXIgYWNjb3JkaW5nbHkuXG4gICAgICogQHBhcmFtIHJhdyBkYXRhIHRvIGJlIHBhcnNlZFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyByYXc6IFQpIHt9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIHJhdyBkYXRhIGludG8gYSBgRnVsbE5hbWVgIHdoaWxlIGNvbnNpZGVyaW5nIHNvbWUgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBhZGRpdGlvbmFsIGNvbmZpZ3VyYXRpb24gdG8gYXBwbHkuXG4gICAgICovXG4gICAgYWJzdHJhY3QgcGFyc2Uob3B0aW9ucz86IFBhcnRpYWw8Q29uZmlnPik6IEZ1bGxOYW1lXG5cbiAgICAvKipcbiAgICAgKiBCdWlsZHMgYSBkeW5hbWljIGBQYXJzZXJgIG9uIHRoZSBmbHkgYW5kIHRocm93cyBhIGBOYW1lRXJyb3JgIHdoZW4gdW5hYmxlXG4gICAgICogdG8gZG8gc28uIFRoZSBidWlsdCBwYXJzZXIgb25seSBrbm93cyBob3cgdG8gb3BlcmF0ZSBiaXJ0aCBuYW1lcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgYnVpbGQodGV4dDogc3RyaW5nKTogUGFyc2VyIHtcbiAgICAgICAgY29uc3QgcGFydHMgPSB0ZXh0LnRyaW0oKS5zcGxpdChTZXBhcmF0b3IuU1BBQ0UudG9rZW4pXG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IHBhcnRzLmxlbmd0aFxuICAgICAgICBpZiAobGVuZ3RoID09IDAgfHwgbGVuZ3RoID09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IHRleHQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ2Nhbm5vdCBidWlsZCBmcm9tIGludmFsaWQgaW5wdXQnLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIGlmIChsZW5ndGggPT0gMiB8fCBsZW5ndGggPT0gMykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdQYXJzZXIodGV4dClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3QgPSBwYXJ0cy5wb3AoKVxuICAgICAgICAgICAgY29uc3QgW2ZpcnN0LCAuLi5taWRkbGVzXSA9IHBhcnRzXG4gICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5U3RyaW5nUGFyc2VyKFtmaXJzdCwgbWlkZGxlcy5qb2luKCcgJyksIGxhc3RdKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnVpbGRzIGFzeW5jaHJvbm91c2x5IGEgZHluYW1pYyBgUGFyc2VyYC5cbiAgICAgKi9cbiAgICBzdGF0aWMgYnVpbGRBc3luYyh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPFBhcnNlcj4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShQYXJzZXIuYnVpbGQodGV4dCkpXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTdHJpbmdQYXJzZXIgZXh0ZW5kcyBQYXJzZXI8c3RyaW5nPiB7XG4gICAgY29uc3RydWN0b3IocmF3OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIocmF3KVxuICAgIH1cblxuICAgIHBhcnNlKG9wdGlvbnM6IFBhcnRpYWw8Q29uZmlnPik6IEZ1bGxOYW1lIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0gQ29uZmlnLm1lcmdlKG9wdGlvbnMpXG4gICAgICAgIGNvbnN0IG5hbWVzID0gdGhpcy5yYXcuc3BsaXQoY29uZmlnLnNlcGFyYXRvci50b2tlbilcbiAgICAgICAgcmV0dXJuIG5ldyBBcnJheVN0cmluZ1BhcnNlcihuYW1lcykucGFyc2Uob3B0aW9ucylcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBcnJheVN0cmluZ1BhcnNlciBleHRlbmRzIFBhcnNlcjxzdHJpbmdbXT4ge1xuICAgIGNvbnN0cnVjdG9yKHJhdzogc3RyaW5nW10pIHtcbiAgICAgICAgc3VwZXIocmF3KVxuICAgIH1cblxuICAgIHBhcnNlKG9wdGlvbnM6IFBhcnRpYWw8Q29uZmlnPik6IEZ1bGxOYW1lIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0gQ29uZmlnLm1lcmdlKG9wdGlvbnMpXG4gICAgICAgIGNvbnN0IGZ1bGxOYW1lID0gbmV3IEZ1bGxOYW1lKGNvbmZpZylcblxuICAgICAgICBjb25zdCByYXcgPSB0aGlzLnJhdy5tYXAoKG4pID0+IG4udHJpbSgpKVxuICAgICAgICBjb25zdCBpbmRleCA9IE5hbWVJbmRleC53aGVuKGNvbmZpZy5vcmRlcmVkQnksIHJhdy5sZW5ndGgpXG4gICAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG5ldyBBcnJheVN0cmluZ1ZhbGlkYXRvcihpbmRleClcblxuICAgICAgICBpZiAoY29uZmlnLmJ5cGFzcykge1xuICAgICAgICAgICAgdmFsaWRhdG9yLnZhbGlkYXRlSW5kZXgocmF3KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsaWRhdG9yLnZhbGlkYXRlKHJhdylcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAocmF3Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIGZ1bGxOYW1lLnNldEZpcnN0TmFtZShuZXcgRmlyc3ROYW1lKHJhd1tpbmRleC5maXJzdE5hbWVdKSlcbiAgICAgICAgICAgICAgICBmdWxsTmFtZS5zZXRMYXN0TmFtZShuZXcgTGFzdE5hbWUocmF3W2luZGV4Lmxhc3ROYW1lXSkpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBmdWxsTmFtZS5zZXRGaXJzdE5hbWUobmV3IEZpcnN0TmFtZShyYXdbaW5kZXguZmlyc3ROYW1lXSkpXG4gICAgICAgICAgICAgICAgZnVsbE5hbWUuc2V0TWlkZGxlTmFtZSh0aGlzLnNwbGl0KHJhd1tpbmRleC5taWRkbGVOYW1lXSwgY29uZmlnKSlcbiAgICAgICAgICAgICAgICBmdWxsTmFtZS5zZXRMYXN0TmFtZShuZXcgTGFzdE5hbWUocmF3W2luZGV4Lmxhc3ROYW1lXSkpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBmdWxsTmFtZS5zZXRQcmVmaXgoTmFtZS5wcmVmaXgocmF3W2luZGV4LnByZWZpeF0pKVxuICAgICAgICAgICAgICAgIGZ1bGxOYW1lLnNldEZpcnN0TmFtZShuZXcgRmlyc3ROYW1lKHJhd1tpbmRleC5maXJzdE5hbWVdKSlcbiAgICAgICAgICAgICAgICBmdWxsTmFtZS5zZXRNaWRkbGVOYW1lKHRoaXMuc3BsaXQocmF3W2luZGV4Lm1pZGRsZU5hbWVdLCBjb25maWcpKVxuICAgICAgICAgICAgICAgIGZ1bGxOYW1lLnNldExhc3ROYW1lKG5ldyBMYXN0TmFtZShyYXdbaW5kZXgubGFzdE5hbWVdKSlcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIGZ1bGxOYW1lLnNldFByZWZpeChOYW1lLnByZWZpeChyYXdbaW5kZXgucHJlZml4XSkpXG4gICAgICAgICAgICAgICAgZnVsbE5hbWUuc2V0Rmlyc3ROYW1lKG5ldyBGaXJzdE5hbWUocmF3W2luZGV4LmZpcnN0TmFtZV0pKVxuICAgICAgICAgICAgICAgIGZ1bGxOYW1lLnNldE1pZGRsZU5hbWUodGhpcy5zcGxpdChyYXdbaW5kZXgubWlkZGxlTmFtZV0sIGNvbmZpZykpXG4gICAgICAgICAgICAgICAgZnVsbE5hbWUuc2V0TGFzdE5hbWUobmV3IExhc3ROYW1lKHJhd1tpbmRleC5sYXN0TmFtZV0pKVxuICAgICAgICAgICAgICAgIGZ1bGxOYW1lLnNldFN1ZmZpeChOYW1lLnN1ZmZpeChyYXdbaW5kZXguc3VmZml4XSkpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVsbE5hbWVcbiAgICB9XG5cbiAgICBwcml2YXRlIHNwbGl0KHJhdzogc3RyaW5nLCBjb25maWc6IENvbmZpZyk6IE5hbWVbXSB7XG4gICAgICAgIHJldHVybiByYXcuc3BsaXQoY29uZmlnLnNlcGFyYXRvci50b2tlbikubWFwKChuYW1lKSA9PiBOYW1lLm1pZGRsZShuYW1lKSlcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBOYW1hUGFyc2VyIGV4dGVuZHMgUGFyc2VyPEpzb25OYW1lPiB7XG4gICAgY29uc3RydWN0b3IocmF3OiBKc29uTmFtZSkge1xuICAgICAgICBzdXBlcihyYXcpXG4gICAgfVxuXG4gICAgcGFyc2Uob3B0aW9uczogUGFydGlhbDxDb25maWc+KTogRnVsbE5hbWUge1xuICAgICAgICBjb25zdCBjb25maWcgPSBDb25maWcubWVyZ2Uob3B0aW9ucylcblxuICAgICAgICBpZiAoY29uZmlnLmJ5cGFzcykge1xuICAgICAgICAgICAgTmFtYVZhbGlkYXRvci5jcmVhdGUoKS52YWxpZGF0ZUtleXModGhpcy5hc05hbWEoKSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIE5hbWFWYWxpZGF0b3IuY3JlYXRlKCkudmFsaWRhdGUodGhpcy5hc05hbWEoKSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBGdWxsTmFtZS5wYXJzZSh0aGlzLnJhdywgY29uZmlnKVxuICAgIH1cblxuICAgIHByaXZhdGUgYXNOYW1hKCk6IE1hcDxOYW1vbiwgc3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBuZXcgTWFwPE5hbW9uLCBzdHJpbmc+KFxuICAgICAgICAgICAgT2JqZWN0LmVudHJpZXModGhpcy5yYXcpLm1hcCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmFtb246IE51bGxhYmxlPE5hbW9uPiA9IE5hbW9uLmNhc3Qoa2V5KVxuICAgICAgICAgICAgICAgIGlmICghbmFtb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElucHV0RXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlOiBPYmplY3QudmFsdWVzKHRoaXMucmF3KS5qb2luKCcgJyksXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgdW5zdXBwb3J0ZWQga2V5IFwiJHtrZXl9XCJgLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gW25hbW9uLCB2YWx1ZSBhcyBzdHJpbmddXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEFycmF5TmFtZVBhcnNlciBleHRlbmRzIFBhcnNlcjxOYW1lW10+IHtcbiAgICBjb25zdHJ1Y3RvcihyYXc6IE5hbWVbXSkge1xuICAgICAgICBzdXBlcihyYXcpXG4gICAgfVxuXG4gICAgcGFyc2Uob3B0aW9uczogUGFydGlhbDxDb25maWc+KTogRnVsbE5hbWUge1xuICAgICAgICBjb25zdCBjb25maWcgPSBDb25maWcubWVyZ2Uob3B0aW9ucylcbiAgICAgICAgY29uc3QgZnVsbE5hbWUgPSBuZXcgRnVsbE5hbWUoY29uZmlnKVxuXG4gICAgICAgIEFycmF5TmFtZVZhbGlkYXRvci5jcmVhdGUoKS52YWxpZGF0ZSh0aGlzLnJhdylcblxuICAgICAgICBmb3IgKGxldCBuYW1lIG9mIHRoaXMucmF3KSB7XG4gICAgICAgICAgICBpZiAobmFtZS5pc1ByZWZpeCkge1xuICAgICAgICAgICAgICAgIGZ1bGxOYW1lLnNldFByZWZpeChuYW1lKVxuICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmlzU3VmZml4KSB7XG4gICAgICAgICAgICAgICAgZnVsbE5hbWUuc2V0U3VmZml4KG5hbWUpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuaXNGaXJzdE5hbWUpIHtcbiAgICAgICAgICAgICAgICBmdWxsTmFtZS5zZXRGaXJzdE5hbWUobmFtZSBpbnN0YW5jZW9mIEZpcnN0TmFtZSA/IG5hbWUgOiBuZXcgRmlyc3ROYW1lKG5hbWUudmFsdWUpKVxuICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmlzTWlkZGxlTmFtZSkge1xuICAgICAgICAgICAgICAgIGZ1bGxOYW1lLm1pZGRsZU5hbWUucHVzaChuYW1lKVxuICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lLmlzTGFzdE5hbWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsYXN0TmFtZSA9IG5ldyBMYXN0TmFtZShcbiAgICAgICAgICAgICAgICAgICAgbmFtZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZSBpbnN0YW5jZW9mIExhc3ROYW1lID8gbmFtZS5tb3RoZXIgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5zdXJuYW1lLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICBmdWxsTmFtZS5zZXRMYXN0TmFtZShsYXN0TmFtZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVsbE5hbWVcbiAgICB9XG59XG4iLCIvKipcbiAqIE1ha2UgYSB0eXBlIG51bGxhYmxlLlxuICovXG5leHBvcnQgdHlwZSBOdWxsYWJsZTxUPiA9IFQgfCBudWxsIHwgdW5kZWZpbmVkXG5cbi8qKlxuICogVGhlIGFiYnJldmlhdGlvbiB0eXBlIHRvIGluZGljYXRlIHdoZXRoZXIgb3Igbm90IHRvIGFkZCBwZXJpb2QgdG8gYSBwcmVmaXhcbiAqIHVzaW5nIHRoZSBBbWVyaWNhbiBvciBCcml0aXNoIHdheS5cbiAqL1xuZXhwb3J0IGVudW0gVGl0bGUge1xuICAgIC8vIEEgcGVyaW9kIGFmdGVyIHRoZSBwcmVmaXguXG4gICAgVVMgPSAnVVMnLFxuXG4gICAgLy8gTm8gcGVyaW9kIGFmdGVyIHRoZSBwcmVmaXguXG4gICAgVUsgPSAnVUsnLFxufVxuXG4vKipcbiAqIEFuIG9wdGlvbiBpbmRpY2F0aW5nIGhvdyB0byBmb3JtYXQgYSBzdXJuYW1lLlxuICpcbiAqIFRoaXMgZW51bSBjYW4gYmUgc2V0IHZpYSBgQ29uZmlnYCBvciB3aGVuIGNyZWF0aW5nIGEgYExhc3ROYW1lYC4gQXMgdGhpcyBjYW5cbiAqIGJlY29tZSBhbWJpZ3VvdXMgYXQgdGhlIHRpbWUgb2YgaGFuZGxpbmcgaXQsIHRoZSB2YWx1ZSBzZXQgaW4gYENvbmZpZ2AgaXNcbiAqIHByaW9yaXRpemVkIGFuZCB2aWV3ZWQgYXMgdGhlIHNvdXJjZSBvZiB0cnV0aCBmb3IgZnV0dXJlIGNvbnNpZGVyYXRpb25zLlxuICovXG5leHBvcnQgZW51bSBTdXJuYW1lIHtcbiAgICAvLyBUaGUgZmF0aGVybHkgc3VybmFtZSBvbmx5LlxuICAgIEZBVEhFUiA9ICdmYXRoZXInLFxuXG4gICAgLy8gVGhlIG1vdGhlcmx5IHN1cm5hbWUgb25seS5cbiAgICBNT1RIRVIgPSAnbW90aGVyJyxcblxuICAgIC8vIFRoZSBqdW5jdGlvbiBvZiBib3RoIHRoZSBmYXRoZXJseSBhbmQgbW90aGVybHkgc3VybmFtZXMgd2l0aCBhIGh5cGhlbi5cbiAgICBIWVBIRU5BVEVEID0gJ2h5cGhlbmF0ZWQnLFxuXG4gICAgLy8gVGhlIGp1bmN0aW9uIG9mIGJvdGggdGhlIGZhdGhlcmx5IGFuZCBtb3RoZXJseSBzdXJuYW1lcyB3aXRoIGEgc3BhY2UuXG4gICAgQUxMID0gJ2FsbCcsXG59XG5cbi8qKlxuICogVGhlIG9yZGVyIG9mIGFwcGVhcmFuY2Ugb2YgYSBgRnVsbE5hbWVgLlxuICovXG5leHBvcnQgZW51bSBOYW1lT3JkZXIge1xuICAgIC8vIFRoZSBmaXJzdCBwYXJ0IG9mIGEgZnVsbCBuYW1lLCB1c3VhbGx5IHRoZSBmaXJzdCBwaWVjZSBvZiBhIHBlcnNvbiBuYW1lLlxuICAgIEZJUlNUX05BTUUgPSAnZmlyc3ROYW1lJyxcblxuICAgIC8vIFRoZSBsYXN0IHBhcnQgb2YgYSBmdWxsIG5hbWUsIHVzdWFsbHkgdGhlIGxhc3QgcGllY2Ugb2YgYSBwZXJzb24gbmFtZS5cbiAgICBMQVNUX05BTUUgPSAnbGFzdE5hbWUnLFxufVxuXG4vKipcbiAqIFRoZSB0eXBlcyBvZiBuYW1lIGhhbmRsZWQgaW4gdGhpcyBhY2NvcmRpbmcgdGhlIG5hbWUgc3RhbmRhcmRzLlxuICovXG5leHBvcnQgZW51bSBOYW1lVHlwZSB7XG4gICAgRklSU1RfTkFNRSA9ICdmaXJzdE5hbWUnLFxuICAgIE1JRERMRV9OQU1FID0gJ21pZGRsZU5hbWUnLFxuICAgIExBU1RfTkFNRSA9ICdsYXN0TmFtZScsXG4gICAgQklSVEhfTkFNRSA9ICdiaXJ0aE5hbWUnLFxufVxuXG4vKipcbiAqIFRoZSBwb3NzaWJsZSB2YXJpYW50cyB0byBpbmRpY2F0ZSBob3cgdG8gZmxhdHRlbiBhIGBGdWxsTmFtZWAuXG4gKi9cbmV4cG9ydCBlbnVtIEZsYXQge1xuICAgIC8vIFVzZSB0aGUgZmlyc3QgbmFtZSdzIGluaXRpYWwgY29tYmluZWQgd2l0aCB0aGUgcmVtYWluaW5nIHBhcnRzLlxuICAgIEZJUlNUX05BTUUgPSAnZmlyc3ROYW1lJyxcblxuICAgIC8vIFVzZSB0aGUgbWlkZGxlIG5hbWUncyBpbml0aWFsIGNvbWJpbmVkIHdpdGggdGhlIHJlbWFpbmluZyBwYXJ0cy5cbiAgICBNSURETEVfTkFNRSA9ICdtaWRkbGVOYW1lJyxcblxuICAgIC8vIFVzZSB0aGUgbGFzdCBuYW1lJ3MgaW5pdGlhbCBjb21iaW5lZCB3aXRoIHRoZSByZW1haW5pbmcgcGFydHMuXG4gICAgTEFTVF9OQU1FID0gJ2xhc3ROYW1lJyxcblxuICAgIC8vIFVzZSBib3RoIHRoZSBmaXJzdCBhbmQgbWlkZGxlIG5hbWVzJyBpbml0aWFscyBjb21iaW5lZCB3aXRoIHRoZSByZW1haW5pbmcgcGFydHMuXG4gICAgRklSU1RfTUlEID0gJ2ZpcnN0TWlkJyxcblxuICAgIC8vIFVzZSBib3RoIHRoZSBsYXN0IGFuZCBtaWRkbGUgbmFtZXMnIGluaXRpYWxzIGNvbWJpbmVkIHdpdGggdGhlIHJlbWFpbmluZyBwYXJ0cy5cbiAgICBNSURfTEFTVCA9ICdtaWRMYXN0JyxcblxuICAgIC8vIFVzZSB0aGUgZmlyc3QsIG1pZGRsZSBhbmQgbGFzdCBuYW1lcycgaW5pdGlhbHMgY29tYmluZWQgd2l0aCB0aGUgcmVtYWluaW5nIHBhcnRzLlxuICAgIEFMTCA9ICdhbGwnLFxufVxuXG4vKipcbiAqIFRoZSByYW5nZSB0byB1c2Ugd2hlbiBjYXBpdGFsaXppbmcgYSBzdHJpbmcgY29udGVudC5cbiAqL1xuZXhwb3J0IGVudW0gQ2Fwc1JhbmdlIHtcbiAgICAvLyBObyBjYXBpdGFsaXphdGlvbi5cbiAgICBOT05FLFxuXG4gICAgLy8gQXBwbHkgY2FwaXRhbGl6YXRpb24gdG8gdGhlIGZpcnN0IGxldHRlci5cbiAgICBJTklUSUFMLFxuXG4gICAgLy8gQXBwbHkgY2FwaXRhbGl6YXRpb24gdG8gYWxsIHRoZSBsZXR0ZXJzLlxuICAgIEFMTCxcbn1cblxuLyoqXG4gKiBUaGUgdHlwZXMgb2YgbmFtZSBoYW5kbGVkIGluIHRoaXMgdXRpbGl0eSBhY2NvcmRpbmcgdGhlIG5hbWUgc3RhbmRhcmRzLlxuICovXG5leHBvcnQgY2xhc3MgTmFtb24ge1xuICAgIHN0YXRpYyByZWFkb25seSBQUkVGSVggPSBuZXcgTmFtb24oMCwgJ3ByZWZpeCcpXG4gICAgc3RhdGljIHJlYWRvbmx5IEZJUlNUX05BTUUgPSBuZXcgTmFtb24oMSwgJ2ZpcnN0TmFtZScpXG4gICAgc3RhdGljIHJlYWRvbmx5IE1JRERMRV9OQU1FID0gbmV3IE5hbW9uKDIsICdtaWRkbGVOYW1lJylcbiAgICBzdGF0aWMgcmVhZG9ubHkgTEFTVF9OQU1FID0gbmV3IE5hbW9uKDMsICdsYXN0TmFtZScpXG4gICAgc3RhdGljIHJlYWRvbmx5IFNVRkZJWCA9IG5ldyBOYW1vbig0LCAnc3VmZml4JylcblxuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0IG9mIHN1cHBvcnRlZCBuYW1lIHR5cGVzLlxuICAgICAqL1xuICAgIHN0YXRpYyByZWFkb25seSB2YWx1ZXM6IE5hbW9uW10gPSBbTmFtb24uUFJFRklYLCBOYW1vbi5GSVJTVF9OQU1FLCBOYW1vbi5NSURETEVfTkFNRSwgTmFtb24uTEFTVF9OQU1FLCBOYW1vbi5TVUZGSVhdXG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHByZWRlZmluZWQgbmFtZSB0eXBlcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgcmVhZG9ubHkgYWxsID0gbmV3IE1hcDxzdHJpbmcsIE5hbW9uPihbXG4gICAgICAgIFtOYW1vbi5QUkVGSVgua2V5LCBOYW1vbi5QUkVGSVhdLFxuICAgICAgICBbTmFtb24uRklSU1RfTkFNRS5rZXksIE5hbW9uLkZJUlNUX05BTUVdLFxuICAgICAgICBbTmFtb24uTUlERExFX05BTUUua2V5LCBOYW1vbi5NSURETEVfTkFNRV0sXG4gICAgICAgIFtOYW1vbi5MQVNUX05BTUUua2V5LCBOYW1vbi5MQVNUX05BTUVdLFxuICAgICAgICBbTmFtb24uU1VGRklYLmtleSwgTmFtb24uU1VGRklYXSxcbiAgICBdKVxuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihyZWFkb25seSBpbmRleDogbnVtYmVyLCByZWFkb25seSBrZXk6IHN0cmluZykge31cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhpcyBzdHJpbmcga2V5IGlzIHBhcnQgb2YgdGhlIHByZWRlZmluZWQga2V5cy5cbiAgICAgKi9cbiAgICBzdGF0aWMgaGFzKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBOYW1vbi5hbGwuaGFzKGtleSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhIHN0cmluZyBrZXkgYSBuYW1vbiB0eXBlLlxuICAgICAqL1xuICAgIHN0YXRpYyBjYXN0KGtleTogc3RyaW5nKTogTnVsbGFibGU8TmFtb24+IHtcbiAgICAgICAgcmV0dXJuIE5hbW9uLmhhcyhrZXkpID8gTmFtb24uYWxsLmdldChrZXkpIDogdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgTmFtb24uJHt0aGlzLmtleX1gXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGlzIGFuZCB0aGUgb3RoZXIgdmFsdWUgYXJlIGVxdWFsLlxuICAgICAqL1xuICAgIGVxdWFsKG90aGVyOiBOYW1vbiB8IHVua25vd24pOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgTmFtb24gJiYgb3RoZXIuaW5kZXggPT0gdGhpcy5pbmRleCAmJiBvdGhlci5rZXkgPT0gdGhpcy5rZXlcbiAgICB9XG59XG5cbi8qKlxuICogVGhlIHRva2VuIHVzZWQgdG8gaW5kaWNhdGUgaG93IHRvIHNwbGl0IHN0cmluZyB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXBhcmF0b3Ige1xuICAgIHN0YXRpYyByZWFkb25seSBDT01NQSA9IG5ldyBTZXBhcmF0b3IoJ2NvbW1hJywgJywnKVxuICAgIHN0YXRpYyByZWFkb25seSBDT0xPTiA9IG5ldyBTZXBhcmF0b3IoJ2NvbG9uJywgJzonKVxuICAgIHN0YXRpYyByZWFkb25seSBET1VCTEVfUVVPVEUgPSBuZXcgU2VwYXJhdG9yKCdkb3VibGVRdW90ZScsICdcIicpXG4gICAgc3RhdGljIHJlYWRvbmx5IEVNUFRZID0gbmV3IFNlcGFyYXRvcignZW1wdHknLCAnJylcbiAgICBzdGF0aWMgcmVhZG9ubHkgSFlQSEVOID0gbmV3IFNlcGFyYXRvcignaHlwaGVuJywgJy0nKVxuICAgIHN0YXRpYyByZWFkb25seSBQRVJJT0QgPSBuZXcgU2VwYXJhdG9yKCdwZXJpb2QnLCAnLicpXG4gICAgc3RhdGljIHJlYWRvbmx5IFNFTUlfQ09MT04gPSBuZXcgU2VwYXJhdG9yKCdzZW1pQ29sb24nLCAnOycpXG4gICAgc3RhdGljIHJlYWRvbmx5IFNJTkdMRV9RVU9URSA9IG5ldyBTZXBhcmF0b3IoJ3NpbmdsZVF1b3RlJywgXCInXCIpXG4gICAgc3RhdGljIHJlYWRvbmx5IFNQQUNFID0gbmV3IFNlcGFyYXRvcignc3BhY2UnLCAnICcpXG4gICAgc3RhdGljIHJlYWRvbmx5IFVOREVSU0NPUkUgPSBuZXcgU2VwYXJhdG9yKCd1bmRlcnNjb3JlJywgJ18nKVxuXG4gICAgLyoqXG4gICAgICogQWxsIHRoZSBhdmFpbGFibGUgc2VwYXJhdG9ycy5cbiAgICAgKi9cbiAgICBzdGF0aWMgcmVhZG9ubHkgYWxsID0gbmV3IE1hcDxzdHJpbmcsIFNlcGFyYXRvcj4oW1xuICAgICAgICBbU2VwYXJhdG9yLkNPTU1BLm5hbWUsIFNlcGFyYXRvci5DT01NQV0sXG4gICAgICAgIFtTZXBhcmF0b3IuQ09MT04ubmFtZSwgU2VwYXJhdG9yLkNPTE9OXSxcbiAgICAgICAgW1NlcGFyYXRvci5ET1VCTEVfUVVPVEUubmFtZSwgU2VwYXJhdG9yLkRPVUJMRV9RVU9URV0sXG4gICAgICAgIFtTZXBhcmF0b3IuRU1QVFkubmFtZSwgU2VwYXJhdG9yLkVNUFRZXSxcbiAgICAgICAgW1NlcGFyYXRvci5IWVBIRU4ubmFtZSwgU2VwYXJhdG9yLkhZUEhFTl0sXG4gICAgICAgIFtTZXBhcmF0b3IuUEVSSU9ELm5hbWUsIFNlcGFyYXRvci5QRVJJT0RdLFxuICAgICAgICBbU2VwYXJhdG9yLlNFTUlfQ09MT04ubmFtZSwgU2VwYXJhdG9yLlNFTUlfQ09MT05dLFxuICAgICAgICBbU2VwYXJhdG9yLlNJTkdMRV9RVU9URS5uYW1lLCBTZXBhcmF0b3IuU0lOR0xFX1FVT1RFXSxcbiAgICAgICAgW1NlcGFyYXRvci5TUEFDRS5uYW1lLCBTZXBhcmF0b3IuU1BBQ0VdLFxuICAgICAgICBbU2VwYXJhdG9yLlVOREVSU0NPUkUubmFtZSwgU2VwYXJhdG9yLlVOREVSU0NPUkVdLFxuICAgIF0pXG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIGF2YWlsYWJsZSB0b2tlbnMuXG4gICAgICovXG4gICAgc3RhdGljIHJlYWRvbmx5IHRva2Vuczogc3RyaW5nW10gPSBbLi4uU2VwYXJhdG9yLmFsbC52YWx1ZXMoKV0ubWFwKChzKSA9PiBzLnRva2VuKVxuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihyZWFkb25seSBuYW1lOiBzdHJpbmcsIHJlYWRvbmx5IHRva2VuOiBzdHJpbmcpIHt9XG5cbiAgICAvKipcbiAgICAgKiBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuXG4gICAgICovXG4gICAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGBTZXBhcmF0b3IuJHt0aGlzLm5hbWV9YFxuICAgIH1cbn1cbiIsImltcG9ydCB7IE1JTl9OVU1CRVJfT0ZfTkFNRV9QQVJUUywgTUFYX05VTUJFUl9PRl9OQU1FX1BBUlRTIH0gZnJvbSAnLi9jb25zdGFudHMnXG5pbXBvcnQgeyBOYW1lIH0gZnJvbSAnLi9uYW1lJ1xuaW1wb3J0IHsgTmFtZU9yZGVyLCBDYXBzUmFuZ2UgfSBmcm9tICcuL3R5cGVzJ1xuXG4vKipcbiAqIEEgZml4ZWQgc2V0IG9mIHZhbHVlcyB0byBoYW5kbGUgc3BlY2lmaWMgcG9zaXRpb25zIGZvciBsaXN0IG9mIG5hbWVzLlxuICpcbiAqIEFzIGZvciBsaXN0IG9mIG5hbWVzLCB0aGlzIGhlbHBzIHRvIGZvbGxvdyBhIHNwZWNpZmljIG9yZGVyIGJhc2VkIG9uIHRoZVxuICogY291bnQgb2YgZWxlbWVudHMuIEl0IGlzIGV4cGVjdGVkIHRoYXQgdGhlIGxpc3QgaGFzIHRvIGJlIGJldHdlZW4gdHdvIGFuZFxuICogZml2ZSBlbGVtZW50cy4gQWxzbywgdGhlIG9yZGVyIG9mIGFwcGVhcmFuY2Ugc2V0IGluIHRoZSBjb25maWd1cmF0aW9uXG4gKiBpbmZsdWVuY2VzIGhvdyB0aGUgcGFyc2luZyBpcyBjYXJyaWVkIG91dC5cbiAqXG4gKiBPcmRlcmVkIGJ5IGZpcnN0IG5hbWUsIHRoZSBwYXJzZXIgd29ya3MgYXMgZm9sbG93czpcbiAqIC0gMiBlbGVtZW50czogZmlyc3ROYW1lIGxhc3ROYW1lXG4gKiAtIDMgZWxlbWVudHM6IGZpcnN0TmFtZSBtaWRkbGVOYW1lIGxhc3ROYW1lXG4gKiAtIDQgZWxlbWVudHM6IHByZWZpeCBmaXJzdE5hbWUgbWlkZGxlTmFtZSBsYXN0TmFtZVxuICogLSA1IGVsZW1lbnRzOiBwcmVmaXggZmlyc3ROYW1lIG1pZGRsZU5hbWUgbGFzdE5hbWUgc3VmZml4XG4gKlxuICogT3JkZXJlZCBieSBsYXN0IG5hbWUsIHRoZSBwYXJzZXIgd29ya3MgYXMgZm9sbG93czpcbiAqIC0gMiBlbGVtZW50czogbGFzdE5hbWUgZmlyc3ROYW1lXG4gKiAtIDMgZWxlbWVudHM6IGxhc3ROYW1lIGZpcnN0TmFtZSBtaWRkbGVOYW1lXG4gKiAtIDQgZWxlbWVudHM6IHByZWZpeCBsYXN0TmFtZSBmaXJzdE5hbWUgbWlkZGxlTmFtZVxuICogLSA1IGVsZW1lbnRzOiBwcmVmaXggbGFzdE5hbWUgZmlyc3ROYW1lIG1pZGRsZU5hbWUgc3VmZml4XG4gKlxuICogRm9yIGV4YW1wbGUsIGBKYW5lIFNtaXRoYCAob3JkZXJlZCBieSBmaXJzdCBuYW1lKSBpcyBleHBlY3RlZCB0byBiZSBpbmRleGVkOlxuICogYFsnSmFuZScsICdTbWl0aCddYC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5hbWVJbmRleCB7XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gbnVtYmVyIG9mIHBhcnRzIGluIGEgbGlzdCBvZiBuYW1lcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1pbigpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gTUlOX05VTUJFUl9PRl9OQU1FX1BBUlRTXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIHBhcnRzIGluIGEgbGlzdCBvZiBuYW1lcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IG1heCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gTUFYX05VTUJFUl9PRl9OQU1FX1BBUlRTXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICAgICAgcmVhZG9ubHkgcHJlZml4OiBudW1iZXIsXG4gICAgICAgIHJlYWRvbmx5IGZpcnN0TmFtZTogbnVtYmVyLFxuICAgICAgICByZWFkb25seSBtaWRkbGVOYW1lOiBudW1iZXIsXG4gICAgICAgIHJlYWRvbmx5IGxhc3ROYW1lOiBudW1iZXIsXG4gICAgICAgIHJlYWRvbmx5IHN1ZmZpeDogbnVtYmVyLFxuICAgICkge31cblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IG9yIGJhc2UgaW5kZXhpbmc6IGZpcnN0TmFtZSBsYXN0TmFtZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgYmFzZSgpOiBOYW1lSW5kZXgge1xuICAgICAgICByZXR1cm4gbmV3IHRoaXMoLTEsIDAsIC0xLCAxLCAtMSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBuYW1lIGluZGV4IGZvciBhIGxpc3Qgb2YgbmFtZXMgYmFzZWQgb24gdGhlIGBjb3VudGAgb2YgZWxlbWVudHNcbiAgICAgKiBhbmQgdGhlaXIgYG9yZGVyYCBvZiBhcHBlYXJhbmNlLlxuICAgICAqL1xuICAgIHN0YXRpYyB3aGVuKG9yZGVyOiBOYW1lT3JkZXIsIGNvdW50ID0gMik6IE5hbWVJbmRleCB7XG4gICAgICAgIGlmIChvcmRlciA9PSBOYW1lT3JkZXIuRklSU1RfTkFNRSkge1xuICAgICAgICAgICAgc3dpdGNoIChjb3VudCkge1xuICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gZmlyc3QgbmFtZSArIGxhc3QgbmFtZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoLTEsIDAsIC0xLCAxLCAtMSlcbiAgICAgICAgICAgICAgICBjYXNlIDM6IC8vIGZpcnN0IG5hbWUgKyBtaWRkbGUgbmFtZSArIGxhc3QgbmFtZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoLTEsIDAsIDEsIDIsIC0xKVxuICAgICAgICAgICAgICAgIGNhc2UgNDogLy8gcHJlZml4ICsgZmlyc3QgbmFtZSArIG1pZGRsZSBuYW1lICsgbGFzdCBuYW1lXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgdGhpcygwLCAxLCAyLCAzLCAtMSlcbiAgICAgICAgICAgICAgICBjYXNlIDU6IC8vIHByZWZpeCArIGZpcnN0IG5hbWUgKyBtaWRkbGUgbmFtZSArIGxhc3QgbmFtZSArIHN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoMCwgMSwgMiwgMywgNClcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTmFtZUluZGV4LmJhc2UoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3dpdGNoIChjb3VudCkge1xuICAgICAgICAgICAgICAgIGNhc2UgMjogLy8gbGFzdCBuYW1lICsgZmlyc3QgbmFtZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoLTEsIDEsIC0xLCAwLCAtMSlcbiAgICAgICAgICAgICAgICBjYXNlIDM6IC8vIGxhc3QgbmFtZSArIGZpcnN0IG5hbWUgKyBtaWRkbGUgbmFtZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoLTEsIDEsIDIsIDAsIC0xKVxuICAgICAgICAgICAgICAgIGNhc2UgNDogLy8gcHJlZml4ICsgbGFzdCBuYW1lICsgZmlyc3QgbmFtZSArIG1pZGRsZSBuYW1lXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgdGhpcygwLCAyLCAzLCAxLCAtMSlcbiAgICAgICAgICAgICAgICBjYXNlIDU6IC8vIHByZWZpeCArIGxhc3QgbmFtZSArIGZpcnN0IG5hbWUgKyBtaWRkbGUgbmFtZSArIHN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoMCwgMiwgMywgMSwgNClcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTmFtZUluZGV4LmJhc2UoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIENhcGl0YWxpemVzIGEgc3RyaW5nIHZpYSBhIGBDYXBzUmFuZ2VgIG9wdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhcGl0YWxpemUoc3RyOiBzdHJpbmcsIHJhbmdlOiBDYXBzUmFuZ2UgPSBDYXBzUmFuZ2UuSU5JVElBTCk6IHN0cmluZyB7XG4gICAgaWYgKCFzdHIgfHwgcmFuZ2UgPT09IENhcHNSYW5nZS5OT05FKSByZXR1cm4gc3RyXG4gICAgY29uc3QgaW5pdGlhbCA9IHN0clswXS50b1VwcGVyQ2FzZSgpXG4gICAgY29uc3QgcmVzdCA9IHN0ci5zbGljZSgxKS50b0xvd2VyQ2FzZSgpXG4gICAgcmV0dXJuIHJhbmdlID09PSBDYXBzUmFuZ2UuSU5JVElBTCA/IGluaXRpYWwuY29uY2F0KHJlc3QpIDogc3RyLnRvVXBwZXJDYXNlKClcbn1cblxuLyoqXG4gKiBEZWNhcGl0YWxpemVzIGEgc3RyaW5nIHZpYSBhIGBDYXBzUmFuZ2VgIG9wdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY2FwaXRhbGl6ZShzdHI6IHN0cmluZywgcmFuZ2U6IENhcHNSYW5nZSA9IENhcHNSYW5nZS5JTklUSUFMKTogc3RyaW5nIHtcbiAgICBpZiAoIXN0ciB8fCByYW5nZSA9PT0gQ2Fwc1JhbmdlLk5PTkUpIHJldHVybiBzdHJcbiAgICBjb25zdCBpbml0aWFsID0gc3RyWzBdLnRvTG93ZXJDYXNlKClcbiAgICBjb25zdCByZXN0ID0gc3RyLnNsaWNlKDEpXG4gICAgcmV0dXJuIHJhbmdlID09PSBDYXBzUmFuZ2UuSU5JVElBTCA/IGluaXRpYWwuY29uY2F0KHJlc3QpIDogc3RyLnRvTG93ZXJDYXNlKClcbn1cblxuLyoqXG4gKiBUb2dnbGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9nZ2xlQ2FzZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY2hhcnMgPSBbXVxuICAgIGZvciAoY29uc3QgYyBvZiBzdHIpIHtcbiAgICAgICAgaWYgKGMgPT09IGMudG9VcHBlckNhc2UoKSkge1xuICAgICAgICAgICAgY2hhcnMucHVzaChjLnRvTG93ZXJDYXNlKCkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjaGFycy5wdXNoKGMudG9VcHBlckNhc2UoKSlcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY2hhcnMuam9pbignJylcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nQXJyYXkodmFsdWU/OiB1bmtub3duKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA+IDAgJiYgdmFsdWUuZXZlcnkoKGUpID0+IHR5cGVvZiBlID09PSAnc3RyaW5nJylcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTmFtZUFycmF5KHZhbHVlPzogdW5rbm93bik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPiAwICYmIHZhbHVlLmV2ZXJ5KChlKSA9PiBlIGluc3RhbmNlb2YgTmFtZSlcbn1cbiIsImltcG9ydCB7IE1JTl9OVU1CRVJfT0ZfTkFNRV9QQVJUUywgTUFYX05VTUJFUl9PRl9OQU1FX1BBUlRTIH0gZnJvbSAnLi9jb25zdGFudHMnXG5pbXBvcnQgeyBJbnB1dEVycm9yLCBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuL2Vycm9yJ1xuaW1wb3J0IHsgRmlyc3ROYW1lLCBMYXN0TmFtZSwgTmFtZSB9IGZyb20gJy4vbmFtZSdcbmltcG9ydCB7IE5hbW9uIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCB7IE5hbWVJbmRleCB9IGZyb20gJy4vdXRpbHMnXG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHNldCBvZiB2YWxpZGF0aW9uIHJ1bGVzIChyZWdleClcbiAqXG4gKiBUaGlzIHJlZ2V4IGlzIGludGVudGVkIHRvIG1hdGNoIHNwZWNpZmljIGFscGhhYmV0cyBvbmx5IGFzIGEgcGVyc29uIG5hbWUgZG9lc1xuICogbm90IGNvbnRhaW4gc3BlY2lhbCBjaGFyYWN0ZXJzLiBgXFx3YCBkb2VzIG5vdCBjb3ZlciBub24tTGF0aW4gY2hhcmFjdGVycy4gU28sXG4gKiBpdCBpcyBleHRlbmRlZCB1c2luZyB1bmljb2RlIGNoYXJzIHRvIGNvdmVyIG1vcmUgY2FzZXMgKGUuZy4sIEljZWxhbmRpYykuXG4gKiBJdCBtYXRjaGVzIGFzIGZvbGxvd3M6XG4gKiAgW2Etel06IExhdGluIGFscGhhYmV0IGZyb20gYSAoaW5kZXggOTcpIHRvIHogKGluZGV4IDEyMilcbiAqICBbQS1aXTogTGF0aW4gYWxwaGFiZXQgZnJvbSBBIChpbmRleCA2NSkgdG8gWiAoaW5kZXggOTApXG4gKiAgW1xcdTAwQzAtXFx1MDBENl06IExhdGluL0dlcm1hbiBjaGFycyBmcm9tIMOAIChpbmRleCAxOTIpIHRvIMOWIChpbmRleCAyMTQpXG4gKiAgW1xcdTAwRDgtXFx1MDBmNl06IEdlcm1hbi9JY2VsYW5kaWMgY2hhcnMgZnJvbSDDmCAoaW5kZXggMjE2KSB0byDDtiAoaW5kZXggMjQ2KVxuICogIFtcXHUwMGY4LVxcdTAwZmZdOiBHZXJtYW4vSWNlbGFuZGljIGNoYXJzIGZyb20gw7ggKGluZGV4IDI0OCkgdG8gw78gKGluZGV4IDI1NSlcbiAqICBbXFx1MDQwMC1cXHUwNEZGXTogQ3lyaWxsaWMgYWxwaGFiZXQgZnJvbSDQgCAoaW5kZXggMTAyNCkgdG8g078gKGluZGV4IDEyNzkpXG4gKiAgW86GLc+JzpEtz45dOiBHcmVlayBhbHBoYWJldCBmcm9tIM6GIChpbmRleCA5MDIpIHRvIM+JIChpbmRleCA5NjkpXG4gKi9cbmNsYXNzIFZhbGlkYXRpb25SdWxlIHtcbiAgICBzdGF0aWMgYmFzZTogUmVnRXhwID0gL1thLXpBLVpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwZjZcXHUwMGY4LVxcdTAwZmZcXHUwNDAwLVxcdTA0RkbOhi3Pic6RLc+OXS9cblxuICAgIC8qKlxuICAgICAqIE1hdGNoZXMgb25lIG5hbWUgcGFydCAobmFtb24pIHRoYXQgaXMgb2YgbmF0dXJlOlxuICAgICAqIC0gTGF0aW4gKEVuZ2xpc2gsIFNwYW5pc2gsIEZyZW5jaCwgZXRjLilcbiAgICAgKiAtIEV1cm9wZWFuIChHcmVlaywgQ3lyaWxsaWMsIEljZWxhbmRpYywgR2VybWFuKVxuICAgICAqIC0gaHlwaGVuYXRlZFxuICAgICAqIC0gd2l0aCBhcG9zdHJvcGhlXG4gICAgICogLSB3aXRoIHNwYWNlXG4gICAgICovXG4gICAgc3RhdGljIG5hbW9uOiBSZWdFeHAgPSBuZXcgUmVnRXhwKFxuICAgICAgICBgXiR7VmFsaWRhdGlvblJ1bGUuYmFzZS5zb3VyY2V9KygoWycgLV0ke1ZhbGlkYXRpb25SdWxlLmJhc2Uuc291cmNlfSk/JHtWYWxpZGF0aW9uUnVsZS5iYXNlLnNvdXJjZX0qKSokYCxcbiAgICApXG5cbiAgICAvKipcbiAgICAgKiBNYXRjaGVzIG9uZSBuYW1lIHBhcnQgKG5hbW9uKSB0aGF0IGlzIG9mIG5hdHVyZTpcbiAgICAgKiAtIExhdGluIChFbmdsaXNoLCBTcGFuaXNoLCBGcmVuY2gsIGV0Yy4pXG4gICAgICogLSBFdXJvcGVhbiAoR3JlZWssIEN5cmlsbGljLCBJY2VsYW5kaWMsIEdlcm1hbilcbiAgICAgKiAtIGh5cGhlbmF0ZWRcbiAgICAgKiAtIHdpdGggYXBvc3Ryb3BoZVxuICAgICAqL1xuICAgIHN0YXRpYyBmaXJzdE5hbWU6IFJlZ0V4cCA9IFZhbGlkYXRpb25SdWxlLm5hbW9uXG5cbiAgICAvKipcbiAgICAgKiBNYXRjaGVzIDErIG5hbWVzIHBhcnQgKG5hbW9uKSB0aGF0IGFyZSBvZiBuYXR1cmU6XG4gICAgICogLSBMYXRpbiAoRW5nbGlzaCwgU3BhbmlzaCwgRnJlbmNoLCBldGMuKVxuICAgICAqIC0gRXVyb3BlYW4gKEdyZWVrLCBDeXJpbGxpYywgSWNlbGFuZGljLCBHZXJtYW4pXG4gICAgICogLSBoeXBoZW5hdGVkXG4gICAgICogLSB3aXRoIGFwb3N0cm9waGVcbiAgICAgKiAtIHdpdGggc3BhY2VcbiAgICAgKi9cbiAgICBzdGF0aWMgbWlkZGxlTmFtZTogUmVnRXhwID0gbmV3IFJlZ0V4cChcbiAgICAgICAgYF4ke1ZhbGlkYXRpb25SdWxlLmJhc2Uuc291cmNlfSsoKFsnIC1dJHtWYWxpZGF0aW9uUnVsZS5iYXNlLnNvdXJjZX0pPyR7VmFsaWRhdGlvblJ1bGUuYmFzZS5zb3VyY2V9KikqJGAsXG4gICAgKVxuXG4gICAgLyoqXG4gICAgICogTWF0Y2hlcyBvbmUgbmFtZSBwYXJ0IChuYW1vbikgdGhhdCBpcyBvZiBuYXR1cmU6XG4gICAgICogLSBMYXRpbiAoRW5nbGlzaCwgU3BhbmlzaCwgRnJlbmNoLCBldGMuKVxuICAgICAqIC0gRXVyb3BlYW4gKEdyZWVrLCBDeXJpbGxpYywgSWNlbGFuZGljLCBHZXJtYW4pXG4gICAgICogLSBoeXBoZW5hdGVkXG4gICAgICogLSB3aXRoIGFwb3N0cm9waGVcbiAgICAgKiAtIHdpdGggc3BhY2VcbiAgICAgKi9cbiAgICBzdGF0aWMgbGFzdE5hbWU6IFJlZ0V4cCA9IFZhbGlkYXRpb25SdWxlLm5hbW9uXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdG9yPFQ+IHtcbiAgICB2YWxpZGF0ZSh2YWx1ZTogVCk6IHZvaWRcbn1cblxuY2xhc3MgQXJyYXlWYWxpZGF0b3I8VCBleHRlbmRzIHN0cmluZyB8IE5hbWU+IGltcGxlbWVudHMgVmFsaWRhdG9yPFRbXT4ge1xuICAgIHZhbGlkYXRlKHZhbHVlczogVFtdKTogdm9pZCB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHZhbHVlcy5sZW5ndGggPT0gMCB8fFxuICAgICAgICAgICAgdmFsdWVzLmxlbmd0aCA8IE1JTl9OVU1CRVJfT0ZfTkFNRV9QQVJUUyB8fFxuICAgICAgICAgICAgdmFsdWVzLmxlbmd0aCA+IE1BWF9OVU1CRVJfT0ZfTkFNRV9QQVJUU1xuICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IHZhbHVlcy5tYXAoKG4pID0+IG4udG9TdHJpbmcoKSksXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogYGV4cGVjdGluZyBhIGxpc3Qgb2YgJHtNSU5fTlVNQkVSX09GX05BTUVfUEFSVFN9LSR7TUlOX05VTUJFUl9PRl9OQU1FX1BBUlRTfSBlbGVtZW50c2AsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBOYW1vblZhbGlkYXRvciBpbXBsZW1lbnRzIFZhbGlkYXRvcjxzdHJpbmcgfCBOYW1lPiB7XG4gICAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdG9yOiBOYW1vblZhbGlkYXRvclxuICAgIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuICAgIHN0YXRpYyBjcmVhdGUoKTogTmFtb25WYWxpZGF0b3Ige1xuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0b3IgfHwgKHRoaXMudmFsaWRhdG9yID0gbmV3IHRoaXMoKSlcbiAgICB9XG5cbiAgICB2YWxpZGF0ZSh2YWx1ZTogc3RyaW5nIHwgTmFtZSwgdHlwZT86IE5hbW9uKTogdm9pZCB7XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE5hbWUpIHtcbiAgICAgICAgICAgIE5hbWVWYWxpZGF0b3IuY3JlYXRlKCkudmFsaWRhdGUodmFsdWUsIHR5cGUpXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgaWYgKCFWYWxpZGF0aW9uUnVsZS5uYW1vbi50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBuYW1lVHlwZTogJ25hbW9uJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ2ludmFsaWQgY29udGVudCcsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IHR5cGVvZiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnZXhwZWN0aW5nIHR5cGVzIG9mIHN0cmluZyB8IE5hbWUnLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgRmlyc3ROYW1lVmFsaWRhdG9yIGltcGxlbWVudHMgVmFsaWRhdG9yPHN0cmluZyB8IEZpcnN0TmFtZT4ge1xuICAgIHByaXZhdGUgc3RhdGljIHZhbGlkYXRvcjogRmlyc3ROYW1lVmFsaWRhdG9yXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG4gICAgc3RhdGljIGNyZWF0ZSgpOiBGaXJzdE5hbWVWYWxpZGF0b3Ige1xuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0b3IgfHwgKHRoaXMudmFsaWRhdG9yID0gbmV3IHRoaXMoKSlcbiAgICB9XG5cbiAgICB2YWxpZGF0ZSh2YWx1ZTogc3RyaW5nIHwgRmlyc3ROYW1lKTogdm9pZCB7XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEZpcnN0TmFtZSkge1xuICAgICAgICAgICAgdmFsdWUuYXNOYW1lcy5mb3JFYWNoKChuYW1lKSA9PiB0aGlzLnZhbGlkYXRlKG5hbWUudmFsdWUpKVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmICghVmFsaWRhdGlvblJ1bGUuZmlyc3ROYW1lLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWVUeXBlOiAnZmlyc3ROYW1lJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ2ludmFsaWQgY29udGVudCcsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IHR5cGVvZiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnZXhwZWN0aW5nIHR5cGVzIHN0cmluZyB8IEZpcnN0TmFtZScsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBNaWRkbGVOYW1lVmFsaWRhdG9yIGltcGxlbWVudHMgVmFsaWRhdG9yPHN0cmluZyB8IHN0cmluZ1tdIHwgTmFtZVtdPiB7XG4gICAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdG9yOiBNaWRkbGVOYW1lVmFsaWRhdG9yXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG4gICAgc3RhdGljIGNyZWF0ZSgpOiBNaWRkbGVOYW1lVmFsaWRhdG9yIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdG9yIHx8ICh0aGlzLnZhbGlkYXRvciA9IG5ldyB0aGlzKCkpXG4gICAgfVxuXG4gICAgdmFsaWRhdGUodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdIHwgTmFtZVtdKTogdm9pZCB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoIVZhbGlkYXRpb25SdWxlLm1pZGRsZU5hbWUudGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZVR5cGU6ICdtaWRkbGVOYW1lJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ2ludmFsaWQgY29udGVudCcsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZGF0b3IgPSBOYW1vblZhbGlkYXRvci5jcmVhdGUoKVxuICAgICAgICAgICAgICAgIGZvciAobGV0IG5hbWUgb2YgdmFsdWUpIHZhbGlkYXRvci52YWxpZGF0ZShuYW1lLCBOYW1vbi5NSURETEVfTkFNRSlcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWVUeXBlOiAnbWlkZGxlTmFtZScsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yPy5tZXNzYWdlLFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW5wdXRFcnJvcih7XG4gICAgICAgICAgICAgICAgc291cmNlOiB0eXBlb2YgdmFsdWUsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ2V4cGVjdGluZyB0eXBlcyBvZiBzdHJpbmcgfCBzdHJpbmdbXSB8IE5hbWVbXScsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBMYXN0TmFtZVZhbGlkYXRvciBpbXBsZW1lbnRzIFZhbGlkYXRvcjxzdHJpbmcgfCBMYXN0TmFtZT4ge1xuICAgIHByaXZhdGUgc3RhdGljIHZhbGlkYXRvcjogTGFzdE5hbWVWYWxpZGF0b3JcbiAgICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cbiAgICBzdGF0aWMgY3JlYXRlKCk6IExhc3ROYW1lVmFsaWRhdG9yIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdG9yIHx8ICh0aGlzLnZhbGlkYXRvciA9IG5ldyB0aGlzKCkpXG4gICAgfVxuXG4gICAgdmFsaWRhdGUodmFsdWU6IHN0cmluZyB8IExhc3ROYW1lKTogdm9pZCB7XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExhc3ROYW1lKSB7XG4gICAgICAgICAgICB2YWx1ZS5hc05hbWVzLmZvckVhY2goKG5hbWUpID0+IHRoaXMudmFsaWRhdGUobmFtZS52YWx1ZSkpXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgaWYgKCFWYWxpZGF0aW9uUnVsZS5sYXN0TmFtZS50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBuYW1lVHlwZTogJ2xhc3ROYW1lJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ2ludmFsaWQgY29udGVudCcsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IHR5cGVvZiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnZXhwZWN0aW5nIHR5cGVzIHN0cmluZyB8IExhc3ROYW1lJyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIE5hbWVWYWxpZGF0b3IgaW1wbGVtZW50cyBWYWxpZGF0b3I8TmFtZT4ge1xuICAgIHByaXZhdGUgc3RhdGljIHZhbGlkYXRvcjogTmFtZVZhbGlkYXRvclxuICAgIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxuICAgIHN0YXRpYyBjcmVhdGUoKTogTmFtZVZhbGlkYXRvciB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRvciB8fCAodGhpcy52YWxpZGF0b3IgPSBuZXcgdGhpcygpKVxuICAgIH1cblxuICAgIHZhbGlkYXRlKG5hbWU6IE5hbWUsIHR5cGU/OiBOYW1vbik6IHZvaWQge1xuICAgICAgICBpZiAodHlwZSAmJiBuYW1lLnR5cGUgIT09IHR5cGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3Ioe1xuICAgICAgICAgICAgICAgIHNvdXJjZTogW25hbWVdLFxuICAgICAgICAgICAgICAgIG5hbWVUeXBlOiBuYW1lLnR5cGUudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnd3JvbmcgdHlwZScsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFWYWxpZGF0aW9uUnVsZS5uYW1vbi50ZXN0KG5hbWUudmFsdWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IFtuYW1lXSxcbiAgICAgICAgICAgICAgICBuYW1lVHlwZTogbmFtZS50eXBlLnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ2ludmFsaWQgY29udGVudCcsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgTmFtYVZhbGlkYXRvciBpbXBsZW1lbnRzIFZhbGlkYXRvcjxNYXA8TmFtb24sIHN0cmluZz4+IHtcbiAgICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0b3I6IE5hbWFWYWxpZGF0b3JcbiAgICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cbiAgICBzdGF0aWMgY3JlYXRlKCk6IE5hbWFWYWxpZGF0b3Ige1xuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0b3IgfHwgKHRoaXMudmFsaWRhdG9yID0gbmV3IHRoaXMoKSlcbiAgICB9XG5cbiAgICB2YWxpZGF0ZSh2YWx1ZTogTWFwPE5hbW9uLCBzdHJpbmc+KTogdm9pZCB7XG4gICAgICAgIHRoaXMudmFsaWRhdGVLZXlzKHZhbHVlKVxuICAgICAgICBWYWxpZGF0b3JzLmZpcnN0TmFtZS52YWxpZGF0ZSh2YWx1ZS5nZXQoTmFtb24uRklSU1RfTkFNRSkpXG4gICAgICAgIFZhbGlkYXRvcnMubGFzdE5hbWUudmFsaWRhdGUodmFsdWUuZ2V0KE5hbW9uLkxBU1RfTkFNRSkpXG5cbiAgICAgICAgaWYgKHZhbHVlLmhhcyhOYW1vbi5QUkVGSVgpKSB7XG4gICAgICAgICAgICBWYWxpZGF0b3JzLm5hbW9uLnZhbGlkYXRlKHZhbHVlLmdldChOYW1vbi5QUkVGSVgpKVxuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZS5oYXMoTmFtb24uU1VGRklYKSkge1xuICAgICAgICAgICAgVmFsaWRhdG9ycy5uYW1vbi52YWxpZGF0ZSh2YWx1ZS5nZXQoTmFtb24uU1VGRklYKSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhbGlkYXRlS2V5cyhuYW1hOiBNYXA8TmFtb24sIHN0cmluZz4pOiB2b2lkIHtcbiAgICAgICAgaWYgKCFuYW1hLnNpemUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHsgc291cmNlOiB1bmRlZmluZWQsIG1lc3NhZ2U6ICdNYXA8ayx2PiBtdXN0IG5vdCBiZSBlbXB0eScgfSlcbiAgICAgICAgfSBlbHNlIGlmIChuYW1hLnNpemUgPCBNSU5fTlVNQkVSX09GX05BTUVfUEFSVFMgfHwgbmFtYS5zaXplID4gTUFYX05VTUJFUl9PRl9OQU1FX1BBUlRTKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW5wdXRFcnJvcih7XG4gICAgICAgICAgICAgICAgc291cmNlOiBbLi4ubmFtYS52YWx1ZXMoKV0sXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogYGV4cGVjdGluZyAke01JTl9OVU1CRVJfT0ZfTkFNRV9QQVJUU30tJHtNSU5fTlVNQkVSX09GX05BTUVfUEFSVFN9IGZpZWxkc2AsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFuYW1hLmhhcyhOYW1vbi5GSVJTVF9OQU1FKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IElucHV0RXJyb3Ioe1xuICAgICAgICAgICAgICAgIHNvdXJjZTogWy4uLm5hbWEudmFsdWVzKCldLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdcImZpcnN0TmFtZVwiIGlzIGEgcmVxdWlyZWQga2V5JyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW5hbWEuaGFzKE5hbW9uLkxBU1RfTkFNRSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IFsuLi5uYW1hLnZhbHVlcygpXSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnXCJsYXN0TmFtZVwiIGlzIGEgcmVxdWlyZWQga2V5JyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBcnJheVN0cmluZ1ZhbGlkYXRvciBleHRlbmRzIEFycmF5VmFsaWRhdG9yPHN0cmluZz4ge1xuICAgIGNvbnN0cnVjdG9yKHJlYWRvbmx5IGluZGV4ID0gTmFtZUluZGV4LmJhc2UoKSkge1xuICAgICAgICBzdXBlcigpXG4gICAgfVxuXG4gICAgdmFsaWRhdGUodmFsdWVzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLnZhbGlkYXRlSW5kZXgodmFsdWVzKVxuXG4gICAgICAgIHN3aXRjaCAodmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIFZhbGlkYXRvcnMuZmlyc3ROYW1lLnZhbGlkYXRlKHZhbHVlc1t0aGlzLmluZGV4LmZpcnN0TmFtZV0pXG4gICAgICAgICAgICAgICAgVmFsaWRhdG9ycy5sYXN0TmFtZS52YWxpZGF0ZSh2YWx1ZXNbdGhpcy5pbmRleC5sYXN0TmFtZV0pXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBWYWxpZGF0b3JzLmZpcnN0TmFtZS52YWxpZGF0ZSh2YWx1ZXNbdGhpcy5pbmRleC5maXJzdE5hbWVdKVxuICAgICAgICAgICAgICAgIFZhbGlkYXRvcnMubWlkZGxlTmFtZS52YWxpZGF0ZSh2YWx1ZXNbdGhpcy5pbmRleC5taWRkbGVOYW1lXSlcbiAgICAgICAgICAgICAgICBWYWxpZGF0b3JzLmxhc3ROYW1lLnZhbGlkYXRlKHZhbHVlc1t0aGlzLmluZGV4Lmxhc3ROYW1lXSlcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIFZhbGlkYXRvcnMubmFtb24udmFsaWRhdGUodmFsdWVzW3RoaXMuaW5kZXgucHJlZml4XSlcbiAgICAgICAgICAgICAgICBWYWxpZGF0b3JzLmZpcnN0TmFtZS52YWxpZGF0ZSh2YWx1ZXNbdGhpcy5pbmRleC5maXJzdE5hbWVdKVxuICAgICAgICAgICAgICAgIFZhbGlkYXRvcnMubWlkZGxlTmFtZS52YWxpZGF0ZSh2YWx1ZXNbdGhpcy5pbmRleC5taWRkbGVOYW1lXSlcbiAgICAgICAgICAgICAgICBWYWxpZGF0b3JzLmxhc3ROYW1lLnZhbGlkYXRlKHZhbHVlc1t0aGlzLmluZGV4Lmxhc3ROYW1lXSlcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIFZhbGlkYXRvcnMubmFtb24udmFsaWRhdGUodmFsdWVzW3RoaXMuaW5kZXgucHJlZml4XSlcbiAgICAgICAgICAgICAgICBWYWxpZGF0b3JzLmZpcnN0TmFtZS52YWxpZGF0ZSh2YWx1ZXNbdGhpcy5pbmRleC5maXJzdE5hbWVdKVxuICAgICAgICAgICAgICAgIFZhbGlkYXRvcnMubWlkZGxlTmFtZS52YWxpZGF0ZSh2YWx1ZXNbdGhpcy5pbmRleC5taWRkbGVOYW1lXSlcbiAgICAgICAgICAgICAgICBWYWxpZGF0b3JzLmxhc3ROYW1lLnZhbGlkYXRlKHZhbHVlc1t0aGlzLmluZGV4Lmxhc3ROYW1lXSlcbiAgICAgICAgICAgICAgICBWYWxpZGF0b3JzLm5hbW9uLnZhbGlkYXRlKHZhbHVlc1t0aGlzLmluZGV4LnN1ZmZpeF0pXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhbGlkYXRlSW5kZXgodmFsdWVzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgICAgICBzdXBlci52YWxpZGF0ZSh2YWx1ZXMpXG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQXJyYXlOYW1lVmFsaWRhdG9yIGltcGxlbWVudHMgVmFsaWRhdG9yPE5hbWVbXT4ge1xuICAgIHByaXZhdGUgc3RhdGljIHZhbGlkYXRvcjogQXJyYXlOYW1lVmFsaWRhdG9yXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG4gICAgc3RhdGljIGNyZWF0ZSgpOiBBcnJheU5hbWVWYWxpZGF0b3Ige1xuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0b3IgfHwgKHRoaXMudmFsaWRhdG9yID0gbmV3IHRoaXMoKSlcbiAgICB9XG5cbiAgICB2YWxpZGF0ZSh2YWx1ZTogTmFtZVtdKTogdm9pZCB7XG4gICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPCBNSU5fTlVNQkVSX09GX05BTUVfUEFSVFMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IHZhbHVlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBleHBlY3RpbmcgYXQgbGVhc3QgJHtNSU5fTlVNQkVSX09GX05BTUVfUEFSVFN9IGVsZW1lbnRzYCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuaGFzQmFzaWNOYW1lcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnB1dEVycm9yKHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IHZhbHVlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdib3RoIGZpcnN0IGFuZCBsYXN0IG5hbWVzIGFyZSByZXF1aXJlZCcsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoYXNCYXNpY05hbWVzKG5hbWVzOiBOYW1lW10pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgYWNjdW11bGF0b3I6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fVxuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgbmFtZXMpIHtcbiAgICAgICAgICAgIGlmIChuYW1lLmlzRmlyc3ROYW1lIHx8IG5hbWUuaXNMYXN0TmFtZSkge1xuICAgICAgICAgICAgICAgIGFjY3VtdWxhdG9yW25hbWUudHlwZS5rZXldID0gbmFtZS50b1N0cmluZygpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGFjY3VtdWxhdG9yKS5sZW5ndGggPT0gTUlOX05VTUJFUl9PRl9OQU1FX1BBUlRTXG4gICAgfVxufVxuXG4vKipcbiAqIEEgbGlzdCBvZiB2YWxpZGF0b3JzIGZvciBhIHNwZWNpZmljIG5hbW9uLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVmFsaWRhdG9ycyB7XG4gICAgc3RhdGljIG5hbW9uID0gTmFtb25WYWxpZGF0b3IuY3JlYXRlKClcbiAgICBzdGF0aWMgbmFtYSA9IE5hbWFWYWxpZGF0b3IuY3JlYXRlKClcbiAgICBzdGF0aWMgcHJlZml4ID0gTmFtb25WYWxpZGF0b3IuY3JlYXRlKClcbiAgICBzdGF0aWMgZmlyc3ROYW1lID0gRmlyc3ROYW1lVmFsaWRhdG9yLmNyZWF0ZSgpXG4gICAgc3RhdGljIG1pZGRsZU5hbWUgPSBNaWRkbGVOYW1lVmFsaWRhdG9yLmNyZWF0ZSgpXG4gICAgc3RhdGljIGxhc3ROYW1lID0gTGFzdE5hbWVWYWxpZGF0b3IuY3JlYXRlKClcbiAgICBzdGF0aWMgc3VmZml4ID0gTmFtb25WYWxpZGF0b3IuY3JlYXRlKClcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=
|