@appium/base-driver 8.7.1 → 8.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/build/lib/basedriver/capabilities.d.ts +207 -42
  2. package/build/lib/basedriver/capabilities.d.ts.map +1 -1
  3. package/build/lib/basedriver/capabilities.js +39 -44
  4. package/build/lib/basedriver/capabilities.js.map +1 -0
  5. package/build/lib/basedriver/commands/event.js +3 -3
  6. package/build/lib/basedriver/commands/event.js.map +1 -0
  7. package/build/lib/basedriver/commands/execute.js +3 -3
  8. package/build/lib/basedriver/commands/execute.js.map +1 -0
  9. package/build/lib/basedriver/commands/find.js.map +1 -0
  10. package/build/lib/basedriver/commands/index.js.map +1 -0
  11. package/build/lib/basedriver/commands/log.js +3 -3
  12. package/build/lib/basedriver/commands/log.js.map +1 -0
  13. package/build/lib/basedriver/commands/session.js +3 -3
  14. package/build/lib/basedriver/commands/session.js.map +1 -0
  15. package/build/lib/basedriver/commands/settings.js.map +1 -0
  16. package/build/lib/basedriver/commands/timeout.js +3 -3
  17. package/build/lib/basedriver/commands/timeout.js.map +1 -0
  18. package/build/lib/basedriver/core.d.ts +171 -20
  19. package/build/lib/basedriver/core.d.ts.map +1 -1
  20. package/build/lib/basedriver/core.js +4 -6
  21. package/build/lib/basedriver/core.js.map +1 -0
  22. package/build/lib/basedriver/desired-caps.d.ts +0 -2
  23. package/build/lib/basedriver/desired-caps.d.ts.map +1 -1
  24. package/build/lib/basedriver/desired-caps.js +4 -53
  25. package/build/lib/basedriver/desired-caps.js.map +1 -0
  26. package/build/lib/basedriver/device-settings.js +3 -3
  27. package/build/lib/basedriver/device-settings.js.map +1 -0
  28. package/build/lib/basedriver/driver.d.ts +323 -28
  29. package/build/lib/basedriver/driver.d.ts.map +1 -1
  30. package/build/lib/basedriver/driver.js +27 -30
  31. package/build/lib/basedriver/driver.js.map +1 -0
  32. package/build/lib/basedriver/helpers.d.ts +1 -1
  33. package/build/lib/basedriver/helpers.d.ts.map +1 -1
  34. package/build/lib/basedriver/helpers.js +3 -3
  35. package/build/lib/basedriver/helpers.js.map +1 -0
  36. package/build/lib/basedriver/logger.js.map +1 -0
  37. package/build/lib/constants.js.map +1 -0
  38. package/build/lib/express/crash.js.map +1 -0
  39. package/build/lib/express/express-logging.js +3 -3
  40. package/build/lib/express/express-logging.js.map +1 -0
  41. package/build/lib/express/idempotency.js +3 -3
  42. package/build/lib/express/idempotency.js.map +1 -0
  43. package/build/lib/express/logger.js.map +1 -0
  44. package/build/lib/express/middleware.js +3 -3
  45. package/build/lib/express/middleware.js.map +1 -0
  46. package/build/lib/express/server.js +3 -3
  47. package/build/lib/express/server.js.map +1 -0
  48. package/build/lib/express/static.js +3 -3
  49. package/build/lib/express/static.js.map +1 -0
  50. package/build/lib/express/websocket.js +3 -3
  51. package/build/lib/express/websocket.js.map +1 -0
  52. package/build/lib/helpers/capabilities.d.ts +66 -5
  53. package/build/lib/helpers/capabilities.d.ts.map +1 -1
  54. package/build/lib/helpers/capabilities.js +7 -7
  55. package/build/lib/helpers/capabilities.js.map +1 -0
  56. package/build/lib/index.d.ts +1 -1
  57. package/build/lib/index.d.ts.map +1 -1
  58. package/build/lib/index.js +10 -3
  59. package/build/lib/index.js.map +1 -0
  60. package/build/lib/jsonwp-proxy/protocol-converter.js +3 -3
  61. package/build/lib/jsonwp-proxy/protocol-converter.js.map +1 -0
  62. package/build/lib/jsonwp-proxy/proxy.js +3 -3
  63. package/build/lib/jsonwp-proxy/proxy.js.map +1 -0
  64. package/build/lib/jsonwp-status/status.js +3 -3
  65. package/build/lib/jsonwp-status/status.js.map +1 -0
  66. package/build/lib/protocol/errors.js +3 -3
  67. package/build/lib/protocol/errors.js.map +1 -0
  68. package/build/lib/protocol/helpers.js +3 -3
  69. package/build/lib/protocol/helpers.js.map +1 -0
  70. package/build/lib/protocol/index.js.map +1 -0
  71. package/build/lib/protocol/protocol.js +3 -3
  72. package/build/lib/protocol/protocol.js.map +1 -0
  73. package/build/lib/protocol/routes.js +3 -3
  74. package/build/lib/protocol/routes.js.map +1 -0
  75. package/build/lib/protocol/validators.js +3 -3
  76. package/build/lib/protocol/validators.js.map +1 -0
  77. package/build/tsconfig.tsbuildinfo +1 -1
  78. package/lib/basedriver/capabilities.js +151 -93
  79. package/lib/basedriver/core.js +34 -18
  80. package/lib/basedriver/desired-caps.js +1 -53
  81. package/lib/basedriver/driver.js +113 -51
  82. package/lib/helpers/capabilities.js +19 -9
  83. package/lib/index.js +1 -0
  84. package/package.json +9 -10
@@ -1,69 +1,234 @@
1
- export type W3CCapabilities = import('@appium/types').W3CCapabilities;
1
+ /**
2
+ * Standard, non-prefixed capabilities
3
+ * @see https://www.w3.org/TR/webdriver/#dfn-table-of-standard-capabilities)
4
+ */
5
+ export const STANDARD_CAPS: Readonly<Set<keyof import("@wdio/types/build/Capabilities").Capabilities>>;
2
6
  export type Constraints = import('@appium/types').Constraints;
3
- export type Capabilities = import('@appium/types').Capabilities;
7
+ export type Constraint = import('@appium/types').Constraint;
8
+ export type StringRecord = import('@appium/types').StringRecord;
9
+ export type BaseDriverCapConstraints = import('@appium/types').BaseDriverCapConstraints;
4
10
  export type ValidateCapsOpts = {
5
11
  /**
6
12
  * - if true, skip the presence constraint
7
13
  */
8
14
  skipPresenceConstraint?: boolean | undefined;
9
15
  };
16
+ export type NSCapabilities<C extends Readonly<Record<string, import("@appium/types").Constraint>> = {
17
+ readonly platformName: {
18
+ readonly presence: true;
19
+ readonly isString: true;
20
+ };
21
+ readonly app: {
22
+ readonly isString: true;
23
+ };
24
+ readonly deviceName: {
25
+ readonly isString: true;
26
+ };
27
+ readonly platformVersion: {
28
+ readonly isString: true;
29
+ };
30
+ readonly newCommandTimeout: {
31
+ readonly isNumber: true;
32
+ };
33
+ readonly automationName: {
34
+ readonly isString: true;
35
+ };
36
+ readonly autoLaunch: {
37
+ readonly isBoolean: true;
38
+ };
39
+ readonly udid: {
40
+ readonly isString: true;
41
+ };
42
+ readonly orientation: {
43
+ readonly inclusion: readonly ["LANDSCAPE", "PORTRAIT"];
44
+ };
45
+ readonly autoWebview: {
46
+ readonly isBoolean: true;
47
+ };
48
+ readonly noReset: {
49
+ readonly isBoolean: true;
50
+ };
51
+ readonly fullReset: {
52
+ readonly isBoolean: true;
53
+ };
54
+ readonly language: {
55
+ readonly isString: true;
56
+ };
57
+ readonly locale: {
58
+ readonly isString: true;
59
+ };
60
+ readonly eventTimings: {
61
+ readonly isBoolean: true;
62
+ };
63
+ readonly printPageSourceOnFindFailure: {
64
+ readonly isBoolean: true;
65
+ };
66
+ }, Extra extends void | import("@appium/types").StringRecord = void> = import('@appium/types').NSCapabilities<C, Extra>;
67
+ export type Capabilities<C extends Readonly<Record<string, import("@appium/types").Constraint>> = {
68
+ readonly platformName: {
69
+ readonly presence: true;
70
+ readonly isString: true;
71
+ };
72
+ readonly app: {
73
+ readonly isString: true;
74
+ };
75
+ readonly deviceName: {
76
+ readonly isString: true;
77
+ };
78
+ readonly platformVersion: {
79
+ readonly isString: true;
80
+ };
81
+ readonly newCommandTimeout: {
82
+ readonly isNumber: true;
83
+ };
84
+ readonly automationName: {
85
+ readonly isString: true;
86
+ };
87
+ readonly autoLaunch: {
88
+ readonly isBoolean: true;
89
+ };
90
+ readonly udid: {
91
+ readonly isString: true;
92
+ };
93
+ readonly orientation: {
94
+ readonly inclusion: readonly ["LANDSCAPE", "PORTRAIT"];
95
+ };
96
+ readonly autoWebview: {
97
+ readonly isBoolean: true;
98
+ };
99
+ readonly noReset: {
100
+ readonly isBoolean: true;
101
+ };
102
+ readonly fullReset: {
103
+ readonly isBoolean: true;
104
+ };
105
+ readonly language: {
106
+ readonly isString: true;
107
+ };
108
+ readonly locale: {
109
+ readonly isString: true;
110
+ };
111
+ readonly eventTimings: {
112
+ readonly isBoolean: true;
113
+ };
114
+ readonly printPageSourceOnFindFailure: {
115
+ readonly isBoolean: true;
116
+ };
117
+ }, Extra extends void | import("@appium/types").StringRecord = void> = import('@appium/types').Capabilities<C, Extra>;
118
+ export type W3CCapabilities<C extends Readonly<Record<string, import("@appium/types").Constraint>> = {
119
+ readonly platformName: {
120
+ readonly presence: true;
121
+ readonly isString: true;
122
+ };
123
+ readonly app: {
124
+ readonly isString: true;
125
+ };
126
+ readonly deviceName: {
127
+ readonly isString: true;
128
+ };
129
+ readonly platformVersion: {
130
+ readonly isString: true;
131
+ };
132
+ readonly newCommandTimeout: {
133
+ readonly isNumber: true;
134
+ };
135
+ readonly automationName: {
136
+ readonly isString: true;
137
+ };
138
+ readonly autoLaunch: {
139
+ readonly isBoolean: true;
140
+ };
141
+ readonly udid: {
142
+ readonly isString: true;
143
+ };
144
+ readonly orientation: {
145
+ readonly inclusion: readonly ["LANDSCAPE", "PORTRAIT"];
146
+ };
147
+ readonly autoWebview: {
148
+ readonly isBoolean: true;
149
+ };
150
+ readonly noReset: {
151
+ readonly isBoolean: true;
152
+ };
153
+ readonly fullReset: {
154
+ readonly isBoolean: true;
155
+ };
156
+ readonly language: {
157
+ readonly isString: true;
158
+ };
159
+ readonly locale: {
160
+ readonly isString: true;
161
+ };
162
+ readonly eventTimings: {
163
+ readonly isBoolean: true;
164
+ };
165
+ readonly printPageSourceOnFindFailure: {
166
+ readonly isBoolean: true;
167
+ };
168
+ }, Extra extends void | import("@appium/types").StringRecord = void> = import('@appium/types').W3CCapabilities<C, Extra>;
10
169
  /**
11
- *
12
- * @param {W3CCapabilities} caps
13
- * @param {Constraints} [constraints]
170
+ * Parse capabilities
171
+ * @template {Constraints} [C={}]
172
+ * @param {import('@appium/types').W3CCapabilities<C>} caps
173
+ * @param {C} [constraints]
14
174
  * @param {boolean} [shouldValidateCaps]
15
- * @returns
175
+ * @see https://www.w3.org/TR/webdriver/#processing-capabilities
16
176
  */
17
- export function parseCaps(caps: W3CCapabilities, constraints?: import("@appium/types").Constraints | undefined, shouldValidateCaps?: boolean | undefined): {
18
- requiredCaps: Partial<import("@wdio/types/build/Capabilities").Capabilities & import("@wdio/types/build/Capabilities").AppiumW3CCapabilities & {
19
- [x: `${string}:${string}`]: any;
20
- }>;
21
- allFirstMatchCaps: Partial<import("@wdio/types/build/Capabilities").Capabilities & import("@wdio/types/build/Capabilities").AppiumW3CCapabilities & {
22
- [x: `${string}:${string}`]: any;
23
- }>[];
24
- validatedFirstMatchCaps: Partial<import("@wdio/types/build/Capabilities").Capabilities & import("@wdio/types/build/Capabilities").AppiumCapabilities & {
25
- [x: string]: any;
26
- }>[];
27
- matchedCaps: Partial<import("@wdio/types/build/Capabilities").Capabilities & import("@wdio/types/build/Capabilities").AppiumCapabilities & {
28
- [x: string]: any;
29
- }> | null;
30
- validationErrors: any[];
177
+ export function parseCaps<C extends Readonly<Record<string, import("@appium/types").Constraint>> = {}>(caps: import("@appium/types").W3CCapabilities<C, void>, constraints?: C | undefined, shouldValidateCaps?: boolean | undefined): {
178
+ requiredCaps: {};
179
+ allFirstMatchCaps: Partial<import("@appium/types").CapsToNSCaps<import("@appium/types").ConstraintsToCaps<C> & void, "appium">>[] | {}[];
180
+ validatedFirstMatchCaps: Partial<import("@appium/types").ConstraintsToCaps<C> & void>[];
181
+ matchedCaps: import("type-fest").Simplify<(import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>> extends infer T ? { [Key in keyof T as import("type-fest/source/enforce-optional").RequiredFilter<import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>>, Key>]: (import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>>)[Key]; } : never) & (import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>> extends infer T_1 ? { [Key_1 in keyof T_1 as import("type-fest/source/enforce-optional").OptionalFilter<import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>>, Key_1>]?: Exclude<(import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<{}> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<C> & void>>>)[Key_1], undefined> | undefined; } : never)> | null;
182
+ validationErrors: string[];
31
183
  };
32
184
  /**
33
- *
34
- * @param {W3CCapabilities} w3cCaps
35
- * @param {Constraints} [constraints]
185
+ * @template {Constraints} C
186
+ * @param {import('@appium/types').W3CCapabilities<C>} w3cCaps
187
+ * @param {C} [constraints]
36
188
  * @param {boolean} [shouldValidateCaps]
37
- * @returns {Capabilities}
189
+ * @returns {import('@appium/types').Capabilities<C>}
38
190
  */
39
- export function processCapabilities(w3cCaps: W3CCapabilities, constraints?: import("@appium/types").Constraints | undefined, shouldValidateCaps?: boolean | undefined): Capabilities;
191
+ export function processCapabilities<C extends Readonly<Record<string, import("@appium/types").Constraint>>>(w3cCaps: import("@appium/types").W3CCapabilities<C, void>, constraints?: C | undefined, shouldValidateCaps?: boolean | undefined): Partial<import("@appium/types").ConstraintsToCaps<C> & void>;
40
192
  /**
41
- *
42
- * @param {Capabilities} caps
43
- * @param {Constraints} [constraints]
193
+ * @template {Constraints} [C={}]
194
+ * @param {Capabilities<C>} caps
195
+ * @param {C} [constraints]
44
196
  * @param {ValidateCapsOpts} [opts]
45
- * @returns {Capabilities}
197
+ * @returns {Capabilities<C>}
46
198
  */
47
- export function validateCaps(caps: Capabilities, constraints?: import("@appium/types").Constraints | undefined, opts?: ValidateCapsOpts | undefined): Capabilities;
199
+ export function validateCaps<C extends Readonly<Record<string, import("@appium/types").Constraint>> = {}>(caps: Partial<import("@appium/types").ConstraintsToCaps<C> & void>, constraints?: C | undefined, opts?: ValidateCapsOpts | undefined): Partial<import("@appium/types").ConstraintsToCaps<C> & void>;
48
200
  /**
49
- * @param {Capabilities} [primary]
50
- * @param {Capabilities} [secondary]
51
- * @returns {Capabilities}
201
+ * Takes primary caps object and merges it into a secondary caps object.
202
+ * @template {Constraints} [T={}]
203
+ * @template {Constraints} [U={}]
204
+ * @param {Capabilities<T>} [primary]
205
+ * @param {Capabilities<U>} [secondary]
206
+ * @returns {import('type-fest').Merge<Capabilities<T>, Capabilities<U>>}
207
+ * @see https://www.w3.org/TR/webdriver/#dfn-merging-capabilities)
52
208
  */
53
- export function mergeCaps(primary?: Partial<import("@wdio/types/build/Capabilities").Capabilities & import("@wdio/types/build/Capabilities").AppiumCapabilities & {
54
- [x: string]: any;
55
- }> | undefined, secondary?: Partial<import("@wdio/types/build/Capabilities").Capabilities & import("@wdio/types/build/Capabilities").AppiumCapabilities & {
56
- [x: string]: any;
57
- }> | undefined): Capabilities;
209
+ export function mergeCaps<T extends Readonly<Record<string, import("@appium/types").Constraint>> = {}, U extends Readonly<Record<string, import("@appium/types").Constraint>> = {}>(primary?: Partial<import("@appium/types").ConstraintsToCaps<T> & void> | undefined, secondary?: Partial<import("@appium/types").ConstraintsToCaps<U> & void> | undefined): import("type-fest").Simplify<(import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>> extends infer T_1 ? { [Key in keyof T_1 as import("type-fest/source/enforce-optional").RequiredFilter<import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>>, Key>]: (import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>>)[Key]; } : never) & (import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>> extends infer T_2 ? { [Key_1 in keyof T_2 as import("type-fest/source/enforce-optional").OptionalFilter<import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>>, Key_1>]?: Exclude<(import("type-fest/source/merge").SimpleMerge<import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").PickIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>> & import("type-fest/source/merge").SimpleMerge<import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<T> & void>>, import("type-fest").OmitIndexSignature<Partial<import("@appium/types").ConstraintsToCaps<U> & void>>>)[Key_1], undefined> | undefined; } : never)>;
58
210
  export const APPIUM_VENDOR_PREFIX: "appium:";
59
211
  export const APPIUM_OPTS_CAP: "options";
60
212
  /**
61
213
  * Get an array of all the unprefixed caps that are being used in 'alwaysMatch' and all of the 'firstMatch' object
62
- * @param {Object} caps A capabilities object
214
+ * @template {Constraints} [C={}]
215
+ * @param {import('@appium/types').W3CCapabilities<C>} caps A capabilities object
216
+ */
217
+ export function findNonPrefixedCaps<C extends Readonly<Record<string, import("@appium/types").Constraint>> = {}>({ alwaysMatch, firstMatch }: import("@appium/types").W3CCapabilities<C, void>): string[];
218
+ /**
219
+ * @param {string} cap
220
+ * @returns {boolean}
221
+ */
222
+ export function isStandardCap(cap: string): boolean;
223
+ /**
224
+ * If the 'appium:' prefix was provided and it's a valid capability, strip out the prefix
225
+ * @template {Constraints} [C={}]
226
+ * @param {import('@appium/types').NSCapabilities<C>} caps
227
+ * @see https://www.w3.org/TR/webdriver/#dfn-extension-capabilities
228
+ * @internal
229
+ * @returns {import('@appium/types').Capabilities<C>}
63
230
  */
64
- export function findNonPrefixedCaps({ alwaysMatch, firstMatch }: any): string[];
65
- export function isStandardCap(cap: any): boolean;
66
- export function stripAppiumPrefixes(caps: any): void;
231
+ export function stripAppiumPrefixes<C extends Readonly<Record<string, import("@appium/types").Constraint>> = {}>(caps: Partial<import("@appium/types").CapsToNSCaps<import("@appium/types").ConstraintsToCaps<C> & void, "appium">>): Partial<import("@appium/types").ConstraintsToCaps<C> & void>;
67
232
  /**
68
233
  * Return a copy of a capabilities object which has taken everything within the 'options'
69
234
  * capability and promoted it to the top level. Note that this function is assumed to be run after
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../lib/basedriver/capabilities.js"],"names":[],"mappings":"8BAiWa,OAAO,eAAe,EAAE,eAAe;0BACvC,OAAO,eAAe,EAAE,WAAW;2BACnC,OAAO,eAAe,EAAE,YAAY;;;;;;;AAtMjD;;;;;;GAMG;AACH,gCALW,eAAe;;;;;;;;;;;;;;EA0GzB;AAGD;;;;;;GAMG;AACH,6CALW,eAAe,4GAGb,YAAY,CAqBxB;AAhQD;;;;;;GAMG;AACH,mCALW,YAAY,uGAGV,YAAY,CAkCxB;AA/DD;;;;GAIG;AACH;;;;iBAFa,YAAY,CAkBxB;AA3BD,6CAAuC;AACvC,wCAAkC;AAkIlC;;;GAGG;AACH,gFAWC;AA9DD,iDAKC;AAID,qDAoCC;AA+JD;;;;;;;;;;GAUG;AACH,mDAHW,MAAM,GACL,MAAM,CA+BjB;AAtUD,8CAA6E"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../lib/basedriver/capabilities.js"],"names":[],"mappings":"AA2FA;;;GAGG;AACH,uGAcE;0BA2RW,OAAO,eAAe,EAAE,WAAW;yBACnC,OAAO,eAAe,EAAE,UAAU;2BAClC,OAAO,eAAe,EAAE,YAAY;uCACpC,OAAO,eAAe,EAAE,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAWhD,OAAO,eAAe,EAAE,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAMhD,OAAO,eAAe,EAAE,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAM9C,OAAO,eAAe,EAAE,eAAe,CAAC,CAAC,EAAE,KAAK,CAAC;AAhO9D;;;;;;;GAOG;AACH;;;;;;EAmGC;AAGD;;;;;;GAMG;AACH,4SAuBC;AApSD;;;;;;GAMG;AACH,8SAwCC;AA7ED;;;;;;;;GAQG;AACH,kmHAkBC;AA/BD,6CAAuC;AACvC,wCAAkC;AAuKlC;;;;GAIG;AACH,0MAWC;AA/ED;;;GAGG;AACH,mCAHW,MAAM,GACJ,OAAO,CAInB;AAED;;;;;;;GAOG;AACH,mSA6CC;AAkKD;;;;;;;;;;GAUG;AACH,mDAHW,MAAM,GACL,MAAM,CA8BjB;AA7WD,8CAA6E"}
@@ -1,11 +1,9 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
3
  Object.defineProperty(exports, "__esModule", {
6
4
  value: true
7
5
  });
8
- exports.PREFIXED_APPIUM_OPTS_CAP = exports.APPIUM_VENDOR_PREFIX = exports.APPIUM_OPTS_CAP = void 0;
6
+ exports.STANDARD_CAPS = exports.PREFIXED_APPIUM_OPTS_CAP = exports.APPIUM_VENDOR_PREFIX = exports.APPIUM_OPTS_CAP = void 0;
9
7
  exports.findNonPrefixedCaps = findNonPrefixedCaps;
10
8
  exports.isStandardCap = isStandardCap;
11
9
  exports.mergeCaps = mergeCaps;
@@ -27,6 +25,8 @@ var _logger = _interopRequireDefault(require("./logger"));
27
25
 
28
26
  var _errors = require("../protocol/errors");
29
27
 
28
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
+
30
30
  const APPIUM_VENDOR_PREFIX = 'appium:';
31
31
  exports.APPIUM_VENDOR_PREFIX = APPIUM_VENDOR_PREFIX;
32
32
  const APPIUM_OPTS_CAP = 'options';
@@ -35,7 +35,8 @@ const PREFIXED_APPIUM_OPTS_CAP = `${APPIUM_VENDOR_PREFIX}${APPIUM_OPTS_CAP}`;
35
35
  exports.PREFIXED_APPIUM_OPTS_CAP = PREFIXED_APPIUM_OPTS_CAP;
36
36
 
37
37
  function mergeCaps(primary = {}, secondary = {}) {
38
- let result = Object.assign({}, primary);
38
+ let result = { ...primary
39
+ };
39
40
 
40
41
  for (let [name, value] of _lodash.default.toPairs(secondary)) {
41
42
  if (!_lodash.default.isUndefined(primary[name])) {
@@ -57,15 +58,19 @@ function validateCaps(caps, constraints = {}, opts = {}) {
57
58
  throw new _errors.errors.InvalidArgumentError(`must be a JSON object`);
58
59
  }
59
60
 
60
- constraints = _lodash.default.cloneDeep(constraints);
61
-
62
- if (skipPresenceConstraint) {
63
- for (let key of _lodash.default.keys(constraints)) {
64
- delete constraints[key].presence;
61
+ constraints = _lodash.default.mapValues(constraints, skipPresenceConstraint ? constraint => _lodash.default.omit(constraint, 'presence') : constraint => {
62
+ if (constraint.presence === true) {
63
+ return { ..._lodash.default.omit(constraint, 'presence'),
64
+ presence: {
65
+ allowEmpty: false
66
+ }
67
+ };
65
68
  }
66
- }
67
69
 
68
- let validationErrors = _desiredCaps.validator.validate(_lodash.default.pickBy(caps, _support.util.hasValue), constraints, {
70
+ return constraint;
71
+ });
72
+
73
+ const validationErrors = _desiredCaps.validator.validate(_lodash.default.pickBy(caps, _support.util.hasValue), constraints, {
69
74
  fullMessages: false
70
75
  });
71
76
 
@@ -84,40 +89,42 @@ function validateCaps(caps, constraints = {}, opts = {}) {
84
89
  return caps;
85
90
  }
86
91
 
87
- const STANDARD_CAPS = ['browserName', 'browserVersion', 'platformName', 'acceptInsecureCerts', 'pageLoadStrategy', 'proxy', 'setWindowRect', 'timeouts', 'unhandledPromptBehavior'];
92
+ const STANDARD_CAPS = Object.freeze(new Set(['browserName', 'browserVersion', 'platformName', 'acceptInsecureCerts', 'pageLoadStrategy', 'proxy', 'setWindowRect', 'timeouts', 'unhandledPromptBehavior']));
93
+ exports.STANDARD_CAPS = STANDARD_CAPS;
94
+ const STANDARD_CAPS_LOWER = new Set([...STANDARD_CAPS].map(cap => cap.toLowerCase()));
88
95
 
89
96
  function isStandardCap(cap) {
90
- return !!_lodash.default.find(STANDARD_CAPS, standardCap => standardCap.toLowerCase() === `${cap}`.toLowerCase());
97
+ return STANDARD_CAPS_LOWER.has(cap.toLowerCase());
91
98
  }
92
99
 
93
100
  function stripAppiumPrefixes(caps) {
94
- const prefix = 'appium:';
101
+ const [prefixedCaps, nonPrefixedCaps] = _lodash.default.partition(_lodash.default.keys(caps), cap => String(cap).startsWith(APPIUM_VENDOR_PREFIX));
95
102
 
96
- const prefixedCaps = _lodash.default.filter(_lodash.default.keys(caps), cap => `${cap}`.startsWith(prefix));
103
+ let strippedCaps = _lodash.default.pick(caps, nonPrefixedCaps);
97
104
 
98
105
  const badPrefixedCaps = [];
99
106
 
100
107
  for (let prefixedCap of prefixedCaps) {
101
- const strippedCapName = prefixedCap.substr(prefix.length);
108
+ const strippedCapName = prefixedCap.substring(APPIUM_VENDOR_PREFIX.length);
102
109
 
103
110
  if (isStandardCap(strippedCapName)) {
104
111
  badPrefixedCaps.push(strippedCapName);
105
112
 
106
- if (_lodash.default.isNil(caps[strippedCapName])) {
107
- caps[strippedCapName] = caps[prefixedCap];
113
+ if (_lodash.default.isNil(strippedCaps[strippedCapName])) {
114
+ strippedCaps[strippedCapName] = caps[prefixedCap];
108
115
  } else {
109
- _logger.default.warn(`Ignoring capability '${prefixedCap}=${caps[prefixedCap]}' and ` + `using capability '${strippedCapName}=${caps[strippedCapName]}'`);
116
+ _logger.default.warn(`Ignoring capability '${prefixedCap}=${caps[prefixedCap]}' and ` + `using capability '${strippedCapName}=${strippedCaps[strippedCapName]}'`);
110
117
  }
111
118
  } else {
112
- caps[strippedCapName] = caps[prefixedCap];
119
+ strippedCaps[strippedCapName] = caps[prefixedCap];
113
120
  }
114
-
115
- delete caps[prefixedCap];
116
121
  }
117
122
 
118
123
  if (badPrefixedCaps.length > 0) {
119
124
  _logger.default.warn(`The capabilities ${JSON.stringify(badPrefixedCaps)} are standard capabilities and do not require "appium:" prefix`);
120
125
  }
126
+
127
+ return strippedCaps;
121
128
  }
122
129
 
123
130
  function findNonPrefixedCaps({
@@ -153,32 +160,20 @@ function parseCaps(caps, constraints = {}, shouldValidateCaps = true) {
153
160
  throw new _errors.errors.InvalidArgumentError(`All non-standard capabilities should have a vendor prefix. The following capabilities did not have one: ${nonPrefixedCaps}`);
154
161
  }
155
162
 
156
- stripAppiumPrefixes(requiredCaps);
157
-
158
- for (let firstMatchCaps of allFirstMatchCaps) {
159
- stripAppiumPrefixes(firstMatchCaps);
160
- }
163
+ let strippedRequiredCaps = stripAppiumPrefixes(requiredCaps);
164
+ let strippedAllFirstMatchCaps = allFirstMatchCaps.map(stripAppiumPrefixes);
161
165
 
162
166
  if (shouldValidateCaps) {
163
- requiredCaps = validateCaps(requiredCaps, constraints, {
167
+ strippedRequiredCaps = validateCaps(strippedRequiredCaps, constraints, {
164
168
  skipPresenceConstraint: true
165
169
  });
166
170
  }
167
171
 
168
- let filteredConstraints = { ...constraints
169
- };
170
-
171
- let requiredCapsKeys = _lodash.default.keys(requiredCaps);
172
-
173
- for (let key of _lodash.default.keys(filteredConstraints)) {
174
- if (requiredCapsKeys.includes(key)) {
175
- delete filteredConstraints[key];
176
- }
177
- }
172
+ const filteredConstraints = _lodash.default.omitBy(constraints, (_, key) => key in strippedRequiredCaps);
178
173
 
179
174
  let validationErrors = [];
180
175
 
181
- let validatedFirstMatchCaps = _lodash.default.compact(allFirstMatchCaps.map(firstMatchCaps => {
176
+ let validatedFirstMatchCaps = _lodash.default.compact(strippedAllFirstMatchCaps.map(firstMatchCaps => {
182
177
  try {
183
178
  return shouldValidateCaps ? validateCaps(firstMatchCaps, filteredConstraints) : firstMatchCaps;
184
179
  } catch (e) {
@@ -190,7 +185,7 @@ function parseCaps(caps, constraints = {}, shouldValidateCaps = true) {
190
185
 
191
186
  for (let firstMatchCaps of validatedFirstMatchCaps) {
192
187
  try {
193
- matchedCaps = mergeCaps(requiredCaps, firstMatchCaps);
188
+ matchedCaps = mergeCaps(strippedRequiredCaps, firstMatchCaps);
194
189
 
195
190
  if (matchedCaps) {
196
191
  break;
@@ -241,18 +236,18 @@ function promoteAppiumOptions(originalCaps) {
241
236
  throw new _errors.errors.SessionNotCreatedError(`The ${APPIUM_OPTS_CAP} capability must be an object`);
242
237
  }
243
238
 
244
- stripAppiumPrefixes(appiumOptions);
239
+ const strippedAppiumOptions = stripAppiumPrefixes(appiumOptions);
245
240
 
246
- const overwrittenKeys = _lodash.default.intersection(Object.keys(caps), Object.keys(appiumOptions));
241
+ const overwrittenKeys = _lodash.default.intersection(Object.keys(caps), Object.keys(strippedAppiumOptions));
247
242
 
248
243
  if (overwrittenKeys.length > 0) {
249
244
  _logger.default.warn(`Found capabilities inside ${PREFIXED_APPIUM_OPTS_CAP} that will overwrite ` + `capabilities at the top level: ${JSON.stringify(overwrittenKeys)}`);
250
245
  }
251
246
 
252
247
  caps = { ...caps,
253
- ...appiumOptions
248
+ ...strippedAppiumOptions
254
249
  };
255
250
  delete caps[APPIUM_OPTS_CAP];
256
251
  return caps;
257
252
  }
258
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJBUFBJVU1fVkVORE9SX1BSRUZJWCIsIkFQUElVTV9PUFRTX0NBUCIsIlBSRUZJWEVEX0FQUElVTV9PUFRTX0NBUCIsIm1lcmdlQ2FwcyIsInByaW1hcnkiLCJzZWNvbmRhcnkiLCJyZXN1bHQiLCJPYmplY3QiLCJhc3NpZ24iLCJuYW1lIiwidmFsdWUiLCJfIiwidG9QYWlycyIsImlzVW5kZWZpbmVkIiwiZXJyb3JzIiwiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCJKU09OIiwic3RyaW5naWZ5IiwidmFsaWRhdGVDYXBzIiwiY2FwcyIsImNvbnN0cmFpbnRzIiwib3B0cyIsInNraXBQcmVzZW5jZUNvbnN0cmFpbnQiLCJpc1BsYWluT2JqZWN0IiwiY2xvbmVEZWVwIiwia2V5Iiwia2V5cyIsInByZXNlbmNlIiwidmFsaWRhdGlvbkVycm9ycyIsInZhbGlkYXRvciIsInZhbGlkYXRlIiwicGlja0J5IiwidXRpbCIsImhhc1ZhbHVlIiwiZnVsbE1lc3NhZ2VzIiwibWVzc2FnZSIsImF0dHJpYnV0ZSIsInJlYXNvbnMiLCJyZWFzb24iLCJwdXNoIiwiam9pbiIsIlNUQU5EQVJEX0NBUFMiLCJpc1N0YW5kYXJkQ2FwIiwiY2FwIiwiZmluZCIsInN0YW5kYXJkQ2FwIiwidG9Mb3dlckNhc2UiLCJzdHJpcEFwcGl1bVByZWZpeGVzIiwicHJlZml4IiwicHJlZml4ZWRDYXBzIiwiZmlsdGVyIiwic3RhcnRzV2l0aCIsImJhZFByZWZpeGVkQ2FwcyIsInByZWZpeGVkQ2FwIiwic3RyaXBwZWRDYXBOYW1lIiwic3Vic3RyIiwibGVuZ3RoIiwiaXNOaWwiLCJsb2ciLCJ3YXJuIiwiZmluZE5vblByZWZpeGVkQ2FwcyIsImFsd2F5c01hdGNoIiwiZmlyc3RNYXRjaCIsImNoYWluIiwicmVkdWNlIiwidW5wcmVmaXhlZENhcHMiLCJpbmNsdWRlcyIsInVuaXEiLCJwYXJzZUNhcHMiLCJzaG91bGRWYWxpZGF0ZUNhcHMiLCJyZXF1aXJlZENhcHMiLCJhbGxGaXJzdE1hdGNoQ2FwcyIsImlzQXJyYXkiLCJub25QcmVmaXhlZENhcHMiLCJpc0VtcHR5IiwiZmlyc3RNYXRjaENhcHMiLCJmaWx0ZXJlZENvbnN0cmFpbnRzIiwicmVxdWlyZWRDYXBzS2V5cyIsInZhbGlkYXRlZEZpcnN0TWF0Y2hDYXBzIiwiY29tcGFjdCIsIm1hcCIsImUiLCJtYXRjaGVkQ2FwcyIsImVyciIsInByb2Nlc3NDYXBhYmlsaXRpZXMiLCJ3M2NDYXBzIiwicHJvbW90ZUFwcGl1bU9wdGlvbnMiLCJvcmlnaW5hbENhcHMiLCJhcHBpdW1PcHRpb25zIiwiU2Vzc2lvbk5vdENyZWF0ZWRFcnJvciIsIm92ZXJ3cml0dGVuS2V5cyIsImludGVyc2VjdGlvbiJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9iYXNlZHJpdmVyL2NhcGFiaWxpdGllcy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7dmFsaWRhdG9yfSBmcm9tICcuL2Rlc2lyZWQtY2Fwcyc7XG5pbXBvcnQge3V0aWx9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgbG9nIGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCB7ZXJyb3JzfSBmcm9tICcuLi9wcm90b2NvbC9lcnJvcnMnO1xuXG5jb25zdCBBUFBJVU1fVkVORE9SX1BSRUZJWCA9ICdhcHBpdW06JztcbmNvbnN0IEFQUElVTV9PUFRTX0NBUCA9ICdvcHRpb25zJztcbmNvbnN0IFBSRUZJWEVEX0FQUElVTV9PUFRTX0NBUCA9IGAke0FQUElVTV9WRU5ET1JfUFJFRklYfSR7QVBQSVVNX09QVFNfQ0FQfWA7XG5cbi8vIFRha2VzIHByaW1hcnkgY2FwcyBvYmplY3QgYW5kIG1lcmdlcyBpdCBpbnRvIGEgc2Vjb25kYXJ5IGNhcHMgb2JqZWN0LlxuLy8gKHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvd2ViZHJpdmVyLyNkZm4tbWVyZ2luZy1jYXBhYmlsaXRpZXMpXG4vKipcbiAqIEBwYXJhbSB7Q2FwYWJpbGl0aWVzfSBbcHJpbWFyeV1cbiAqIEBwYXJhbSB7Q2FwYWJpbGl0aWVzfSBbc2Vjb25kYXJ5XVxuICogQHJldHVybnMge0NhcGFiaWxpdGllc31cbiAqL1xuZnVuY3Rpb24gbWVyZ2VDYXBzKHByaW1hcnkgPSB7fSwgc2Vjb25kYXJ5ID0ge30pIHtcbiAgbGV0IHJlc3VsdCA9IE9iamVjdC5hc3NpZ24oe30sIHByaW1hcnkpO1xuXG4gIGZvciAobGV0IFtuYW1lLCB2YWx1ZV0gb2YgXy50b1BhaXJzKHNlY29uZGFyeSkpIHtcbiAgICAvLyBPdmVyd3JpdGluZyBpcyBub3QgYWxsb3dlZC4gUHJpbWFyeSBhbmQgc2Vjb25kYXJ5IG11c3QgaGF2ZSBkaWZmZXJlbnQgcHJvcGVydGllcyAodzNjIHJ1bGUgNC40KVxuICAgIGlmICghXy5pc1VuZGVmaW5lZChwcmltYXJ5W25hbWVdKSkge1xuICAgICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkQXJndW1lbnRFcnJvcihcbiAgICAgICAgYHByb3BlcnR5ICcke25hbWV9JyBzaG91bGQgbm90IGV4aXN0IG9uIGJvdGggcHJpbWFyeSAoJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICBwcmltYXJ5XG4gICAgICAgICl9KSBhbmQgc2Vjb25kYXJ5ICgke0pTT04uc3RyaW5naWZ5KHNlY29uZGFyeSl9KSBvYmplY3RgXG4gICAgICApO1xuICAgIH1cbiAgICByZXN1bHRbbmFtZV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIFZhbGlkYXRlcyBjYXBzIGFnYWluc3QgYSBzZXQgb2YgY29uc3RyYWludHNcbi8qKlxuICpcbiAqIEBwYXJhbSB7Q2FwYWJpbGl0aWVzfSBjYXBzXG4gKiBAcGFyYW0ge0NvbnN0cmFpbnRzfSBbY29uc3RyYWludHNdXG4gKiBAcGFyYW0ge1ZhbGlkYXRlQ2Fwc09wdHN9IFtvcHRzXVxuICogQHJldHVybnMge0NhcGFiaWxpdGllc31cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVDYXBzKGNhcHMsIGNvbnN0cmFpbnRzID0ge30sIG9wdHMgPSB7fSkge1xuICBsZXQge3NraXBQcmVzZW5jZUNvbnN0cmFpbnR9ID0gb3B0cztcblxuICBpZiAoIV8uaXNQbGFpbk9iamVjdChjYXBzKSkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IoYG11c3QgYmUgYSBKU09OIG9iamVjdGApO1xuICB9XG5cbiAgY29uc3RyYWludHMgPSBfLmNsb25lRGVlcChjb25zdHJhaW50cyk7IC8vIERlZmVuc2l2ZSBjb3B5XG5cbiAgaWYgKHNraXBQcmVzZW5jZUNvbnN0cmFpbnQpIHtcbiAgICAvLyBSZW1vdmUgdGhlICdwcmVzZW5jZScgY29uc3RyYWludCBpZiB3ZSdyZSBub3QgY2hlY2tpbmcgZm9yIGl0XG4gICAgZm9yIChsZXQga2V5IG9mIF8ua2V5cyhjb25zdHJhaW50cykpIHtcbiAgICAgIGRlbGV0ZSBjb25zdHJhaW50c1trZXldLnByZXNlbmNlO1xuICAgIH1cbiAgfVxuXG4gIGxldCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdG9yLnZhbGlkYXRlKF8ucGlja0J5KGNhcHMsIHV0aWwuaGFzVmFsdWUpLCBjb25zdHJhaW50cywge1xuICAgIGZ1bGxNZXNzYWdlczogZmFsc2UsXG4gIH0pO1xuXG4gIGlmICh2YWxpZGF0aW9uRXJyb3JzKSB7XG4gICAgbGV0IG1lc3NhZ2UgPSBbXTtcbiAgICBmb3IgKGxldCBbYXR0cmlidXRlLCByZWFzb25zXSBvZiBfLnRvUGFpcnModmFsaWRhdGlvbkVycm9ycykpIHtcbiAgICAgIGZvciAobGV0IHJlYXNvbiBvZiByZWFzb25zKSB7XG4gICAgICAgIG1lc3NhZ2UucHVzaChgJyR7YXR0cmlidXRlfScgJHtyZWFzb259YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IobWVzc2FnZS5qb2luKCc7ICcpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBjYXBzXG4gIHJldHVybiBjYXBzO1xufVxuXG4vLyBTdGFuZGFyZCwgbm9uLXByZWZpeGVkIGNhcGFiaWxpdGllcyAoc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJkcml2ZXIvI2Rmbi10YWJsZS1vZi1zdGFuZGFyZC1jYXBhYmlsaXRpZXMpXG5jb25zdCBTVEFOREFSRF9DQVBTID0gW1xuICAnYnJvd3Nlck5hbWUnLFxuICAnYnJvd3NlclZlcnNpb24nLFxuICAncGxhdGZvcm1OYW1lJyxcbiAgJ2FjY2VwdEluc2VjdXJlQ2VydHMnLFxuICAncGFnZUxvYWRTdHJhdGVneScsXG4gICdwcm94eScsXG4gICdzZXRXaW5kb3dSZWN0JyxcbiAgJ3RpbWVvdXRzJyxcbiAgJ3VuaGFuZGxlZFByb21wdEJlaGF2aW9yJyxcbl07XG5cbmZ1bmN0aW9uIGlzU3RhbmRhcmRDYXAoY2FwKSB7XG4gIHJldHVybiAhIV8uZmluZChcbiAgICBTVEFOREFSRF9DQVBTLFxuICAgIChzdGFuZGFyZENhcCkgPT4gc3RhbmRhcmRDYXAudG9Mb3dlckNhc2UoKSA9PT0gYCR7Y2FwfWAudG9Mb3dlckNhc2UoKVxuICApO1xufVxuXG4vLyBJZiB0aGUgJ2FwcGl1bTonIHByZWZpeCB3YXMgcHJvdmlkZWQgYW5kIGl0J3MgYSB2YWxpZCBjYXBhYmlsaXR5LCBzdHJpcCBvdXQgdGhlIHByZWZpeCAoc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJkcml2ZXIvI2Rmbi1leHRlbnNpb24tY2FwYWJpbGl0aWVzKVxuLy8gKE5PVEU6IE1ldGhvZCBpcyBkZXN0cnVjdGl2ZSBhbmQgbXV0YXRlcyBjb250ZW50cyBvZiBjYXBzKVxuZnVuY3Rpb24gc3RyaXBBcHBpdW1QcmVmaXhlcyhjYXBzKSB7XG4gIGNvbnN0IHByZWZpeCA9ICdhcHBpdW06JztcbiAgY29uc3QgcHJlZml4ZWRDYXBzID0gXy5maWx0ZXIoXy5rZXlzKGNhcHMpLCAoY2FwKSA9PiBgJHtjYXB9YC5zdGFydHNXaXRoKHByZWZpeCkpO1xuICBjb25zdCBiYWRQcmVmaXhlZENhcHMgPSBbXTtcblxuICAvLyBTdHJpcCBvdXQgdGhlICdhcHBpdW06JyBwcmVmaXhcbiAgZm9yIChsZXQgcHJlZml4ZWRDYXAgb2YgcHJlZml4ZWRDYXBzKSB7XG4gICAgY29uc3Qgc3RyaXBwZWRDYXBOYW1lID0gcHJlZml4ZWRDYXAuc3Vic3RyKHByZWZpeC5sZW5ndGgpO1xuXG4gICAgLy8gSWYgaXQncyBzdGFuZGFyZCBjYXBhYmlsaXR5IHRoYXQgd2FzIHByZWZpeGVkLCBhZGQgaXQgdG8gYW4gYXJyYXkgb2YgaW5jb3JyZWN0bHkgcHJlZml4ZWQgY2FwYWJpbGl0aWVzXG4gICAgaWYgKGlzU3RhbmRhcmRDYXAoc3RyaXBwZWRDYXBOYW1lKSkge1xuICAgICAgYmFkUHJlZml4ZWRDYXBzLnB1c2goc3RyaXBwZWRDYXBOYW1lKTtcbiAgICAgIGlmIChfLmlzTmlsKGNhcHNbc3RyaXBwZWRDYXBOYW1lXSkpIHtcbiAgICAgICAgY2Fwc1tzdHJpcHBlZENhcE5hbWVdID0gY2Fwc1twcmVmaXhlZENhcF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2cud2FybihcbiAgICAgICAgICBgSWdub3JpbmcgY2FwYWJpbGl0eSAnJHtwcmVmaXhlZENhcH09JHtjYXBzW3ByZWZpeGVkQ2FwXX0nIGFuZCBgICtcbiAgICAgICAgICAgIGB1c2luZyBjYXBhYmlsaXR5ICcke3N0cmlwcGVkQ2FwTmFtZX09JHtjYXBzW3N0cmlwcGVkQ2FwTmFtZV19J2BcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY2Fwc1tzdHJpcHBlZENhcE5hbWVdID0gY2Fwc1twcmVmaXhlZENhcF07XG4gICAgfVxuXG4gICAgLy8gU3RyaXAgb3V0IHRoZSBwcmVmaXhcbiAgICBkZWxldGUgY2Fwc1twcmVmaXhlZENhcF07XG4gIH1cblxuICAvLyBJZiB3ZSBmb3VuZCBzdGFuZGFyZCBjYXBzIHRoYXQgd2VyZSBpbmNvcnJlY3RseSBwcmVmaXhlZCwgdGhyb3cgYW4gZXhjZXB0aW9uIChlLmcuOiBkb24ndCBhY2NlcHQgJ2FwcGl1bTpwbGF0Zm9ybU5hbWUnLCBvbmx5IGFjY2VwdCBqdXN0ICdwbGF0Zm9ybU5hbWUnKVxuICBpZiAoYmFkUHJlZml4ZWRDYXBzLmxlbmd0aCA+IDApIHtcbiAgICBsb2cud2FybihcbiAgICAgIGBUaGUgY2FwYWJpbGl0aWVzICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIGJhZFByZWZpeGVkQ2Fwc1xuICAgICAgKX0gYXJlIHN0YW5kYXJkIGNhcGFiaWxpdGllcyBhbmQgZG8gbm90IHJlcXVpcmUgXCJhcHBpdW06XCIgcHJlZml4YFxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgYW4gYXJyYXkgb2YgYWxsIHRoZSB1bnByZWZpeGVkIGNhcHMgdGhhdCBhcmUgYmVpbmcgdXNlZCBpbiAnYWx3YXlzTWF0Y2gnIGFuZCBhbGwgb2YgdGhlICdmaXJzdE1hdGNoJyBvYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBjYXBzIEEgY2FwYWJpbGl0aWVzIG9iamVjdFxuICovXG5mdW5jdGlvbiBmaW5kTm9uUHJlZml4ZWRDYXBzKHthbHdheXNNYXRjaCA9IHt9LCBmaXJzdE1hdGNoID0gW119KSB7XG4gIHJldHVybiBfLmNoYWluKFthbHdheXNNYXRjaCwgLi4uZmlyc3RNYXRjaF0pXG4gICAgLnJlZHVjZShcbiAgICAgICh1bnByZWZpeGVkQ2FwcywgY2FwcykgPT4gW1xuICAgICAgICAuLi51bnByZWZpeGVkQ2FwcyxcbiAgICAgICAgLi4uT2JqZWN0LmtleXMoY2FwcykuZmlsdGVyKChjYXApID0+ICFjYXAuaW5jbHVkZXMoJzonKSAmJiAhaXNTdGFuZGFyZENhcChjYXApKSxcbiAgICAgIF0sXG4gICAgICBbXVxuICAgIClcbiAgICAudW5pcSgpXG4gICAgLnZhbHVlKCk7XG59XG5cbi8vIFBhcnNlIGNhcGFiaWxpdGllcyAoYmFzZWQgb24gaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYmRyaXZlci8jcHJvY2Vzc2luZy1jYXBhYmlsaXRpZXMpXG4vKipcbiAqXG4gKiBAcGFyYW0ge1czQ0NhcGFiaWxpdGllc30gY2Fwc1xuICogQHBhcmFtIHtDb25zdHJhaW50c30gW2NvbnN0cmFpbnRzXVxuICogQHBhcmFtIHtib29sZWFufSBbc2hvdWxkVmFsaWRhdGVDYXBzXVxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gcGFyc2VDYXBzKGNhcHMsIGNvbnN0cmFpbnRzID0ge30sIHNob3VsZFZhbGlkYXRlQ2FwcyA9IHRydWUpIHtcbiAgLy8gSWYgY2FwYWJpbGl0aWVzIHJlcXVlc3QgaXMgbm90IGFuIG9iamVjdCwgcmV0dXJuIGVycm9yICgjMS4xKVxuICBpZiAoIV8uaXNQbGFpbk9iamVjdChjYXBzKSkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IoXG4gICAgICAnVGhlIGNhcGFiaWxpdGllcyBhcmd1bWVudCB3YXMgbm90IHZhbGlkIGZvciB0aGUgZm9sbG93aW5nIHJlYXNvbihzKTogXCJjYXBhYmlsaXRpZXNcIiBtdXN0IGJlIGEgSlNPTiBvYmplY3QuJ1xuICAgICk7XG4gIH1cblxuICAvLyBMZXQgJ3JlcXVpcmVkQ2FwcycgYmUgcHJvcGVydHkgbmFtZWQgJ2Fsd2F5c01hdGNoJyBmcm9tIGNhcGFiaWxpdGllcyByZXF1ZXN0ICgjMilcbiAgLy8gYW5kICdhbGxGaXJzdE1hdGNoQ2FwcycgYmUgcHJvcGVydHkgbmFtZWQgJ2ZpcnN0TWF0Y2gnIGZyb20gY2FwYWJpbGl0aWVzIHJlcXVlc3QgKCMzKVxuICBsZXQge1xuICAgIGFsd2F5c01hdGNoOiByZXF1aXJlZENhcHMgPSB7fSwgLy8gSWYgJ3JlcXVpcmVkQ2FwcycgaXMgdW5kZWZpbmVkLCBzZXQgaXQgdG8gYW4gZW1wdHkgSlNPTiBvYmplY3QgKCMyLjEpXG4gICAgZmlyc3RNYXRjaDogYWxsRmlyc3RNYXRjaENhcHMgPSBbe31dLCAvLyBJZiAnZmlyc3RNYXRjaCcgaXMgdW5kZWZpbmVkIHNldCBpdCB0byBhIHNpbmdsZXRvbiBsaXN0IHdpdGggb25lIGVtcHR5IG9iamVjdCAoIzMuMSlcbiAgfSA9IGNhcHM7XG5cbiAgLy8gUmVqZWN0ICdmaXJzdE1hdGNoJyBhcmd1bWVudCBpZiBpdCdzIG5vdCBhbiBhcnJheSAoIzMuMilcbiAgaWYgKCFfLmlzQXJyYXkoYWxsRmlyc3RNYXRjaENhcHMpKSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkQXJndW1lbnRFcnJvcihcbiAgICAgICdUaGUgY2FwYWJpbGl0aWVzLmZpcnN0TWF0Y2ggYXJndW1lbnQgd2FzIG5vdCB2YWxpZCBmb3IgdGhlIGZvbGxvd2luZyByZWFzb24ocyk6IFwiY2FwYWJpbGl0aWVzLmZpcnN0TWF0Y2hcIiBtdXN0IGJlIGEgSlNPTiBhcnJheSBvciB1bmRlZmluZWQnXG4gICAgKTtcbiAgfVxuXG4gIC8vIElmIGFuIGVtcHR5IGFycmF5IGFzIHByb3ZpZGVkLCB3ZSdsbCBiZSBmb3JnaXZpbmcgYW5kIG1ha2UgaXQgYW4gYXJyYXkgb2Ygb25lIGVtcHR5IG9iamVjdFxuICAvLyBJbiB0aGUgZnV0dXJlLCByZWplY3QgJ2ZpcnN0TWF0Y2gnIGFyZ3VtZW50IGlmIGl0cyBhcnJheSBkaWQgbm90IGhhdmUgb25lIG9yIG1vcmUgZW50cmllcyAoIzMuMilcbiAgaWYgKGFsbEZpcnN0TWF0Y2hDYXBzLmxlbmd0aCA9PT0gMCkge1xuICAgIGxvZy53YXJuKFxuICAgICAgYFRoZSBmaXJzdE1hdGNoIGFycmF5IGluIHRoZSBnaXZlbiBjYXBhYmlsaXRpZXMgaGFzIG5vIGVudHJpZXMuIEFkZGluZyBhbiBlbXB0eSBlbnRyeSBmbyBybm93LCBgICtcbiAgICAgICAgYGJ1dCBpdCB3aWxsIHJlcXVpcmUgb25lIG9yIG1vcmUgZW50cmllcyBhcyBXM0Mgc3BlYy5gXG4gICAgKTtcbiAgICBhbGxGaXJzdE1hdGNoQ2Fwcy5wdXNoKHt9KTtcbiAgfVxuXG4gIC8vIENoZWNrIGZvciBub24tcHJlZml4ZWQsIG5vbi1zdGFuZGFyZCBjYXBhYmlsaXRpZXMgYW5kIGxvZyB3YXJuaW5ncyBpZiB0aGV5IGFyZSBmb3VuZFxuICBsZXQgbm9uUHJlZml4ZWRDYXBzID0gZmluZE5vblByZWZpeGVkQ2FwcyhjYXBzKTtcbiAgaWYgKCFfLmlzRW1wdHkobm9uUHJlZml4ZWRDYXBzKSkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IoXG4gICAgICBgQWxsIG5vbi1zdGFuZGFyZCBjYXBhYmlsaXRpZXMgc2hvdWxkIGhhdmUgYSB2ZW5kb3IgcHJlZml4LiBUaGUgZm9sbG93aW5nIGNhcGFiaWxpdGllcyBkaWQgbm90IGhhdmUgb25lOiAke25vblByZWZpeGVkQ2Fwc31gXG4gICAgKTtcbiAgfVxuXG4gIC8vIFN0cmlwIG91dCB0aGUgJ2FwcGl1bTonIHByZWZpeCBmcm9tIGFsbFxuICBzdHJpcEFwcGl1bVByZWZpeGVzKHJlcXVpcmVkQ2Fwcyk7XG4gIGZvciAobGV0IGZpcnN0TWF0Y2hDYXBzIG9mIGFsbEZpcnN0TWF0Y2hDYXBzKSB7XG4gICAgc3RyaXBBcHBpdW1QcmVmaXhlcyhmaXJzdE1hdGNoQ2Fwcyk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSB0aGUgcmVxdWlyZWRDYXBzLiBCdXQgZG9uJ3QgdmFsaWRhdGUgJ3ByZXNlbmNlJyBiZWNhdXNlIGlmIHRoYXQgY29uc3RyYWludCBmYWlscyBvbiAnYWx3YXlzTWF0Y2gnIGl0IGNvdWxkIHN0aWxsIHBhc3Mgb24gb25lIG9mIHRoZSAnZmlyc3RNYXRjaCcga2V5c1xuICBpZiAoc2hvdWxkVmFsaWRhdGVDYXBzKSB7XG4gICAgcmVxdWlyZWRDYXBzID0gdmFsaWRhdGVDYXBzKHJlcXVpcmVkQ2FwcywgY29uc3RyYWludHMsIHtcbiAgICAgIHNraXBQcmVzZW5jZUNvbnN0cmFpbnQ6IHRydWUsXG4gICAgfSk7XG4gIH1cblxuICAvLyBSZW1vdmUgdGhlICdwcmVzZW5jZScgY29uc3RyYWludCBmb3IgYW55IGtleXMgdGhhdCBhcmUgYWxyZWFkeSBwcmVzZW50IGluICdyZXF1aXJlZENhcHMnXG4gIC8vIHNpbmNlIHdlIGtub3cgdGhhdCB0aGlzIGNvbnN0cmFpbnQgaGFzIGFscmVhZHkgcGFzc2VkXG4gIGxldCBmaWx0ZXJlZENvbnN0cmFpbnRzID0gey4uLmNvbnN0cmFpbnRzfTtcbiAgbGV0IHJlcXVpcmVkQ2Fwc0tleXMgPSBfLmtleXMocmVxdWlyZWRDYXBzKTtcbiAgZm9yIChsZXQga2V5IG9mIF8ua2V5cyhmaWx0ZXJlZENvbnN0cmFpbnRzKSkge1xuICAgIGlmIChyZXF1aXJlZENhcHNLZXlzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgIGRlbGV0ZSBmaWx0ZXJlZENvbnN0cmFpbnRzW2tleV07XG4gICAgfVxuICB9XG5cbiAgLy8gVmFsaWRhdGUgYWxsIG9mIHRoZSBmaXJzdCBtYXRjaCBjYXBhYmlsaXRpZXMgYW5kIHJldHVybiBhbiBhcnJheSB3aXRoIG9ubHkgdGhlIHZhbGlkIGNhcHMgKHNlZSBzcGVjICM1KVxuICBsZXQgdmFsaWRhdGlvbkVycm9ycyA9IFtdO1xuICAvKiogQHR5cGUge0NhcGFiaWxpdGllc1tdfSAqL1xuICBsZXQgdmFsaWRhdGVkRmlyc3RNYXRjaENhcHMgPSBfLmNvbXBhY3QoXG4gICAgYWxsRmlyc3RNYXRjaENhcHMubWFwKChmaXJzdE1hdGNoQ2FwcykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gVmFsaWRhdGUgZmlyc3RNYXRjaCBjYXBzXG4gICAgICAgIHJldHVybiBzaG91bGRWYWxpZGF0ZUNhcHNcbiAgICAgICAgICA/IHZhbGlkYXRlQ2FwcyhmaXJzdE1hdGNoQ2FwcywgZmlsdGVyZWRDb25zdHJhaW50cylcbiAgICAgICAgICA6IGZpcnN0TWF0Y2hDYXBzO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB2YWxpZGF0aW9uRXJyb3JzLnB1c2goZS5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICB9KVxuICApO1xuXG4gIC8vIFRyeSB0byBtZXJnZSByZXF1aXJlZENhcHMgd2l0aCBmaXJzdCBtYXRjaCBjYXBhYmlsaXRpZXMsIGJyZWFrIG9uY2UgaXQgZmluZHMgaXRzIGZpcnN0IG1hdGNoIChzZWUgc3BlYyAjNilcbiAgbGV0IG1hdGNoZWRDYXBzID0gbnVsbDtcbiAgZm9yIChsZXQgZmlyc3RNYXRjaENhcHMgb2YgdmFsaWRhdGVkRmlyc3RNYXRjaENhcHMpIHtcbiAgICB0cnkge1xuICAgICAgbWF0Y2hlZENhcHMgPSBtZXJnZUNhcHMocmVxdWlyZWRDYXBzLCBmaXJzdE1hdGNoQ2Fwcyk7XG4gICAgICBpZiAobWF0Y2hlZENhcHMpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBsb2cud2FybihlcnIubWVzc2FnZSk7XG4gICAgICB2YWxpZGF0aW9uRXJyb3JzLnB1c2goZXJyLm1lc3NhZ2UpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgdmFyaWFibGVzIGZvciB0ZXN0aW5nIHB1cnBvc2VzXG4gIHJldHVybiB7XG4gICAgcmVxdWlyZWRDYXBzLFxuICAgIGFsbEZpcnN0TWF0Y2hDYXBzLFxuICAgIHZhbGlkYXRlZEZpcnN0TWF0Y2hDYXBzLFxuICAgIG1hdGNoZWRDYXBzLFxuICAgIHZhbGlkYXRpb25FcnJvcnMsXG4gIH07XG59XG5cbi8vIENhbGxzIHBhcnNlQ2FwcyBhbmQganVzdCByZXR1cm5zIHRoZSBtYXRjaGVkQ2FwcyB2YXJpYWJsZVxuLyoqXG4gKlxuICogQHBhcmFtIHtXM0NDYXBhYmlsaXRpZXN9IHczY0NhcHNcbiAqIEBwYXJhbSB7Q29uc3RyYWludHN9IFtjb25zdHJhaW50c11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Nob3VsZFZhbGlkYXRlQ2Fwc11cbiAqIEByZXR1cm5zIHtDYXBhYmlsaXRpZXN9XG4gKi9cbmZ1bmN0aW9uIHByb2Nlc3NDYXBhYmlsaXRpZXModzNjQ2FwcywgY29uc3RyYWludHMgPSB7fSwgc2hvdWxkVmFsaWRhdGVDYXBzID0gdHJ1ZSkge1xuICBjb25zdCB7bWF0Y2hlZENhcHMsIHZhbGlkYXRpb25FcnJvcnN9ID0gcGFyc2VDYXBzKHczY0NhcHMsIGNvbnN0cmFpbnRzLCBzaG91bGRWYWxpZGF0ZUNhcHMpO1xuXG4gIC8vIElmIHdlIGZvdW5kIGFuIGVycm9yIHRocm93IGFuIGV4Y2VwdGlvblxuICBpZiAoIXV0aWwuaGFzVmFsdWUobWF0Y2hlZENhcHMpKSB7XG4gICAgaWYgKF8uaXNBcnJheSh3M2NDYXBzLmZpcnN0TWF0Y2gpICYmIHczY0NhcHMuZmlyc3RNYXRjaC5sZW5ndGggPiAxKSB7XG4gICAgICAvLyBJZiB0aGVyZSB3YXMgbW9yZSB0aGFuIG9uZSAnZmlyc3RNYXRjaCcgY2FwLCBpbmRpY2F0ZSB0aGF0IHdlIGNvdWxkbid0IGZpbmQgYSBtYXRjaGluZyBjYXBhYmlsaXRpZXMgc2V0IGFuZCBzaG93IGFsbCB0aGUgZXJyb3JzXG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRBcmd1bWVudEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGZpbmQgbWF0Y2hpbmcgY2FwYWJpbGl0aWVzIGZyb20gJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICB3M2NDYXBzXG4gICAgICAgICl9OlxcbiAke3ZhbGlkYXRpb25FcnJvcnMuam9pbignXFxuJyl9YFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gT3RoZXJ3aXNlLCBqdXN0IHNob3cgdGhlIHNpbmd1bGFyIGVycm9yIG1lc3NhZ2VcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IodmFsaWRhdGlvbkVycm9yc1swXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1hdGNoZWRDYXBzID8/IHt9O1xufVxuXG4vKipcbiAqIFJldHVybiBhIGNvcHkgb2YgYSBjYXBhYmlsaXRpZXMgb2JqZWN0IHdoaWNoIGhhcyB0YWtlbiBldmVyeXRoaW5nIHdpdGhpbiB0aGUgJ29wdGlvbnMnXG4gKiBjYXBhYmlsaXR5IGFuZCBwcm9tb3RlZCBpdCB0byB0aGUgdG9wIGxldmVsLiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbiBpcyBhc3N1bWVkIHRvIGJlIHJ1biBhZnRlclxuICogYWxsIHZlbmRvciBwcmVmaXhlcyBoYXZlIGFscmVhZHkgYmVlbiBzdHJpcHBlZCBmcm9tIHRoZSB0b3AgbGV2ZWwuIFNvIHdlIGFyZSBkZWFsaW5nIHdpdGggZS5nLlxuICogJ29wdGlvbnMnIGFuZCBub3QgJ2FwcGl1bTpvcHRpb25zJyBhdCB0aGlzIHBvaW50LiBBbnkgcHJlZml4ZXMgX2luc2lkZV8gdGhlICdvcHRpb25zJyBjYXBhYmlsaXR5XG4gKiB3aWxsIHRoZW1zZWx2ZXMgYmUgc3RyaXBwZWQuIFRoaXMgaXMgZGVzaWduZWQgYXMgYW4gaW50ZXJuYWwgZnVuY3Rpb24sIG5vdCBvbmUgdG8gb3BlcmF0ZSBvblxuICogdXNlci1jb25zdHJ1Y3RlZCBjYXBhYmlsaXRpZXMuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG9yaWdpbmFsQ2FwcyAtIHRoZSBjYXBhYmlsaXRpZXMgdG8gYW5hbHl6ZSBhbmQgcHJvbW90ZSBmcm9tICdvcHRpb25zJ1xuICogQHJldHVybiB7b2JqZWN0IX0gLSB0aGUgY2FwYWJpbGl0aWVzIHdpdGggJ29wdGlvbnMnIHByb21vdGVkIGlmIG5lY2Vzc2FyeVxuICovXG5mdW5jdGlvbiBwcm9tb3RlQXBwaXVtT3B0aW9ucyhvcmlnaW5hbENhcHMpIHtcbiAgY29uc3QgYXBwaXVtT3B0aW9ucyA9IG9yaWdpbmFsQ2Fwc1tBUFBJVU1fT1BUU19DQVBdO1xuICBpZiAoIWFwcGl1bU9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3JpZ2luYWxDYXBzO1xuICB9XG5cbiAgbGV0IGNhcHMgPSBfLmNsb25lRGVlcChvcmlnaW5hbENhcHMpO1xuICBpZiAoIV8uaXNQbGFpbk9iamVjdChhcHBpdW1PcHRpb25zKSkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuU2Vzc2lvbk5vdENyZWF0ZWRFcnJvcihgVGhlICR7QVBQSVVNX09QVFNfQ0FQfSBjYXBhYmlsaXR5IG11c3QgYmUgYW4gb2JqZWN0YCk7XG4gIH1cblxuICAvLyBmaXJzdCBnZXQgcmlkIG9mIGFueSBwcmVmaXhlcyBpbnNpZGUgYXBwaXVtOm9wdGlvbnNcbiAgc3RyaXBBcHBpdW1QcmVmaXhlcyhhcHBpdW1PcHRpb25zKTtcblxuICAvLyB3YXJuIGlmIHdlIGFyZSBnb2luZyB0byBvdmVyd3JpdGUgYW55IGtleXMgb24gdGhlIGJhc2UgY2FwcyBvYmplY3RcbiAgY29uc3Qgb3ZlcndyaXR0ZW5LZXlzID0gXy5pbnRlcnNlY3Rpb24oT2JqZWN0LmtleXMoY2FwcyksIE9iamVjdC5rZXlzKGFwcGl1bU9wdGlvbnMpKTtcbiAgaWYgKG92ZXJ3cml0dGVuS2V5cy5sZW5ndGggPiAwKSB7XG4gICAgbG9nLndhcm4oXG4gICAgICBgRm91bmQgY2FwYWJpbGl0aWVzIGluc2lkZSAke1BSRUZJWEVEX0FQUElVTV9PUFRTX0NBUH0gdGhhdCB3aWxsIG92ZXJ3cml0ZSBgICtcbiAgICAgICAgYGNhcGFiaWxpdGllcyBhdCB0aGUgdG9wIGxldmVsOiAke0pTT04uc3RyaW5naWZ5KG92ZXJ3cml0dGVuS2V5cyl9YFxuICAgICk7XG4gIH1cblxuICAvLyBub3cganVzdCBhcHBseSB0aGVtIHRvIHRoZSBtYWluIGNhcHMgb2JqZWN0XG4gIGNhcHMgPSB7Li4uY2FwcywgLi4uYXBwaXVtT3B0aW9uc307XG5cbiAgLy8gYW5kIHJlbW92ZSBhbGwgdHJhY2VzIG9mIHRoZSBvcHRpb25zIGNhcFxuICBkZWxldGUgY2Fwc1tBUFBJVU1fT1BUU19DQVBdO1xuICByZXR1cm4gY2Fwcztcbn1cblxuZXhwb3J0IHtcbiAgcGFyc2VDYXBzLFxuICBwcm9jZXNzQ2FwYWJpbGl0aWVzLFxuICB2YWxpZGF0ZUNhcHMsXG4gIG1lcmdlQ2FwcyxcbiAgQVBQSVVNX1ZFTkRPUl9QUkVGSVgsXG4gIEFQUElVTV9PUFRTX0NBUCxcbiAgZmluZE5vblByZWZpeGVkQ2FwcyxcbiAgaXNTdGFuZGFyZENhcCxcbiAgc3RyaXBBcHBpdW1QcmVmaXhlcyxcbiAgcHJvbW90ZUFwcGl1bU9wdGlvbnMsXG4gIFBSRUZJWEVEX0FQUElVTV9PUFRTX0NBUCxcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLlczQ0NhcGFiaWxpdGllc30gVzNDQ2FwYWJpbGl0aWVzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuQ29uc3RyYWludHN9IENvbnN0cmFpbnRzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuQ2FwYWJpbGl0aWVzfSBDYXBhYmlsaXRpZXNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIFZhbGlkYXRlQ2Fwc09wdHNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3NraXBQcmVzZW5jZUNvbnN0cmFpbnRdIC0gaWYgdHJ1ZSwgc2tpcCB0aGUgcHJlc2VuY2UgY29uc3RyYWludFxuICovXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQSxNQUFNQSxvQkFBb0IsR0FBRyxTQUE3Qjs7QUFDQSxNQUFNQyxlQUFlLEdBQUcsU0FBeEI7O0FBQ0EsTUFBTUMsd0JBQXdCLEdBQUksR0FBRUYsb0JBQXFCLEdBQUVDLGVBQWdCLEVBQTNFOzs7QUFTQSxTQUFTRSxTQUFULENBQW1CQyxPQUFPLEdBQUcsRUFBN0IsRUFBaUNDLFNBQVMsR0FBRyxFQUE3QyxFQUFpRDtFQUMvQyxJQUFJQyxNQUFNLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLEVBQWQsRUFBa0JKLE9BQWxCLENBQWI7O0VBRUEsS0FBSyxJQUFJLENBQUNLLElBQUQsRUFBT0MsS0FBUCxDQUFULElBQTBCQyxlQUFBLENBQUVDLE9BQUYsQ0FBVVAsU0FBVixDQUExQixFQUFnRDtJQUU5QyxJQUFJLENBQUNNLGVBQUEsQ0FBRUUsV0FBRixDQUFjVCxPQUFPLENBQUNLLElBQUQsQ0FBckIsQ0FBTCxFQUFtQztNQUNqQyxNQUFNLElBQUlLLGNBQUEsQ0FBT0Msb0JBQVgsQ0FDSCxhQUFZTixJQUFLLHVDQUFzQ08sSUFBSSxDQUFDQyxTQUFMLENBQ3REYixPQURzRCxDQUV0RCxvQkFBbUJZLElBQUks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
253
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJBUFBJVU1fVkVORE9SX1BSRUZJWCIsIkFQUElVTV9PUFRTX0NBUCIsIlBSRUZJWEVEX0FQUElVTV9PUFRTX0NBUCIsIm1lcmdlQ2FwcyIsInByaW1hcnkiLCJzZWNvbmRhcnkiLCJyZXN1bHQiLCJuYW1lIiwidmFsdWUiLCJfIiwidG9QYWlycyIsImlzVW5kZWZpbmVkIiwiZXJyb3JzIiwiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCJKU09OIiwic3RyaW5naWZ5IiwidmFsaWRhdGVDYXBzIiwiY2FwcyIsImNvbnN0cmFpbnRzIiwib3B0cyIsInNraXBQcmVzZW5jZUNvbnN0cmFpbnQiLCJpc1BsYWluT2JqZWN0IiwibWFwVmFsdWVzIiwiY29uc3RyYWludCIsIm9taXQiLCJwcmVzZW5jZSIsImFsbG93RW1wdHkiLCJ2YWxpZGF0aW9uRXJyb3JzIiwidmFsaWRhdG9yIiwidmFsaWRhdGUiLCJwaWNrQnkiLCJ1dGlsIiwiaGFzVmFsdWUiLCJmdWxsTWVzc2FnZXMiLCJtZXNzYWdlIiwiYXR0cmlidXRlIiwicmVhc29ucyIsInJlYXNvbiIsInB1c2giLCJqb2luIiwiU1RBTkRBUkRfQ0FQUyIsIk9iamVjdCIsImZyZWV6ZSIsIlNldCIsIlNUQU5EQVJEX0NBUFNfTE9XRVIiLCJtYXAiLCJjYXAiLCJ0b0xvd2VyQ2FzZSIsImlzU3RhbmRhcmRDYXAiLCJoYXMiLCJzdHJpcEFwcGl1bVByZWZpeGVzIiwicHJlZml4ZWRDYXBzIiwibm9uUHJlZml4ZWRDYXBzIiwicGFydGl0aW9uIiwia2V5cyIsIlN0cmluZyIsInN0YXJ0c1dpdGgiLCJzdHJpcHBlZENhcHMiLCJwaWNrIiwiYmFkUHJlZml4ZWRDYXBzIiwicHJlZml4ZWRDYXAiLCJzdHJpcHBlZENhcE5hbWUiLCJzdWJzdHJpbmciLCJsZW5ndGgiLCJpc05pbCIsImxvZyIsIndhcm4iLCJmaW5kTm9uUHJlZml4ZWRDYXBzIiwiYWx3YXlzTWF0Y2giLCJmaXJzdE1hdGNoIiwiY2hhaW4iLCJyZWR1Y2UiLCJ1bnByZWZpeGVkQ2FwcyIsImZpbHRlciIsImluY2x1ZGVzIiwidW5pcSIsInBhcnNlQ2FwcyIsInNob3VsZFZhbGlkYXRlQ2FwcyIsInJlcXVpcmVkQ2FwcyIsImFsbEZpcnN0TWF0Y2hDYXBzIiwiaXNBcnJheSIsImlzRW1wdHkiLCJzdHJpcHBlZFJlcXVpcmVkQ2FwcyIsInN0cmlwcGVkQWxsRmlyc3RNYXRjaENhcHMiLCJmaWx0ZXJlZENvbnN0cmFpbnRzIiwib21pdEJ5Iiwia2V5IiwidmFsaWRhdGVkRmlyc3RNYXRjaENhcHMiLCJjb21wYWN0IiwiZmlyc3RNYXRjaENhcHMiLCJlIiwibWF0Y2hlZENhcHMiLCJlcnIiLCJwcm9jZXNzQ2FwYWJpbGl0aWVzIiwidzNjQ2FwcyIsInByb21vdGVBcHBpdW1PcHRpb25zIiwib3JpZ2luYWxDYXBzIiwiYXBwaXVtT3B0aW9ucyIsImNsb25lRGVlcCIsIlNlc3Npb25Ob3RDcmVhdGVkRXJyb3IiLCJzdHJpcHBlZEFwcGl1bU9wdGlvbnMiLCJvdmVyd3JpdHRlbktleXMiLCJpbnRlcnNlY3Rpb24iXSwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvYmFzZWRyaXZlci9jYXBhYmlsaXRpZXMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQge3ZhbGlkYXRvcn0gZnJvbSAnLi9kZXNpcmVkLWNhcHMnO1xuaW1wb3J0IHt1dGlsfSBmcm9tICdAYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQge2Vycm9yc30gZnJvbSAnLi4vcHJvdG9jb2wvZXJyb3JzJztcblxuY29uc3QgQVBQSVVNX1ZFTkRPUl9QUkVGSVggPSAnYXBwaXVtOic7XG5jb25zdCBBUFBJVU1fT1BUU19DQVAgPSAnb3B0aW9ucyc7XG5jb25zdCBQUkVGSVhFRF9BUFBJVU1fT1BUU19DQVAgPSBgJHtBUFBJVU1fVkVORE9SX1BSRUZJWH0ke0FQUElVTV9PUFRTX0NBUH1gO1xuXG4vKipcbiAqIFRha2VzIHByaW1hcnkgY2FwcyBvYmplY3QgYW5kIG1lcmdlcyBpdCBpbnRvIGEgc2Vjb25kYXJ5IGNhcHMgb2JqZWN0LlxuICogQHRlbXBsYXRlIHtDb25zdHJhaW50c30gW1Q9e31dXG4gKiBAdGVtcGxhdGUge0NvbnN0cmFpbnRzfSBbVT17fV1cbiAqIEBwYXJhbSB7Q2FwYWJpbGl0aWVzPFQ+fSBbcHJpbWFyeV1cbiAqIEBwYXJhbSB7Q2FwYWJpbGl0aWVzPFU+fSBbc2Vjb25kYXJ5XVxuICogQHJldHVybnMge2ltcG9ydCgndHlwZS1mZXN0JykuTWVyZ2U8Q2FwYWJpbGl0aWVzPFQ+LCBDYXBhYmlsaXRpZXM8VT4+fVxuICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvd2ViZHJpdmVyLyNkZm4tbWVyZ2luZy1jYXBhYmlsaXRpZXMpXG4gKi9cbmZ1bmN0aW9uIG1lcmdlQ2FwcyhwcmltYXJ5ID0ge30sIHNlY29uZGFyeSA9IHt9KSB7XG4gIGxldCByZXN1bHQgPSAvKiogQHR5cGUge2ltcG9ydCgndHlwZS1mZXN0JykuTWVyZ2U8Q2FwYWJpbGl0aWVzPFQ+LCBDYXBhYmlsaXRpZXM8VT4+fSAqLyAoe1xuICAgIC4uLnByaW1hcnksXG4gIH0pO1xuXG4gIGZvciAobGV0IFtuYW1lLCB2YWx1ZV0gb2YgLyoqIEB0eXBlIHtba2V5b2YgdHlwZW9mIHNlY29uZGFyeSwgYW55XX0gKi8gKF8udG9QYWlycyhzZWNvbmRhcnkpKSkge1xuICAgIC8vIE92ZXJ3cml0aW5nIGlzIG5vdCBhbGxvd2VkLiBQcmltYXJ5IGFuZCBzZWNvbmRhcnkgbXVzdCBoYXZlIGRpZmZlcmVudCBwcm9wZXJ0aWVzICh3M2MgcnVsZSA0LjQpXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHByaW1hcnlbbmFtZV0pKSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRBcmd1bWVudEVycm9yKFxuICAgICAgICBgcHJvcGVydHkgJyR7bmFtZX0nIHNob3VsZCBub3QgZXhpc3Qgb24gYm90aCBwcmltYXJ5ICgke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIHByaW1hcnlcbiAgICAgICAgKX0pIGFuZCBzZWNvbmRhcnkgKCR7SlNPTi5zdHJpbmdpZnkoc2Vjb25kYXJ5KX0pIG9iamVjdGBcbiAgICAgICk7XG4gICAgfVxuICAgIHJlc3VsdFsvKiogQHR5cGUge2tleW9mIHR5cGVvZiByZXN1bHR9ICovIChuYW1lKV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIFZhbGlkYXRlcyBjYXBzIGFnYWluc3QgYSBzZXQgb2YgY29uc3RyYWludHNcbi8qKlxuICogQHRlbXBsYXRlIHtDb25zdHJhaW50c30gW0M9e31dXG4gKiBAcGFyYW0ge0NhcGFiaWxpdGllczxDPn0gY2Fwc1xuICogQHBhcmFtIHtDfSBbY29uc3RyYWludHNdXG4gKiBAcGFyYW0ge1ZhbGlkYXRlQ2Fwc09wdHN9IFtvcHRzXVxuICogQHJldHVybnMge0NhcGFiaWxpdGllczxDPn1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVDYXBzKGNhcHMsIGNvbnN0cmFpbnRzID0gLyoqIEB0eXBlIHtDfSAqLyAoe30pLCBvcHRzID0ge30pIHtcbiAgbGV0IHtza2lwUHJlc2VuY2VDb25zdHJhaW50fSA9IG9wdHM7XG5cbiAgaWYgKCFfLmlzUGxhaW5PYmplY3QoY2FwcykpIHtcbiAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRBcmd1bWVudEVycm9yKGBtdXN0IGJlIGEgSlNPTiBvYmplY3RgKTtcbiAgfVxuXG4gIC8vIFJlbW92ZSB0aGUgJ3ByZXNlbmNlJyBjb25zdHJhaW50IGlmIHdlJ3JlIG5vdCBjaGVja2luZyBmb3IgaXRcbiAgY29uc3RyYWludHMgPSAvKiogQHR5cGUge0N9ICovIChcbiAgICBfLm1hcFZhbHVlcyhcbiAgICAgIGNvbnN0cmFpbnRzLFxuICAgICAgc2tpcFByZXNlbmNlQ29uc3RyYWludFxuICAgICAgICA/IC8qKiBAcGFyYW0ge0NvbnN0cmFpbnR9IGNvbnN0cmFpbnQgKi9cbiAgICAgICAgICAoY29uc3RyYWludCkgPT4gXy5vbWl0KGNvbnN0cmFpbnQsICdwcmVzZW5jZScpXG4gICAgICAgIDogLyoqIEBwYXJhbSB7Q29uc3RyYWludH0gY29uc3RyYWludCAqL1xuICAgICAgICAgIChjb25zdHJhaW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoY29uc3RyYWludC5wcmVzZW5jZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICByZXR1cm4gey4uLl8ub21pdChjb25zdHJhaW50LCAncHJlc2VuY2UnKSwgcHJlc2VuY2U6IHthbGxvd0VtcHR5OiBmYWxzZX19O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnQ7XG4gICAgICAgICAgfVxuICAgIClcbiAgKTtcblxuICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdG9yLnZhbGlkYXRlKF8ucGlja0J5KGNhcHMsIHV0aWwuaGFzVmFsdWUpLCBjb25zdHJhaW50cywge1xuICAgIGZ1bGxNZXNzYWdlczogZmFsc2UsXG4gIH0pO1xuXG4gIGlmICh2YWxpZGF0aW9uRXJyb3JzKSB7XG4gICAgbGV0IG1lc3NhZ2UgPSBbXTtcbiAgICBmb3IgKGxldCBbYXR0cmlidXRlLCByZWFzb25zXSBvZiBfLnRvUGFpcnModmFsaWRhdGlvbkVycm9ycykpIHtcbiAgICAgIGZvciAobGV0IHJlYXNvbiBvZiByZWFzb25zKSB7XG4gICAgICAgIG1lc3NhZ2UucHVzaChgJyR7YXR0cmlidXRlfScgJHtyZWFzb259YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IobWVzc2FnZS5qb2luKCc7ICcpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBjYXBzXG4gIHJldHVybiBjYXBzO1xufVxuXG4vKipcbiAqIFN0YW5kYXJkLCBub24tcHJlZml4ZWQgY2FwYWJpbGl0aWVzXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJkcml2ZXIvI2Rmbi10YWJsZS1vZi1zdGFuZGFyZC1jYXBhYmlsaXRpZXMpXG4gKi9cbmV4cG9ydCBjb25zdCBTVEFOREFSRF9DQVBTID0gT2JqZWN0LmZyZWV6ZShcbiAgbmV3IFNldChcbiAgICAvKiogQHR5cGUge2ltcG9ydCgndHlwZS1mZXN0JykuU3RyaW5nS2V5T2Y8aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuU3RhbmRhcmRDYXBhYmlsaXRpZXM+W119ICovIChbXG4gICAgICAnYnJvd3Nlck5hbWUnLFxuICAgICAgJ2Jyb3dzZXJWZXJzaW9uJyxcbiAgICAgICdwbGF0Zm9ybU5hbWUnLFxuICAgICAgJ2FjY2VwdEluc2VjdXJlQ2VydHMnLFxuICAgICAgJ3BhZ2VMb2FkU3RyYXRlZ3knLFxuICAgICAgJ3Byb3h5JyxcbiAgICAgICdzZXRXaW5kb3dSZWN0JyxcbiAgICAgICd0aW1lb3V0cycsXG4gICAgICAndW5oYW5kbGVkUHJvbXB0QmVoYXZpb3InLFxuICAgIF0pXG4gIClcbik7XG5cbmNvbnN0IFNUQU5EQVJEX0NBUFNfTE9XRVIgPSBuZXcgU2V0KFsuLi5TVEFOREFSRF9DQVBTXS5tYXAoKGNhcCkgPT4gY2FwLnRvTG93ZXJDYXNlKCkpKTtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gY2FwXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNTdGFuZGFyZENhcChjYXApIHtcbiAgcmV0dXJuIFNUQU5EQVJEX0NBUFNfTE9XRVIuaGFzKGNhcC50b0xvd2VyQ2FzZSgpKTtcbn1cblxuLyoqXG4gKiBJZiB0aGUgJ2FwcGl1bTonIHByZWZpeCB3YXMgcHJvdmlkZWQgYW5kIGl0J3MgYSB2YWxpZCBjYXBhYmlsaXR5LCBzdHJpcCBvdXQgdGhlIHByZWZpeFxuICogQHRlbXBsYXRlIHtDb25zdHJhaW50c30gW0M9e31dXG4gKiBAcGFyYW0ge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLk5TQ2FwYWJpbGl0aWVzPEM+fSBjYXBzXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJkcml2ZXIvI2Rmbi1leHRlbnNpb24tY2FwYWJpbGl0aWVzXG4gKiBAaW50ZXJuYWxcbiAqIEByZXR1cm5zIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5DYXBhYmlsaXRpZXM8Qz59XG4gKi9cbmZ1bmN0aW9uIHN0cmlwQXBwaXVtUHJlZml4ZXMoY2Fwcykge1xuICAvLyBzcGxpdCBpbnRvIHByZWZpeGVkIGFuZCBub24tcHJlZml4ZWQuXG4gIC8vIG5vbi1wcmVmaXhlZCBzaG91bGQgYmUgc3RhbmRhcmQgY2FwcyBhdCB0aGlzIHBvaW50XG4gIGNvbnN0IFtwcmVmaXhlZENhcHMsIG5vblByZWZpeGVkQ2Fwc10gPSBfLnBhcnRpdGlvbihfLmtleXMoY2FwcyksIChjYXApID0+XG4gICAgU3RyaW5nKGNhcCkuc3RhcnRzV2l0aChBUFBJVU1fVkVORE9SX1BSRUZJWClcbiAgKTtcblxuICAvLyBpbml0aWFsaXplIHRoaXMgd2l0aCB0aGUgay92IHBhaXJzIG9mIHRoZSBub24tcHJlZml4ZWQgY2Fwc1xuICBsZXQgc3RyaXBwZWRDYXBzID0gLyoqIEB0eXBlIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5DYXBhYmlsaXRpZXM8Qz59ICovIChcbiAgICBfLnBpY2soY2Fwcywgbm9uUHJlZml4ZWRDYXBzKVxuICApO1xuICBjb25zdCBiYWRQcmVmaXhlZENhcHMgPSBbXTtcblxuICAvLyBTdHJpcCBvdXQgdGhlICdhcHBpdW06JyBwcmVmaXhcbiAgZm9yIChsZXQgcHJlZml4ZWRDYXAgb2YgcHJlZml4ZWRDYXBzKSB7XG4gICAgY29uc3Qgc3RyaXBwZWRDYXBOYW1lID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KCd0eXBlLWZlc3QnKS5TdHJpbmdLZXlPZjxpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5DYXBhYmlsaXRpZXM8Qz4+fSAqLyAoXG4gICAgICAgIHByZWZpeGVkQ2FwLnN1YnN0cmluZyhBUFBJVU1fVkVORE9SX1BSRUZJWC5sZW5ndGgpXG4gICAgICApO1xuXG4gICAgLy8gSWYgaXQncyBzdGFuZGFyZCBjYXBhYmlsaXR5IHRoYXQgd2FzIHByZWZpeGVkLCBhZGQgaXQgdG8gYW4gYXJyYXkgb2YgaW5jb3JyZWN0bHkgcHJlZml4ZWQgY2FwYWJpbGl0aWVzXG4gICAgaWYgKGlzU3RhbmRhcmRDYXAoc3RyaXBwZWRDYXBOYW1lKSkge1xuICAgICAgYmFkUHJlZml4ZWRDYXBzLnB1c2goc3RyaXBwZWRDYXBOYW1lKTtcbiAgICAgIGlmIChfLmlzTmlsKHN0cmlwcGVkQ2Fwc1tzdHJpcHBlZENhcE5hbWVdKSkge1xuICAgICAgICBzdHJpcHBlZENhcHNbc3RyaXBwZWRDYXBOYW1lXSA9IGNhcHNbcHJlZml4ZWRDYXBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nLndhcm4oXG4gICAgICAgICAgYElnbm9yaW5nIGNhcGFiaWxpdHkgJyR7cHJlZml4ZWRDYXB9PSR7Y2Fwc1twcmVmaXhlZENhcF19JyBhbmQgYCArXG4gICAgICAgICAgICBgdXNpbmcgY2FwYWJpbGl0eSAnJHtzdHJpcHBlZENhcE5hbWV9PSR7c3RyaXBwZWRDYXBzW3N0cmlwcGVkQ2FwTmFtZV19J2BcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyaXBwZWRDYXBzW3N0cmlwcGVkQ2FwTmFtZV0gPSBjYXBzW3ByZWZpeGVkQ2FwXTtcbiAgICB9XG4gIH1cblxuICAvLyBJZiB3ZSBmb3VuZCBzdGFuZGFyZCBjYXBzIHRoYXQgd2VyZSBpbmNvcnJlY3RseSBwcmVmaXhlZCwgdGhyb3cgYW4gZXhjZXB0aW9uIChlLmcuOiBkb24ndCBhY2NlcHQgJ2FwcGl1bTpwbGF0Zm9ybU5hbWUnLCBvbmx5IGFjY2VwdCBqdXN0ICdwbGF0Zm9ybU5hbWUnKVxuICBpZiAoYmFkUHJlZml4ZWRDYXBzLmxlbmd0aCA+IDApIHtcbiAgICBsb2cud2FybihcbiAgICAgIGBUaGUgY2FwYWJpbGl0aWVzICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIGJhZFByZWZpeGVkQ2Fwc1xuICAgICAgKX0gYXJlIHN0YW5kYXJkIGNhcGFiaWxpdGllcyBhbmQgZG8gbm90IHJlcXVpcmUgXCJhcHBpdW06XCIgcHJlZml4YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHN0cmlwcGVkQ2Fwcztcbn1cblxuLyoqXG4gKiBHZXQgYW4gYXJyYXkgb2YgYWxsIHRoZSB1bnByZWZpeGVkIGNhcHMgdGhhdCBhcmUgYmVpbmcgdXNlZCBpbiAnYWx3YXlzTWF0Y2gnIGFuZCBhbGwgb2YgdGhlICdmaXJzdE1hdGNoJyBvYmplY3RcbiAqIEB0ZW1wbGF0ZSB7Q29uc3RyYWludHN9IFtDPXt9XVxuICogQHBhcmFtIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5XM0NDYXBhYmlsaXRpZXM8Qz59IGNhcHMgQSBjYXBhYmlsaXRpZXMgb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIGZpbmROb25QcmVmaXhlZENhcHMoe2Fsd2F5c01hdGNoID0ge30sIGZpcnN0TWF0Y2ggPSBbXX0pIHtcbiAgcmV0dXJuIF8uY2hhaW4oW2Fsd2F5c01hdGNoLCAuLi5maXJzdE1hdGNoXSlcbiAgICAucmVkdWNlKFxuICAgICAgKHVucHJlZml4ZWRDYXBzLCBjYXBzKSA9PiBbXG4gICAgICAgIC4uLnVucHJlZml4ZWRDYXBzLFxuICAgICAgICAuLi5PYmplY3Qua2V5cyhjYXBzKS5maWx0ZXIoKGNhcCkgPT4gIWNhcC5pbmNsdWRlcygnOicpICYmICFpc1N0YW5kYXJkQ2FwKGNhcCkpLFxuICAgICAgXSxcbiAgICAgIFtdXG4gICAgKVxuICAgIC51bmlxKClcbiAgICAudmFsdWUoKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBjYXBhYmlsaXRpZXNcbiAqIEB0ZW1wbGF0ZSB7Q29uc3RyYWludHN9IFtDPXt9XVxuICogQHBhcmFtIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5XM0NDYXBhYmlsaXRpZXM8Qz59IGNhcHNcbiAqIEBwYXJhbSB7Q30gW2NvbnN0cmFpbnRzXVxuICogQHBhcmFtIHtib29sZWFufSBbc2hvdWxkVmFsaWRhdGVDYXBzXVxuICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvd2ViZHJpdmVyLyNwcm9jZXNzaW5nLWNhcGFiaWxpdGllc1xuICovXG5mdW5jdGlvbiBwYXJzZUNhcHMoY2FwcywgY29uc3RyYWludHMgPSAvKiogQHR5cGUge0N9ICovICh7fSksIHNob3VsZFZhbGlkYXRlQ2FwcyA9IHRydWUpIHtcbiAgLy8gSWYgY2FwYWJpbGl0aWVzIHJlcXVlc3QgaXMgbm90IGFuIG9iamVjdCwgcmV0dXJuIGVycm9yICgjMS4xKVxuICBpZiAoIV8uaXNQbGFpbk9iamVjdChjYXBzKSkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IoXG4gICAgICAnVGhlIGNhcGFiaWxpdGllcyBhcmd1bWVudCB3YXMgbm90IHZhbGlkIGZvciB0aGUgZm9sbG93aW5nIHJlYXNvbihzKTogXCJjYXBhYmlsaXRpZXNcIiBtdXN0IGJlIGEgSlNPTiBvYmplY3QuJ1xuICAgICk7XG4gIH1cblxuICAvLyBMZXQgJ3JlcXVpcmVkQ2FwcycgYmUgcHJvcGVydHkgbmFtZWQgJ2Fsd2F5c01hdGNoJyBmcm9tIGNhcGFiaWxpdGllcyByZXF1ZXN0ICgjMilcbiAgLy8gYW5kICdhbGxGaXJzdE1hdGNoQ2FwcycgYmUgcHJvcGVydHkgbmFtZWQgJ2ZpcnN0TWF0Y2gnIGZyb20gY2FwYWJpbGl0aWVzIHJlcXVlc3QgKCMzKVxuICBsZXQge1xuICAgIGFsd2F5c01hdGNoOiByZXF1aXJlZENhcHMgPSB7fSwgLy8gSWYgJ3JlcXVpcmVkQ2FwcycgaXMgdW5kZWZpbmVkLCBzZXQgaXQgdG8gYW4gZW1wdHkgSlNPTiBvYmplY3QgKCMyLjEpXG4gICAgZmlyc3RNYXRjaDogYWxsRmlyc3RNYXRjaENhcHMgPSBbe31dLCAvLyBJZiAnZmlyc3RNYXRjaCcgaXMgdW5kZWZpbmVkIHNldCBpdCB0byBhIHNpbmdsZXRvbiBsaXN0IHdpdGggb25lIGVtcHR5IG9iamVjdCAoIzMuMSlcbiAgfSA9IGNhcHM7XG5cbiAgLy8gUmVqZWN0ICdmaXJzdE1hdGNoJyBhcmd1bWVudCBpZiBpdCdzIG5vdCBhbiBhcnJheSAoIzMuMilcbiAgaWYgKCFfLmlzQXJyYXkoYWxsRmlyc3RNYXRjaENhcHMpKSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkQXJndW1lbnRFcnJvcihcbiAgICAgICdUaGUgY2FwYWJpbGl0aWVzLmZpcnN0TWF0Y2ggYXJndW1lbnQgd2FzIG5vdCB2YWxpZCBmb3IgdGhlIGZvbGxvd2luZyByZWFzb24ocyk6IFwiY2FwYWJpbGl0aWVzLmZpcnN0TWF0Y2hcIiBtdXN0IGJlIGEgSlNPTiBhcnJheSBvciB1bmRlZmluZWQnXG4gICAgKTtcbiAgfVxuXG4gIC8vIElmIGFuIGVtcHR5IGFycmF5IGFzIHByb3ZpZGVkLCB3ZSdsbCBiZSBmb3JnaXZpbmcgYW5kIG1ha2UgaXQgYW4gYXJyYXkgb2Ygb25lIGVtcHR5IG9iamVjdFxuICAvLyBJbiB0aGUgZnV0dXJlLCByZWplY3QgJ2ZpcnN0TWF0Y2gnIGFyZ3VtZW50IGlmIGl0cyBhcnJheSBkaWQgbm90IGhhdmUgb25lIG9yIG1vcmUgZW50cmllcyAoIzMuMilcbiAgaWYgKGFsbEZpcnN0TWF0Y2hDYXBzLmxlbmd0aCA9PT0gMCkge1xuICAgIGxvZy53YXJuKFxuICAgICAgYFRoZSBmaXJzdE1hdGNoIGFycmF5IGluIHRoZSBnaXZlbiBjYXBhYmlsaXRpZXMgaGFzIG5vIGVudHJpZXMuIEFkZGluZyBhbiBlbXB0eSBlbnRyeSBmbyBybm93LCBgICtcbiAgICAgICAgYGJ1dCBpdCB3aWxsIHJlcXVpcmUgb25lIG9yIG1vcmUgZW50cmllcyBhcyBXM0Mgc3BlYy5gXG4gICAgKTtcbiAgICBhbGxGaXJzdE1hdGNoQ2Fwcy5wdXNoKHt9KTtcbiAgfVxuXG4gIC8vIENoZWNrIGZvciBub24tcHJlZml4ZWQsIG5vbi1zdGFuZGFyZCBjYXBhYmlsaXRpZXMgYW5kIGxvZyB3YXJuaW5ncyBpZiB0aGV5IGFyZSBmb3VuZFxuICBsZXQgbm9uUHJlZml4ZWRDYXBzID0gZmluZE5vblByZWZpeGVkQ2FwcyhjYXBzKTtcbiAgaWYgKCFfLmlzRW1wdHkobm9uUHJlZml4ZWRDYXBzKSkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEFyZ3VtZW50RXJyb3IoXG4gICAgICBgQWxsIG5vbi1zdGFuZGFyZCBjYXBhYmlsaXRpZXMgc2hvdWxkIGhhdmUgYSB2ZW5kb3IgcHJlZml4LiBUaGUgZm9sbG93aW5nIGNhcGFiaWxpdGllcyBkaWQgbm90IGhhdmUgb25lOiAke25vblByZWZpeGVkQ2Fwc31gXG4gICAgKTtcbiAgfVxuXG4gIC8vIFN0cmlwIG91dCB0aGUgJ2FwcGl1bTonIHByZWZpeCBmcm9tIGFsbFxuICBsZXQgc3RyaXBwZWRSZXF1aXJlZENhcHMgPSBzdHJpcEFwcGl1bVByZWZpeGVzKHJlcXVpcmVkQ2Fwcyk7XG4gIGxldCBzdHJpcHBlZEFsbEZpcnN0TWF0Y2hDYXBzID0gYWxsRmlyc3RNYXRjaENhcHMubWFwKHN0cmlwQXBwaXVtUHJlZml4ZXMpO1xuXG4gIC8vIFZhbGlkYXRlIHRoZSByZXF1aXJlZENhcHMuIEJ1dCBkb24ndCB2YWxpZGF0ZSAncHJlc2VuY2UnIGJlY2F1c2UgaWYgdGhhdCBjb25zdHJhaW50IGZhaWxzIG9uICdhbHdheXNNYXRjaCcgaXQgY291bGQgc3RpbGwgcGFzcyBvbiBvbmUgb2YgdGhlICdmaXJzdE1hdGNoJyBrZXlzXG4gIGlmIChzaG91bGRWYWxpZGF0ZUNhcHMpIHtcbiAgICBzdHJpcHBlZFJlcXVpcmVkQ2FwcyA9IHZhbGlkYXRlQ2FwcyhzdHJpcHBlZFJlcXVpcmVkQ2FwcywgY29uc3RyYWludHMsIHtcbiAgICAgIHNraXBQcmVzZW5jZUNvbnN0cmFpbnQ6IHRydWUsXG4gICAgfSk7XG4gIH1cbiAgLy8gUmVtb3ZlIHRoZSAncHJlc2VuY2UnIGNvbnN0cmFpbnQgZm9yIGFueSBrZXlzIHRoYXQgYXJlIGFscmVhZHkgcHJlc2VudCBpbiAncmVxdWlyZWRDYXBzJ1xuICAvLyBzaW5jZSB3ZSBrbm93IHRoYXQgdGhpcyBjb25zdHJhaW50IGhhcyBhbHJlYWR5IHBhc3NlZFxuICBjb25zdCBmaWx0ZXJlZENvbnN0cmFpbnRzID0gLyoqIEB0eXBlIHtDfSAqLyAoXG4gICAgXy5vbWl0QnkoY29uc3RyYWludHMsIChfLCBrZXkpID0+IGtleSBpbiBzdHJpcHBlZFJlcXVpcmVkQ2FwcylcbiAgKTtcblxuICAvLyBWYWxpZGF0ZSBhbGwgb2YgdGhlIGZpcnN0IG1hdGNoIGNhcGFiaWxpdGllcyBhbmQgcmV0dXJuIGFuIGFycmF5IHdpdGggb25seSB0aGUgdmFsaWQgY2FwcyAoc2VlIHNwZWMgIzUpXG4gIC8qKiBAdHlwZSB7c3RyaW5nW119ICovXG4gIGxldCB2YWxpZGF0aW9uRXJyb3JzID0gW107XG4gIGxldCB2YWxpZGF0ZWRGaXJzdE1hdGNoQ2FwcyA9IF8uY29tcGFjdChcbiAgICBzdHJpcHBlZEFsbEZpcnN0TWF0Y2hDYXBzLm1hcChcbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5DYXBhYmlsaXRpZXM8Qz59IGZpcnN0TWF0Y2hDYXBzXG4gICAgICAgKi9cbiAgICAgIChmaXJzdE1hdGNoQ2FwcykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFZhbGlkYXRlIGZpcnN0TWF0Y2ggY2Fwc1xuICAgICAgICAgIHJldHVybiBzaG91bGRWYWxpZGF0ZUNhcHNcbiAgICAgICAgICAgID8gdmFsaWRhdGVDYXBzKGZpcnN0TWF0Y2hDYXBzLCBmaWx0ZXJlZENvbnN0cmFpbnRzKVxuICAgICAgICAgICAgOiBmaXJzdE1hdGNoQ2FwcztcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHZhbGlkYXRpb25FcnJvcnMucHVzaChlLm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKVxuICApO1xuXG4gIC8vIFRyeSB0byBtZXJnZSByZXF1aXJlZENhcHMgd2l0aCBmaXJzdCBtYXRjaCBjYXBhYmlsaXRpZXMsIGJyZWFrIG9uY2UgaXQgZmluZHMgaXRzIGZpcnN0IG1hdGNoIChzZWUgc3BlYyAjNilcbiAgbGV0IG1hdGNoZWRDYXBzID0gbnVsbDtcbiAgZm9yIChsZXQgZmlyc3RNYXRjaENhcHMgb2YgdmFsaWRhdGVkRmlyc3RNYXRjaENhcHMpIHtcbiAgICB0cnkge1xuICAgICAgbWF0Y2hlZENhcHMgPSBtZXJnZUNhcHMoc3RyaXBwZWRSZXF1aXJlZENhcHMsIGZpcnN0TWF0Y2hDYXBzKTtcbiAgICAgIGlmIChtYXRjaGVkQ2Fwcykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZy53YXJuKGVyci5tZXNzYWdlKTtcbiAgICAgIHZhbGlkYXRpb25FcnJvcnMucHVzaChlcnIubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gUmV0dXJucyB2YXJpYWJsZXMgZm9yIHRlc3RpbmcgcHVycG9zZXNcbiAgcmV0dXJuIHtcbiAgICByZXF1aXJlZENhcHMsXG4gICAgYWxsRmlyc3RNYXRjaENhcHMsXG4gICAgdmFsaWRhdGVkRmlyc3RNYXRjaENhcHMsXG4gICAgbWF0Y2hlZENhcHMsXG4gICAgdmFsaWRhdGlvbkVycm9ycyxcbiAgfTtcbn1cblxuLy8gQ2FsbHMgcGFyc2VDYXBzIGFuZCBqdXN0IHJldHVybnMgdGhlIG1hdGNoZWRDYXBzIHZhcmlhYmxlXG4vKipcbiAqIEB0ZW1wbGF0ZSB7Q29uc3RyYWludHN9IENcbiAqIEBwYXJhbSB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuVzNDQ2FwYWJpbGl0aWVzPEM+fSB3M2NDYXBzXG4gKiBAcGFyYW0ge0N9IFtjb25zdHJhaW50c11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Nob3VsZFZhbGlkYXRlQ2Fwc11cbiAqIEByZXR1cm5zIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5DYXBhYmlsaXRpZXM8Qz59XG4gKi9cbmZ1bmN0aW9uIHByb2Nlc3NDYXBhYmlsaXRpZXMoXG4gIHczY0NhcHMsXG4gIGNvbnN0cmFpbnRzID0gLyoqIEB0eXBlIHtDfSAqLyAoe30pLFxuICBzaG91bGRWYWxpZGF0ZUNhcHMgPSB0cnVlXG4pIHtcbiAgY29uc3Qge21hdGNoZWRDYXBzLCB2YWxpZGF0aW9uRXJyb3JzfSA9IHBhcnNlQ2Fwcyh3M2NDYXBzLCBjb25zdHJhaW50cywgc2hvdWxkVmFsaWRhdGVDYXBzKTtcblxuICAvLyBJZiB3ZSBmb3VuZCBhbiBlcnJvciB0aHJvdyBhbiBleGNlcHRpb25cbiAgaWYgKCF1dGlsLmhhc1ZhbHVlKG1hdGNoZWRDYXBzKSkge1xuICAgIGlmIChfLmlzQXJyYXkodzNjQ2Fwcy5maXJzdE1hdGNoKSAmJiB3M2NDYXBzLmZpcnN0TWF0Y2gubGVuZ3RoID4gMSkge1xuICAgICAgLy8gSWYgdGhlcmUgd2FzIG1vcmUgdGhhbiBvbmUgJ2ZpcnN0TWF0Y2gnIGNhcCwgaW5kaWNhdGUgdGhhdCB3ZSBjb3VsZG4ndCBmaW5kIGEgbWF0Y2hpbmcgY2FwYWJpbGl0aWVzIHNldCBhbmQgc2hvdyBhbGwgdGhlIGVycm9yc1xuICAgICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkQXJndW1lbnRFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBmaW5kIG1hdGNoaW5nIGNhcGFiaWxpdGllcyBmcm9tICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgdzNjQ2Fwc1xuICAgICAgICApfTpcXG4gJHt2YWxpZGF0aW9uRXJyb3JzLmpvaW4oJ1xcbicpfWBcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE90aGVyd2lzZSwganVzdCBzaG93IHRoZSBzaW5ndWxhciBlcnJvciBtZXNzYWdlXG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRBcmd1bWVudEVycm9yKHZhbGlkYXRpb25FcnJvcnNbMF0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAvKiogQHR5cGUge0NhcGFiaWxpdGllczxDPn0gKi8gKG1hdGNoZWRDYXBzID8/IHt9KTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBjb3B5IG9mIGEgY2FwYWJpbGl0aWVzIG9iamVjdCB3aGljaCBoYXMgdGFrZW4gZXZlcnl0aGluZyB3aXRoaW4gdGhlICdvcHRpb25zJ1xuICogY2FwYWJpbGl0eSBhbmQgcHJvbW90ZWQgaXQgdG8gdGhlIHRvcCBsZXZlbC4gTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gaXMgYXNzdW1lZCB0byBiZSBydW4gYWZ0ZXJcbiAqIGFsbCB2ZW5kb3IgcHJlZml4ZXMgaGF2ZSBhbHJlYWR5IGJlZW4gc3RyaXBwZWQgZnJvbSB0aGUgdG9wIGxldmVsLiBTbyB3ZSBhcmUgZGVhbGluZyB3aXRoIGUuZy5cbiAqICdvcHRpb25zJyBhbmQgbm90ICdhcHBpdW06b3B0aW9ucycgYXQgdGhpcyBwb2ludC4gQW55IHByZWZpeGVzIF9pbnNpZGVfIHRoZSAnb3B0aW9ucycgY2FwYWJpbGl0eVxuICogd2lsbCB0aGVtc2VsdmVzIGJlIHN0cmlwcGVkLiBUaGlzIGlzIGRlc2lnbmVkIGFzIGFuIGludGVybmFsIGZ1bmN0aW9uLCBub3Qgb25lIHRvIG9wZXJhdGUgb25cbiAqIHVzZXItY29uc3RydWN0ZWQgY2FwYWJpbGl0aWVzLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcmlnaW5hbENhcHMgLSB0aGUgY2FwYWJpbGl0aWVzIHRvIGFuYWx5emUgYW5kIHByb21vdGUgZnJvbSAnb3B0aW9ucydcbiAqIEByZXR1cm4ge29iamVjdCF9IC0gdGhlIGNhcGFiaWxpdGllcyB3aXRoICdvcHRpb25zJyBwcm9tb3RlZCBpZiBuZWNlc3NhcnlcbiAqL1xuZnVuY3Rpb24gcHJvbW90ZUFwcGl1bU9wdGlvbnMob3JpZ2luYWxDYXBzKSB7XG4gIGNvbnN0IGFwcGl1bU9wdGlvbnMgPSBvcmlnaW5hbENhcHNbQVBQSVVNX09QVFNfQ0FQXTtcbiAgaWYgKCFhcHBpdW1PcHRpb25zKSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsQ2FwcztcbiAgfVxuXG4gIGxldCBjYXBzID0gXy5jbG9uZURlZXAob3JpZ2luYWxDYXBzKTtcbiAgaWYgKCFfLmlzUGxhaW5PYmplY3QoYXBwaXVtT3B0aW9ucykpIHtcbiAgICB0aHJvdyBuZXcgZXJyb3JzLlNlc3Npb25Ob3RDcmVhdGVkRXJyb3IoYFRoZSAke0FQUElVTV9PUFRTX0NBUH0gY2FwYWJpbGl0eSBtdXN0IGJlIGFuIG9iamVjdGApO1xuICB9XG5cbiAgLy8gZmlyc3QgZ2V0IHJpZCBvZiBhbnkgcHJlZml4ZXMgaW5zaWRlIGFwcGl1bTpvcHRpb25zXG4gIGNvbnN0IHN0cmlwcGVkQXBwaXVtT3B0aW9ucyA9IHN0cmlwQXBwaXVtUHJlZml4ZXMoYXBwaXVtT3B0aW9ucyk7XG4gIC8vIHdhcm4gaWYgd2UgYXJlIGdvaW5nIHRvIG92ZXJ3cml0ZSBhbnkga2V5cyBvbiB0aGUgYmFzZSBjYXBzIG9iamVjdFxuICBjb25zdCBvdmVyd3JpdHRlbktleXMgPSBfLmludGVyc2VjdGlvbihPYmplY3Qua2V5cyhjYXBzKSwgT2JqZWN0LmtleXMoc3RyaXBwZWRBcHBpdW1PcHRpb25zKSk7XG4gIGlmIChvdmVyd3JpdHRlbktleXMubGVuZ3RoID4gMCkge1xuICAgIGxvZy53YXJuKFxuICAgICAgYEZvdW5kIGNhcGFiaWxpdGllcyBpbnNpZGUgJHtQUkVGSVhFRF9BUFBJVU1fT1BUU19DQVB9IHRoYXQgd2lsbCBvdmVyd3JpdGUgYCArXG4gICAgICAgIGBjYXBhYmlsaXRpZXMgYXQgdGhlIHRvcCBsZXZlbDogJHtKU09OLnN0cmluZ2lmeShvdmVyd3JpdHRlbktleXMpfWBcbiAgICApO1xuICB9XG5cbiAgLy8gbm93IGp1c3QgYXBwbHkgdGhlbSB0byB0aGUgbWFpbiBjYXBzIG9iamVjdFxuICBjYXBzID0gey4uLmNhcHMsIC4uLnN0cmlwcGVkQXBwaXVtT3B0aW9uc307XG5cbiAgLy8gYW5kIHJlbW92ZSBhbGwgdHJhY2VzIG9mIHRoZSBvcHRpb25zIGNhcFxuICBkZWxldGUgY2Fwc1tBUFBJVU1fT1BUU19DQVBdO1xuICByZXR1cm4gY2Fwcztcbn1cblxuZXhwb3J0IHtcbiAgcGFyc2VDYXBzLFxuICBwcm9jZXNzQ2FwYWJpbGl0aWVzLFxuICB2YWxpZGF0ZUNhcHMsXG4gIG1lcmdlQ2FwcyxcbiAgQVBQSVVNX1ZFTkRPUl9QUkVGSVgsXG4gIEFQUElVTV9PUFRTX0NBUCxcbiAgZmluZE5vblByZWZpeGVkQ2FwcyxcbiAgaXNTdGFuZGFyZENhcCxcbiAgc3RyaXBBcHBpdW1QcmVmaXhlcyxcbiAgcHJvbW90ZUFwcGl1bU9wdGlvbnMsXG4gIFBSRUZJWEVEX0FQUElVTV9PUFRTX0NBUCxcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkNvbnN0cmFpbnRzfSBDb25zdHJhaW50c1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkNvbnN0cmFpbnR9IENvbnN0cmFpbnRcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5TdHJpbmdSZWNvcmR9IFN0cmluZ1JlY29yZFxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkJhc2VEcml2ZXJDYXBDb25zdHJhaW50c30gQmFzZURyaXZlckNhcENvbnN0cmFpbnRzXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBWYWxpZGF0ZUNhcHNPcHRzXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtza2lwUHJlc2VuY2VDb25zdHJhaW50XSAtIGlmIHRydWUsIHNraXAgdGhlIHByZXNlbmNlIGNvbnN0cmFpbnRcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7Q29uc3RyYWludHN9IFtDPUJhc2VEcml2ZXJDYXBDb25zdHJhaW50c11cbiAqIEB0ZW1wbGF0ZSB7U3RyaW5nUmVjb3JkfHZvaWR9IFtFeHRyYT12b2lkXVxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLk5TQ2FwYWJpbGl0aWVzPEMsIEV4dHJhPn0gTlNDYXBhYmlsaXRpZXNcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7Q29uc3RyYWludHN9IFtDPUJhc2VEcml2ZXJDYXBDb25zdHJhaW50c11cbiAqIEB0ZW1wbGF0ZSB7U3RyaW5nUmVjb3JkfHZvaWR9IFtFeHRyYT12b2lkXVxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkNhcGFiaWxpdGllczxDLCBFeHRyYT59IENhcGFiaWxpdGllc1xuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIHtDb25zdHJhaW50c30gW0M9QmFzZURyaXZlckNhcENvbnN0cmFpbnRzXVxuICogQHRlbXBsYXRlIHtTdHJpbmdSZWNvcmR8dm9pZH0gW0V4dHJhPXZvaWRdXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuVzNDQ2FwYWJpbGl0aWVzPEMsIEV4dHJhPn0gVzNDQ2FwYWJpbGl0aWVzXG4gKi9cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLG9CQUFvQixHQUFHLFNBQTdCOztBQUNBLE1BQU1DLGVBQWUsR0FBRyxTQUF4Qjs7QUFDQSxNQUFNQyx3QkFBd0IsR0FBSSxHQUFFRixvQkFBcUIsR0FBRUMsZUFBZ0IsRUFBM0U7OztBQVdBLFNBQVNFLFNBQVQsQ0FBbUJDLE9BQU8sR0FBRyxFQUE3QixFQUFpQ0MsU0FBUyxHQUFHLEVBQTdDLEVBQWlEO0VBQy9DLElBQUlDLE1BQU0sR0FBK0UsRUFDdkYsR0FBR0Y7RUFEb0YsQ0FBekY7O0VBSUEsS0FBSyxJQUFJLENBQUNHLElBQUQsRUFBT0MsS0FBUCxDQUFULElBQXdFQyxlQUFBLENBQUVDLE9BQUYsQ0FBVUwsU0FBVixDQUF4RSxFQUErRjtJQUU3RixJQUFJLENBQUNJLGVBQUEsQ0FBRUUsV0FBRixDQUFjUCxPQUFPLENBQUNHLElBQUQsQ0FBckIsQ0FBTCxFQUFtQztNQUNqQyxNQUFNLElBQUlLLGNBQUEsQ0FBT0Msb0JBQVgsQ0FDSCxhQUFZTixJQUFLLHVDQUFzQ08sSUFBSSxDQUFDQyxTQUFMLENBQ3REWCxPQURzRCxDQUV0RCxvQkFBbUJVLElBQUksQ0FBQ0MsU0FBTCxDQUFlVixTQUFmLENBQTBCLFVBSDNDLENBQU47SUFLRDs7SUFDREMsTUFBTSxDQUFxQ0MsSUFBckMsQ0FBTixHQUFvREMsS0FBcEQ7RUFD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