-
Notifications
You must be signed in to change notification settings - Fork 0
/
source-map.html
327 lines (310 loc) · 101 KB
/
source-map.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
<!doctype html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="data:text/css;base64,LyogVmVuZG9yZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vcm1taC93ZWJ0cmVlbWFwL2Jsb2IvOWZhMGMwNjZhMTBlYTQ0MDJkOTYwYjBjNmMxYTQzMjg0NmFjN2ZjNC93ZWJ0cmVlbWFwLmNzcyAqLwoKLndlYnRyZWVtYXAtbm9kZSB7CiAgLyogUmVxdWlyZWQgYXR0cmlidXRlcy4gKi8KICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgb3ZlcmZsb3c6IGhpZGRlbjsgICAvKiBUbyBoaWRlIG92ZXJsb25nIGNhcHRpb25zLiAqLwogIGJhY2tncm91bmQ6IHdoaXRlOyAgLyogTm9kZXMgbXVzdCBiZSBvcGFxdWUgZm9yIHpJbmRleCBsYXllcmluZy4gKi8KICBib3JkZXI6IHNvbGlkIDFweCBibGFjazsgIC8qIENhbGN1bGF0aW9ucyBhc3N1bWUgMXB4IGJvcmRlci4gKi8KCiAgLyogT3B0aW9uYWw6IENTUyBhbmltYXRpb24uICovCiAgdHJhbnNpdGlvbjogdG9wICAgIDAuM3MsCiAgICAgICAgICAgICAgbGVmdCAgIDAuM3MsCiAgICAgICAgICAgICAgd2lkdGggIDAuM3MsCiAgICAgICAgICAgICAgaGVpZ2h0IDAuM3M7Cn0KCi8qIE9wdGlvbmFsOiBoaWdobGlnaHQgbm9kZXMgb24gbW91c2VvdmVyLiAqLwoud2VidHJlZW1hcC1ub2RlOmhvdmVyIHsKICBiYWNrZ3JvdW5kOiAjZWVlOwp9CgovKiBPcHRpb25hbDogRGlmZmVyZW50IGJhY2tncm91bmQgY29sb3JzIGRlcGVuZGluZyBvbiBzeW1ib2wuICovCi53ZWJ0cmVlbWFwLXN5bWJvbC1ic3MgewogIGJhY2tncm91bmQ6ICM2NkMyQTU7Cn0KLndlYnRyZWVtYXAtc3ltYm9sLWRhdGEgewogIGJhY2tncm91bmQ6ICNGQzhENjI7Cn0KLndlYnRyZWVtYXAtc3ltYm9sLXJlYWQtb25seV9kYXRhIHsKICBiYWNrZ3JvdW5kOiAjOERBMENCOwp9Ci53ZWJ0cmVlbWFwLXN5bWJvbC1jb2RlIHsKICBiYWNrZ3JvdW5kOiAjRTc4QUMzOwp9Ci53ZWJ0cmVlbWFwLXN5bWJvbC13ZWFrX3N5bWJvbCB7CiAgYmFja2dyb3VuZDogI0E2RDg1NDsKfQoud2VidHJlZW1hcC1zeW1ib2wtYnNzLndlYnRyZWVtYXAtYWdncmVnYXRlIHsKICBiYWNrZ3JvdW5kOiAjQjNFMkNEOwp9Ci53ZWJ0cmVlbWFwLXN5bWJvbC1kYXRhLndlYnRyZWVtYXAtYWdncmVnYXRlIHsKICBiYWNrZ3JvdW5kOiAjRkRDREFDOwp9Ci53ZWJ0cmVlbWFwLXN5bWJvbC1yZWFkLW9ubHlfZGF0YS53ZWJ0cmVlbWFwLWFnZ3JlZ2F0ZSB7CiAgYmFja2dyb3VuZDogI0NCRDVFODsKfQoud2VidHJlZW1hcC1zeW1ib2wtY29kZS53ZWJ0cmVlbWFwLWFnZ3JlZ2F0ZSB7CiAgYmFja2dyb3VuZDogI0Y0Q0FFNDsKfQoud2VidHJlZW1hcC1zeW1ib2wtd2Vha19zeW1ib2wud2VidHJlZW1hcC1hZ2dyZWdhdGUgewogIGJhY2tncm91bmQ6ICNFNkY1Qzk7Cn0KCiNsZWdlbmQgPiAqIHsKICBib3JkZXI6IHNvbGlkIDFweCAjNDQ0Owp9CgovKiBPcHRpb25hbDogRGlmZmVyZW50IGJvcmRlcnMgZGVwZW5kaW5nIG9uIGxldmVsLiAqLwoud2VidHJlZW1hcC1sZXZlbDAgewogIGJvcmRlcjogc29saWQgMXB4ICM0NDQ7Cn0KLndlYnRyZWVtYXAtbGV2ZWwxIHsKICBib3JkZXI6IHNvbGlkIDFweCAjNjY2Owp9Ci53ZWJ0cmVlbWFwLWxldmVsMiB7CiAgYm9yZGVyOiBzb2xpZCAxcHggIzg4ODsKfQoud2VidHJlZW1hcC1sZXZlbDMgewogIGJvcmRlcjogc29saWQgMXB4ICNhYWE7Cn0KLndlYnRyZWVtYXAtbGV2ZWw0IHsKICBib3JkZXI6IHNvbGlkIDFweCAjY2NjOwp9CgovKiBPcHRpb25hbDogc3R5bGluZyBvbiBub2RlIGNhcHRpb25zLiAqLwoud2VidHJlZW1hcC1jYXB0aW9uIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZjsKICBmb250LXNpemU6IDExcHg7CiAgcGFkZGluZzogMnB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKLyogT3B0aW9uYWw6IHN0eWxpbmcgb24gY2FwdGlvbnMgb24gbW91c2UgaG92ZXIuICovCi8qLndlYnRyZWVtYXAtbm9kZTpob3ZlciA+IC53ZWJ0cmVlbWFwLWNhcHRpb24gewogIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOwp9Ki8K">
<title>./dist/index.js - Source Map Explorer</title>
<style>
html, body {
height: 100%;
}
body {
font-family: sans-serif;
font-size: 0.8em;
margin: 0;
}
#map {
top: 10px;
bottom: 10px;
left: 10px;
right: 10px;
position: absolute;
cursor: pointer;
-webkit-user-select: none;
}
</style>
</head>
<body>
<div id='map'></div>
</body>
<script>
// https://stackoverflow.com/a/18650828/388951
function formatBytes(bytes, decimals) {
if (bytes == 0) return '0 B';
var k = 1000,
dm = decimals || 2,
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
</script>
<script>
var tree = {
"node_modules/lodash/_setCacheHas.js": 1013,
"node_modules/object-assign/index.js": 927,
"node_modules/react/cjs/react.production.min.js": 5785,
"node_modules/react/index.js": 69,
"node_modules/prop-types/lib/ReactPropTypesSecret.js": 83,
"node_modules/prop-types/factoryWithThrowingShims.js": 603,
"node_modules/prop-types/index.js": 65,
"node_modules/react-redux/es/utils/PropTypes.js": 569,
"node_modules/react-redux/es/utils/warning.js": 214,
"node_modules/react-redux/es/components/Provider.js": 1800,
"node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js": 650,
"node_modules/invariant/browser.js": 370,
"node_modules/react-redux/es/utils/Subscription.js": 1240,
"node_modules/react-redux/es/components/connectAdvanced.js": 5077,
"node_modules/react-redux/es/utils/shallowEqual.js": 448,
"node_modules/symbol-observable/es/ponyfill.js": 226,
"node_modules/symbol-observable/es/index.js": 368,
"node_modules/redux/es/redux.js": 7148,
"node_modules/lodash-es/_freeGlobal.js": 169,
"node_modules/lodash-es/_root.js": 305,
"node_modules/lodash-es/_Symbol.js": 218,
"node_modules/lodash-es/_getRawTag.js": 422,
"node_modules/lodash-es/_objectToString.js": 184,
"node_modules/lodash-es/_baseGetTag.js": 452,
"node_modules/lodash-es/_overArg.js": 168,
"node_modules/lodash-es/_getPrototype.js": 248,
"node_modules/lodash-es/isObjectLike.js": 166,
"node_modules/lodash-es/isPlainObject.js": 598,
"node_modules/react-redux/es/utils/verifyPlainObject.js": 326,
"node_modules/react-redux/es/connect/wrapMapToProps.js": 810,
"node_modules/react-redux/es/connect/mapDispatchToProps.js": 620,
"node_modules/react-redux/es/connect/mapStateToProps.js": 409,
"node_modules/react-redux/es/connect/mergeProps.js": 833,
"node_modules/react-redux/es/connect/verifySubselectors.js": 531,
"node_modules/react-redux/es/connect/selectorFactory.js": 1132,
"node_modules/react-redux/es/connect/connect.js": 2025,
"node_modules/react-redux/es/index.js": 920,
"node_modules/redux-saga/es/internal/utils.js": 5323,
"node_modules/redux-saga/es/internal/buffers.js": 964,
"node_modules/redux-saga/es/internal/scheduler.js": 307,
"node_modules/redux-saga/es/internal/channel.js": 2666,
"node_modules/redux-saga/es/internal/sagaHelpers/fsmIterator.js": 597,
"node_modules/redux-saga/es/internal/sagaHelpers/takeEvery.js": 847,
"node_modules/redux-saga/es/internal/sagaHelpers/takeLatest.js": 997,
"node_modules/redux-saga/es/internal/sagaHelpers/throttle.js": 1089,
"node_modules/redux-saga/es/internal/sagaHelpers/index.js": 1125,
"node_modules/redux-saga/es/internal/io.js": 5493,
"node_modules/redux-saga/es/internal/proc.js": 8555,
"node_modules/redux-saga/es/internal/runSaga.js": 1055,
"node_modules/redux-saga/es/internal/middleware.js": 1488,
"node_modules/redux-saga/es/effects.js": 1955,
"node_modules/redux-saga/es/utils.js": 1108,
"node_modules/redux-saga/es/index.js": 1818,
"node_modules/redux-devtools-extension/index.js": 474,
"node_modules/@babel/runtime/helpers/taggedTemplateLiteral.js": 131,
"node_modules/@babel/runtime/helpers/classCallCheck.js": 111,
"node_modules/@babel/runtime/helpers/createClass.js": 240,
"node_modules/@babel/runtime/helpers/typeof.js": 496,
"node_modules/@babel/runtime/helpers/assertThisInitialized.js": 140,
"node_modules/@babel/runtime/helpers/possibleConstructorReturn.js": 160,
"node_modules/@babel/runtime/helpers/getPrototypeOf.js": 162,
"node_modules/@babel/runtime/helpers/setPrototypeOf.js": 125,
"node_modules/@babel/runtime/helpers/inherits.js": 279,
"node_modules/@babel/runtime/helpers/defineProperty.js": 137,
"node_modules/@babel/runtime/helpers/objectSpread.js": 375,
"node_modules/fbjs/lib/hyphenate.js": 101,
"node_modules/fbjs/lib/hyphenateStyleName.js": 112,
"node_modules/stylis/stylis.js": 12062,
"node_modules/stylis-rule-sheet/index.js": 521,
"node_modules/react-is/cjs/react-is.production.min.js": 1658,
"node_modules/react-is/index.js": 72,
"../.config/yarn/global/node_modules/process/browser.js": 1675,
"src/constructors/injectGlobal.js": 30318,
"src/models/StyleTags.js": 18,
"src/models/StyleSheetManager.js": 39,
"src/models/ThemeProvider.js": 10,
"src/models/StyledComponent.js": 73,
"src/models/ComponentStyle.js": 18,
"src/constructors/keyframes.js": 19,
"node_modules/lodash/isObject.js": 91,
"node_modules/lodash/_freeGlobal.js": 82,
"node_modules/lodash/_root.js": 140,
"node_modules/lodash/_Symbol.js": 53,
"node_modules/lodash/_getRawTag.js": 245,
"node_modules/lodash/_objectToString.js": 84,
"node_modules/lodash/_baseGetTag.js": 239,
"node_modules/lodash/isObjectLike.js": 66,
"node_modules/lodash/isSymbol.js": 150,
"node_modules/lodash/toNumber.js": 418,
"node_modules/lodash/toFinite.js": 152,
"node_modules/lodash/toInteger.js": 98,
"node_modules/lodash/_arrayMap.js": 111,
"node_modules/lodash/isArray.js": 37,
"node_modules/lodash/_baseToString.js": 307,
"node_modules/lodash/toString.js": 87,
"node_modules/lodash/_createRound.js": 306,
"node_modules/lodash/round.js": 62,
"src/GradientContainer/ReactGradientContainer.ducks.js": 1359,
"src/GradientContainer/ReactGradientContainer.jsx": 2146,
"node_modules/@babel/runtime/helpers/arrayWithHoles.js": 60,
"node_modules/@babel/runtime/helpers/iterableToArrayLimit.js": 255,
"node_modules/@babel/runtime/helpers/nonIterableRest.js": 106,
"node_modules/@babel/runtime/helpers/slicedToArray.js": 159,
"node_modules/regenerator-runtime/runtime.js": 6333,
"node_modules/regenerator-runtime/runtime-module.js": 367,
"node_modules/@babel/runtime/regenerator/index.js": 46,
"node_modules/lodash/_baseSlice.js": 167,
"node_modules/lodash/eq.js": 58,
"node_modules/lodash/isFunction.js": 244,
"node_modules/lodash/isLength.js": 99,
"node_modules/lodash/isArrayLike.js": 120,
"node_modules/lodash/_isIndex.js": 174,
"node_modules/lodash/_isIterateeCall.js": 238,
"node_modules/lodash/chunk.js": 292,
"node_modules/lodash/_listCacheClear.js": 59,
"node_modules/lodash/_assocIndexOf.js": 113,
"node_modules/lodash/_listCacheDelete.js": 189,
"node_modules/lodash/_listCacheGet.js": 119,
"node_modules/lodash/_listCacheHas.js": 93,
"node_modules/lodash/_listCacheSet.js": 149,
"node_modules/lodash/_ListCache.js": 367,
"node_modules/lodash/_stackClear.js": 92,
"node_modules/lodash/_stackDelete.js": 91,
"node_modules/lodash/_stackGet.js": 59,
"node_modules/lodash/_stackHas.js": 59,
"node_modules/lodash/_coreJsData.js": 68,
"node_modules/lodash/_isMasked.js": 179,
"node_modules/lodash/_toSource.js": 148,
"node_modules/lodash/_baseIsNative.js": 427,
"node_modules/lodash/_getValue.js": 60,
"node_modules/lodash/_getNative.js": 125,
"node_modules/lodash/_Map.js": 81,
"node_modules/lodash/_nativeCreate.js": 68,
"node_modules/lodash/_hashClear.js": 102,
"node_modules/lodash/_hashDelete.js": 100,
"node_modules/lodash/_hashGet.js": 222,
"node_modules/lodash/_hashHas.js": 157,
"node_modules/lodash/_hashSet.js": 178,
"node_modules/lodash/_Hash.js": 342,
"node_modules/lodash/_mapCacheClear.js": 167,
"node_modules/lodash/_isKeyable.js": 129,
"node_modules/lodash/_getMapData.js": 136,
"node_modules/lodash/_mapCacheDelete.js": 114,
"node_modules/lodash/_mapCacheGet.js": 86,
"node_modules/lodash/_mapCacheHas.js": 86,
"node_modules/lodash/_mapCacheSet.js": 137,
"node_modules/lodash/_MapCache.js": 362,
"node_modules/lodash/_stackSet.js": 300,
"node_modules/lodash/_Stack.js": 332,
"node_modules/lodash/_setCacheAdd.js": 100,
"node_modules/lodash/_SetCache.js": 245,
"node_modules/lodash/_arraySome.js": 107,
"node_modules/lodash/_cacheHas.js": 49,
"node_modules/lodash/_equalArrays.js": 568,
"node_modules/lodash/_Uint8Array.js": 57,
"node_modules/lodash/_mapToArray.js": 104,
"node_modules/lodash/_setToArray.js": 98,
"node_modules/lodash/_equalByTag.js": 974,
"node_modules/lodash/_arrayPush.js": 96,
"node_modules/lodash/_baseGetAllKeys.js": 123,
"node_modules/lodash/_arrayFilter.js": 125,
"node_modules/lodash/stubArray.js": 39,
"node_modules/lodash/_getSymbols.js": 240,
"node_modules/lodash/_baseTimes.js": 83,
"node_modules/lodash/_baseIsArguments.js": 134,
"node_modules/lodash/isArguments.js": 248,
"node_modules/lodash/stubFalse.js": 39,
"node_modules/lodash/isBuffer.js": 262,
"node_modules/lodash/_baseIsTypedArray.js": 813,
"node_modules/lodash/_baseUnary.js": 63,
"node_modules/lodash/_nodeUtil.js": 326,
"node_modules/lodash/isTypedArray.js": 136,
"node_modules/lodash/_arrayLikeKeys.js": 494,
"node_modules/lodash/_isPrototype.js": 127,
"node_modules/lodash/_overArg.js": 68,
"node_modules/lodash/_nativeKeys.js": 69,
"node_modules/lodash/_baseKeys.js": 231,
"node_modules/lodash/keys.js": 139,
"node_modules/lodash/_getAllKeys.js": 129,
"node_modules/lodash/_equalObjects.js": 681,
"node_modules/lodash/_DataView.js": 86,
"node_modules/lodash/_Promise.js": 85,
"node_modules/lodash/_Set.js": 81,
"node_modules/lodash/_WeakMap.js": 85,
"node_modules/lodash/_getTag.js": 623,
"node_modules/lodash/_baseIsEqualDeep.js": 738,
"node_modules/lodash/_baseIsEqual.js": 176,
"node_modules/lodash/_baseIsMatch.js": 410,
"node_modules/lodash/_isStrictComparable.js": 78,
"node_modules/lodash/_getMatchData.js": 165,
"node_modules/lodash/_matchesStrictComparable.js": 110,
"node_modules/lodash/_baseMatches.js": 226,
"node_modules/lodash/_isKey.js": 293,
"node_modules/lodash/memoize.js": 357,
"node_modules/lodash/_memoizeCapped.js": 138,
"node_modules/lodash/_stringToPath.js": 299,
"node_modules/lodash/_castPath.js": 168,
"node_modules/lodash/_toKey.js": 142,
"node_modules/lodash/_baseGet.js": 169,
"node_modules/lodash/get.js": 113,
"node_modules/lodash/_baseHasIn.js": 64,
"node_modules/lodash/_hasPath.js": 353,
"node_modules/lodash/hasIn.js": 112,
"node_modules/lodash/_baseMatchesProperty.js": 329,
"node_modules/lodash/identity.js": 40,
"node_modules/lodash/_baseProperty.js": 78,
"node_modules/lodash/_basePropertyDeep.js": 93,
"node_modules/lodash/property.js": 166,
"node_modules/lodash/_baseIteratee.js": 256,
"node_modules/lodash/_createBaseFor.js": 156,
"node_modules/lodash/_baseFor.js": 57,
"node_modules/lodash/_baseForOwn.js": 100,
"node_modules/lodash/_createBaseEach.js": 212,
"node_modules/lodash/_baseEach.js": 86,
"node_modules/lodash/_baseMap.js": 171,
"node_modules/lodash/map.js": 165,
"node_modules/lodash/_baseNth.js": 116,
"node_modules/lodash/nth.js": 122,
"node_modules/lodash/toUpper.js": 85,
"src/utils/helpers.js": 821,
"src/GradientContainer/ReactGradientContainer.sagas.js": 1773,
"src/GradientContainer/index.js": 526,
"src/index.jsx": 838,
"<unmapped>": 18903
};
</script>
<script src="data:application/javascript;base64,Ly8gICAgIFVuZGVyc2NvcmUuanMgMS45LjEKLy8gICAgIGh0dHA6Ly91bmRlcnNjb3JlanMub3JnCi8vICAgICAoYykgMjAwOS0yMDE4IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzCi8vICAgICBVbmRlcnNjb3JlIG1heSBiZSBmcmVlbHkgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLgoKKGZ1bmN0aW9uKCkgewoKICAvLyBCYXNlbGluZSBzZXR1cAogIC8vIC0tLS0tLS0tLS0tLS0tCgogIC8vIEVzdGFibGlzaCB0aGUgcm9vdCBvYmplY3QsIGB3aW5kb3dgIChgc2VsZmApIGluIHRoZSBicm93c2VyLCBgZ2xvYmFsYAogIC8vIG9uIHRoZSBzZXJ2ZXIsIG9yIGB0aGlzYCBpbiBzb21lIHZpcnR1YWwgbWFjaGluZXMuIFdlIHVzZSBgc2VsZmAKICAvLyBpbnN0ZWFkIG9mIGB3aW5kb3dgIGZvciBgV2ViV29ya2VyYCBzdXBwb3J0LgogIHZhciByb290ID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZi5zZWxmID09PSBzZWxmICYmIHNlbGYgfHwKICAgICAgICAgICAgdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwuZ2xvYmFsID09PSBnbG9iYWwgJiYgZ2xvYmFsIHx8CiAgICAgICAgICAgIHRoaXMgfHwKICAgICAgICAgICAge307CgogIC8vIFNhdmUgdGhlIHByZXZpb3VzIHZhbHVlIG9mIHRoZSBgX2AgdmFyaWFibGUuCiAgdmFyIHByZXZpb3VzVW5kZXJzY29yZSA9IHJvb3QuXzsKCiAgLy8gU2F2ZSBieXRlcyBpbiB0aGUgbWluaWZpZWQgKGJ1dCBub3QgZ3ppcHBlZCkgdmVyc2lvbjoKICB2YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSwgT2JqUHJvdG8gPSBPYmplY3QucHJvdG90eXBlOwogIHZhciBTeW1ib2xQcm90byA9IHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnID8gU3ltYm9sLnByb3RvdHlwZSA6IG51bGw7CgogIC8vIENyZWF0ZSBxdWljayByZWZlcmVuY2UgdmFyaWFibGVzIGZvciBzcGVlZCBhY2Nlc3MgdG8gY29yZSBwcm90b3R5cGVzLgogIHZhciBwdXNoID0gQXJyYXlQcm90by5wdXNoLAogICAgICBzbGljZSA9IEFycmF5UHJvdG8uc2xpY2UsCiAgICAgIHRvU3RyaW5nID0gT2JqUHJvdG8udG9TdHJpbmcsCiAgICAgIGhhc093blByb3BlcnR5ID0gT2JqUHJvdG8uaGFzT3duUHJvcGVydHk7CgogIC8vIEFsbCAqKkVDTUFTY3JpcHQgNSoqIG5hdGl2ZSBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMgdGhhdCB3ZSBob3BlIHRvIHVzZQogIC8vIGFyZSBkZWNsYXJlZCBoZXJlLgogIHZhciBuYXRpdmVJc0FycmF5ID0gQXJyYXkuaXNBcnJheSwKICAgICAgbmF0aXZlS2V5cyA9IE9iamVjdC5rZXlzLAogICAgICBuYXRpdmVDcmVhdGUgPSBPYmplY3QuY3JlYXRlOwoKICAvLyBOYWtlZCBmdW5jdGlvbiByZWZlcmVuY2UgZm9yIHN1cnJvZ2F0ZS1wcm90b3R5cGUtc3dhcHBpbmcuCiAgdmFyIEN0b3IgPSBmdW5jdGlvbigpe307CgogIC8vIENyZWF0ZSBhIHNhZmUgcmVmZXJlbmNlIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdCBmb3IgdXNlIGJlbG93LgogIHZhciBfID0gZnVuY3Rpb24ob2JqKSB7CiAgICBpZiAob2JqIGluc3RhbmNlb2YgXykgcmV0dXJuIG9iajsKICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBfKSkgcmV0dXJuIG5ldyBfKG9iaik7CiAgICB0aGlzLl93cmFwcGVkID0gb2JqOwogIH07CgogIC8vIEV4cG9ydCB0aGUgVW5kZXJzY29yZSBvYmplY3QgZm9yICoqTm9kZS5qcyoqLCB3aXRoCiAgLy8gYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgZm9yIHRoZWlyIG9sZCBtb2R1bGUgQVBJLiBJZiB3ZSdyZSBpbgogIC8vIHRoZSBicm93c2VyLCBhZGQgYF9gIGFzIGEgZ2xvYmFsIG9iamVjdC4KICAvLyAoYG5vZGVUeXBlYCBpcyBjaGVja2VkIHRvIGVuc3VyZSB0aGF0IGBtb2R1bGVgCiAgLy8gYW5kIGBleHBvcnRzYCBhcmUgbm90IEhUTUwgZWxlbWVudHMuKQogIGlmICh0eXBlb2YgZXhwb3J0cyAhPSAndW5kZWZpbmVkJyAmJiAhZXhwb3J0cy5ub2RlVHlwZSkgewogICAgaWYgKHR5cGVvZiBtb2R1bGUgIT0gJ3VuZGVmaW5lZCcgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfOwogICAgfQogICAgZXhwb3J0cy5fID0gXzsKICB9IGVsc2UgewogICAgcm9vdC5fID0gXzsKICB9CgogIC8vIEN1cnJlbnQgdmVyc2lvbi4KICBfLlZFUlNJT04gPSAnMS45LjEnOwoKICAvLyBJbnRlcm5hbCBmdW5jdGlvbiB0aGF0IHJldHVybnMgYW4gZWZmaWNpZW50IChmb3IgY3VycmVudCBlbmdpbmVzKSB2ZXJzaW9uCiAgLy8gb2YgdGhlIHBhc3NlZC1pbiBjYWxsYmFjaywgdG8gYmUgcmVwZWF0ZWRseSBhcHBsaWVkIGluIG90aGVyIFVuZGVyc2NvcmUKICAvLyBmdW5jdGlvbnMuCiAgdmFyIG9wdGltaXplQ2IgPSBmdW5jdGlvbihmdW5jLCBjb250ZXh0LCBhcmdDb3VudCkgewogICAgaWYgKGNvbnRleHQgPT09IHZvaWQgMCkgcmV0dXJuIGZ1bmM7CiAgICBzd2l0Y2ggKGFyZ0NvdW50ID09IG51bGwgPyAzIDogYXJnQ291bnQpIHsKICAgICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICByZXR1cm4gZnVuYy5jYWxsKGNvbnRleHQsIHZhbHVlKTsKICAgICAgfTsKICAgICAgLy8gVGhlIDItYXJndW1lbnQgY2FzZSBpcyBvbWl0dGVkIGJlY2F1c2Ugd2XigJlyZSBub3QgdXNpbmcgaXQuCiAgICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikgewogICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTsKICAgICAgfTsKICAgICAgY2FzZSA0OiByZXR1cm4gZnVuY3Rpb24oYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikgewogICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7CiAgICAgIH07CiAgICB9CiAgICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7CiAgICB9OwogIH07CgogIHZhciBidWlsdGluSXRlcmF0ZWU7CgogIC8vIEFuIGludGVybmFsIGZ1bmN0aW9uIHRvIGdlbmVyYXRlIGNhbGxiYWNrcyB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGVhY2gKICAvLyBlbGVtZW50IGluIGEgY29sbGVjdGlvbiwgcmV0dXJuaW5nIHRoZSBkZXNpcmVkIHJlc3VsdCDigJQgZWl0aGVyIGBpZGVudGl0eWAsCiAgLy8gYW4gYXJiaXRyYXJ5IGNhbGxiYWNrLCBhIHByb3BlcnR5IG1hdGNoZXIsIG9yIGEgcHJvcGVydHkgYWNjZXNzb3IuCiAgdmFyIGNiID0gZnVuY3Rpb24odmFsdWUsIGNvbnRleHQsIGFyZ0NvdW50KSB7CiAgICBpZiAoXy5pdGVyYXRlZSAhPT0gYnVpbHRpbkl0ZXJhdGVlKSByZXR1cm4gXy5pdGVyYXRlZSh2YWx1ZSwgY29udGV4dCk7CiAgICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIF8uaWRlbnRpdHk7CiAgICBpZiAoXy5pc0Z1bmN0aW9uKHZhbHVlKSkgcmV0dXJuIG9wdGltaXplQ2IodmFsdWUsIGNvbnRleHQsIGFyZ0NvdW50KTsKICAgIGlmIChfLmlzT2JqZWN0KHZhbHVlKSAmJiAhXy5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIF8ubWF0Y2hlcih2YWx1ZSk7CiAgICByZXR1cm4gXy5wcm9wZXJ0eSh2YWx1ZSk7CiAgfTsKCiAgLy8gRXh0ZXJuYWwgd3JhcHBlciBmb3Igb3VyIGNhbGxiYWNrIGdlbmVyYXRvci4gVXNlcnMgbWF5IGN1c3RvbWl6ZQogIC8vIGBfLml0ZXJhdGVlYCBpZiB0aGV5IHdhbnQgYWRkaXRpb25hbCBwcmVkaWNhdGUvaXRlcmF0ZWUgc2hvcnRoYW5kIHN0eWxlcy4KICAvLyBUaGlzIGFic3RyYWN0aW9uIGhpZGVzIHRoZSBpbnRlcm5hbC1vbmx5IGFyZ0NvdW50IGFyZ3VtZW50LgogIF8uaXRlcmF0ZWUgPSBidWlsdGluSXRlcmF0ZWUgPSBmdW5jdGlvbih2YWx1ZSwgY29udGV4dCkgewogICAgcmV0dXJuIGNiKHZhbHVlLCBjb250ZXh0LCBJbmZpbml0eSk7CiAgfTsKCiAgLy8gU29tZSBmdW5jdGlvbnMgdGFrZSBhIHZhcmlhYmxlIG51bWJlciBvZiBhcmd1bWVudHMsIG9yIGEgZmV3IGV4cGVjdGVkCiAgLy8gYXJndW1lbnRzIGF0IHRoZSBiZWdpbm5pbmcgYW5kIHRoZW4gYSB2YXJpYWJsZSBudW1iZXIgb2YgdmFsdWVzIHRvIG9wZXJhdGUKICAvLyBvbi4gVGhpcyBoZWxwZXIgYWNjdW11bGF0ZXMgYWxsIHJlbWFpbmluZyBhcmd1bWVudHMgcGFzdCB0aGUgZnVuY3Rpb27igJlzCiAgLy8gYXJndW1lbnQgbGVuZ3RoIChvciBhbiBleHBsaWNpdCBgc3RhcnRJbmRleGApLCBpbnRvIGFuIGFycmF5IHRoYXQgYmVjb21lcwogIC8vIHRoZSBsYXN0IGFyZ3VtZW50LiBTaW1pbGFyIHRvIEVTNuKAmXMgInJlc3QgcGFyYW1ldGVyIi4KICB2YXIgcmVzdEFyZ3VtZW50cyA9IGZ1bmN0aW9uKGZ1bmMsIHN0YXJ0SW5kZXgpIHsKICAgIHN0YXJ0SW5kZXggPSBzdGFydEluZGV4ID09IG51bGwgPyBmdW5jLmxlbmd0aCAtIDEgOiArc3RhcnRJbmRleDsKICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgdmFyIGxlbmd0aCA9IE1hdGgubWF4KGFyZ3VtZW50cy5sZW5ndGggLSBzdGFydEluZGV4LCAwKSwKICAgICAgICAgIHJlc3QgPSBBcnJheShsZW5ndGgpLAogICAgICAgICAgaW5kZXggPSAwOwogICAgICBmb3IgKDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHsKICAgICAgICByZXN0W2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleCArIHN0YXJ0SW5kZXhdOwogICAgICB9CiAgICAgIHN3aXRjaCAoc3RhcnRJbmRleCkgewogICAgICAgIGNhc2UgMDogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzLCByZXN0KTsKICAgICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJndW1lbnRzWzBdLCByZXN0KTsKICAgICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sIHJlc3QpOwogICAgICB9CiAgICAgIHZhciBhcmdzID0gQXJyYXkoc3RhcnRJbmRleCArIDEpOwogICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBzdGFydEluZGV4OyBpbmRleCsrKSB7CiAgICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdOwogICAgICB9CiAgICAgIGFyZ3Nbc3RhcnRJbmRleF0gPSByZXN0OwogICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTsKICAgIH07CiAgfTsKCiAgLy8gQW4gaW50ZXJuYWwgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGEgbmV3IG9iamVjdCB0aGF0IGluaGVyaXRzIGZyb20gYW5vdGhlci4KICB2YXIgYmFzZUNyZWF0ZSA9IGZ1bmN0aW9uKHByb3RvdHlwZSkgewogICAgaWYgKCFfLmlzT2JqZWN0KHByb3RvdHlwZSkpIHJldHVybiB7fTsKICAgIGlmIChuYXRpdmVDcmVhdGUpIHJldHVybiBuYXRpdmVDcmVhdGUocHJvdG90eXBlKTsKICAgIEN0b3IucHJvdG90eXBlID0gcHJvdG90eXBlOwogICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yOwogICAgQ3Rvci5wcm90b3R5cGUgPSBudWxsOwogICAgcmV0dXJuIHJlc3VsdDsKICB9OwoKICB2YXIgc2hhbGxvd1Byb3BlcnR5ID0gZnVuY3Rpb24oa2V5KSB7CiAgICByZXR1cm4gZnVuY3Rpb24ob2JqKSB7CiAgICAgIHJldHVybiBvYmogPT0gbnVsbCA/IHZvaWQgMCA6IG9ialtrZXldOwogICAgfTsKICB9OwoKICB2YXIgaGFzID0gZnVuY3Rpb24ob2JqLCBwYXRoKSB7CiAgICByZXR1cm4gb2JqICE9IG51bGwgJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHBhdGgpOwogIH0KCiAgdmFyIGRlZXBHZXQgPSBmdW5jdGlvbihvYmosIHBhdGgpIHsKICAgIHZhciBsZW5ndGggPSBwYXRoLmxlbmd0aDsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gdm9pZCAwOwogICAgICBvYmogPSBvYmpbcGF0aFtpXV07CiAgICB9CiAgICByZXR1cm4gbGVuZ3RoID8gb2JqIDogdm9pZCAwOwogIH07CgogIC8vIEhlbHBlciBmb3IgY29sbGVjdGlvbiBtZXRob2RzIHRvIGRldGVybWluZSB3aGV0aGVyIGEgY29sbGVjdGlvbgogIC8vIHNob3VsZCBiZSBpdGVyYXRlZCBhcyBhbiBhcnJheSBvciBhcyBhbiBvYmplY3QuCiAgLy8gUmVsYXRlZDogaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgKICAvLyBBdm9pZHMgYSB2ZXJ5IG5hc3R5IGlPUyA4IEpJVCBidWcgb24gQVJNLTY0LiAjMjA5NAogIHZhciBNQVhfQVJSQVlfSU5ERVggPSBNYXRoLnBvdygyLCA1MykgLSAxOwogIHZhciBnZXRMZW5ndGggPSBzaGFsbG93UHJvcGVydHkoJ2xlbmd0aCcpOwogIHZhciBpc0FycmF5TGlrZSA9IGZ1bmN0aW9uKGNvbGxlY3Rpb24pIHsKICAgIHZhciBsZW5ndGggPSBnZXRMZW5ndGgoY29sbGVjdGlvbik7CiAgICByZXR1cm4gdHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPj0gMCAmJiBsZW5ndGggPD0gTUFYX0FSUkFZX0lOREVYOwogIH07CgogIC8vIENvbGxlY3Rpb24gRnVuY3Rpb25zCiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLy8gVGhlIGNvcm5lcnN0b25lLCBhbiBgZWFjaGAgaW1wbGVtZW50YXRpb24sIGFrYSBgZm9yRWFjaGAuCiAgLy8gSGFuZGxlcyByYXcgb2JqZWN0cyBpbiBhZGRpdGlvbiB0byBhcnJheS1saWtlcy4gVHJlYXRzIGFsbAogIC8vIHNwYXJzZSBhcnJheS1saWtlcyBhcyBpZiB0aGV5IHdlcmUgZGVuc2UuCiAgXy5lYWNoID0gXy5mb3JFYWNoID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkgewogICAgaXRlcmF0ZWUgPSBvcHRpbWl6ZUNiKGl0ZXJhdGVlLCBjb250ZXh0KTsKICAgIHZhciBpLCBsZW5ndGg7CiAgICBpZiAoaXNBcnJheUxpa2Uob2JqKSkgewogICAgICBmb3IgKGkgPSAwLCBsZW5ndGggPSBvYmoubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICBpdGVyYXRlZShvYmpbaV0sIGksIG9iaik7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7CiAgICAgIGZvciAoaSA9IDAsIGxlbmd0aCA9IGtleXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICBpdGVyYXRlZShvYmpba2V5c1tpXV0sIGtleXNbaV0sIG9iaik7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBvYmo7CiAgfTsKCiAgLy8gUmV0dXJuIHRoZSByZXN1bHRzIG9mIGFwcGx5aW5nIHRoZSBpdGVyYXRlZSB0byBlYWNoIGVsZW1lbnQuCiAgXy5tYXAgPSBfLmNvbGxlY3QgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7CiAgICBpdGVyYXRlZSA9IGNiKGl0ZXJhdGVlLCBjb250ZXh0KTsKICAgIHZhciBrZXlzID0gIWlzQXJyYXlMaWtlKG9iaikgJiYgXy5rZXlzKG9iaiksCiAgICAgICAgbGVuZ3RoID0gKGtleXMgfHwgb2JqKS5sZW5ndGgsCiAgICAgICAgcmVzdWx0cyA9IEFycmF5KGxlbmd0aCk7CiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgIHZhciBjdXJyZW50S2V5ID0ga2V5cyA/IGtleXNbaW5kZXhdIDogaW5kZXg7CiAgICAgIHJlc3VsdHNbaW5kZXhdID0gaXRlcmF0ZWUob2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopOwogICAgfQogICAgcmV0dXJuIHJlc3VsdHM7CiAgfTsKCiAgLy8gQ3JlYXRlIGEgcmVkdWNpbmcgZnVuY3Rpb24gaXRlcmF0aW5nIGxlZnQgb3IgcmlnaHQuCiAgdmFyIGNyZWF0ZVJlZHVjZSA9IGZ1bmN0aW9uKGRpcikgewogICAgLy8gV3JhcCBjb2RlIHRoYXQgcmVhc3NpZ25zIGFyZ3VtZW50IHZhcmlhYmxlcyBpbiBhIHNlcGFyYXRlIGZ1bmN0aW9uIHRoYW4KICAgIC8vIHRoZSBvbmUgdGhhdCBhY2Nlc3NlcyBgYXJndW1lbnRzLmxlbmd0aGAgdG8gYXZvaWQgYSBwZXJmIGhpdC4gKCMxOTkxKQogICAgdmFyIHJlZHVjZXIgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBtZW1vLCBpbml0aWFsKSB7CiAgICAgIHZhciBrZXlzID0gIWlzQXJyYXlMaWtlKG9iaikgJiYgXy5rZXlzKG9iaiksCiAgICAgICAgICBsZW5ndGggPSAoa2V5cyB8fCBvYmopLmxlbmd0aCwKICAgICAgICAgIGluZGV4ID0gZGlyID4gMCA/IDAgOiBsZW5ndGggLSAxOwogICAgICBpZiAoIWluaXRpYWwpIHsKICAgICAgICBtZW1vID0gb2JqW2tleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4XTsKICAgICAgICBpbmRleCArPSBkaXI7CiAgICAgIH0KICAgICAgZm9yICg7IGluZGV4ID49IDAgJiYgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IGRpcikgewogICAgICAgIHZhciBjdXJyZW50S2V5ID0ga2V5cyA/IGtleXNbaW5kZXhdIDogaW5kZXg7CiAgICAgICAgbWVtbyA9IGl0ZXJhdGVlKG1lbW8sIG9ialtjdXJyZW50S2V5XSwgY3VycmVudEtleSwgb2JqKTsKICAgICAgfQogICAgICByZXR1cm4gbWVtbzsKICAgIH07CgogICAgcmV0dXJuIGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIG1lbW8sIGNvbnRleHQpIHsKICAgICAgdmFyIGluaXRpYWwgPSBhcmd1bWVudHMubGVuZ3RoID49IDM7CiAgICAgIHJldHVybiByZWR1Y2VyKG9iaiwgb3B0aW1pemVDYihpdGVyYXRlZSwgY29udGV4dCwgNCksIG1lbW8sIGluaXRpYWwpOwogICAgfTsKICB9OwoKICAvLyAqKlJlZHVjZSoqIGJ1aWxkcyB1cCBhIHNpbmdsZSByZXN1bHQgZnJvbSBhIGxpc3Qgb2YgdmFsdWVzLCBha2EgYGluamVjdGAsCiAgLy8gb3IgYGZvbGRsYC4KICBfLnJlZHVjZSA9IF8uZm9sZGwgPSBfLmluamVjdCA9IGNyZWF0ZVJlZHVjZSgxKTsKCiAgLy8gVGhlIHJpZ2h0LWFzc29jaWF0aXZlIHZlcnNpb24gb2YgcmVkdWNlLCBhbHNvIGtub3duIGFzIGBmb2xkcmAuCiAgXy5yZWR1Y2VSaWdodCA9IF8uZm9sZHIgPSBjcmVhdGVSZWR1Y2UoLTEpOwoKICAvLyBSZXR1cm4gdGhlIGZpcnN0IHZhbHVlIHdoaWNoIHBhc3NlcyBhIHRydXRoIHRlc3QuIEFsaWFzZWQgYXMgYGRldGVjdGAuCiAgXy5maW5kID0gXy5kZXRlY3QgPSBmdW5jdGlvbihvYmosIHByZWRpY2F0ZSwgY29udGV4dCkgewogICAgdmFyIGtleUZpbmRlciA9IGlzQXJyYXlMaWtlKG9iaikgPyBfLmZpbmRJbmRleCA6IF8uZmluZEtleTsKICAgIHZhciBrZXkgPSBrZXlGaW5kZXIob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpOwogICAgaWYgKGtleSAhPT0gdm9pZCAwICYmIGtleSAhPT0gLTEpIHJldHVybiBvYmpba2V5XTsKICB9OwoKICAvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyB0aGF0IHBhc3MgYSB0cnV0aCB0ZXN0LgogIC8vIEFsaWFzZWQgYXMgYHNlbGVjdGAuCiAgXy5maWx0ZXIgPSBfLnNlbGVjdCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgcHJlZGljYXRlID0gY2IocHJlZGljYXRlLCBjb250ZXh0KTsKICAgIF8uZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkgewogICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgbGlzdCkpIHJlc3VsdHMucHVzaCh2YWx1ZSk7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHRzOwogIH07CgogIC8vIFJldHVybiBhbGwgdGhlIGVsZW1lbnRzIGZvciB3aGljaCBhIHRydXRoIHRlc3QgZmFpbHMuCiAgXy5yZWplY3QgPSBmdW5jdGlvbihvYmosIHByZWRpY2F0ZSwgY29udGV4dCkgewogICAgcmV0dXJuIF8uZmlsdGVyKG9iaiwgXy5uZWdhdGUoY2IocHJlZGljYXRlKSksIGNvbnRleHQpOwogIH07CgogIC8vIERldGVybWluZSB3aGV0aGVyIGFsbCBvZiB0aGUgZWxlbWVudHMgbWF0Y2ggYSB0cnV0aCB0ZXN0LgogIC8vIEFsaWFzZWQgYXMgYGFsbGAuCiAgXy5ldmVyeSA9IF8uYWxsID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHsKICAgIHByZWRpY2F0ZSA9IGNiKHByZWRpY2F0ZSwgY29udGV4dCk7CiAgICB2YXIga2V5cyA9ICFpc0FycmF5TGlrZShvYmopICYmIF8ua2V5cyhvYmopLAogICAgICAgIGxlbmd0aCA9IChrZXlzIHx8IG9iaikubGVuZ3RoOwogICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykgewogICAgICB2YXIgY3VycmVudEtleSA9IGtleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4OwogICAgICBpZiAoIXByZWRpY2F0ZShvYmpbY3VycmVudEtleV0sIGN1cnJlbnRLZXksIG9iaikpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiB0cnVlOwogIH07CgogIC8vIERldGVybWluZSBpZiBhdCBsZWFzdCBvbmUgZWxlbWVudCBpbiB0aGUgb2JqZWN0IG1hdGNoZXMgYSB0cnV0aCB0ZXN0LgogIC8vIEFsaWFzZWQgYXMgYGFueWAuCiAgXy5zb21lID0gXy5hbnkgPSBmdW5jdGlvbihvYmosIHByZWRpY2F0ZSwgY29udGV4dCkgewogICAgcHJlZGljYXRlID0gY2IocHJlZGljYXRlLCBjb250ZXh0KTsKICAgIHZhciBrZXlzID0gIWlzQXJyYXlMaWtlKG9iaikgJiYgXy5rZXlzKG9iaiksCiAgICAgICAgbGVuZ3RoID0gKGtleXMgfHwgb2JqKS5sZW5ndGg7CiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgIHZhciBjdXJyZW50S2V5ID0ga2V5cyA/IGtleXNbaW5kZXhdIDogaW5kZXg7CiAgICAgIGlmIChwcmVkaWNhdGUob2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopKSByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKICAvLyBEZXRlcm1pbmUgaWYgdGhlIGFycmF5IG9yIG9iamVjdCBjb250YWlucyBhIGdpdmVuIGl0ZW0gKHVzaW5nIGA9PT1gKS4KICAvLyBBbGlhc2VkIGFzIGBpbmNsdWRlc2AgYW5kIGBpbmNsdWRlYC4KICBfLmNvbnRhaW5zID0gXy5pbmNsdWRlcyA9IF8uaW5jbHVkZSA9IGZ1bmN0aW9uKG9iaiwgaXRlbSwgZnJvbUluZGV4LCBndWFyZCkgewogICAgaWYgKCFpc0FycmF5TGlrZShvYmopKSBvYmogPSBfLnZhbHVlcyhvYmopOwogICAgaWYgKHR5cGVvZiBmcm9tSW5kZXggIT0gJ251bWJlcicgfHwgZ3VhcmQpIGZyb21JbmRleCA9IDA7CiAgICByZXR1cm4gXy5pbmRleE9mKG9iaiwgaXRlbSwgZnJvbUluZGV4KSA+PSAwOwogIH07CgogIC8vIEludm9rZSBhIG1ldGhvZCAod2l0aCBhcmd1bWVudHMpIG9uIGV2ZXJ5IGl0ZW0gaW4gYSBjb2xsZWN0aW9uLgogIF8uaW52b2tlID0gcmVzdEFyZ3VtZW50cyhmdW5jdGlvbihvYmosIHBhdGgsIGFyZ3MpIHsKICAgIHZhciBjb250ZXh0UGF0aCwgZnVuYzsKICAgIGlmIChfLmlzRnVuY3Rpb24ocGF0aCkpIHsKICAgICAgZnVuYyA9IHBhdGg7CiAgICB9IGVsc2UgaWYgKF8uaXNBcnJheShwYXRoKSkgewogICAgICBjb250ZXh0UGF0aCA9IHBhdGguc2xpY2UoMCwgLTEpOwogICAgICBwYXRoID0gcGF0aFtwYXRoLmxlbmd0aCAtIDFdOwogICAgfQogICAgcmV0dXJuIF8ubWFwKG9iaiwgZnVuY3Rpb24oY29udGV4dCkgewogICAgICB2YXIgbWV0aG9kID0gZnVuYzsKICAgICAgaWYgKCFtZXRob2QpIHsKICAgICAgICBpZiAoY29udGV4dFBhdGggJiYgY29udGV4dFBhdGgubGVuZ3RoKSB7CiAgICAgICAgICBjb250ZXh0ID0gZGVlcEdldChjb250ZXh0LCBjb250ZXh0UGF0aCk7CiAgICAgICAgfQogICAgICAgIGlmIChjb250ZXh0ID09IG51bGwpIHJldHVybiB2b2lkIDA7CiAgICAgICAgbWV0aG9kID0gY29udGV4dFtwYXRoXTsKICAgICAgfQogICAgICByZXR1cm4gbWV0aG9kID09IG51bGwgPyBtZXRob2QgOiBtZXRob2QuYXBwbHkoY29udGV4dCwgYXJncyk7CiAgICB9KTsKICB9KTsKCiAgLy8gQ29udmVuaWVuY2UgdmVyc2lvbiBvZiBhIGNvbW1vbiB1c2UgY2FzZSBvZiBgbWFwYDogZmV0Y2hpbmcgYSBwcm9wZXJ0eS4KICBfLnBsdWNrID0gZnVuY3Rpb24ob2JqLCBrZXkpIHsKICAgIHJldHVybiBfLm1hcChvYmosIF8ucHJvcGVydHkoa2V5KSk7CiAgfTsKCiAgLy8gQ29udmVuaWVuY2UgdmVyc2lvbiBvZiBhIGNvbW1vbiB1c2UgY2FzZSBvZiBgZmlsdGVyYDogc2VsZWN0aW5nIG9ubHkgb2JqZWN0cwogIC8vIGNvbnRhaW5pbmcgc3BlY2lmaWMgYGtleTp2YWx1ZWAgcGFpcnMuCiAgXy53aGVyZSA9IGZ1bmN0aW9uKG9iaiwgYXR0cnMpIHsKICAgIHJldHVybiBfLmZpbHRlcihvYmosIF8ubWF0Y2hlcihhdHRycykpOwogIH07CgogIC8vIENvbnZlbmllbmNlIHZlcnNpb24gb2YgYSBjb21tb24gdXNlIGNhc2Ugb2YgYGZpbmRgOiBnZXR0aW5nIHRoZSBmaXJzdCBvYmplY3QKICAvLyBjb250YWluaW5nIHNwZWNpZmljIGBrZXk6dmFsdWVgIHBhaXJzLgogIF8uZmluZFdoZXJlID0gZnVuY3Rpb24ob2JqLCBhdHRycykgewogICAgcmV0dXJuIF8uZmluZChvYmosIF8ubWF0Y2hlcihhdHRycykpOwogIH07CgogIC8vIFJldHVybiB0aGUgbWF4aW11bSBlbGVtZW50IChvciBlbGVtZW50LWJhc2VkIGNvbXB1dGF0aW9uKS4KICBfLm1heCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpIHsKICAgIHZhciByZXN1bHQgPSAtSW5maW5pdHksIGxhc3RDb21wdXRlZCA9IC1JbmZpbml0eSwKICAgICAgICB2YWx1ZSwgY29tcHV0ZWQ7CiAgICBpZiAoaXRlcmF0ZWUgPT0gbnVsbCB8fCB0eXBlb2YgaXRlcmF0ZWUgPT0gJ251bWJlcicgJiYgdHlwZW9mIG9ialswXSAhPSAnb2JqZWN0JyAmJiBvYmogIT0gbnVsbCkgewogICAgICBvYmogPSBpc0FycmF5TGlrZShvYmopID8gb2JqIDogXy52YWx1ZXMob2JqKTsKICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICAgIHZhbHVlID0gb2JqW2ldOwogICAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIHZhbHVlID4gcmVzdWx0KSB7CiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGl0ZXJhdGVlID0gY2IoaXRlcmF0ZWUsIGNvbnRleHQpOwogICAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2LCBpbmRleCwgbGlzdCkgewogICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUodiwgaW5kZXgsIGxpc3QpOwogICAgICAgIGlmIChjb21wdXRlZCA+IGxhc3RDb21wdXRlZCB8fCBjb21wdXRlZCA9PT0gLUluZmluaXR5ICYmIHJlc3VsdCA9PT0gLUluZmluaXR5KSB7CiAgICAgICAgICByZXN1bHQgPSB2OwogICAgICAgICAgbGFzdENvbXB1dGVkID0gY29tcHV0ZWQ7CiAgICAgICAgfQogICAgICB9KTsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKCiAgLy8gUmV0dXJuIHRoZSBtaW5pbXVtIGVsZW1lbnQgKG9yIGVsZW1lbnQtYmFzZWQgY29tcHV0YXRpb24pLgogIF8ubWluID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkgewogICAgdmFyIHJlc3VsdCA9IEluZmluaXR5LCBsYXN0Q29tcHV0ZWQgPSBJbmZpbml0eSwKICAgICAgICB2YWx1ZSwgY29tcHV0ZWQ7CiAgICBpZiAoaXRlcmF0ZWUgPT0gbnVsbCB8fCB0eXBlb2YgaXRlcmF0ZWUgPT0gJ251bWJlcicgJiYgdHlwZW9mIG9ialswXSAhPSAnb2JqZWN0JyAmJiBvYmogIT0gbnVsbCkgewogICAgICBvYmogPSBpc0FycmF5TGlrZShvYmopID8gb2JqIDogXy52YWx1ZXMob2JqKTsKICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICAgIHZhbHVlID0gb2JqW2ldOwogICAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIHZhbHVlIDwgcmVzdWx0KSB7CiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGl0ZXJhdGVlID0gY2IoaXRlcmF0ZWUsIGNvbnRleHQpOwogICAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2LCBpbmRleCwgbGlzdCkgewogICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUodiwgaW5kZXgsIGxpc3QpOwogICAgICAgIGlmIChjb21wdXRlZCA8IGxhc3RDb21wdXRlZCB8fCBjb21wdXRlZCA9PT0gSW5maW5pdHkgJiYgcmVzdWx0ID09PSBJbmZpbml0eSkgewogICAgICAgICAgcmVzdWx0ID0gdjsKICAgICAgICAgIGxhc3RDb21wdXRlZCA9IGNvbXB1dGVkOwogICAgICAgIH0KICAgICAgfSk7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0OwogIH07CgogIC8vIFNodWZmbGUgYSBjb2xsZWN0aW9uLgogIF8uc2h1ZmZsZSA9IGZ1bmN0aW9uKG9iaikgewogICAgcmV0dXJuIF8uc2FtcGxlKG9iaiwgSW5maW5pdHkpOwogIH07CgogIC8vIFNhbXBsZSAqKm4qKiByYW5kb20gdmFsdWVzIGZyb20gYSBjb2xsZWN0aW9uIHVzaW5nIHRoZSBtb2Rlcm4gdmVyc2lvbiBvZiB0aGUKICAvLyBbRmlzaGVyLVlhdGVzIHNodWZmbGVdKGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRmlzaGVy4oCTWWF0ZXNfc2h1ZmZsZSkuCiAgLy8gSWYgKipuKiogaXMgbm90IHNwZWNpZmllZCwgcmV0dXJucyBhIHNpbmdsZSByYW5kb20gZWxlbWVudC4KICAvLyBUaGUgaW50ZXJuYWwgYGd1YXJkYCBhcmd1bWVudCBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGBtYXBgLgogIF8uc2FtcGxlID0gZnVuY3Rpb24ob2JqLCBuLCBndWFyZCkgewogICAgaWYgKG4gPT0gbnVsbCB8fCBndWFyZCkgewogICAgICBpZiAoIWlzQXJyYXlMaWtlKG9iaikpIG9iaiA9IF8udmFsdWVzKG9iaik7CiAgICAgIHJldHVybiBvYmpbXy5yYW5kb20ob2JqLmxlbmd0aCAtIDEpXTsKICAgIH0KICAgIHZhciBzYW1wbGUgPSBpc0FycmF5TGlrZShvYmopID8gXy5jbG9uZShvYmopIDogXy52YWx1ZXMob2JqKTsKICAgIHZhciBsZW5ndGggPSBnZXRMZW5ndGgoc2FtcGxlKTsKICAgIG4gPSBNYXRoLm1heChNYXRoLm1pbihuLCBsZW5ndGgpLCAwKTsKICAgIHZhciBsYXN0ID0gbGVuZ3RoIC0gMTsKICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBuOyBpbmRleCsrKSB7CiAgICAgIHZhciByYW5kID0gXy5yYW5kb20oaW5kZXgsIGxhc3QpOwogICAgICB2YXIgdGVtcCA9IHNhbXBsZVtpbmRleF07CiAgICAgIHNhbXBsZVtpbmRleF0gPSBzYW1wbGVbcmFuZF07CiAgICAgIHNhbXBsZVtyYW5kXSA9IHRlbXA7CiAgICB9CiAgICByZXR1cm4gc2FtcGxlLnNsaWNlKDAsIG4pOwogIH07CgogIC8vIFNvcnQgdGhlIG9iamVjdCdzIHZhbHVlcyBieSBhIGNyaXRlcmlvbiBwcm9kdWNlZCBieSBhbiBpdGVyYXRlZS4KICBfLnNvcnRCeSA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpIHsKICAgIHZhciBpbmRleCA9IDA7CiAgICBpdGVyYXRlZSA9IGNiKGl0ZXJhdGVlLCBjb250ZXh0KTsKICAgIHJldHVybiBfLnBsdWNrKF8ubWFwKG9iaiwgZnVuY3Rpb24odmFsdWUsIGtleSwgbGlzdCkgewogICAgICByZXR1cm4gewogICAgICAgIHZhbHVlOiB2YWx1ZSwKICAgICAgICBpbmRleDogaW5kZXgrKywKICAgICAgICBjcml0ZXJpYTogaXRlcmF0ZWUodmFsdWUsIGtleSwgbGlzdCkKICAgICAgfTsKICAgIH0pLnNvcnQoZnVuY3Rpb24obGVmdCwgcmlnaHQpIHsKICAgICAgdmFyIGEgPSBsZWZ0LmNyaXRlcmlhOwogICAgICB2YXIgYiA9IHJpZ2h0LmNyaXRlcmlhOwogICAgICBpZiAoYSAhPT0gYikgewogICAgICAgIGlmIChhID4gYiB8fCBhID09PSB2b2lkIDApIHJldHVybiAxOwogICAgICAgIGlmIChhIDwgYiB8fCBiID09PSB2b2lkIDApIHJldHVybiAtMTsKICAgICAgfQogICAgICByZXR1cm4gbGVmdC5pbmRleCAtIHJpZ2h0LmluZGV4OwogICAgfSksICd2YWx1ZScpOwogIH07CgogIC8vIEFuIGludGVybmFsIGZ1bmN0aW9uIHVzZWQgZm9yIGFnZ3JlZ2F0ZSAiZ3JvdXAgYnkiIG9wZXJhdGlvbnMuCiAgdmFyIGdyb3VwID0gZnVuY3Rpb24oYmVoYXZpb3IsIHBhcnRpdGlvbikgewogICAgcmV0dXJuIGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpIHsKICAgICAgdmFyIHJlc3VsdCA9IHBhcnRpdGlvbiA/IFtbXSwgW11dIDoge307CiAgICAgIGl0ZXJhdGVlID0gY2IoaXRlcmF0ZWUsIGNvbnRleHQpOwogICAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgICB2YXIga2V5ID0gaXRlcmF0ZWUodmFsdWUsIGluZGV4LCBvYmopOwogICAgICAgIGJlaGF2aW9yKHJlc3VsdCwgdmFsdWUsIGtleSk7CiAgICAgIH0pOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfTsKICB9OwoKICAvLyBHcm91cHMgdGhlIG9iamVjdCdzIHZhbHVlcyBieSBhIGNyaXRlcmlvbi4gUGFzcyBlaXRoZXIgYSBzdHJpbmcgYXR0cmlidXRlCiAgLy8gdG8gZ3JvdXAgYnksIG9yIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBjcml0ZXJpb24uCiAgXy5ncm91cEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7CiAgICBpZiAoaGFzKHJlc3VsdCwga2V5KSkgcmVzdWx0W2tleV0ucHVzaCh2YWx1ZSk7IGVsc2UgcmVzdWx0W2tleV0gPSBbdmFsdWVdOwogIH0pOwoKICAvLyBJbmRleGVzIHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24sIHNpbWlsYXIgdG8gYGdyb3VwQnlgLCBidXQgZm9yCiAgLy8gd2hlbiB5b3Uga25vdyB0aGF0IHlvdXIgaW5kZXggdmFsdWVzIHdpbGwgYmUgdW5pcXVlLgogIF8uaW5kZXhCeSA9IGdyb3VwKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkgewogICAgcmVzdWx0W2tleV0gPSB2YWx1ZTsKICB9KTsKCiAgLy8gQ291bnRzIGluc3RhbmNlcyBvZiBhbiBvYmplY3QgdGhhdCBncm91cCBieSBhIGNlcnRhaW4gY3JpdGVyaW9uLiBQYXNzCiAgLy8gZWl0aGVyIGEgc3RyaW5nIGF0dHJpYnV0ZSB0byBjb3VudCBieSwgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlCiAgLy8gY3JpdGVyaW9uLgogIF8uY291bnRCeSA9IGdyb3VwKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkgewogICAgaWYgKGhhcyhyZXN1bHQsIGtleSkpIHJlc3VsdFtrZXldKys7IGVsc2UgcmVzdWx0W2tleV0gPSAxOwogIH0pOwoKICB2YXIgcmVTdHJTeW1ib2wgPSAvW15cdWQ4MDAtXHVkZmZmXXxbXHVkODAwLVx1ZGJmZl1bXHVkYzAwLVx1ZGZmZl18W1x1ZDgwMC1cdWRmZmZdL2c7CiAgLy8gU2FmZWx5IGNyZWF0ZSBhIHJlYWwsIGxpdmUgYXJyYXkgZnJvbSBhbnl0aGluZyBpdGVyYWJsZS4KICBfLnRvQXJyYXkgPSBmdW5jdGlvbihvYmopIHsKICAgIGlmICghb2JqKSByZXR1cm4gW107CiAgICBpZiAoXy5pc0FycmF5KG9iaikpIHJldHVybiBzbGljZS5jYWxsKG9iaik7CiAgICBpZiAoXy5pc1N0cmluZyhvYmopKSB7CiAgICAgIC8vIEtlZXAgc3Vycm9nYXRlIHBhaXIgY2hhcmFjdGVycyB0b2dldGhlcgogICAgICByZXR1cm4gb2JqLm1hdGNoKHJlU3RyU3ltYm9sKTsKICAgIH0KICAgIGlmIChpc0FycmF5TGlrZShvYmopKSByZXR1cm4gXy5tYXAob2JqLCBfLmlkZW50aXR5KTsKICAgIHJldHVybiBfLnZhbHVlcyhvYmopOwogIH07CgogIC8vIFJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIGFuIG9iamVjdC4KICBfLnNpemUgPSBmdW5jdGlvbihvYmopIHsKICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIDA7CiAgICByZXR1cm4gaXNBcnJheUxpa2Uob2JqKSA/IG9iai5sZW5ndGggOiBfLmtleXMob2JqKS5sZW5ndGg7CiAgfTsKCiAgLy8gU3BsaXQgYSBjb2xsZWN0aW9uIGludG8gdHdvIGFycmF5czogb25lIHdob3NlIGVsZW1lbnRzIGFsbCBzYXRpc2Z5IHRoZSBnaXZlbgogIC8vIHByZWRpY2F0ZSwgYW5kIG9uZSB3aG9zZSBlbGVtZW50cyBhbGwgZG8gbm90IHNhdGlzZnkgdGhlIHByZWRpY2F0ZS4KICBfLnBhcnRpdGlvbiA9IGdyb3VwKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIHBhc3MpIHsKICAgIHJlc3VsdFtwYXNzID8gMCA6IDFdLnB1c2godmFsdWUpOwogIH0sIHRydWUpOwoKICAvLyBBcnJheSBGdW5jdGlvbnMKICAvLyAtLS0tLS0tLS0tLS0tLS0KCiAgLy8gR2V0IHRoZSBmaXJzdCBlbGVtZW50IG9mIGFuIGFycmF5LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIHRoZSBmaXJzdCBOCiAgLy8gdmFsdWVzIGluIHRoZSBhcnJheS4gQWxpYXNlZCBhcyBgaGVhZGAgYW5kIGB0YWtlYC4gVGhlICoqZ3VhcmQqKiBjaGVjawogIC8vIGFsbG93cyBpdCB0byB3b3JrIHdpdGggYF8ubWFwYC4KICBfLmZpcnN0ID0gXy5oZWFkID0gXy50YWtlID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7CiAgICBpZiAoYXJyYXkgPT0gbnVsbCB8fCBhcnJheS5sZW5ndGggPCAxKSByZXR1cm4gbiA9PSBudWxsID8gdm9pZCAwIDogW107CiAgICBpZiAobiA9PSBudWxsIHx8IGd1YXJkKSByZXR1cm4gYXJyYXlbMF07CiAgICByZXR1cm4gXy5pbml0aWFsKGFycmF5LCBhcnJheS5sZW5ndGggLSBuKTsKICB9OwoKICAvLyBSZXR1cm5zIGV2ZXJ5dGhpbmcgYnV0IHRoZSBsYXN0IGVudHJ5IG9mIHRoZSBhcnJheS4gRXNwZWNpYWxseSB1c2VmdWwgb24KICAvLyB0aGUgYXJndW1lbnRzIG9iamVjdC4gUGFzc2luZyAqKm4qKiB3aWxsIHJldHVybiBhbGwgdGhlIHZhbHVlcyBpbgogIC8vIHRoZSBhcnJheSwgZXhjbHVkaW5nIHRoZSBsYXN0IE4uCiAgXy5pbml0aWFsID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7CiAgICByZXR1cm4gc2xpY2UuY2FsbChhcnJheSwgMCwgTWF0aC5tYXgoMCwgYXJyYXkubGVuZ3RoIC0gKG4gPT0gbnVsbCB8fCBndWFyZCA/IDEgOiBuKSkpOwogIH07CgogIC8vIEdldCB0aGUgbGFzdCBlbGVtZW50IG9mIGFuIGFycmF5LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIHRoZSBsYXN0IE4KICAvLyB2YWx1ZXMgaW4gdGhlIGFycmF5LgogIF8ubGFzdCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkgewogICAgaWYgKGFycmF5ID09IG51bGwgfHwgYXJyYXkubGVuZ3RoIDwgMSkgcmV0dXJuIG4gPT0gbnVsbCA/IHZvaWQgMCA6IFtdOwogICAgaWYgKG4gPT0gbnVsbCB8fCBndWFyZCkgcmV0dXJuIGFycmF5W2FycmF5Lmxlbmd0aCAtIDFdOwogICAgcmV0dXJuIF8ucmVzdChhcnJheSwgTWF0aC5tYXgoMCwgYXJyYXkubGVuZ3RoIC0gbikpOwogIH07CgogIC8vIFJldHVybnMgZXZlcnl0aGluZyBidXQgdGhlIGZpcnN0IGVudHJ5IG9mIHRoZSBhcnJheS4gQWxpYXNlZCBhcyBgdGFpbGAgYW5kIGBkcm9wYC4KICAvLyBFc3BlY2lhbGx5IHVzZWZ1bCBvbiB0aGUgYXJndW1lbnRzIG9iamVjdC4gUGFzc2luZyBhbiAqKm4qKiB3aWxsIHJldHVybgogIC8vIHRoZSByZXN0IE4gdmFsdWVzIGluIHRoZSBhcnJheS4KICBfLnJlc3QgPSBfLnRhaWwgPSBfLmRyb3AgPSBmdW5jdGlvbihhcnJheSwgbiwgZ3VhcmQpIHsKICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCBuID09IG51bGwgfHwgZ3VhcmQgPyAxIDogbik7CiAgfTsKCiAgLy8gVHJpbSBvdXQgYWxsIGZhbHN5IHZhbHVlcyBmcm9tIGFuIGFycmF5LgogIF8uY29tcGFjdCA9IGZ1bmN0aW9uKGFycmF5KSB7CiAgICByZXR1cm4gXy5maWx0ZXIoYXJyYXksIEJvb2xlYW4pOwogIH07CgogIC8vIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIGEgcmVjdXJzaXZlIGBmbGF0dGVuYCBmdW5jdGlvbi4KICB2YXIgZmxhdHRlbiA9IGZ1bmN0aW9uKGlucHV0LCBzaGFsbG93LCBzdHJpY3QsIG91dHB1dCkgewogICAgb3V0cHV0ID0gb3V0cHV0IHx8IFtdOwogICAgdmFyIGlkeCA9IG91dHB1dC5sZW5ndGg7CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gZ2V0TGVuZ3RoKGlucHV0KTsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciB2YWx1ZSA9IGlucHV0W2ldOwogICAgICBpZiAoaXNBcnJheUxpa2UodmFsdWUpICYmIChfLmlzQXJyYXkodmFsdWUpIHx8IF8uaXNBcmd1bWVudHModmFsdWUpKSkgewogICAgICAgIC8vIEZsYXR0ZW4gY3VycmVudCBsZXZlbCBvZiBhcnJheSBvciBhcmd1bWVudHMgb2JqZWN0LgogICAgICAgIGlmIChzaGFsbG93KSB7CiAgICAgICAgICB2YXIgaiA9IDAsIGxlbiA9IHZhbHVlLmxlbmd0aDsKICAgICAgICAgIHdoaWxlIChqIDwgbGVuKSBvdXRwdXRbaWR4KytdID0gdmFsdWVbaisrXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmxhdHRlbih2YWx1ZSwgc2hhbGxvdywgc3RyaWN0LCBvdXRwdXQpOwogICAgICAgICAgaWR4ID0gb3V0cHV0Lmxlbmd0aDsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoIXN0cmljdCkgewogICAgICAgIG91dHB1dFtpZHgrK10gPSB2YWx1ZTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIG91dHB1dDsKICB9OwoKICAvLyBGbGF0dGVuIG91dCBhbiBhcnJheSwgZWl0aGVyIHJlY3Vyc2l2ZWx5IChieSBkZWZhdWx0KSwgb3IganVzdCBvbmUgbGV2ZWwuCiAgXy5mbGF0dGVuID0gZnVuY3Rpb24oYXJyYXksIHNoYWxsb3cpIHsKICAgIHJldHVybiBmbGF0dGVuKGFycmF5LCBzaGFsbG93LCBmYWxzZSk7CiAgfTsKCiAgLy8gUmV0dXJuIGEgdmVyc2lvbiBvZiB0aGUgYXJyYXkgdGhhdCBkb2VzIG5vdCBjb250YWluIHRoZSBzcGVjaWZpZWQgdmFsdWUocykuCiAgXy53aXRob3V0ID0gcmVzdEFyZ3VtZW50cyhmdW5jdGlvbihhcnJheSwgb3RoZXJBcnJheXMpIHsKICAgIHJldHVybiBfLmRpZmZlcmVuY2UoYXJyYXksIG90aGVyQXJyYXlzKTsKICB9KTsKCiAgLy8gUHJvZHVjZSBhIGR1cGxpY2F0ZS1mcmVlIHZlcnNpb24gb2YgdGhlIGFycmF5LiBJZiB0aGUgYXJyYXkgaGFzIGFscmVhZHkKICAvLyBiZWVuIHNvcnRlZCwgeW91IGhhdmUgdGhlIG9wdGlvbiBvZiB1c2luZyBhIGZhc3RlciBhbGdvcml0aG0uCiAgLy8gVGhlIGZhc3RlciBhbGdvcml0aG0gd2lsbCBub3Qgd29yayB3aXRoIGFuIGl0ZXJhdGVlIGlmIHRoZSBpdGVyYXRlZQogIC8vIGlzIG5vdCBhIG9uZS10by1vbmUgZnVuY3Rpb24sIHNvIHByb3ZpZGluZyBhbiBpdGVyYXRlZSB3aWxsIGRpc2FibGUKICAvLyB0aGUgZmFzdGVyIGFsZ29yaXRobS4KICAvLyBBbGlhc2VkIGFzIGB1bmlxdWVgLgogIF8udW5pcSA9IF8udW5pcXVlID0gZnVuY3Rpb24oYXJyYXksIGlzU29ydGVkLCBpdGVyYXRlZSwgY29udGV4dCkgewogICAgaWYgKCFfLmlzQm9vbGVhbihpc1NvcnRlZCkpIHsKICAgICAgY29udGV4dCA9IGl0ZXJhdGVlOwogICAgICBpdGVyYXRlZSA9IGlzU29ydGVkOwogICAgICBpc1NvcnRlZCA9IGZhbHNlOwogICAgfQogICAgaWYgKGl0ZXJhdGVlICE9IG51bGwpIGl0ZXJhdGVlID0gY2IoaXRlcmF0ZWUsIGNvbnRleHQpOwogICAgdmFyIHJlc3VsdCA9IFtdOwogICAgdmFyIHNlZW4gPSBbXTsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBnZXRMZW5ndGgoYXJyYXkpOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaV0sCiAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID8gaXRlcmF0ZWUodmFsdWUsIGksIGFycmF5KSA6IHZhbHVlOwogICAgICBpZiAoaXNTb3J0ZWQgJiYgIWl0ZXJhdGVlKSB7CiAgICAgICAgaWYgKCFpIHx8IHNlZW4gIT09IGNvbXB1dGVkKSByZXN1bHQucHVzaCh2YWx1ZSk7CiAgICAgICAgc2VlbiA9IGNvbXB1dGVkOwogICAgICB9IGVsc2UgaWYgKGl0ZXJhdGVlKSB7CiAgICAgICAgaWYgKCFfLmNvbnRhaW5zKHNlZW4sIGNvbXB1dGVkKSkgewogICAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTsKICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoIV8uY29udGFpbnMocmVzdWx0LCB2YWx1ZSkpIHsKICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKCiAgLy8gUHJvZHVjZSBhbiBhcnJheSB0aGF0IGNvbnRhaW5zIHRoZSB1bmlvbjogZWFjaCBkaXN0aW5jdCBlbGVtZW50IGZyb20gYWxsIG9mCiAgLy8gdGhlIHBhc3NlZC1pbiBhcnJheXMuCiAgXy51bmlvbiA9IHJlc3RBcmd1bWVudHMoZnVuY3Rpb24oYXJyYXlzKSB7CiAgICByZXR1cm4gXy51bmlxKGZsYXR0ZW4oYXJyYXlzLCB0cnVlLCB0cnVlKSk7CiAgfSk7CgogIC8vIFByb2R1Y2UgYW4gYXJyYXkgdGhhdCBjb250YWlucyBldmVyeSBpdGVtIHNoYXJlZCBiZXR3ZWVuIGFsbCB0aGUKICAvLyBwYXNzZWQtaW4gYXJyYXlzLgogIF8uaW50ZXJzZWN0aW9uID0gZnVuY3Rpb24oYXJyYXkpIHsKICAgIHZhciByZXN1bHQgPSBbXTsKICAgIHZhciBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBnZXRMZW5ndGgoYXJyYXkpOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGl0ZW0gPSBhcnJheVtpXTsKICAgICAgaWYgKF8uY29udGFpbnMocmVzdWx0LCBpdGVtKSkgY29udGludWU7CiAgICAgIHZhciBqOwogICAgICBmb3IgKGogPSAxOyBqIDwgYXJnc0xlbmd0aDsgaisrKSB7CiAgICAgICAgaWYgKCFfLmNvbnRhaW5zKGFyZ3VtZW50c1tqXSwgaXRlbSkpIGJyZWFrOwogICAgICB9CiAgICAgIGlmIChqID09PSBhcmdzTGVuZ3RoKSByZXN1bHQucHVzaChpdGVtKTsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKCiAgLy8gVGFrZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG9uZSBhcnJheSBhbmQgYSBudW1iZXIgb2Ygb3RoZXIgYXJyYXlzLgogIC8vIE9ubHkgdGhlIGVsZW1lbnRzIHByZXNlbnQgaW4ganVzdCB0aGUgZmlyc3QgYXJyYXkgd2lsbCByZW1haW4uCiAgXy5kaWZmZXJlbmNlID0gcmVzdEFyZ3VtZW50cyhmdW5jdGlvbihhcnJheSwgcmVzdCkgewogICAgcmVzdCA9IGZsYXR0ZW4ocmVzdCwgdHJ1ZSwgdHJ1ZSk7CiAgICByZXR1cm4gXy5maWx0ZXIoYXJyYXksIGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgcmV0dXJuICFfLmNvbnRhaW5zKHJlc3QsIHZhbHVlKTsKICAgIH0pOwogIH0pOwoKICAvLyBDb21wbGVtZW50IG9mIF8uemlwLiBVbnppcCBhY2NlcHRzIGFuIGFycmF5IG9mIGFycmF5cyBhbmQgZ3JvdXBzCiAgLy8gZWFjaCBhcnJheSdzIGVsZW1lbnRzIG9uIHNoYXJlZCBpbmRpY2VzLgogIF8udW56aXAgPSBmdW5jdGlvbihhcnJheSkgewogICAgdmFyIGxlbmd0aCA9IGFycmF5ICYmIF8ubWF4KGFycmF5LCBnZXRMZW5ndGgpLmxlbmd0aCB8fCAwOwogICAgdmFyIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7CgogICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykgewogICAgICByZXN1bHRbaW5kZXhdID0gXy5wbHVjayhhcnJheSwgaW5kZXgpOwogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKICB9OwoKICAvLyBaaXAgdG9nZXRoZXIgbXVsdGlwbGUgbGlzdHMgaW50byBhIHNpbmdsZSBhcnJheSAtLSBlbGVtZW50cyB0aGF0IHNoYXJlCiAgLy8gYW4gaW5kZXggZ28gdG9nZXRoZXIuCiAgXy56aXAgPSByZXN0QXJndW1lbnRzKF8udW56aXApOwoKICAvLyBDb252ZXJ0cyBsaXN0cyBpbnRvIG9iamVjdHMuIFBhc3MgZWl0aGVyIGEgc2luZ2xlIGFycmF5IG9mIGBba2V5LCB2YWx1ZV1gCiAgLy8gcGFpcnMsIG9yIHR3byBwYXJhbGxlbCBhcnJheXMgb2YgdGhlIHNhbWUgbGVuZ3RoIC0tIG9uZSBvZiBrZXlzLCBhbmQgb25lIG9mCiAgLy8gdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzLiBQYXNzaW5nIGJ5IHBhaXJzIGlzIHRoZSByZXZlcnNlIG9mIF8ucGFpcnMuCiAgXy5vYmplY3QgPSBmdW5jdGlvbihsaXN0LCB2YWx1ZXMpIHsKICAgIHZhciByZXN1bHQgPSB7fTsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBnZXRMZW5ndGgobGlzdCk7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICBpZiAodmFsdWVzKSB7CiAgICAgICAgcmVzdWx0W2xpc3RbaV1dID0gdmFsdWVzW2ldOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdFtsaXN0W2ldWzBdXSA9IGxpc3RbaV1bMV07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKCiAgLy8gR2VuZXJhdG9yIGZ1bmN0aW9uIHRvIGNyZWF0ZSB0aGUgZmluZEluZGV4IGFuZCBmaW5kTGFzdEluZGV4IGZ1bmN0aW9ucy4KICB2YXIgY3JlYXRlUHJlZGljYXRlSW5kZXhGaW5kZXIgPSBmdW5jdGlvbihkaXIpIHsKICAgIHJldHVybiBmdW5jdGlvbihhcnJheSwgcHJlZGljYXRlLCBjb250ZXh0KSB7CiAgICAgIHByZWRpY2F0ZSA9IGNiKHByZWRpY2F0ZSwgY29udGV4dCk7CiAgICAgIHZhciBsZW5ndGggPSBnZXRMZW5ndGgoYXJyYXkpOwogICAgICB2YXIgaW5kZXggPSBkaXIgPiAwID8gMCA6IGxlbmd0aCAtIDE7CiAgICAgIGZvciAoOyBpbmRleCA+PSAwICYmIGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSBkaXIpIHsKICAgICAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkgcmV0dXJuIGluZGV4OwogICAgICB9CiAgICAgIHJldHVybiAtMTsKICAgIH07CiAgfTsKCiAgLy8gUmV0dXJucyB0aGUgZmlyc3QgaW5kZXggb24gYW4gYXJyYXktbGlrZSB0aGF0IHBhc3NlcyBhIHByZWRpY2F0ZSB0ZXN0LgogIF8uZmluZEluZGV4ID0gY3JlYXRlUHJlZGljYXRlSW5kZXhGaW5kZXIoMSk7CiAgXy5maW5kTGFzdEluZGV4ID0gY3JlYXRlUHJlZGljYXRlSW5kZXhGaW5kZXIoLTEpOwoKICAvLyBVc2UgYSBjb21wYXJhdG9yIGZ1bmN0aW9uIHRvIGZpZ3VyZSBvdXQgdGhlIHNtYWxsZXN0IGluZGV4IGF0IHdoaWNoCiAgLy8gYW4gb2JqZWN0IHNob3VsZCBiZSBpbnNlcnRlZCBzbyBhcyB0byBtYWludGFpbiBvcmRlci4gVXNlcyBiaW5hcnkgc2VhcmNoLgogIF8uc29ydGVkSW5kZXggPSBmdW5jdGlvbihhcnJheSwgb2JqLCBpdGVyYXRlZSwgY29udGV4dCkgewogICAgaXRlcmF0ZWUgPSBjYihpdGVyYXRlZSwgY29udGV4dCwgMSk7CiAgICB2YXIgdmFsdWUgPSBpdGVyYXRlZShvYmopOwogICAgdmFyIGxvdyA9IDAsIGhpZ2ggPSBnZXRMZW5ndGgoYXJyYXkpOwogICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHsKICAgICAgdmFyIG1pZCA9IE1hdGguZmxvb3IoKGxvdyArIGhpZ2gpIC8gMik7CiAgICAgIGlmIChpdGVyYXRlZShhcnJheVttaWRdKSA8IHZhbHVlKSBsb3cgPSBtaWQgKyAxOyBlbHNlIGhpZ2ggPSBtaWQ7CiAgICB9CiAgICByZXR1cm4gbG93OwogIH07CgogIC8vIEdlbmVyYXRvciBmdW5jdGlvbiB0byBjcmVhdGUgdGhlIGluZGV4T2YgYW5kIGxhc3RJbmRleE9mIGZ1bmN0aW9ucy4KICB2YXIgY3JlYXRlSW5kZXhGaW5kZXIgPSBmdW5jdGlvbihkaXIsIHByZWRpY2F0ZUZpbmQsIHNvcnRlZEluZGV4KSB7CiAgICByZXR1cm4gZnVuY3Rpb24oYXJyYXksIGl0ZW0sIGlkeCkgewogICAgICB2YXIgaSA9IDAsIGxlbmd0aCA9IGdldExlbmd0aChhcnJheSk7CiAgICAgIGlmICh0eXBlb2YgaWR4ID09ICdudW1iZXInKSB7CiAgICAgICAgaWYgKGRpciA+IDApIHsKICAgICAgICAgIGkgPSBpZHggPj0gMCA/IGlkeCA6IE1hdGgubWF4KGlkeCArIGxlbmd0aCwgaSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGxlbmd0aCA9IGlkeCA+PSAwID8gTWF0aC5taW4oaWR4ICsgMSwgbGVuZ3RoKSA6IGlkeCArIGxlbmd0aCArIDE7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHNvcnRlZEluZGV4ICYmIGlkeCAmJiBsZW5ndGgpIHsKICAgICAgICBpZHggPSBzb3J0ZWRJbmRleChhcnJheSwgaXRlbSk7CiAgICAgICAgcmV0dXJuIGFycmF5W2lkeF0gPT09IGl0ZW0gPyBpZHggOiAtMTsKICAgICAgfQogICAgICBpZiAoaXRlbSAhPT0gaXRlbSkgewogICAgICAgIGlkeCA9IHByZWRpY2F0ZUZpbmQoc2xpY2UuY2FsbChhcnJheSwgaSwgbGVuZ3RoKSwgXy5pc05hTik7CiAgICAgICAgcmV0dXJuIGlkeCA+PSAwID8gaWR4ICsgaSA6IC0xOwogICAgICB9CiAgICAgIGZvciAoaWR4ID0gZGlyID4gMCA/IGkgOiBsZW5ndGggLSAxOyBpZHggPj0gMCAmJiBpZHggPCBsZW5ndGg7IGlkeCArPSBkaXIpIHsKICAgICAgICBpZiAoYXJyYXlbaWR4XSA9PT0gaXRlbSkgcmV0dXJuIGlkeDsKICAgICAgfQogICAgICByZXR1cm4gLTE7CiAgICB9OwogIH07CgogIC8vIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYW4gaXRlbSBpbiBhbiBhcnJheSwKICAvLyBvciAtMSBpZiB0aGUgaXRlbSBpcyBub3QgaW5jbHVkZWQgaW4gdGhlIGFycmF5LgogIC8vIElmIHRoZSBhcnJheSBpcyBsYXJnZSBhbmQgYWxyZWFkeSBpbiBzb3J0IG9yZGVyLCBwYXNzIGB0cnVlYAogIC8vIGZvciAqKmlzU29ydGVkKiogdG8gdXNlIGJpbmFyeSBzZWFyY2guCiAgXy5pbmRleE9mID0gY3JlYXRlSW5kZXhGaW5kZXIoMSwgXy5maW5kSW5kZXgsIF8uc29ydGVkSW5kZXgpOwogIF8ubGFzdEluZGV4T2YgPSBjcmVhdGVJbmRleEZpbmRlcigtMSwgXy5maW5kTGFzdEluZGV4KTsKCiAgLy8gR2VuZXJhdGUgYW4gaW50ZWdlciBBcnJheSBjb250YWluaW5nIGFuIGFyaXRobWV0aWMgcHJvZ3Jlc3Npb24uIEEgcG9ydCBvZgogIC8vIHRoZSBuYXRpdmUgUHl0aG9uIGByYW5nZSgpYCBmdW5jdGlvbi4gU2VlCiAgLy8gW3RoZSBQeXRob24gZG9jdW1lbnRhdGlvbl0oaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L2Z1bmN0aW9ucy5odG1sI3JhbmdlKS4KICBfLnJhbmdlID0gZnVuY3Rpb24oc3RhcnQsIHN0b3AsIHN0ZXApIHsKICAgIGlmIChzdG9wID09IG51bGwpIHsKICAgICAgc3RvcCA9IHN0YXJ0IHx8IDA7CiAgICAgIHN0YXJ0ID0gMDsKICAgIH0KICAgIGlmICghc3RlcCkgewogICAgICBzdGVwID0gc3RvcCA8IHN0YXJ0ID8gLTEgOiAxOwogICAgfQoKICAgIHZhciBsZW5ndGggPSBNYXRoLm1heChNYXRoLmNlaWwoKHN0b3AgLSBzdGFydCkgLyBzdGVwKSwgMCk7CiAgICB2YXIgcmFuZ2UgPSBBcnJheShsZW5ndGgpOwoKICAgIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IGxlbmd0aDsgaWR4KyssIHN0YXJ0ICs9IHN0ZXApIHsKICAgICAgcmFuZ2VbaWR4XSA9IHN0YXJ0OwogICAgfQoKICAgIHJldHVybiByYW5nZTsKICB9OwoKICAvLyBDaHVuayBhIHNpbmdsZSBhcnJheSBpbnRvIG11bHRpcGxlIGFycmF5cywgZWFjaCBjb250YWluaW5nIGBjb3VudGAgb3IgZmV3ZXIKICAvLyBpdGVtcy4KICBfLmNodW5rID0gZnVuY3Rpb24oYXJyYXksIGNvdW50KSB7CiAgICBpZiAoY291bnQgPT0gbnVsbCB8fCBjb3VudCA8IDEpIHJldHVybiBbXTsKICAgIHZhciByZXN1bHQgPSBbXTsKICAgIHZhciBpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOwogICAgd2hpbGUgKGkgPCBsZW5ndGgpIHsKICAgICAgcmVzdWx0LnB1c2goc2xpY2UuY2FsbChhcnJheSwgaSwgaSArPSBjb3VudCkpOwogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKICB9OwoKICAvLyBGdW5jdGlvbiAoYWhlbSkgRnVuY3Rpb25zCiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8vIERldGVybWluZXMgd2hldGhlciB0byBleGVjdXRlIGEgZnVuY3Rpb24gYXMgYSBjb25zdHJ1Y3RvcgogIC8vIG9yIGEgbm9ybWFsIGZ1bmN0aW9uIHdpdGggdGhlIHByb3ZpZGVkIGFyZ3VtZW50cy4KICB2YXIgZXhlY3V0ZUJvdW5kID0gZnVuY3Rpb24oc291cmNlRnVuYywgYm91bmRGdW5jLCBjb250ZXh0LCBjYWxsaW5nQ29udGV4dCwgYXJncykgewogICAgaWYgKCEoY2FsbGluZ0NvbnRleHQgaW5zdGFuY2VvZiBib3VuZEZ1bmMpKSByZXR1cm4gc291cmNlRnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTsKICAgIHZhciBzZWxmID0gYmFzZUNyZWF0ZShzb3VyY2VGdW5jLnByb3RvdHlwZSk7CiAgICB2YXIgcmVzdWx0ID0gc291cmNlRnVuYy5hcHBseShzZWxmLCBhcmdzKTsKICAgIGlmIChfLmlzT2JqZWN0KHJlc3VsdCkpIHJldHVybiByZXN1bHQ7CiAgICByZXR1cm4gc2VsZjsKICB9OwoKICAvLyBDcmVhdGUgYSBmdW5jdGlvbiBib3VuZCB0byBhIGdpdmVuIG9iamVjdCAoYXNzaWduaW5nIGB0aGlzYCwgYW5kIGFyZ3VtZW50cywKICAvLyBvcHRpb25hbGx5KS4gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYEZ1bmN0aW9uLmJpbmRgIGlmCiAgLy8gYXZhaWxhYmxlLgogIF8uYmluZCA9IHJlc3RBcmd1bWVudHMoZnVuY3Rpb24oZnVuYywgY29udGV4dCwgYXJncykgewogICAgaWYgKCFfLmlzRnVuY3Rpb24oZnVuYykpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0JpbmQgbXVzdCBiZSBjYWxsZWQgb24gYSBmdW5jdGlvbicpOwogICAgdmFyIGJvdW5kID0gcmVzdEFyZ3VtZW50cyhmdW5jdGlvbihjYWxsQXJncykgewogICAgICByZXR1cm4gZXhlY3V0ZUJvdW5kKGZ1bmMsIGJvdW5kLCBjb250ZXh0LCB0aGlzLCBhcmdzLmNvbmNhdChjYWxsQXJncykpOwogICAgfSk7CiAgICByZXR1cm4gYm91bmQ7CiAgfSk7CgogIC8vIFBhcnRpYWxseSBhcHBseSBhIGZ1bmN0aW9uIGJ5IGNyZWF0aW5nIGEgdmVyc2lvbiB0aGF0IGhhcyBoYWQgc29tZSBvZiBpdHMKICAvLyBhcmd1bWVudHMgcHJlLWZpbGxlZCwgd2l0aG91dCBjaGFuZ2luZyBpdHMgZHluYW1pYyBgdGhpc2AgY29udGV4dC4gXyBhY3RzCiAgLy8gYXMgYSBwbGFjZWhvbGRlciBieSBkZWZhdWx0LCBhbGxvd2luZyBhbnkgY29tYmluYXRpb24gb2YgYXJndW1lbnRzIHRvIGJlCiAgLy8gcHJlLWZpbGxlZC4gU2V0IGBfLnBhcnRpYWwucGxhY2Vob2xkZXJgIGZvciBhIGN1c3RvbSBwbGFjZWhvbGRlciBhcmd1bWVudC4KICBfLnBhcnRpYWwgPSByZXN0QXJndW1lbnRzKGZ1bmN0aW9uKGZ1bmMsIGJvdW5kQXJncykgewogICAgdmFyIHBsYWNlaG9sZGVyID0gXy5wYXJ0aWFsLnBsYWNlaG9sZGVyOwogICAgdmFyIGJvdW5kID0gZnVuY3Rpb24oKSB7CiAgICAgIHZhciBwb3NpdGlvbiA9IDAsIGxlbmd0aCA9IGJvdW5kQXJncy5sZW5ndGg7CiAgICAgIHZhciBhcmdzID0gQXJyYXkobGVuZ3RoKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICAgIGFyZ3NbaV0gPSBib3VuZEFyZ3NbaV0gPT09IHBsYWNlaG9sZGVyID8gYXJndW1lbnRzW3Bvc2l0aW9uKytdIDogYm91bmRBcmdzW2ldOwogICAgICB9CiAgICAgIHdoaWxlIChwb3NpdGlvbiA8IGFyZ3VtZW50cy5sZW5ndGgpIGFyZ3MucHVzaChhcmd1bWVudHNbcG9zaXRpb24rK10pOwogICAgICByZXR1cm4gZXhlY3V0ZUJvdW5kKGZ1bmMsIGJvdW5kLCB0aGlzLCB0aGlzLCBhcmdzKTsKICAgIH07CiAgICByZXR1cm4gYm91bmQ7CiAgfSk7CgogIF8ucGFydGlhbC5wbGFjZWhvbGRlciA9IF87CgogIC8vIEJpbmQgYSBudW1iZXIgb2YgYW4gb2JqZWN0J3MgbWV0aG9kcyB0byB0aGF0IG9iamVjdC4gUmVtYWluaW5nIGFyZ3VtZW50cwogIC8vIGFyZSB0aGUgbWV0aG9kIG5hbWVzIHRvIGJlIGJvdW5kLiBVc2VmdWwgZm9yIGVuc3VyaW5nIHRoYXQgYWxsIGNhbGxiYWNrcwogIC8vIGRlZmluZWQgb24gYW4gb2JqZWN0IGJlbG9uZyB0byBpdC4KICBfLmJpbmRBbGwgPSByZXN0QXJndW1lbnRzKGZ1bmN0aW9uKG9iaiwga2V5cykgewogICAga2V5cyA9IGZsYXR0ZW4oa2V5cywgZmFsc2UsIGZhbHNlKTsKICAgIHZhciBpbmRleCA9IGtleXMubGVuZ3RoOwogICAgaWYgKGluZGV4IDwgMSkgdGhyb3cgbmV3IEVycm9yKCdiaW5kQWxsIG11c3QgYmUgcGFzc2VkIGZ1bmN0aW9uIG5hbWVzJyk7CiAgICB3aGlsZSAoaW5kZXgtLSkgewogICAgICB2YXIga2V5ID0ga2V5c1tpbmRleF07CiAgICAgIG9ialtrZXldID0gXy5iaW5kKG9ialtrZXldLCBvYmopOwogICAgfQogIH0pOwoKICAvLyBNZW1vaXplIGFuIGV4cGVuc2l2ZSBmdW5jdGlvbiBieSBzdG9yaW5nIGl0cyByZXN1bHRzLgogIF8ubWVtb2l6ZSA9IGZ1bmN0aW9uKGZ1bmMsIGhhc2hlcikgewogICAgdmFyIG1lbW9pemUgPSBmdW5jdGlvbihrZXkpIHsKICAgICAgdmFyIGNhY2hlID0gbWVtb2l6ZS5jYWNoZTsKICAgICAgdmFyIGFkZHJlc3MgPSAnJyArIChoYXNoZXIgPyBoYXNoZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IGtleSk7CiAgICAgIGlmICghaGFzKGNhY2hlLCBhZGRyZXNzKSkgY2FjaGVbYWRkcmVzc10gPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgIHJldHVybiBjYWNoZVthZGRyZXNzXTsKICAgIH07CiAgICBtZW1vaXplLmNhY2hlID0ge307CiAgICByZXR1cm4gbWVtb2l6ZTsKICB9OwoKICAvLyBEZWxheXMgYSBmdW5jdGlvbiBmb3IgdGhlIGdpdmVuIG51bWJlciBvZiBtaWxsaXNlY29uZHMsIGFuZCB0aGVuIGNhbGxzCiAgLy8gaXQgd2l0aCB0aGUgYXJndW1lbnRzIHN1cHBsaWVkLgogIF8uZGVsYXkgPSByZXN0QXJndW1lbnRzKGZ1bmN0aW9uKGZ1bmMsIHdhaXQsIGFyZ3MpIHsKICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gZnVuYy5hcHBseShudWxsLCBhcmdzKTsKICAgIH0sIHdhaXQpOwogIH0pOwoKICAvLyBEZWZlcnMgYSBmdW5jdGlvbiwgc2NoZWR1bGluZyBpdCB0byBydW4gYWZ0ZXIgdGhlIGN1cnJlbnQgY2FsbCBzdGFjayBoYXMKICAvLyBjbGVhcmVkLgogIF8uZGVmZXIgPSBfLnBhcnRpYWwoXy5kZWxheSwgXywgMSk7CgogIC8vIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgd2hlbiBpbnZva2VkLCB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGF0IG1vc3Qgb25jZQogIC8vIGR1cmluZyBhIGdpdmVuIHdpbmRvdyBvZiB0aW1lLiBOb3JtYWxseSwgdGhlIHRocm90dGxlZCBmdW5jdGlvbiB3aWxsIHJ1bgogIC8vIGFzIG11Y2ggYXMgaXQgY2FuLCB3aXRob3V0IGV2ZXIgZ29pbmcgbW9yZSB0aGFuIG9uY2UgcGVyIGB3YWl0YCBkdXJhdGlvbjsKICAvLyBidXQgaWYgeW91J2QgbGlrZSB0byBkaXNhYmxlIHRoZSBleGVjdXRpb24gb24gdGhlIGxlYWRpbmcgZWRnZSwgcGFzcwogIC8vIGB7bGVhZGluZzogZmFsc2V9YC4gVG8gZGlzYWJsZSBleGVjdXRpb24gb24gdGhlIHRyYWlsaW5nIGVkZ2UsIGRpdHRvLgogIF8udGhyb3R0bGUgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBvcHRpb25zKSB7CiAgICB2YXIgdGltZW91dCwgY29udGV4dCwgYXJncywgcmVzdWx0OwogICAgdmFyIHByZXZpb3VzID0gMDsKICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9OwoKICAgIHZhciBsYXRlciA9IGZ1bmN0aW9uKCkgewogICAgICBwcmV2aW91cyA9IG9wdGlvbnMubGVhZGluZyA9PT0gZmFsc2UgPyAwIDogXy5ub3coKTsKICAgICAgdGltZW91dCA9IG51bGw7CiAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7CiAgICAgIGlmICghdGltZW91dCkgY29udGV4dCA9IGFyZ3MgPSBudWxsOwogICAgfTsKCiAgICB2YXIgdGhyb3R0bGVkID0gZnVuY3Rpb24oKSB7CiAgICAgIHZhciBub3cgPSBfLm5vdygpOwogICAgICBpZiAoIXByZXZpb3VzICYmIG9wdGlvbnMubGVhZGluZyA9PT0gZmFsc2UpIHByZXZpb3VzID0gbm93OwogICAgICB2YXIgcmVtYWluaW5nID0gd2FpdCAtIChub3cgLSBwcmV2aW91cyk7CiAgICAgIGNvbnRleHQgPSB0aGlzOwogICAgICBhcmdzID0gYXJndW1lbnRzOwogICAgICBpZiAocmVtYWluaW5nIDw9IDAgfHwgcmVtYWluaW5nID4gd2FpdCkgewogICAgICAgIGlmICh0aW1lb3V0KSB7CiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7CiAgICAgICAgICB0aW1lb3V0ID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcHJldmlvdXMgPSBub3c7CiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTsKICAgICAgICBpZiAoIXRpbWVvdXQpIGNvbnRleHQgPSBhcmdzID0gbnVsbDsKICAgICAgfSBlbHNlIGlmICghdGltZW91dCAmJiBvcHRpb25zLnRyYWlsaW5nICE9PSBmYWxzZSkgewogICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCByZW1haW5pbmcpOwogICAgICB9CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9OwoKICAgIHRocm90dGxlZC5jYW5jZWwgPSBmdW5jdGlvbigpIHsKICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpOwogICAgICBwcmV2aW91cyA9IDA7CiAgICAgIHRpbWVvdXQgPSBjb250ZXh0ID0gYXJncyA9IG51bGw7CiAgICB9OwoKICAgIHJldHVybiB0aHJvdHRsZWQ7CiAgfTsKCiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uLCB0aGF0LCBhcyBsb25nIGFzIGl0IGNvbnRpbnVlcyB0byBiZSBpbnZva2VkLCB3aWxsIG5vdAogIC8vIGJlIHRyaWdnZXJlZC4gVGhlIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGl0IHN0b3BzIGJlaW5nIGNhbGxlZCBmb3IKICAvLyBOIG1pbGxpc2Vjb25kcy4gSWYgYGltbWVkaWF0ZWAgaXMgcGFzc2VkLCB0cmlnZ2VyIHRoZSBmdW5jdGlvbiBvbiB0aGUKICAvLyBsZWFkaW5nIGVkZ2UsIGluc3RlYWQgb2YgdGhlIHRyYWlsaW5nLgogIF8uZGVib3VuY2UgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHsKICAgIHZhciB0aW1lb3V0LCByZXN1bHQ7CgogICAgdmFyIGxhdGVyID0gZnVuY3Rpb24oY29udGV4dCwgYXJncykgewogICAgICB0aW1lb3V0ID0gbnVsbDsKICAgICAgaWYgKGFyZ3MpIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7CiAgICB9OwoKICAgIHZhciBkZWJvdW5jZWQgPSByZXN0QXJndW1lbnRzKGZ1bmN0aW9uKGFyZ3MpIHsKICAgICAgaWYgKHRpbWVvdXQpIGNsZWFyVGltZW91dCh0aW1lb3V0KTsKICAgICAgaWYgKGltbWVkaWF0ZSkgewogICAgICAgIHZhciBjYWxsTm93ID0gIXRpbWVvdXQ7CiAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpOwogICAgICAgIGlmIChjYWxsTm93KSByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpOwogICAgICB9IGVsc2UgewogICAgICAgIHRpbWVvdXQgPSBfLmRlbGF5KGxhdGVyLCB3YWl0LCB0aGlzLCBhcmdzKTsKICAgICAgfQoKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0pOwoKICAgIGRlYm91bmNlZC5jYW5jZWwgPSBmdW5jdGlvbigpIHsKICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpOwogICAgICB0aW1lb3V0ID0gbnVsbDsKICAgIH07CgogICAgcmV0dXJuIGRlYm91bmNlZDsKICB9OwoKICAvLyBSZXR1cm5zIHRoZSBmaXJzdCBmdW5jdGlvbiBwYXNzZWQgYXMgYW4gYXJndW1lbnQgdG8gdGhlIHNlY29uZCwKICAvLyBhbGxvd2luZyB5b3UgdG8gYWRqdXN0IGFyZ3VtZW50cywgcnVuIGNvZGUgYmVmb3JlIGFuZCBhZnRlciwgYW5kCiAgLy8gY29uZGl0aW9uYWxseSBleGVjdXRlIHRoZSBvcmlnaW5hbCBmdW5jdGlvbi4KICBfLndyYXAgPSBmdW5jdGlvbihmdW5jLCB3cmFwcGVyKSB7CiAgICByZXR1cm4gXy5wYXJ0aWFsKHdyYXBwZXIsIGZ1bmMpOwogIH07CgogIC8vIFJldHVybnMgYSBuZWdhdGVkIHZlcnNpb24gb2YgdGhlIHBhc3NlZC1pbiBwcmVkaWNhdGUuCiAgXy5uZWdhdGUgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHsKICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuICFwcmVkaWNhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH07CiAgfTsKCiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIGEgbGlzdCBvZiBmdW5jdGlvbnMsIGVhY2gKICAvLyBjb25zdW1pbmcgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgZnVuY3Rpb24gdGhhdCBmb2xsb3dzLgogIF8uY29tcG9zZSA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7CiAgICB2YXIgc3RhcnQgPSBhcmdzLmxlbmd0aCAtIDE7CiAgICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICAgIHZhciBpID0gc3RhcnQ7CiAgICAgIHZhciByZXN1bHQgPSBhcmdzW3N0YXJ0XS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICB3aGlsZSAoaS0tKSByZXN1bHQgPSBhcmdzW2ldLmNhbGwodGhpcywgcmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH07CiAgfTsKCiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBvbmx5IGJlIGV4ZWN1dGVkIG9uIGFuZCBhZnRlciB0aGUgTnRoIGNhbGwuCiAgXy5hZnRlciA9IGZ1bmN0aW9uKHRpbWVzLCBmdW5jKSB7CiAgICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICAgIGlmICgtLXRpbWVzIDwgMSkgewogICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgIH0KICAgIH07CiAgfTsKCiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBvbmx5IGJlIGV4ZWN1dGVkIHVwIHRvIChidXQgbm90IGluY2x1ZGluZykgdGhlIE50aCBjYWxsLgogIF8uYmVmb3JlID0gZnVuY3Rpb24odGltZXMsIGZ1bmMpIHsKICAgIHZhciBtZW1vOwogICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICBpZiAoLS10aW1lcyA+IDApIHsKICAgICAgICBtZW1vID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICB9CiAgICAgIGlmICh0aW1lcyA8PSAxKSBmdW5jID0gbnVsbDsKICAgICAgcmV0dXJuIG1lbW87CiAgICB9OwogIH07CgogIC8vIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgZXhlY3V0ZWQgYXQgbW9zdCBvbmUgdGltZSwgbm8gbWF0dGVyIGhvdwogIC8vIG9mdGVuIHlvdSBjYWxsIGl0LiBVc2VmdWwgZm9yIGxhenkgaW5pdGlhbGl6YXRpb24uCiAgXy5vbmNlID0gXy5wYXJ0aWFsKF8uYmVmb3JlLCAyKTsKCiAgXy5yZXN0QXJndW1lbnRzID0gcmVzdEFyZ3VtZW50czsKCiAgLy8gT2JqZWN0IEZ1bmN0aW9ucwogIC8vIC0tLS0tLS0tLS0tLS0tLS0KCiAgLy8gS2V5cyBpbiBJRSA8IDkgdGhhdCB3b24ndCBiZSBpdGVyYXRlZCBieSBgZm9yIGtleSBpbiAuLi5gIGFuZCB0aHVzIG1pc3NlZC4KICB2YXIgaGFzRW51bUJ1ZyA9ICF7dG9TdHJpbmc6IG51bGx9LnByb3BlcnR5SXNFbnVtZXJhYmxlKCd0b1N0cmluZycpOwogIHZhciBub25FbnVtZXJhYmxlUHJvcHMgPSBbJ3ZhbHVlT2YnLCAnaXNQcm90b3R5cGVPZicsICd0b1N0cmluZycsCiAgICAncHJvcGVydHlJc0VudW1lcmFibGUnLCAnaGFzT3duUHJvcGVydHknLCAndG9Mb2NhbGVTdHJpbmcnXTsKCiAgdmFyIGNvbGxlY3ROb25FbnVtUHJvcHMgPSBmdW5jdGlvbihvYmosIGtleXMpIHsKICAgIHZhciBub25FbnVtSWR4ID0gbm9uRW51bWVyYWJsZVByb3BzLmxlbmd0aDsKICAgIHZhciBjb25zdHJ1Y3RvciA9IG9iai5jb25zdHJ1Y3RvcjsKICAgIHZhciBwcm90byA9IF8uaXNGdW5jdGlvbihjb25zdHJ1Y3RvcikgJiYgY29uc3RydWN0b3IucHJvdG90eXBlIHx8IE9ialByb3RvOwoKICAgIC8vIENvbnN0cnVjdG9yIGlzIGEgc3BlY2lhbCBjYXNlLgogICAgdmFyIHByb3AgPSAnY29uc3RydWN0b3InOwogICAgaWYgKGhhcyhvYmosIHByb3ApICYmICFfLmNvbnRhaW5zKGtleXMsIHByb3ApKSBrZXlzLnB1c2gocHJvcCk7CgogICAgd2hpbGUgKG5vbkVudW1JZHgtLSkgewogICAgICBwcm9wID0gbm9uRW51bWVyYWJsZVByb3BzW25vbkVudW1JZHhdOwogICAgICBpZiAocHJvcCBpbiBvYmogJiYgb2JqW3Byb3BdICE9PSBwcm90b1twcm9wXSAmJiAhXy5jb250YWlucyhrZXlzLCBwcm9wKSkgewogICAgICAgIGtleXMucHVzaChwcm9wKTsKICAgICAgfQogICAgfQogIH07CgogIC8vIFJldHJpZXZlIHRoZSBuYW1lcyBvZiBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcy4KICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgT2JqZWN0LmtleXNgLgogIF8ua2V5cyA9IGZ1bmN0aW9uKG9iaikgewogICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBbXTsKICAgIGlmIChuYXRpdmVLZXlzKSByZXR1cm4gbmF0aXZlS2V5cyhvYmopOwogICAgdmFyIGtleXMgPSBbXTsKICAgIGZvciAodmFyIGtleSBpbiBvYmopIGlmIChoYXMob2JqLCBrZXkpKSBrZXlzLnB1c2goa2V5KTsKICAgIC8vIEFoZW0sIElFIDwgOS4KICAgIGlmIChoYXNFbnVtQnVnKSBjb2xsZWN0Tm9uRW51bVByb3BzKG9iaiwga2V5cyk7CiAgICByZXR1cm4ga2V5czsKICB9OwoKICAvLyBSZXRyaWV2ZSBhbGwgdGhlIHByb3BlcnR5IG5hbWVzIG9mIGFuIG9iamVjdC4KICBfLmFsbEtleXMgPSBmdW5jdGlvbihvYmopIHsKICAgIGlmICghXy5pc09iamVjdChvYmopKSByZXR1cm4gW107CiAgICB2YXIga2V5cyA9IFtdOwogICAgZm9yICh2YXIga2V5IGluIG9iaikga2V5cy5wdXNoKGtleSk7CiAgICAvLyBBaGVtLCBJRSA8IDkuCiAgICBpZiAoaGFzRW51bUJ1ZykgY29sbGVjdE5vbkVudW1Qcm9wcyhvYmosIGtleXMpOwogICAgcmV0dXJuIGtleXM7CiAgfTsKCiAgLy8gUmV0cmlldmUgdGhlIHZhbHVlcyBvZiBhbiBvYmplY3QncyBwcm9wZXJ0aWVzLgogIF8udmFsdWVzID0gZnVuY3Rpb24ob2JqKSB7CiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopOwogICAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoOwogICAgdmFyIHZhbHVlcyA9IEFycmF5KGxlbmd0aCk7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhbHVlc1tpXSA9IG9ialtrZXlzW2ldXTsKICAgIH0KICAgIHJldHVybiB2YWx1ZXM7CiAgfTsKCiAgLy8gUmV0dXJucyB0aGUgcmVzdWx0cyBvZiBhcHBseWluZyB0aGUgaXRlcmF0ZWUgdG8gZWFjaCBlbGVtZW50IG9mIHRoZSBvYmplY3QuCiAgLy8gSW4gY29udHJhc3QgdG8gXy5tYXAgaXQgcmV0dXJucyBhbiBvYmplY3QuCiAgXy5tYXBPYmplY3QgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7CiAgICBpdGVyYXRlZSA9IGNiKGl0ZXJhdGVlLCBjb250ZXh0KTsKICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaiksCiAgICAgICAgbGVuZ3RoID0ga2V5cy5sZW5ndGgsCiAgICAgICAgcmVzdWx0cyA9IHt9OwogICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykgewogICAgICB2YXIgY3VycmVudEtleSA9IGtleXNbaW5kZXhdOwogICAgICByZXN1bHRzW2N1cnJlbnRLZXldID0gaXRlcmF0ZWUob2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopOwogICAgfQogICAgcmV0dXJuIHJlc3VsdHM7CiAgfTsKCiAgLy8gQ29udmVydCBhbiBvYmplY3QgaW50byBhIGxpc3Qgb2YgYFtrZXksIHZhbHVlXWAgcGFpcnMuCiAgLy8gVGhlIG9wcG9zaXRlIG9mIF8ub2JqZWN0LgogIF8ucGFpcnMgPSBmdW5jdGlvbihvYmopIHsKICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7CiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7CiAgICB2YXIgcGFpcnMgPSBBcnJheShsZW5ndGgpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICBwYWlyc1tpXSA9IFtrZXlzW2ldLCBvYmpba2V5c1tpXV1dOwogICAgfQogICAgcmV0dXJuIHBhaXJzOwogIH07CgogIC8vIEludmVydCB0aGUga2V5cyBhbmQgdmFsdWVzIG9mIGFuIG9iamVjdC4gVGhlIHZhbHVlcyBtdXN0IGJlIHNlcmlhbGl6YWJsZS4KICBfLmludmVydCA9IGZ1bmN0aW9uKG9iaikgewogICAgdmFyIHJlc3VsdCA9IHt9OwogICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHJlc3VsdFtvYmpba2V5c1tpXV1dID0ga2V5c1tpXTsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfTsKCiAgLy8gUmV0dXJuIGEgc29ydGVkIGxpc3Qgb2YgdGhlIGZ1bmN0aW9uIG5hbWVzIGF2YWlsYWJsZSBvbiB0aGUgb2JqZWN0LgogIC8vIEFsaWFzZWQgYXMgYG1ldGhvZHNgLgogIF8uZnVuY3Rpb25zID0gXy5tZXRob2RzID0gZnVuY3Rpb24ob2JqKSB7CiAgICB2YXIgbmFtZXMgPSBbXTsKICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsKICAgICAgaWYgKF8uaXNGdW5jdGlvbihvYmpba2V5XSkpIG5hbWVzLnB1c2goa2V5KTsKICAgIH0KICAgIHJldHVybiBuYW1lcy5zb3J0KCk7CiAgfTsKCiAgLy8gQW4gaW50ZXJuYWwgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIGFzc2lnbmVyIGZ1bmN0aW9ucy4KICB2YXIgY3JlYXRlQXNzaWduZXIgPSBmdW5jdGlvbihrZXlzRnVuYywgZGVmYXVsdHMpIHsKICAgIHJldHVybiBmdW5jdGlvbihvYmopIHsKICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7CiAgICAgIGlmIChkZWZhdWx0cykgb2JqID0gT2JqZWN0KG9iaik7CiAgICAgIGlmIChsZW5ndGggPCAyIHx8IG9iaiA9PSBudWxsKSByZXR1cm4gb2JqOwogICAgICBmb3IgKHZhciBpbmRleCA9IDE7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpbmRleF0sCiAgICAgICAgICAgIGtleXMgPSBrZXlzRnVuYyhzb3VyY2UpLAogICAgICAgICAgICBsID0ga2V5cy5sZW5ndGg7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyBpKyspIHsKICAgICAgICAgIHZhciBrZXkgPSBrZXlzW2ldOwogICAgICAgICAgaWYgKCFkZWZhdWx0cyB8fCBvYmpba2V5XSA9PT0gdm9pZCAwKSBvYmpba2V5XSA9IHNvdXJjZVtrZXldOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gb2JqOwogICAgfTsKICB9OwoKICAvLyBFeHRlbmQgYSBnaXZlbiBvYmplY3Qgd2l0aCBhbGwgdGhlIHByb3BlcnRpZXMgaW4gcGFzc2VkLWluIG9iamVjdChzKS4KICBfLmV4dGVuZCA9IGNyZWF0ZUFzc2lnbmVyKF8uYWxsS2V5cyk7CgogIC8vIEFzc2lnbnMgYSBnaXZlbiBvYmplY3Qgd2l0aCBhbGwgdGhlIG93biBwcm9wZXJ0aWVzIGluIHRoZSBwYXNzZWQtaW4gb2JqZWN0KHMpLgogIC8vIChodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvYXNzaWduKQogIF8uZXh0ZW5kT3duID0gXy5hc3NpZ24gPSBjcmVhdGVBc3NpZ25lcihfLmtleXMpOwoKICAvLyBSZXR1cm5zIHRoZSBmaXJzdCBrZXkgb24gYW4gb2JqZWN0IHRoYXQgcGFzc2VzIGEgcHJlZGljYXRlIHRlc3QuCiAgXy5maW5kS2V5ID0gZnVuY3Rpb24ob2JqLCBwcmVkaWNhdGUsIGNvbnRleHQpIHsKICAgIHByZWRpY2F0ZSA9IGNiKHByZWRpY2F0ZSwgY29udGV4dCk7CiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopLCBrZXk7CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICBrZXkgPSBrZXlzW2ldOwogICAgICBpZiAocHJlZGljYXRlKG9ialtrZXldLCBrZXksIG9iaikpIHJldHVybiBrZXk7CiAgICB9CiAgfTsKCiAgLy8gSW50ZXJuYWwgcGljayBoZWxwZXIgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGlmIGBvYmpgIGhhcyBrZXkgYGtleWAuCiAgdmFyIGtleUluT2JqID0gZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqKSB7CiAgICByZXR1cm4ga2V5IGluIG9iajsKICB9OwoKICAvLyBSZXR1cm4gYSBjb3B5IG9mIHRoZSBvYmplY3Qgb25seSBjb250YWluaW5nIHRoZSB3aGl0ZWxpc3RlZCBwcm9wZXJ0aWVzLgogIF8ucGljayA9IHJlc3RBcmd1bWVudHMoZnVuY3Rpb24ob2JqLCBrZXlzKSB7CiAgICB2YXIgcmVzdWx0ID0ge30sIGl0ZXJhdGVlID0ga2V5c1swXTsKICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdDsKICAgIGlmIChfLmlzRnVuY3Rpb24oaXRlcmF0ZWUpKSB7CiAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIGl0ZXJhdGVlID0gb3B0aW1pemVDYihpdGVyYXRlZSwga2V5c1sxXSk7CiAgICAgIGtleXMgPSBfLmFsbEtleXMob2JqKTsKICAgIH0gZWxzZSB7CiAgICAgIGl0ZXJhdGVlID0ga2V5SW5PYmo7CiAgICAgIGtleXMgPSBmbGF0dGVuKGtleXMsIGZhbHNlLCBmYWxzZSk7CiAgICAgIG9iaiA9IE9iamVjdChvYmopOwogICAgfQogICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGtleXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGtleSA9IGtleXNbaV07CiAgICAgIHZhciB2YWx1ZSA9IG9ialtrZXldOwogICAgICBpZiAoaXRlcmF0ZWUodmFsdWUsIGtleSwgb2JqKSkgcmVzdWx0W2tleV0gPSB2YWx1ZTsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7CiAgfSk7CgogIC8vIFJldHVybiBhIGNvcHkgb2YgdGhlIG9iamVjdCB3aXRob3V0IHRoZSBibGFja2xpc3RlZCBwcm9wZXJ0aWVzLgogIF8ub21pdCA9IHJlc3RBcmd1bWVudHMoZnVuY3Rpb24ob2JqLCBrZXlzKSB7CiAgICB2YXIgaXRlcmF0ZWUgPSBrZXlzWzBdLCBjb250ZXh0OwogICAgaWYgKF8uaXNGdW5jdGlvbihpdGVyYXRlZSkpIHsKICAgICAgaXRlcmF0ZWUgPSBfLm5lZ2F0ZShpdGVyYXRlZSk7CiAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIGNvbnRleHQgPSBrZXlzWzFdOwogICAgfSBlbHNlIHsKICAgICAga2V5cyA9IF8ubWFwKGZsYXR0ZW4oa2V5cywgZmFsc2UsIGZhbHNlKSwgU3RyaW5nKTsKICAgICAgaXRlcmF0ZWUgPSBmdW5jdGlvbih2YWx1ZSwga2V5KSB7CiAgICAgICAgcmV0dXJuICFfLmNvbnRhaW5zKGtleXMsIGtleSk7CiAgICAgIH07CiAgICB9CiAgICByZXR1cm4gXy5waWNrKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpOwogIH0pOwoKICAvLyBGaWxsIGluIGEgZ2l2ZW4gb2JqZWN0IHdpdGggZGVmYXVsdCBwcm9wZXJ0aWVzLgogIF8uZGVmYXVsdHMgPSBjcmVhdGVBc3NpZ25lcihfLmFsbEtleXMsIHRydWUpOwoKICAvLyBDcmVhdGVzIGFuIG9iamVjdCB0aGF0IGluaGVyaXRzIGZyb20gdGhlIGdpdmVuIHByb3RvdHlwZSBvYmplY3QuCiAgLy8gSWYgYWRkaXRpb25hbCBwcm9wZXJ0aWVzIGFyZSBwcm92aWRlZCB0aGVuIHRoZXkgd2lsbCBiZSBhZGRlZCB0byB0aGUKICAvLyBjcmVhdGVkIG9iamVjdC4KICBfLmNyZWF0ZSA9IGZ1bmN0aW9uKHByb3RvdHlwZSwgcHJvcHMpIHsKICAgIHZhciByZXN1bHQgPSBiYXNlQ3JlYXRlKHByb3RvdHlwZSk7CiAgICBpZiAocHJvcHMpIF8uZXh0ZW5kT3duKHJlc3VsdCwgcHJvcHMpOwogICAgcmV0dXJuIHJlc3VsdDsKICB9OwoKICAvLyBDcmVhdGUgYSAoc2hhbGxvdy1jbG9uZWQpIGR1cGxpY2F0ZSBvZiBhbiBvYmplY3QuCiAgXy5jbG9uZSA9IGZ1bmN0aW9uKG9iaikgewogICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7CiAgICByZXR1cm4gXy5pc0FycmF5KG9iaikgPyBvYmouc2xpY2UoKSA6IF8uZXh0ZW5kKHt9LCBvYmopOwogIH07CgogIC8vIEludm9rZXMgaW50ZXJjZXB0b3Igd2l0aCB0aGUgb2JqLCBhbmQgdGhlbiByZXR1cm5zIG9iai4KICAvLyBUaGUgcHJpbWFyeSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvICJ0YXAgaW50byIgYSBtZXRob2QgY2hhaW4sIGluCiAgLy8gb3JkZXIgdG8gcGVyZm9ybSBvcGVyYXRpb25zIG9uIGludGVybWVkaWF0ZSByZXN1bHRzIHdpdGhpbiB0aGUgY2hhaW4uCiAgXy50YXAgPSBmdW5jdGlvbihvYmosIGludGVyY2VwdG9yKSB7CiAgICBpbnRlcmNlcHRvcihvYmopOwogICAgcmV0dXJuIG9iajsKICB9OwoKICAvLyBSZXR1cm5zIHdoZXRoZXIgYW4gb2JqZWN0IGhhcyBhIGdpdmVuIHNldCBvZiBga2V5OnZhbHVlYCBwYWlycy4KICBfLmlzTWF0Y2ggPSBmdW5jdGlvbihvYmplY3QsIGF0dHJzKSB7CiAgICB2YXIga2V5cyA9IF8ua2V5cyhhdHRycyksIGxlbmd0aCA9IGtleXMubGVuZ3RoOwogICAgaWYgKG9iamVjdCA9PSBudWxsKSByZXR1cm4gIWxlbmd0aDsKICAgIHZhciBvYmogPSBPYmplY3Qob2JqZWN0KTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGtleSA9IGtleXNbaV07CiAgICAgIGlmIChhdHRyc1trZXldICE9PSBvYmpba2V5XSB8fCAhKGtleSBpbiBvYmopKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9OwoKCiAgLy8gSW50ZXJuYWwgcmVjdXJzaXZlIGNvbXBhcmlzb24gZnVuY3Rpb24gZm9yIGBpc0VxdWFsYC4KICB2YXIgZXEsIGRlZXBFcTsKICBlcSA9IGZ1bmN0aW9uKGEsIGIsIGFTdGFjaywgYlN0YWNrKSB7CiAgICAvLyBJZGVudGljYWwgb2JqZWN0cyBhcmUgZXF1YWwuIGAwID09PSAtMGAsIGJ1dCB0aGV5IGFyZW4ndCBpZGVudGljYWwuCiAgICAvLyBTZWUgdGhlIFtIYXJtb255IGBlZ2FsYCBwcm9wb3NhbF0oaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9aGFybW9ueTplZ2FsKS4KICAgIGlmIChhID09PSBiKSByZXR1cm4gYSAhPT0gMCB8fCAxIC8gYSA9PT0gMSAvIGI7CiAgICAvLyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgb25seSBlcXVhbCB0byBpdHNlbGYgKHN0cmljdCBjb21wYXJpc29uKS4KICAgIGlmIChhID09IG51bGwgfHwgYiA9PSBudWxsKSByZXR1cm4gZmFsc2U7CiAgICAvLyBgTmFOYHMgYXJlIGVxdWl2YWxlbnQsIGJ1dCBub24tcmVmbGV4aXZlLgogICAgaWYgKGEgIT09IGEpIHJldHVybiBiICE9PSBiOwogICAgLy8gRXhoYXVzdCBwcmltaXRpdmUgY2hlY2tzCiAgICB2YXIgdHlwZSA9IHR5cGVvZiBhOwogICAgaWYgKHR5cGUgIT09ICdmdW5jdGlvbicgJiYgdHlwZSAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIGIgIT0gJ29iamVjdCcpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiBkZWVwRXEoYSwgYiwgYVN0YWNrLCBiU3RhY2spOwogIH07CgogIC8vIEludGVybmFsIHJlY3Vyc2l2ZSBjb21wYXJpc29uIGZ1bmN0aW9uIGZvciBgaXNFcXVhbGAuCiAgZGVlcEVxID0gZnVuY3Rpb24oYSwgYiwgYVN0YWNrLCBiU3RhY2spIHsKICAgIC8vIFVud3JhcCBhbnkgd3JhcHBlZCBvYmplY3RzLgogICAgaWYgKGEgaW5zdGFuY2VvZiBfKSBhID0gYS5fd3JhcHBlZDsKICAgIGlmIChiIGluc3RhbmNlb2YgXykgYiA9IGIuX3dyYXBwZWQ7CiAgICAvLyBDb21wYXJlIGBbW0NsYXNzXV1gIG5hbWVzLgogICAgdmFyIGNsYXNzTmFtZSA9IHRvU3RyaW5nLmNhbGwoYSk7CiAgICBpZiAoY2xhc3NOYW1lICE9PSB0b1N0cmluZy5jYWxsKGIpKSByZXR1cm4gZmFsc2U7CiAgICBzd2l0Y2ggKGNsYXNzTmFtZSkgewogICAgICAvLyBTdHJpbmdzLCBudW1iZXJzLCByZWd1bGFyIGV4cHJlc3Npb25zLCBkYXRlcywgYW5kIGJvb2xlYW5zIGFyZSBjb21wYXJlZCBieSB2YWx1ZS4KICAgICAgY2FzZSAnW29iamVjdCBSZWdFeHBdJzoKICAgICAgLy8gUmVnRXhwcyBhcmUgY29lcmNlZCB0byBzdHJpbmdzIGZvciBjb21wYXJpc29uIChOb3RlOiAnJyArIC9hL2kgPT09ICcvYS9pJykKICAgICAgY2FzZSAnW29iamVjdCBTdHJpbmddJzoKICAgICAgICAvLyBQcmltaXRpdmVzIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIG9iamVjdCB3cmFwcGVycyBhcmUgZXF1aXZhbGVudDsgdGh1cywgYCI1ImAgaXMKICAgICAgICAvLyBlcXVpdmFsZW50IHRvIGBuZXcgU3RyaW5nKCI1IilgLgogICAgICAgIHJldHVybiAnJyArIGEgPT09ICcnICsgYjsKICAgICAgY2FzZSAnW29iamVjdCBOdW1iZXJdJzoKICAgICAgICAvLyBgTmFOYHMgYXJlIGVxdWl2YWxlbnQsIGJ1dCBub24tcmVmbGV4aXZlLgogICAgICAgIC8vIE9iamVjdChOYU4pIGlzIGVxdWl2YWxlbnQgdG8gTmFOLgogICAgICAgIGlmICgrYSAhPT0gK2EpIHJldHVybiArYiAhPT0gK2I7CiAgICAgICAgLy8gQW4gYGVnYWxgIGNvbXBhcmlzb24gaXMgcGVyZm9ybWVkIGZvciBvdGhlciBudW1lcmljIHZhbHVlcy4KICAgICAgICByZXR1cm4gK2EgPT09IDAgPyAxIC8gK2EgPT09IDEgLyBiIDogK2EgPT09ICtiOwogICAgICBjYXNlICdbb2JqZWN0IERhdGVdJzoKICAgICAgY2FzZSAnW29iamVjdCBCb29sZWFuXSc6CiAgICAgICAgLy8gQ29lcmNlIGRhdGVzIGFuZCBib29sZWFucyB0byBudW1lcmljIHByaW1pdGl2ZSB2YWx1ZXMuIERhdGVzIGFyZSBjb21wYXJlZCBieSB0aGVpcgogICAgICAgIC8vIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9ucy4gTm90ZSB0aGF0IGludmFsaWQgZGF0ZXMgd2l0aCBtaWxsaXNlY29uZCByZXByZXNlbnRhdGlvbnMKICAgICAgICAvLyBvZiBgTmFOYCBhcmUgbm90IGVxdWl2YWxlbnQuCiAgICAgICAgcmV0dXJuICthID09PSArYjsKICAgICAgY2FzZSAnW29iamVjdCBTeW1ib2xdJzoKICAgICAgICByZXR1cm4gU3ltYm9sUHJvdG8udmFsdWVPZi5jYWxsKGEpID09PSBTeW1ib2xQcm90by52YWx1ZU9mLmNhbGwoYik7CiAgICB9CgogICAgdmFyIGFyZUFycmF5cyA9IGNsYXNzTmFtZSA9PT0gJ1tvYmplY3QgQXJyYXldJzsKICAgIGlmICghYXJlQXJyYXlzKSB7CiAgICAgIGlmICh0eXBlb2YgYSAhPSAnb2JqZWN0JyB8fCB0eXBlb2YgYiAhPSAnb2JqZWN0JykgcmV0dXJuIGZhbHNlOwoKICAgICAgLy8gT2JqZWN0cyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVpdmFsZW50LCBidXQgYE9iamVjdGBzIG9yIGBBcnJheWBzCiAgICAgIC8vIGZyb20gZGlmZmVyZW50IGZyYW1lcyBhcmUuCiAgICAgIHZhciBhQ3RvciA9IGEuY29uc3RydWN0b3IsIGJDdG9yID0gYi5jb25zdHJ1Y3RvcjsKICAgICAgaWYgKGFDdG9yICE9PSBiQ3RvciAmJiAhKF8uaXNGdW5jdGlvbihhQ3RvcikgJiYgYUN0b3IgaW5zdGFuY2VvZiBhQ3RvciAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5pc0Z1bmN0aW9uKGJDdG9yKSAmJiBiQ3RvciBpbnN0YW5jZW9mIGJDdG9yKQogICAgICAgICAgICAgICAgICAgICAgICAgICYmICgnY29uc3RydWN0b3InIGluIGEgJiYgJ2NvbnN0cnVjdG9yJyBpbiBiKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfQogICAgLy8gQXNzdW1lIGVxdWFsaXR5IGZvciBjeWNsaWMgc3RydWN0dXJlcy4gVGhlIGFsZ29yaXRobSBmb3IgZGV0ZWN0aW5nIGN5Y2xpYwogICAgLy8gc3RydWN0dXJlcyBpcyBhZGFwdGVkIGZyb20gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMywgYWJzdHJhY3Qgb3BlcmF0aW9uIGBKT2AuCgogICAgLy8gSW5pdGlhbGl6aW5nIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLgogICAgLy8gSXQncyBkb25lIGhlcmUgc2luY2Ugd2Ugb25seSBuZWVkIHRoZW0gZm9yIG9iamVjdHMgYW5kIGFycmF5cyBjb21wYXJpc29uLgogICAgYVN0YWNrID0gYVN0YWNrIHx8IFtdOwogICAgYlN0YWNrID0gYlN0YWNrIHx8IFtdOwogICAgdmFyIGxlbmd0aCA9IGFTdGFjay5sZW5ndGg7CiAgICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgICAgLy8gTGluZWFyIHNlYXJjaC4gUGVyZm9ybWFuY2UgaXMgaW52ZXJzZWx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mCiAgICAgIC8vIHVuaXF1ZSBuZXN0ZWQgc3RydWN0dXJlcy4KICAgICAgaWYgKGFTdGFja1tsZW5ndGhdID09PSBhKSByZXR1cm4gYlN0YWNrW2xlbmd0aF0gPT09IGI7CiAgICB9CgogICAgLy8gQWRkIHRoZSBmaXJzdCBvYmplY3QgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLgogICAgYVN0YWNrLnB1c2goYSk7CiAgICBiU3RhY2sucHVzaChiKTsKCiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgYW5kIGFycmF5cy4KICAgIGlmIChhcmVBcnJheXMpIHsKICAgICAgLy8gQ29tcGFyZSBhcnJheSBsZW5ndGhzIHRvIGRldGVybWluZSBpZiBhIGRlZXAgY29tcGFyaXNvbiBpcyBuZWNlc3NhcnkuCiAgICAgIGxlbmd0aCA9IGEubGVuZ3RoOwogICAgICBpZiAobGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlOwogICAgICAvLyBEZWVwIGNvbXBhcmUgdGhlIGNvbnRlbnRzLCBpZ25vcmluZyBub24tbnVtZXJpYyBwcm9wZXJ0aWVzLgogICAgICB3aGlsZSAobGVuZ3RoLS0pIHsKICAgICAgICBpZiAoIWVxKGFbbGVuZ3RoXSwgYltsZW5ndGhdLCBhU3RhY2ssIGJTdGFjaykpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLy8gRGVlcCBjb21wYXJlIG9iamVjdHMuCiAgICAgIHZhciBrZXlzID0gXy5rZXlzKGEpLCBrZXk7CiAgICAgIGxlbmd0aCA9IGtleXMubGVuZ3RoOwogICAgICAvLyBFbnN1cmUgdGhhdCBib3RoIG9iamVjdHMgY29udGFpbiB0aGUgc2FtZSBudW1iZXIgb2YgcHJvcGVydGllcyBiZWZvcmUgY29tcGFyaW5nIGRlZXAgZXF1YWxpdHkuCiAgICAgIGlmIChfLmtleXMoYikubGVuZ3RoICE9PSBsZW5ndGgpIHJldHVybiBmYWxzZTsKICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7CiAgICAgICAgLy8gRGVlcCBjb21wYXJlIGVhY2ggbWVtYmVyCiAgICAgICAga2V5ID0ga2V5c1tsZW5ndGhdOwogICAgICAgIGlmICghKGhhcyhiLCBrZXkpICYmIGVxKGFba2V5XSwgYltrZXldLCBhU3RhY2ssIGJTdGFjaykpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgIH0KICAgIC8vIFJlbW92ZSB0aGUgZmlyc3Qgb2JqZWN0IGZyb20gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLgogICAgYVN0YWNrLnBvcCgpOwogICAgYlN0YWNrLnBvcCgpOwogICAgcmV0dXJuIHRydWU7CiAgfTsKCiAgLy8gUGVyZm9ybSBhIGRlZXAgY29tcGFyaXNvbiB0byBjaGVjayBpZiB0d28gb2JqZWN0cyBhcmUgZXF1YWwuCiAgXy5pc0VxdWFsID0gZnVuY3Rpb24oYSwgYikgewogICAgcmV0dXJuIGVxKGEsIGIpOwogIH07CgogIC8vIElzIGEgZ2l2ZW4gYXJyYXksIHN0cmluZywgb3Igb2JqZWN0IGVtcHR5PwogIC8vIEFuICJlbXB0eSIgb2JqZWN0IGhhcyBubyBlbnVtZXJhYmxlIG93bi1wcm9wZXJ0aWVzLgogIF8uaXNFbXB0eSA9IGZ1bmN0aW9uKG9iaikgewogICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gdHJ1ZTsKICAgIGlmIChpc0FycmF5TGlrZShvYmopICYmIChfLmlzQXJyYXkob2JqKSB8fCBfLmlzU3RyaW5nKG9iaikgfHwgXy5pc0FyZ3VtZW50cyhvYmopKSkgcmV0dXJuIG9iai5sZW5ndGggPT09IDA7CiAgICByZXR1cm4gXy5rZXlzKG9iaikubGVuZ3RoID09PSAwOwogIH07CgogIC8vIElzIGEgZ2l2ZW4gdmFsdWUgYSBET00gZWxlbWVudD8KICBfLmlzRWxlbWVudCA9IGZ1bmN0aW9uKG9iaikgewogICAgcmV0dXJuICEhKG9iaiAmJiBvYmoubm9kZVR5cGUgPT09IDEpOwogIH07CgogIC8vIElzIGEgZ2l2ZW4gdmFsdWUgYW4gYXJyYXk/CiAgLy8gRGVsZWdhdGVzIHRvIEVDTUE1J3MgbmF0aXZlIEFycmF5LmlzQXJyYXkKICBfLmlzQXJyYXkgPSBuYXRpdmVJc0FycmF5IHx8IGZ1bmN0aW9uKG9iaikgewogICAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJzsKICB9OwoKICAvLyBJcyBhIGdpdmVuIHZhcmlhYmxlIGFuIG9iamVjdD8KICBfLmlzT2JqZWN0ID0gZnVuY3Rpb24ob2JqKSB7CiAgICB2YXIgdHlwZSA9IHR5cGVvZiBvYmo7CiAgICByZXR1cm4gdHlwZSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlID09PSAnb2JqZWN0JyAmJiAhIW9iajsKICB9OwoKICAvLyBBZGQgc29tZSBpc1R5cGUgbWV0aG9kczogaXNBcmd1bWVudHMsIGlzRnVuY3Rpb24sIGlzU3RyaW5nLCBpc051bWJlciwgaXNEYXRlLCBpc1JlZ0V4cCwgaXNFcnJvciwgaXNNYXAsIGlzV2Vha01hcCwgaXNTZXQsIGlzV2Vha1NldC4KICBfLmVhY2goWydBcmd1bWVudHMnLCAnRnVuY3Rpb24nLCAnU3RyaW5nJywgJ051bWJlcicsICdEYXRlJywgJ1JlZ0V4cCcsICdFcnJvcicsICdTeW1ib2wnLCAnTWFwJywgJ1dlYWtNYXAnLCAnU2V0JywgJ1dlYWtTZXQnXSwgZnVuY3Rpb24obmFtZSkgewogICAgX1snaXMnICsgbmFtZV0gPSBmdW5jdGlvbihvYmopIHsKICAgICAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgJyArIG5hbWUgKyAnXSc7CiAgICB9OwogIH0pOwoKICAvLyBEZWZpbmUgYSBmYWxsYmFjayB2ZXJzaW9uIG9mIHRoZSBtZXRob2QgaW4gYnJvd3NlcnMgKGFoZW0sIElFIDwgOSksIHdoZXJlCiAgLy8gdGhlcmUgaXNuJ3QgYW55IGluc3BlY3RhYmxlICJBcmd1bWVudHMiIHR5cGUuCiAgaWYgKCFfLmlzQXJndW1lbnRzKGFyZ3VtZW50cykpIHsKICAgIF8uaXNBcmd1bWVudHMgPSBmdW5jdGlvbihvYmopIHsKICAgICAgcmV0dXJuIGhhcyhvYmosICdjYWxsZWUnKTsKICAgIH07CiAgfQoKICAvLyBPcHRpbWl6ZSBgaXNGdW5jdGlvbmAgaWYgYXBwcm9wcmlhdGUuIFdvcmsgYXJvdW5kIHNvbWUgdHlwZW9mIGJ1Z3MgaW4gb2xkIHY4LAogIC8vIElFIDExICgjMTYyMSksIFNhZmFyaSA4ICgjMTkyOSksIGFuZCBQaGFudG9tSlMgKCMyMjM2KS4KICB2YXIgbm9kZWxpc3QgPSByb290LmRvY3VtZW50ICYmIHJvb3QuZG9jdW1lbnQuY2hpbGROb2RlczsKICBpZiAodHlwZW9mIC8uLyAhPSAnZnVuY3Rpb24nICYmIHR5cGVvZiBJbnQ4QXJyYXkgIT0gJ29iamVjdCcgJiYgdHlwZW9mIG5vZGVsaXN0ICE9ICdmdW5jdGlvbicpIHsKICAgIF8uaXNGdW5jdGlvbiA9IGZ1bmN0aW9uKG9iaikgewogICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PSAnZnVuY3Rpb24nIHx8IGZhbHNlOwogICAgfTsKICB9CgogIC8vIElzIGEgZ2l2ZW4gb2JqZWN0IGEgZmluaXRlIG51bWJlcj8KICBfLmlzRmluaXRlID0gZnVuY3Rpb24ob2JqKSB7CiAgICByZXR1cm4gIV8uaXNTeW1ib2wob2JqKSAmJiBpc0Zpbml0ZShvYmopICYmICFpc05hTihwYXJzZUZsb2F0KG9iaikpOwogIH07CgogIC8vIElzIHRoZSBnaXZlbiB2YWx1ZSBgTmFOYD8KICBfLmlzTmFOID0gZnVuY3Rpb24ob2JqKSB7CiAgICByZXR1cm4gXy5pc051bWJlcihvYmopICYmIGlzTmFOKG9iaik7CiAgfTsKCiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBhIGJvb2xlYW4/CiAgXy5pc0Jvb2xlYW4gPSBmdW5jdGlvbihvYmopIHsKICAgIHJldHVybiBvYmogPT09IHRydWUgfHwgb2JqID09PSBmYWxzZSB8fCB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEJvb2xlYW5dJzsKICB9OwoKICAvLyBJcyBhIGdpdmVuIHZhbHVlIGVxdWFsIHRvIG51bGw/CiAgXy5pc051bGwgPSBmdW5jdGlvbihvYmopIHsKICAgIHJldHVybiBvYmogPT09IG51bGw7CiAgfTsKCiAgLy8gSXMgYSBnaXZlbiB2YXJpYWJsZSB1bmRlZmluZWQ/CiAgXy5pc1VuZGVmaW5lZCA9IGZ1bmN0aW9uKG9iaikgewogICAgcmV0dXJuIG9iaiA9PT0gdm9pZCAwOwogIH07CgogIC8vIFNob3J0Y3V0IGZ1bmN0aW9uIGZvciBjaGVja2luZyBpZiBhbiBvYmplY3QgaGFzIGEgZ2l2ZW4gcHJvcGVydHkgZGlyZWN0bHkKICAvLyBvbiBpdHNlbGYgKGluIG90aGVyIHdvcmRzLCBub3Qgb24gYSBwcm90b3R5cGUpLgogIF8uaGFzID0gZnVuY3Rpb24ob2JqLCBwYXRoKSB7CiAgICBpZiAoIV8uaXNBcnJheShwYXRoKSkgewogICAgICByZXR1cm4gaGFzKG9iaiwgcGF0aCk7CiAgICB9CiAgICB2YXIgbGVuZ3RoID0gcGF0aC5sZW5ndGg7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBrZXkgPSBwYXRoW2ldOwogICAgICBpZiAob2JqID09IG51bGwgfHwgIWhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG9iaiA9IG9ialtrZXldOwogICAgfQogICAgcmV0dXJuICEhbGVuZ3RoOwogIH07CgogIC8vIFV0aWxpdHkgRnVuY3Rpb25zCiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0KCiAgLy8gUnVuIFVuZGVyc2NvcmUuanMgaW4gKm5vQ29uZmxpY3QqIG1vZGUsIHJldHVybmluZyB0aGUgYF9gIHZhcmlhYmxlIHRvIGl0cwogIC8vIHByZXZpb3VzIG93bmVyLiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdC4KICBfLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHsKICAgIHJvb3QuXyA9IHByZXZpb3VzVW5kZXJzY29yZTsKICAgIHJldHVybiB0aGlzOwogIH07CgogIC8vIEtlZXAgdGhlIGlkZW50aXR5IGZ1bmN0aW9uIGFyb3VuZCBmb3IgZGVmYXVsdCBpdGVyYXRlZXMuCiAgXy5pZGVudGl0eSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICByZXR1cm4gdmFsdWU7CiAgfTsKCiAgLy8gUHJlZGljYXRlLWdlbmVyYXRpbmcgZnVuY3Rpb25zLiBPZnRlbiB1c2VmdWwgb3V0c2lkZSBvZiBVbmRlcnNjb3JlLgogIF8uY29uc3RhbnQgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdmFsdWU7CiAgICB9OwogIH07CgogIF8ubm9vcCA9IGZ1bmN0aW9uKCl7fTsKCiAgLy8gQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQsIHdoZW4gcGFzc2VkIGFuIG9iamVjdCwgd2lsbCB0cmF2ZXJzZSB0aGF0IG9iamVjdOKAmXMKICAvLyBwcm9wZXJ0aWVzIGRvd24gdGhlIGdpdmVuIGBwYXRoYCwgc3BlY2lmaWVkIGFzIGFuIGFycmF5IG9mIGtleXMgb3IgaW5kZXhlcy4KICBfLnByb3BlcnR5ID0gZnVuY3Rpb24ocGF0aCkgewogICAgaWYgKCFfLmlzQXJyYXkocGF0aCkpIHsKICAgICAgcmV0dXJuIHNoYWxsb3dQcm9wZXJ0eShwYXRoKTsKICAgIH0KICAgIHJldHVybiBmdW5jdGlvbihvYmopIHsKICAgICAgcmV0dXJuIGRlZXBHZXQob2JqLCBwYXRoKTsKICAgIH07CiAgfTsKCiAgLy8gR2VuZXJhdGVzIGEgZnVuY3Rpb24gZm9yIGEgZ2l2ZW4gb2JqZWN0IHRoYXQgcmV0dXJucyBhIGdpdmVuIHByb3BlcnR5LgogIF8ucHJvcGVydHlPZiA9IGZ1bmN0aW9uKG9iaikgewogICAgaWYgKG9iaiA9PSBudWxsKSB7CiAgICAgIHJldHVybiBmdW5jdGlvbigpe307CiAgICB9CiAgICByZXR1cm4gZnVuY3Rpb24ocGF0aCkgewogICAgICByZXR1cm4gIV8uaXNBcnJheShwYXRoKSA/IG9ialtwYXRoXSA6IGRlZXBHZXQob2JqLCBwYXRoKTsKICAgIH07CiAgfTsKCiAgLy8gUmV0dXJucyBhIHByZWRpY2F0ZSBmb3IgY2hlY2tpbmcgd2hldGhlciBhbiBvYmplY3QgaGFzIGEgZ2l2ZW4gc2V0IG9mCiAgLy8gYGtleTp2YWx1ZWAgcGFpcnMuCiAgXy5tYXRjaGVyID0gXy5tYXRjaGVzID0gZnVuY3Rpb24oYXR0cnMpIHsKICAgIGF0dHJzID0gXy5leHRlbmRPd24oe30sIGF0dHJzKTsKICAgIHJldHVybiBmdW5jdGlvbihvYmopIHsKICAgICAgcmV0dXJuIF8uaXNNYXRjaChvYmosIGF0dHJzKTsKICAgIH07CiAgfTsKCiAgLy8gUnVuIGEgZnVuY3Rpb24gKipuKiogdGltZXMuCiAgXy50aW1lcyA9IGZ1bmN0aW9uKG4sIGl0ZXJhdGVlLCBjb250ZXh0KSB7CiAgICB2YXIgYWNjdW0gPSBBcnJheShNYXRoLm1heCgwLCBuKSk7CiAgICBpdGVyYXRlZSA9IG9wdGltaXplQ2IoaXRlcmF0ZWUsIGNvbnRleHQsIDEpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIGFjY3VtW2ldID0gaXRlcmF0ZWUoaSk7CiAgICByZXR1cm4gYWNjdW07CiAgfTsKCiAgLy8gUmV0dXJuIGEgcmFuZG9tIGludGVnZXIgYmV0d2VlbiBtaW4gYW5kIG1heCAoaW5jbHVzaXZlKS4KICBfLnJhbmRvbSA9IGZ1bmN0aW9uKG1pbiwgbWF4KSB7CiAgICBpZiAobWF4ID09IG51bGwpIHsKICAgICAgbWF4ID0gbWluOwogICAgICBtaW4gPSAwOwogICAgfQogICAgcmV0dXJuIG1pbiArIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4gKyAxKSk7CiAgfTsKCiAgLy8gQSAocG9zc2libHkgZmFzdGVyKSB3YXkgdG8gZ2V0IHRoZSBjdXJyZW50IHRpbWVzdGFtcCBhcyBhbiBpbnRlZ2VyLgogIF8ubm93ID0gRGF0ZS5ub3cgfHwgZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7CiAgfTsKCiAgLy8gTGlzdCBvZiBIVE1MIGVudGl0aWVzIGZvciBlc2NhcGluZy4KICB2YXIgZXNjYXBlTWFwID0gewogICAgJyYnOiAnJmFtcDsnLAogICAgJzwnOiAnJmx0OycsCiAgICAnPic6ICcmZ3Q7JywKICAgICciJzogJyZxdW90OycsCiAgICAiJyI6ICcmI3gyNzsnLAogICAgJ2AnOiAnJiN4NjA7JwogIH07CiAgdmFyIHVuZXNjYXBlTWFwID0gXy5pbnZlcnQoZXNjYXBlTWFwKTsKCiAgLy8gRnVuY3Rpb25zIGZvciBlc2NhcGluZyBhbmQgdW5lc2NhcGluZyBzdHJpbmdzIHRvL2Zyb20gSFRNTCBpbnRlcnBvbGF0aW9uLgogIHZhciBjcmVhdGVFc2NhcGVyID0gZnVuY3Rpb24obWFwKSB7CiAgICB2YXIgZXNjYXBlciA9IGZ1bmN0aW9uKG1hdGNoKSB7CiAgICAgIHJldHVybiBtYXBbbWF0Y2hdOwogICAgfTsKICAgIC8vIFJlZ2V4ZXMgZm9yIGlkZW50aWZ5aW5nIGEga2V5IHRoYXQgbmVlZHMgdG8gYmUgZXNjYXBlZC4KICAgIHZhciBzb3VyY2UgPSAnKD86JyArIF8ua2V5cyhtYXApLmpvaW4oJ3wnKSArICcpJzsKICAgIHZhciB0ZXN0UmVnZXhwID0gUmVnRXhwKHNvdXJjZSk7CiAgICB2YXIgcmVwbGFjZVJlZ2V4cCA9IFJlZ0V4cChzb3VyY2UsICdnJyk7CiAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7CiAgICAgIHN0cmluZyA9IHN0cmluZyA9PSBudWxsID8gJycgOiAnJyArIHN0cmluZzsKICAgICAgcmV0dXJuIHRlc3RSZWdleHAudGVzdChzdHJpbmcpID8gc3RyaW5nLnJlcGxhY2UocmVwbGFjZVJlZ2V4cCwgZXNjYXBlcikgOiBzdHJpbmc7CiAgICB9OwogIH07CiAgXy5lc2NhcGUgPSBjcmVhdGVFc2NhcGVyKGVzY2FwZU1hcCk7CiAgXy51bmVzY2FwZSA9IGNyZWF0ZUVzY2FwZXIodW5lc2NhcGVNYXApOwoKICAvLyBUcmF2ZXJzZXMgdGhlIGNoaWxkcmVuIG9mIGBvYmpgIGFsb25nIGBwYXRoYC4gSWYgYSBjaGlsZCBpcyBhIGZ1bmN0aW9uLCBpdAogIC8vIGlzIGludm9rZWQgd2l0aCBpdHMgcGFyZW50IGFzIGNvbnRleHQuIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBmaW5hbAogIC8vIGNoaWxkLCBvciBgZmFsbGJhY2tgIGlmIGFueSBjaGlsZCBpcyB1bmRlZmluZWQuCiAgXy5yZXN1bHQgPSBmdW5jdGlvbihvYmosIHBhdGgsIGZhbGxiYWNrKSB7CiAgICBpZiAoIV8uaXNBcnJheShwYXRoKSkgcGF0aCA9IFtwYXRoXTsKICAgIHZhciBsZW5ndGggPSBwYXRoLmxlbmd0aDsKICAgIGlmICghbGVuZ3RoKSB7CiAgICAgIHJldHVybiBfLmlzRnVuY3Rpb24oZmFsbGJhY2spID8gZmFsbGJhY2suY2FsbChvYmopIDogZmFsbGJhY2s7CiAgICB9CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBwcm9wID0gb2JqID09IG51bGwgPyB2b2lkIDAgOiBvYmpbcGF0aFtpXV07CiAgICAgIGlmIChwcm9wID09PSB2b2lkIDApIHsKICAgICAgICBwcm9wID0gZmFsbGJhY2s7CiAgICAgICAgaSA9IGxlbmd0aDsgLy8gRW5zdXJlIHdlIGRvbid0IGNvbnRpbnVlIGl0ZXJhdGluZy4KICAgICAgfQogICAgICBvYmogPSBfLmlzRnVuY3Rpb24ocHJvcCkgPyBwcm9wLmNhbGwob2JqKSA6IHByb3A7CiAgICB9CiAgICByZXR1cm4gb2JqOwogIH07CgogIC8vIEdlbmVyYXRlIGEgdW5pcXVlIGludGVnZXIgaWQgKHVuaXF1ZSB3aXRoaW4gdGhlIGVudGlyZSBjbGllbnQgc2Vzc2lvbikuCiAgLy8gVXNlZnVsIGZvciB0ZW1wb3JhcnkgRE9NIGlkcy4KICB2YXIgaWRDb3VudGVyID0gMDsKICBfLnVuaXF1ZUlkID0gZnVuY3Rpb24ocHJlZml4KSB7CiAgICB2YXIgaWQgPSArK2lkQ291bnRlciArICcnOwogICAgcmV0dXJuIHByZWZpeCA/IHByZWZpeCArIGlkIDogaWQ7CiAgfTsKCiAgLy8gQnkgZGVmYXVsdCwgVW5kZXJzY29yZSB1c2VzIEVSQi1zdHlsZSB0ZW1wbGF0ZSBkZWxpbWl0ZXJzLCBjaGFuZ2UgdGhlCiAgLy8gZm9sbG93aW5nIHRlbXBsYXRlIHNldHRpbmdzIHRvIHVzZSBhbHRlcm5hdGl2ZSBkZWxpbWl0ZXJzLgogIF8udGVtcGxhdGVTZXR0aW5ncyA9IHsKICAgIGV2YWx1YXRlOiAvPCUoW1xzXFNdKz8pJT4vZywKICAgIGludGVycG9sYXRlOiAvPCU9KFtcc1xTXSs/KSU+L2csCiAgICBlc2NhcGU6IC88JS0oW1xzXFNdKz8pJT4vZwogIH07CgogIC8vIFdoZW4gY3VzdG9taXppbmcgYHRlbXBsYXRlU2V0dGluZ3NgLCBpZiB5b3UgZG9uJ3Qgd2FudCB0byBkZWZpbmUgYW4KICAvLyBpbnRlcnBvbGF0aW9uLCBldmFsdWF0aW9uIG9yIGVzY2FwaW5nIHJlZ2V4LCB3ZSBuZWVkIG9uZSB0aGF0IGlzCiAgLy8gZ3VhcmFudGVlZCBub3QgdG8gbWF0Y2guCiAgdmFyIG5vTWF0Y2ggPSAvKC4pXi87CgogIC8vIENlcnRhaW4gY2hhcmFjdGVycyBuZWVkIHRvIGJlIGVzY2FwZWQgc28gdGhhdCB0aGV5IGNhbiBiZSBwdXQgaW50byBhCiAgLy8gc3RyaW5nIGxpdGVyYWwuCiAgdmFyIGVzY2FwZXMgPSB7CiAgICAiJyI6ICInIiwKICAgICdcXCc6ICdcXCcsCiAgICAnXHInOiAncicsCiAgICAnXG4nOiAnbicsCiAgICAnXHUyMDI4JzogJ3UyMDI4JywKICAgICdcdTIwMjknOiAndTIwMjknCiAgfTsKCiAgdmFyIGVzY2FwZVJlZ0V4cCA9IC9cXHwnfFxyfFxufFx1MjAyOHxcdTIwMjkvZzsKCiAgdmFyIGVzY2FwZUNoYXIgPSBmdW5jdGlvbihtYXRjaCkgewogICAgcmV0dXJuICdcXCcgKyBlc2NhcGVzW21hdGNoXTsKICB9OwoKICAvLyBKYXZhU2NyaXB0IG1pY3JvLXRlbXBsYXRpbmcsIHNpbWlsYXIgdG8gSm9obiBSZXNpZydzIGltcGxlbWVudGF0aW9uLgogIC8vIFVuZGVyc2NvcmUgdGVtcGxhdGluZyBoYW5kbGVzIGFyYml0cmFyeSBkZWxpbWl0ZXJzLCBwcmVzZXJ2ZXMgd2hpdGVzcGFjZSwKICAvLyBhbmQgY29ycmVjdGx5IGVzY2FwZXMgcXVvdGVzIHdpdGhpbiBpbnRlcnBvbGF0ZWQgY29kZS4KICAvLyBOQjogYG9sZFNldHRpbmdzYCBvbmx5IGV4aXN0cyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuCiAgXy50ZW1wbGF0ZSA9IGZ1bmN0aW9uKHRleHQsIHNldHRpbmdzLCBvbGRTZXR0aW5ncykgewogICAgaWYgKCFzZXR0aW5ncyAmJiBvbGRTZXR0aW5ncykgc2V0dGluZ3MgPSBvbGRTZXR0aW5nczsKICAgIHNldHRpbmdzID0gXy5kZWZhdWx0cyh7fSwgc2V0dGluZ3MsIF8udGVtcGxhdGVTZXR0aW5ncyk7CgogICAgLy8gQ29tYmluZSBkZWxpbWl0ZXJzIGludG8gb25lIHJlZ3VsYXIgZXhwcmVzc2lvbiB2aWEgYWx0ZXJuYXRpb24uCiAgICB2YXIgbWF0Y2hlciA9IFJlZ0V4cChbCiAgICAgIChzZXR0aW5ncy5lc2NhcGUgfHwgbm9NYXRjaCkuc291cmNlLAogICAgICAoc2V0dGluZ3MuaW50ZXJwb2xhdGUgfHwgbm9NYXRjaCkuc291cmNlLAogICAgICAoc2V0dGluZ3MuZXZhbHVhdGUgfHwgbm9NYXRjaCkuc291cmNlCiAgICBdLmpvaW4oJ3wnKSArICd8JCcsICdnJyk7CgogICAgLy8gQ29tcGlsZSB0aGUgdGVtcGxhdGUgc291cmNlLCBlc2NhcGluZyBzdHJpbmcgbGl0ZXJhbHMgYXBwcm9wcmlhdGVseS4KICAgIHZhciBpbmRleCA9IDA7CiAgICB2YXIgc291cmNlID0gIl9fcCs9JyI7CiAgICB0ZXh0LnJlcGxhY2UobWF0Y2hlciwgZnVuY3Rpb24obWF0Y2gsIGVzY2FwZSwgaW50ZXJwb2xhdGUsIGV2YWx1YXRlLCBvZmZzZXQpIHsKICAgICAgc291cmNlICs9IHRleHQuc2xpY2UoaW5kZXgsIG9mZnNldCkucmVwbGFjZShlc2NhcGVSZWdFeHAsIGVzY2FwZUNoYXIpOwogICAgICBpbmRleCA9IG9mZnNldCArIG1hdGNoLmxlbmd0aDsKCiAgICAgIGlmIChlc2NhcGUpIHsKICAgICAgICBzb3VyY2UgKz0gIicrXG4oKF9fdD0oIiArIGVzY2FwZSArICIpKT09bnVsbD8nJzpfLmVzY2FwZShfX3QpKStcbiciOwogICAgICB9IGVsc2UgaWYgKGludGVycG9sYXRlKSB7CiAgICAgICAgc291cmNlICs9ICInK1xuKChfX3Q9KCIgKyBpbnRlcnBvbGF0ZSArICIpKT09bnVsbD8nJzpfX3QpK1xuJyI7CiAgICAgIH0gZWxzZSBpZiAoZXZhbHVhdGUpIHsKICAgICAgICBzb3VyY2UgKz0gIic7XG4iICsgZXZhbHVhdGUgKyAiXG5fX3ArPSciOwogICAgICB9CgogICAgICAvLyBBZG9iZSBWTXMgbmVlZCB0aGUgbWF0Y2ggcmV0dXJuZWQgdG8gcHJvZHVjZSB0aGUgY29ycmVjdCBvZmZzZXQuCiAgICAgIHJldHVybiBtYXRjaDsKICAgIH0pOwogICAgc291cmNlICs9ICInO1xuIjsKCiAgICAvLyBJZiBhIHZhcmlhYmxlIGlzIG5vdCBzcGVjaWZpZWQsIHBsYWNlIGRhdGEgdmFsdWVzIGluIGxvY2FsIHNjb3BlLgogICAgaWYgKCFzZXR0aW5ncy52YXJpYWJsZSkgc291cmNlID0gJ3dpdGgob2JqfHx7fSl7XG4nICsgc291cmNlICsgJ31cbic7CgogICAgc291cmNlID0gInZhciBfX3QsX19wPScnLF9faj1BcnJheS5wcm90b3R5cGUuam9pbiwiICsKICAgICAgInByaW50PWZ1bmN0aW9uKCl7X19wKz1fX2ouY2FsbChhcmd1bWVudHMsJycpO307XG4iICsKICAgICAgc291cmNlICsgJ3JldHVybiBfX3A7XG4nOwoKICAgIHZhciByZW5kZXI7CiAgICB0cnkgewogICAgICByZW5kZXIgPSBuZXcgRnVuY3Rpb24oc2V0dGluZ3MudmFyaWFibGUgfHwgJ29iaicsICdfJywgc291cmNlKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgZS5zb3VyY2UgPSBzb3VyY2U7CiAgICAgIHRocm93IGU7CiAgICB9CgogICAgdmFyIHRlbXBsYXRlID0gZnVuY3Rpb24oZGF0YSkgewogICAgICByZXR1cm4gcmVuZGVyLmNhbGwodGhpcywgZGF0YSwgXyk7CiAgICB9OwoKICAgIC8vIFByb3ZpZGUgdGhlIGNvbXBpbGVkIHNvdXJjZSBhcyBhIGNvbnZlbmllbmNlIGZvciBwcmVjb21waWxhdGlvbi4KICAgIHZhciBhcmd1bWVudCA9IHNldHRpbmdzLnZhcmlhYmxlIHx8ICdvYmonOwogICAgdGVtcGxhdGUuc291cmNlID0gJ2Z1bmN0aW9uKCcgKyBhcmd1bWVudCArICcpe1xuJyArIHNvdXJjZSArICd9JzsKCiAgICByZXR1cm4gdGVtcGxhdGU7CiAgfTsKCiAgLy8gQWRkIGEgImNoYWluIiBmdW5jdGlvbi4gU3RhcnQgY2hhaW5pbmcgYSB3cmFwcGVkIFVuZGVyc2NvcmUgb2JqZWN0LgogIF8uY2hhaW4gPSBmdW5jdGlvbihvYmopIHsKICAgIHZhciBpbnN0YW5jZSA9IF8ob2JqKTsKICAgIGluc3RhbmNlLl9jaGFpbiA9IHRydWU7CiAgICByZXR1cm4gaW5zdGFuY2U7CiAgfTsKCiAgLy8gT09QCiAgLy8gLS0tLS0tLS0tLS0tLS0tCiAgLy8gSWYgVW5kZXJzY29yZSBpcyBjYWxsZWQgYXMgYSBmdW5jdGlvbiwgaXQgcmV0dXJucyBhIHdyYXBwZWQgb2JqZWN0IHRoYXQKICAvLyBjYW4gYmUgdXNlZCBPTy1zdHlsZS4gVGhpcyB3cmFwcGVyIGhvbGRzIGFsdGVyZWQgdmVyc2lvbnMgb2YgYWxsIHRoZQogIC8vIHVuZGVyc2NvcmUgZnVuY3Rpb25zLiBXcmFwcGVkIG9iamVjdHMgbWF5IGJlIGNoYWluZWQuCgogIC8vIEhlbHBlciBmdW5jdGlvbiB0byBjb250aW51ZSBjaGFpbmluZyBpbnRlcm1lZGlhdGUgcmVzdWx0cy4KICB2YXIgY2hhaW5SZXN1bHQgPSBmdW5jdGlvbihpbnN0YW5jZSwgb2JqKSB7CiAgICByZXR1cm4gaW5zdGFuY2UuX2NoYWluID8gXyhvYmopLmNoYWluKCkgOiBvYmo7CiAgfTsKCiAgLy8gQWRkIHlvdXIgb3duIGN1c3RvbSBmdW5jdGlvbnMgdG8gdGhlIFVuZGVyc2NvcmUgb2JqZWN0LgogIF8ubWl4aW4gPSBmdW5jdGlvbihvYmopIHsKICAgIF8uZWFjaChfLmZ1bmN0aW9ucyhvYmopLCBmdW5jdGlvbihuYW1lKSB7CiAgICAgIHZhciBmdW5jID0gX1tuYW1lXSA9IG9ialtuYW1lXTsKICAgICAgXy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgYXJncyA9IFt0aGlzLl93cmFwcGVkXTsKICAgICAgICBwdXNoLmFwcGx5KGFyZ3MsIGFyZ3VtZW50cyk7CiAgICAgICAgcmV0dXJuIGNoYWluUmVzdWx0KHRoaXMsIGZ1bmMuYXBwbHkoXywgYXJncykpOwogICAgICB9OwogICAgfSk7CiAgICByZXR1cm4gXzsKICB9OwoKICAvLyBBZGQgYWxsIG9mIHRoZSBVbmRlcnNjb3JlIGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlciBvYmplY3QuCiAgXy5taXhpbihfKTsKCiAgLy8gQWRkIGFsbCBtdXRhdG9yIEFycmF5IGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlci4KICBfLmVhY2goWydwb3AnLCAncHVzaCcsICdyZXZlcnNlJywgJ3NoaWZ0JywgJ3NvcnQnLCAnc3BsaWNlJywgJ3Vuc2hpZnQnXSwgZnVuY3Rpb24obmFtZSkgewogICAgdmFyIG1ldGhvZCA9IEFycmF5UHJvdG9bbmFtZV07CiAgICBfLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKCkgewogICAgICB2YXIgb2JqID0gdGhpcy5fd3JhcHBlZDsKICAgICAgbWV0aG9kLmFwcGx5KG9iaiwgYXJndW1lbnRzKTsKICAgICAgaWYgKChuYW1lID09PSAnc2hpZnQnIHx8IG5hbWUgPT09ICdzcGxpY2UnKSAmJiBvYmoubGVuZ3RoID09PSAwKSBkZWxldGUgb2JqWzBdOwogICAgICByZXR1cm4gY2hhaW5SZXN1bHQodGhpcywgb2JqKTsKICAgIH07CiAgfSk7CgogIC8vIEFkZCBhbGwgYWNjZXNzb3IgQXJyYXkgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyLgogIF8uZWFjaChbJ2NvbmNhdCcsICdqb2luJywgJ3NsaWNlJ10sIGZ1bmN0aW9uKG5hbWUpIHsKICAgIHZhciBtZXRob2QgPSBBcnJheVByb3RvW25hbWVdOwogICAgXy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIGNoYWluUmVzdWx0KHRoaXMsIG1ldGhvZC5hcHBseSh0aGlzLl93cmFwcGVkLCBhcmd1bWVudHMpKTsKICAgIH07CiAgfSk7CgogIC8vIEV4dHJhY3RzIHRoZSByZXN1bHQgZnJvbSBhIHdyYXBwZWQgYW5kIGNoYWluZWQgb2JqZWN0LgogIF8ucHJvdG90eXBlLnZhbHVlID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5fd3JhcHBlZDsKICB9OwoKICAvLyBQcm92aWRlIHVud3JhcHBpbmcgcHJveHkgZm9yIHNvbWUgbWV0aG9kcyB1c2VkIGluIGVuZ2luZSBvcGVyYXRpb25zCiAgLy8gc3VjaCBhcyBhcml0aG1ldGljIGFuZCBKU09OIHN0cmluZ2lmaWNhdGlvbi4KICBfLnByb3RvdHlwZS52YWx1ZU9mID0gXy5wcm90b3R5cGUudG9KU09OID0gXy5wcm90b3R5cGUudmFsdWU7CgogIF8ucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gU3RyaW5nKHRoaXMuX3dyYXBwZWQpOwogIH07CgogIC8vIEFNRCByZWdpc3RyYXRpb24gaGFwcGVucyBhdCB0aGUgZW5kIGZvciBjb21wYXRpYmlsaXR5IHdpdGggQU1EIGxvYWRlcnMKICAvLyB0aGF0IG1heSBub3QgZW5mb3JjZSBuZXh0LXR1cm4gc2VtYW50aWNzIG9uIG1vZHVsZXMuIEV2ZW4gdGhvdWdoIGdlbmVyYWwKICAvLyBwcmFjdGljZSBmb3IgQU1EIHJlZ2lzdHJhdGlvbiBpcyB0byBiZSBhbm9ueW1vdXMsIHVuZGVyc2NvcmUgcmVnaXN0ZXJzCiAgLy8gYXMgYSBuYW1lZCBtb2R1bGUgYmVjYXVzZSwgbGlrZSBqUXVlcnksIGl0IGlzIGEgYmFzZSBsaWJyYXJ5IHRoYXQgaXMKICAvLyBwb3B1bGFyIGVub3VnaCB0byBiZSBidW5kbGVkIGluIGEgdGhpcmQgcGFydHkgbGliLCBidXQgbm90IGJlIHBhcnQgb2YKICAvLyBhbiBBTUQgbG9hZCByZXF1ZXN0LiBUaG9zZSBjYXNlcyBjb3VsZCBnZW5lcmF0ZSBhbiBlcnJvciB3aGVuIGFuCiAgLy8gYW5vbnltb3VzIGRlZmluZSgpIGlzIGNhbGxlZCBvdXRzaWRlIG9mIGEgbG9hZGVyIHJlcXVlc3QuCiAgaWYgKHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7CiAgICBkZWZpbmUoJ3VuZGVyc2NvcmUnLCBbXSwgZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBfOwogICAgfSk7CiAgfQp9KCkpOwo="></script>
<script src="data:application/javascript;base64,Ly8gVmVuZG9yZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vcm1taC93ZWJ0cmVlbWFwL2Jsb2IvOWZhMGMwNjZhMTBlYTQ0MDJkOTYwYjBjNmMxYTQzMjg0NmFjN2ZjNC93ZWJ0cmVlbWFwLmpzCgovLyBDb3B5cmlnaHQgMjAxMyBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLgovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAovLwovLyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi8vIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgovLyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoKLy8gU2l6ZSBvZiBib3JkZXIgYXJvdW5kIG5vZGVzLgovLyBXZSBjb3VsZCBzdXBwb3J0IGFyYml0cmFyeSBib3JkZXJzIHVzaW5nIGdldENvbXB1dGVkU3R5bGUoKSwgYnV0IEkgYW0KLy8gc2tlcHRpY2FsIHRoZSBleHRyYSBjb21wbGV4aXR5IChhbmQgcGVyZm9ybWFuY2UgaGl0KSBpcyB3b3J0aCBpdC4KCjsoZnVuY3Rpb24oKSB7CnZhciBrQm9yZGVyV2lkdGggPSAxOwoKLy8gUGFkZGluZyBhcm91bmQgY29udGVudHMuCi8vIFRPRE86IGRvIHRoaXMgd2l0aCBhIG5lc3RlZCBkaXYgdG8gYWxsb3cgaXQgdG8gYmUgQ1NTLXN0eWxlYWJsZS4KdmFyIGtQYWRkaW5nID0gNDsKCi8vIHgveSByYXRpbyB0byBhaW0gZm9yIC0tIHdpZGVyIHJlY3RhbmdsZXMgYXJlIGJldHRlciBmb3IgdGV4dCBkaXNwbGF5CnZhciBrQXNwZWN0UmF0aW8gPSAxLjI7Cgp2YXIgZm9jdXNlZCA9IG51bGw7CgpmdW5jdGlvbiBmb2N1cyh0cmVlKSB7CiAgZm9jdXNlZCA9IHRyZWU7CgogIC8vIEhpZGUgYWxsIHZpc2libGUgc2libGluZ3Mgb2YgYWxsIG91ciBhbmNlc3RvcnMgYnkgbG93ZXJpbmcgdGhlbS4KICB2YXIgbGV2ZWwgPSAwOwogIHZhciByb290ID0gdHJlZTsKICB3aGlsZSAocm9vdC5wYXJlbnQpIHsKICAgIHJvb3QgPSByb290LnBhcmVudDsKICAgIGxldmVsICs9IDE7CiAgICBmb3IgKHZhciBpID0gMCwgc2libGluZzsgc2libGluZyA9IHJvb3QuY2hpbGRyZW5baV07ICsraSkgewogICAgICBpZiAoc2libGluZy5kb20pCiAgICAgICAgc2libGluZy5kb20uc3R5bGUuekluZGV4ID0gMDsKICAgIH0KICB9CiAgdmFyIHdpZHRoID0gcm9vdC5kb20ub2Zmc2V0V2lkdGg7CiAgdmFyIGhlaWdodCA9IHJvb3QuZG9tLm9mZnNldEhlaWdodDsKICAvLyBVbmhpZGUgKHJhaXNlKSBhbmQgbWF4aW1pemUgdXMgYW5kIG91ciBhbmNlc3RvcnMuCiAgZm9yICh2YXIgdCA9IHRyZWU7IHQucGFyZW50OyB0ID0gdC5wYXJlbnQpIHsKICAgIC8vIFNoaWZ0IG9mZiBieSBib3JkZXIgc28gd2UgZG9uJ3QgZ2V0IG5lc3RlZCBib3JkZXJzLgogICAgLy8gVE9ETzogYWN0dWFsbHkgbWFrZSBuZXN0ZWQgYm9yZGVycyB3b3JrIChuZWVkIHRvIGFkanVzdCB3aWR0aC9oZWlnaHQpLgogICAgcG9zaXRpb24odC5kb20sIC1rQm9yZGVyV2lkdGgsIC1rQm9yZGVyV2lkdGgsIHdpZHRoLCBoZWlnaHQpOwogICAgdC5kb20uc3R5bGUuekluZGV4ID0gMTsKICB9CiAgLy8gQW5kIGxheW91dCBpbnRvIHRoZSB0b3Btb3N0IGJveC4KICBsYXlvdXQodHJlZSwgbGV2ZWwsIHdpZHRoLCBoZWlnaHQpOwp9CgpmdW5jdGlvbiBtYWtlRG9tKHRyZWUsIGxldmVsKSB7CiAgdmFyIGRvbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogIGRvbS5zdHlsZS56SW5kZXggPSAxOwogIGRvbS5jbGFzc05hbWUgPSAnd2VidHJlZW1hcC1ub2RlIHdlYnRyZWVtYXAtbGV2ZWwnICsgTWF0aC5taW4obGV2ZWwsIDQpOwogIGlmICh0cmVlLmRhdGFbJyRzeW1ib2wnXSkgewogICAgZG9tLmNsYXNzTmFtZSArPSAoJyB3ZWJ0cmVlbWFwLXN5bWJvbC0nICsKICB0cmVlLmRhdGFbJyRzeW1ib2wnXS5yZXBsYWNlKCcgJywgJ18nKSk7CiAgfQogIGlmICh0cmVlLmRhdGFbJyRkb21pbmFudF9zeW1ib2wnXSkgewogICAgZG9tLmNsYXNzTmFtZSArPSAoJyB3ZWJ0cmVlbWFwLXN5bWJvbC0nICsKICB0cmVlLmRhdGFbJyRkb21pbmFudF9zeW1ib2wnXS5yZXBsYWNlKCcgJywgJ18nKSk7CiAgICBkb20uY2xhc3NOYW1lICs9ICgnIHdlYnRyZWVtYXAtYWdncmVnYXRlJyk7CiAgfQoKICBkb20ub25tb3VzZWRvd24gPSBmdW5jdGlvbihlKSB7CiAgICBpZiAoZS5idXR0b24gPT0gMCkgewogICAgICBpZiAoZm9jdXNlZCAmJiB0cmVlID09IGZvY3VzZWQgJiYgZm9jdXNlZC5wYXJlbnQpIHsKICAgICAgICBmb2N1cyhmb2N1c2VkLnBhcmVudCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZm9jdXModHJlZSk7CiAgICAgIH0KICAgIH0KICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICByZXR1cm4gdHJ1ZTsKICB9OwoKICB2YXIgY2FwdGlvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogIGNhcHRpb24uY2xhc3NOYW1lID0gJ3dlYnRyZWVtYXAtY2FwdGlvbic7CiAgY2FwdGlvbi5pbm5lckhUTUwgPSB0cmVlLm5hbWU7CiAgZG9tLmFwcGVuZENoaWxkKGNhcHRpb24pOwogIGRvbS50aXRsZSA9IHRyZWUubmFtZTsKCiAgdHJlZS5kb20gPSBkb207CiAgcmV0dXJuIGRvbTsKfQoKZnVuY3Rpb24gcG9zaXRpb24oZG9tLCB4LCB5LCB3aWR0aCwgaGVpZ2h0KSB7CiAgLy8gQ1NTIHdpZHRoL2hlaWdodCBkb2VzIG5vdCBpbmNsdWRlIGJvcmRlci4KICB3aWR0aCAtPSBrQm9yZGVyV2lkdGgqMjsKICBoZWlnaHQgLT0ga0JvcmRlcldpZHRoKjI7CgogIGRvbS5zdHlsZS5sZWZ0ICAgPSB4ICsgJ3B4JzsKICBkb20uc3R5bGUudG9wICAgID0geSArICdweCc7CiAgZG9tLnN0eWxlLndpZHRoICA9IE1hdGgubWF4KHdpZHRoLCAwKSArICdweCc7CiAgZG9tLnN0eWxlLmhlaWdodCA9IE1hdGgubWF4KGhlaWdodCwgMCkgKyAncHgnOwp9CgovLyBHaXZlbiBhIGxpc3Qgb2YgcmVjdGFuZ2xlcyB8bm9kZXN8LCB0aGUgMS1kIHNwYWNlIGF2YWlsYWJsZQovLyB8c3BhY2V8LCBhbmQgYSBzdGFydGluZyByZWN0YW5nbGUgaW5kZXggfHN0YXJ0fCwgY29tcHV0ZSBhbiBzcGFuIG9mCi8vIHJlY3RhbmdsZXMgdGhhdCBvcHRpbWl6ZXMgYSBwbGVhc2FudCBhc3BlY3QgcmF0aW8uCi8vCi8vIFJldHVybnMgW2VuZCwgc3VtXSwgd2hlcmUgZW5kIGlzIG9uZSBwYXN0IHRoZSBsYXN0IHJlY3RhbmdsZSBhbmQgc3VtIGlzIHRoZQovLyAyLWQgc3VtIG9mIHRoZSByZWN0YW5nbGVzJyBhcmVhcy4KZnVuY3Rpb24gc2VsZWN0U3Bhbihub2Rlcywgc3BhY2UsIHN0YXJ0KSB7CiAgLy8gQWRkIHJlY3RhbmdsZSBvbmUgYnkgb25lLCBzdG9wcGluZyB3aGVuIGFzcGVjdCByYXRpb3MgYmVnaW4gdG8gZ28KICAvLyBiYWQuICBSZXN1bHQgaXMgW3N0YXJ0LGVuZCkgY292ZXJpbmcgdGhlIGJlc3QgcnVuIGZvciB0aGlzIHNwYW4uCiAgLy8gaHR0cDovL2NpdGVzZWVyeC5pc3QucHN1LmVkdS92aWV3ZG9jL3N1bW1hcnk/ZG9pPTEwLjEuMS4zNi42Njg1CiAgdmFyIG5vZGUgPSBub2Rlc1tzdGFydF07CiAgdmFyIHJtaW4gPSBub2RlLmRhdGFbJyRhcmVhJ107ICAvLyBTbWFsbGVzdCBzZWVuIGNoaWxkIHNvIGZhci4KICB2YXIgcm1heCA9IHJtaW47ICAgICAgICAgICAgICAgIC8vIExhcmdlc3QgY2hpbGQuCiAgdmFyIHJzdW0gPSAwOyAgICAgICAgICAgICAgICAgICAvLyBTdW0gb2YgY2hpbGRyZW4gaW4gdGhpcyBzcGFuLgogIHZhciBsYXN0X3Njb3JlID0gMDsgICAgICAgICAgICAgLy8gQmVzdCBzY29yZSB5ZXQgZm91bmQuCiAgZm9yICh2YXIgZW5kID0gc3RhcnQ7IG5vZGUgPSBub2Rlc1tlbmRdOyArK2VuZCkgewogICAgdmFyIHNpemUgPSBub2RlLmRhdGFbJyRhcmVhJ107CiAgICBpZiAoc2l6ZSA8IHJtaW4pCiAgICAgIHJtaW4gPSBzaXplOwogICAgaWYgKHNpemUgPiBybWF4KQogICAgICBybWF4ID0gc2l6ZTsKICAgIHJzdW0gKz0gc2l6ZTsKCiAgICAvLyBUaGlzIGZvcm11bGEgaXMgZnJvbSB0aGUgcGFwZXIsIGJ1dCB5b3UgY2FuIGVhc2lseSBwcm92ZSB0bwogICAgLy8geW91cnNlbGYgaXQncyB0YWtpbmcgdGhlIGxhcmdlciBvZiB0aGUgeC95IGFzcGVjdCByYXRpbyBvciB0aGUKICAgIC8vIHkveCBhc3BlY3QgcmF0aW8uICBUaGUgYWRkaXRpb25hbCBtYWdpYyBmdWRnZSBjb25zdGFudCBvZiBrQXNwZWN0UmF0aW8KICAgIC8vIGxldHMgdXMgcHJlZmVyIHdpZGVyIHJlY3RhbmdsZXMgdG8gdGFsbGVyIG9uZXMuCiAgICB2YXIgc2NvcmUgPSBNYXRoLm1heChzcGFjZSpzcGFjZSpybWF4IC8gKHJzdW0qcnN1bSksCiAgICAgICAgICAgICAgICAgICAgICAgICBrQXNwZWN0UmF0aW8qcnN1bSpyc3VtIC8gKHNwYWNlKnNwYWNlKnJtaW4pKTsKICAgIGlmIChsYXN0X3Njb3JlICYmIHNjb3JlID4gbGFzdF9zY29yZSkgewogICAgICByc3VtIC09IHNpemU7ICAvLyBVbmRvIHNpemUgYWRkaXRpb24gZnJvbSBqdXN0IGFib3ZlLgogICAgICBicmVhazsKICAgIH0KICAgIGxhc3Rfc2NvcmUgPSBzY29yZTsKICB9CiAgcmV0dXJuIFtlbmQsIHJzdW1dOwp9CgpmdW5jdGlvbiBsYXlvdXQodHJlZSwgbGV2ZWwsIHdpZHRoLCBoZWlnaHQpIHsKICBpZiAoISgnY2hpbGRyZW4nIGluIHRyZWUpKQogICAgcmV0dXJuOwoKICB2YXIgdG90YWwgPSB0cmVlLmRhdGFbJyRhcmVhJ107CgogIC8vIFhYWCB3aHkgZG8gSSBuZWVkIGFuIGV4dHJhIC0xLy0yIGhlcmUgZm9yIHdpZHRoL2hlaWdodCB0byBsb29rIHJpZ2h0PwogIHZhciB4MSA9IDAsIHkxID0gMCwgeDIgPSB3aWR0aCAtIDEsIHkyID0gaGVpZ2h0IC0gMjsKICB4MSArPSBrUGFkZGluZzsgeTEgKz0ga1BhZGRpbmc7CiAgeDIgLT0ga1BhZGRpbmc7IHkyIC09IGtQYWRkaW5nOwogIHkxICs9IDE0OyAgLy8gWFhYIGdldCBmaXJzdCBjaGlsZCBoZWlnaHQgZm9yIGNhcHRpb24gc3BhY2luZwoKICB2YXIgcGl4ZWxzX3RvX3VuaXRzID0gTWF0aC5zcXJ0KHRvdGFsIC8gKCh4MiAtIHgxKSAqICh5MiAtIHkxKSkpOwoKICAvLyBUaGUgYWxnb3JpdGhtIGRvZXMgYmVzdCBhdCBsYXlpbmcgb3V0IGl0ZW1zIGZyb20gbGFyZ2VzdCB0byBzbWFsbGVzdC4KICAvLyBTb3J0IHRoZW0gdG8gZW5zdXJlIHRoaXMuCiAgaWYgKCF0cmVlLmNoaWxkcmVuLnNvcnRlZCkgewogICAgdHJlZS5jaGlsZHJlbi5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7CiAgICAgIHJldHVybiBiLmRhdGFbJyRhcmVhJ10gLSBhLmRhdGFbJyRhcmVhJ107CiAgICB9KTsKICAgIHRyZWUuY2hpbGRyZW4uc29ydGVkID0gdHJ1ZTsKICB9CgogIGZvciAodmFyIHN0YXJ0ID0gMCwgY2hpbGQ7IGNoaWxkID0gdHJlZS5jaGlsZHJlbltzdGFydF07ICsrc3RhcnQpIHsKICAgIGlmICh4MiAtIHgxIDwgNjAgfHwgeTIgLSB5MSA8IDQwKSB7CiAgICAgIGlmIChjaGlsZC5kb20pIHsKICAgICAgICBjaGlsZC5kb20uc3R5bGUuekluZGV4ID0gMDsKICAgICAgICBwb3NpdGlvbihjaGlsZC5kb20sIC0yLCAtMiwgMCwgMCk7CiAgICAgIH0KICAgICAgY29udGludWU7CiAgICB9CgogICAgLy8gRHluYW1pY2FsbHkgZGVjaWRlIHdoZXRoZXIgdG8gc3BsaXQgaW4geCBvciB5IGJhc2VkIG9uIGFzcGVjdCByYXRpby4KICAgIHZhciB5c3BsaXQgPSAoKHkyIC0geTEpIC8gKHgyIC0geDEpKSA+IGtBc3BlY3RSYXRpbzsKCiAgICB2YXIgc3BhY2U7ICAvLyBTcGFjZSBhdmFpbGFibGUgYWxvbmcgbGF5b3V0IGF4aXMuCiAgICBpZiAoeXNwbGl0KQogICAgICBzcGFjZSA9ICh5MiAtIHkxKSAqIHBpeGVsc190b191bml0czsKICAgIGVsc2UKICAgICAgc3BhY2UgPSAoeDIgLSB4MSkgKiBwaXhlbHNfdG9fdW5pdHM7CgogICAgdmFyIHNwYW4gPSBzZWxlY3RTcGFuKHRyZWUuY2hpbGRyZW4sIHNwYWNlLCBzdGFydCk7CiAgICB2YXIgZW5kID0gc3BhblswXSwgcnN1bSA9IHNwYW5bMV07CgogICAgLy8gTm93IHRoYXQgd2UndmUgc2VsZWN0ZWQgYSBzcGFuLCBsYXkgb3V0IHJlY3RhbmdsZXMgW3N0YXJ0LGVuZCkgaW4gb3VyCiAgICAvLyBhdmFpbGFibGUgc3BhY2UuCiAgICB2YXIgeCA9IHgxLCB5ID0geTE7CiAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkgewogICAgICBjaGlsZCA9IHRyZWUuY2hpbGRyZW5baV07CiAgICAgIGlmICghY2hpbGQuZG9tKSB7CiAgICAgICAgY2hpbGQucGFyZW50ID0gdHJlZTsKICAgICAgICBjaGlsZC5kb20gPSBtYWtlRG9tKGNoaWxkLCBsZXZlbCArIDEpOwogICAgICAgIHRyZWUuZG9tLmFwcGVuZENoaWxkKGNoaWxkLmRvbSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY2hpbGQuZG9tLnN0eWxlLnpJbmRleCA9IDE7CiAgICAgIH0KICAgICAgdmFyIHNpemUgPSBjaGlsZC5kYXRhWyckYXJlYSddOwogICAgICB2YXIgZnJhYyA9IHNpemUgLyByc3VtOwogICAgICBpZiAoeXNwbGl0KSB7CiAgICAgICAgd2lkdGggPSByc3VtIC8gc3BhY2U7CiAgICAgICAgaGVpZ2h0ID0gc2l6ZSAvIHdpZHRoOwogICAgICB9IGVsc2UgewogICAgICAgIGhlaWdodCA9IHJzdW0gLyBzcGFjZTsKICAgICAgICB3aWR0aCA9IHNpemUgLyBoZWlnaHQ7CiAgICAgIH0KICAgICAgd2lkdGggLz0gcGl4ZWxzX3RvX3VuaXRzOwogICAgICBoZWlnaHQgLz0gcGl4ZWxzX3RvX3VuaXRzOwogICAgICB3aWR0aCA9IE1hdGgucm91bmQod2lkdGgpOwogICAgICBoZWlnaHQgPSBNYXRoLnJvdW5kKGhlaWdodCk7CiAgICAgIHBvc2l0aW9uKGNoaWxkLmRvbSwgeCwgeSwgd2lkdGgsIGhlaWdodCk7CiAgICAgIGlmICgnY2hpbGRyZW4nIGluIGNoaWxkKSB7CiAgICAgICAgbGF5b3V0KGNoaWxkLCBsZXZlbCArIDEsIHdpZHRoLCBoZWlnaHQpOwogICAgICB9CiAgICAgIGlmICh5c3BsaXQpCiAgICAgICAgeSArPSBoZWlnaHQ7CiAgICAgIGVsc2UKICAgICAgICB4ICs9IHdpZHRoOwogICAgfQoKICAgIC8vIFNocmluayBvdXIgYXZhaWxhYmxlIHNwYWNlIGJhc2VkIG9uIHRoZSBhbW91bnQgd2UgdXNlZC4KICAgIGlmICh5c3BsaXQpCiAgICAgIHgxICs9IE1hdGgucm91bmQoKHJzdW0gLyBzcGFjZSkgLyBwaXhlbHNfdG9fdW5pdHMpOwogICAgZWxzZQogICAgICB5MSArPSBNYXRoLnJvdW5kKChyc3VtIC8gc3BhY2UpIC8gcGl4ZWxzX3RvX3VuaXRzKTsKCiAgICAvLyBlbmQgcG9pbnRzIG9uZSBwYXN0IHdoZXJlIHdlIGVuZGVkLCB3aGljaCBpcyB3aGVyZSB3ZSB3YW50IHRvCiAgICAvLyBiZWdpbiB0aGUgbmV4dCBpdGVyYXRpb24sIGJ1dCBzdWJ0cmFjdCBvbmUgdG8gYmFsYW5jZSB0aGUgKysgaW4KICAgIC8vIHRoZSBsb29wLgogICAgc3RhcnQgPSBlbmQgLSAxOwogIH0KfQoKZnVuY3Rpb24gYXBwZW5kVHJlZW1hcChkb20sIGRhdGEpIHsKICB2YXIgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGRvbSwgbnVsbCk7CiAgdmFyIHdpZHRoID0gcGFyc2VJbnQoc3R5bGUud2lkdGgpOwogIHZhciBoZWlnaHQgPSBwYXJzZUludChzdHlsZS5oZWlnaHQpOwogIGlmICghZGF0YS5kb20pCiAgICBtYWtlRG9tKGRhdGEsIDApOwogIGRvbS5hcHBlbmRDaGlsZChkYXRhLmRvbSk7CiAgcG9zaXRpb24oZGF0YS5kb20sIDAsIDAsIHdpZHRoLCBoZWlnaHQpOwogIGxheW91dChkYXRhLCAwLCB3aWR0aCwgaGVpZ2h0KTsKfQoKd2luZG93LmFwcGVuZFRyZWVtYXAgPSBhcHBlbmRUcmVlbWFwOwp9KSh3aW5kb3cpOwo="></script>
<script>
function newNode(name) {
return {
name: name,
data: {
'$area': 0
},
children: []
};
}
var treeData = newNode('/');
function addNode(path, size) {
var parts = path.split('/');
var node = treeData;
node.data['$area'] += size;
parts.forEach(function(part) {
var child = _.find(node.children, function(child) { return child.name == part; });
if (!child) {
var child = newNode(part);
node.children.push(child);
}
node = child;
node.data['$area'] += size;
});
}
function addSizeToTitle(node, total) {
var size = node.data['$area'],
pct = 100.0 * size / total;
node.name += ' • ' + formatBytes(size) + ' • ' + pct.toFixed(1) + '%';
node.children.forEach(function(x) { addSizeToTitle(x, total) });
}
for (var source in tree) {
addNode(source, tree[source]);
}
addSizeToTitle(treeData, treeData.data['$area']);
var map = document.getElementById('map');
appendTreemap(map, treeData);
window.addEventListener('resize', function() {
appendTreemap(map, treeData);
});
</script>