jsforce2 1.11.1 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jsforce2 might be problematic. Click here for more details.

Files changed (80) hide show
  1. package/index.js +46 -1
  2. package/package.json +7 -105
  3. package/LICENSE +0 -22
  4. package/README.md +0 -74
  5. package/bin/jsforce +0 -3
  6. package/bower.json +0 -30
  7. package/build/jsforce-api-analytics.js +0 -393
  8. package/build/jsforce-api-analytics.min.js +0 -2
  9. package/build/jsforce-api-analytics.min.js.map +0 -1
  10. package/build/jsforce-api-apex.js +0 -183
  11. package/build/jsforce-api-apex.min.js +0 -2
  12. package/build/jsforce-api-apex.min.js.map +0 -1
  13. package/build/jsforce-api-bulk.js +0 -1054
  14. package/build/jsforce-api-bulk.min.js +0 -2
  15. package/build/jsforce-api-bulk.min.js.map +0 -1
  16. package/build/jsforce-api-chatter.js +0 -320
  17. package/build/jsforce-api-chatter.min.js +0 -2
  18. package/build/jsforce-api-chatter.min.js.map +0 -1
  19. package/build/jsforce-api-metadata.js +0 -3020
  20. package/build/jsforce-api-metadata.min.js +0 -2
  21. package/build/jsforce-api-metadata.min.js.map +0 -1
  22. package/build/jsforce-api-soap.js +0 -403
  23. package/build/jsforce-api-soap.min.js +0 -2
  24. package/build/jsforce-api-soap.min.js.map +0 -1
  25. package/build/jsforce-api-streaming.js +0 -3479
  26. package/build/jsforce-api-streaming.min.js +0 -2
  27. package/build/jsforce-api-streaming.min.js.map +0 -1
  28. package/build/jsforce-api-tooling.js +0 -319
  29. package/build/jsforce-api-tooling.min.js +0 -2
  30. package/build/jsforce-api-tooling.min.js.map +0 -1
  31. package/build/jsforce-core.js +0 -25250
  32. package/build/jsforce-core.min.js +0 -2
  33. package/build/jsforce-core.min.js.map +0 -1
  34. package/build/jsforce.js +0 -31637
  35. package/build/jsforce.min.js +0 -2
  36. package/build/jsforce.min.js.map +0 -1
  37. package/core.js +0 -1
  38. package/lib/VERSION.js +0 -2
  39. package/lib/_required.js +0 -29
  40. package/lib/api/analytics.js +0 -387
  41. package/lib/api/apex.js +0 -177
  42. package/lib/api/bulk.js +0 -862
  43. package/lib/api/chatter.js +0 -314
  44. package/lib/api/index.js +0 -8
  45. package/lib/api/metadata.js +0 -848
  46. package/lib/api/soap.js +0 -397
  47. package/lib/api/streaming-extension.js +0 -136
  48. package/lib/api/streaming.js +0 -270
  49. package/lib/api/tooling.js +0 -313
  50. package/lib/browser/canvas.js +0 -90
  51. package/lib/browser/client.js +0 -241
  52. package/lib/browser/core.js +0 -5
  53. package/lib/browser/jsforce.js +0 -6
  54. package/lib/browser/jsonp.js +0 -52
  55. package/lib/browser/request.js +0 -70
  56. package/lib/cache.js +0 -252
  57. package/lib/cli/cli.js +0 -431
  58. package/lib/cli/repl.js +0 -337
  59. package/lib/connection.js +0 -1881
  60. package/lib/core.js +0 -16
  61. package/lib/csv.js +0 -50
  62. package/lib/date.js +0 -163
  63. package/lib/http-api.js +0 -300
  64. package/lib/jsforce.js +0 -10
  65. package/lib/logger.js +0 -52
  66. package/lib/oauth2.js +0 -206
  67. package/lib/process.js +0 -275
  68. package/lib/promise.js +0 -164
  69. package/lib/query.js +0 -881
  70. package/lib/quick-action.js +0 -90
  71. package/lib/record-stream.js +0 -305
  72. package/lib/record.js +0 -107
  73. package/lib/registry/file-registry.js +0 -48
  74. package/lib/registry/index.js +0 -3
  75. package/lib/registry/registry.js +0 -111
  76. package/lib/require.js +0 -14
  77. package/lib/soap.js +0 -207
  78. package/lib/sobject.js +0 -558
  79. package/lib/soql-builder.js +0 -236
  80. package/lib/transport.js +0 -233
@@ -1,3020 +0,0 @@
1
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.jsforce||(g.jsforce = {}));g=(g.modules||(g.modules = {}));g=(g.api||(g.api = {}));g.Metadata = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
- (function (process,Buffer){
3
- /*global process, Buffer */
4
- /**
5
- * @file Manages Salesforce Metadata API
6
- * @author Shinichi Tomita <shinichi.tomita@gmail.com>
7
- */
8
-
9
- 'use strict';
10
-
11
- var inherits = window.jsforce.require('inherits'),
12
- events = window.jsforce.require('events'),
13
- stream = window.jsforce.require('readable-stream'),
14
- _ = window.jsforce.require('lodash/core'),
15
- jsforce = window.jsforce.require('./core'),
16
- Promise = window.jsforce.require('./promise'),
17
- SOAP = window.jsforce.require('./soap');
18
-
19
- /*--------------------------------------------*/
20
- /**
21
- * Class for Salesforce Metadata API
22
- *
23
- * @class
24
- * @param {Connection} conn - Connection object
25
- */
26
- var Metadata = module.exports = function(conn) {
27
- this._conn = conn;
28
- };
29
-
30
-
31
- /**
32
- * Polling interval in milliseconds
33
- * @type {Number}
34
- */
35
- Metadata.prototype.pollInterval = 1000;
36
-
37
- /**
38
- * Polling timeout in milliseconds
39
- * @type {Number}
40
- */
41
- Metadata.prototype.pollTimeout = 10000;
42
-
43
-
44
- /**
45
- * Call Metadata API SOAP endpoint
46
- *
47
- * @private
48
- */
49
- Metadata.prototype._invoke = function(method, message, callback) {
50
- var soapEndpoint = new SOAP(this._conn, {
51
- xmlns: "http://soap.sforce.com/2006/04/metadata",
52
- endpointUrl: this._conn.instanceUrl + "/services/Soap/m/" + this._conn.version
53
- });
54
- return soapEndpoint.invoke(method, message).then(function(res) {
55
- return res.result;
56
- }).thenCall(callback);
57
- };
58
-
59
-
60
- /**
61
- * @typedef {Object} Metadata~MetadataInfo
62
- * @prop {String} fullName - The name of the component
63
- */
64
-
65
- /**
66
- * Asynchronously adds one or more new metadata components to the organization.
67
- *
68
- * @param {String} type - The type of metadata to create
69
- * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Metadata to create
70
- * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function
71
- * @returns {Metadata~AsyncResultLocator}
72
- */
73
- Metadata.prototype.createAsync = function(type, metadata, callback) {
74
- if (Number(this._conn.version) > 30) {
75
- throw new Error("Async metadata CRUD calls are not supported on ver 31.0 or later.");
76
- }
77
- var convert = function(md) {
78
- md["@xsi:type"] = type;
79
- return md;
80
- };
81
- var isArray = _.isArray(metadata);
82
- metadata = isArray ? _.map(metadata, convert) : convert(metadata);
83
- var res = this._invoke("create", { metadata: metadata });
84
- return new AsyncResultLocator(this, res, isArray).thenCall(callback);
85
- };
86
-
87
- /**
88
- * @typedef {Object} Metadata~SaveResult
89
- * @prop {Boolean} success - True if metadata is successfully saved
90
- * @prop {String} fullName - Full name of metadata object
91
- */
92
-
93
- /**
94
- * @private
95
- */
96
- function convertToSaveResult(result) {
97
- var saveResult = _.clone(result);
98
- saveResult.success = saveResult.success === 'true';
99
- return saveResult;
100
- }
101
-
102
- /**
103
- * @typedef {Object} Metadata~UpsertResult
104
- * @prop {Boolean} success - True if metadata is successfully saved
105
- * @prop {String} fullName - Full name of metadata object
106
- * @prop {Boolean} created - True if metadata is newly created
107
- */
108
-
109
- /**
110
- * @private
111
- */
112
- function convertToUpsertResult(result) {
113
- var upsertResult = convertToSaveResult(result);
114
- upsertResult.created = upsertResult.created === 'true';
115
- return upsertResult;
116
- }
117
-
118
- /**
119
- * Synonym of Metadata#create().
120
- *
121
- * @method Metadata#createSync
122
- * @param {String} type - The type of metadata to create
123
- * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Metadata to create
124
- * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function
125
- * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>}
126
- */
127
- /**
128
- * Synchronously adds one or more new metadata components to the organization.
129
- *
130
- * @method Metadata#create
131
- * @param {String} type - The type of metadata to create
132
- * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Metadata to create
133
- * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function
134
- * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>}
135
- */
136
- Metadata.prototype.createSync =
137
- Metadata.prototype.create = function(type, metadata, callback) {
138
- var convert = function(md) {
139
- md["@xsi:type"] = type;
140
- return md;
141
- };
142
- var isArray = _.isArray(metadata);
143
- metadata = isArray ? _.map(metadata, convert) : convert(metadata);
144
- return this._invoke("createMetadata", { metadata: metadata }).then(function(results) {
145
- return _.isArray(results) ? _.map(results, convertToSaveResult) : convertToSaveResult(results);
146
- }).thenCall(callback);
147
- };
148
-
149
- /**
150
- * @private
151
- */
152
- function convertToMetadataInfo(rec) {
153
- var metadataInfo = _.clone(rec);
154
- delete metadataInfo.$;
155
- return metadataInfo;
156
- }
157
-
158
- /**
159
- * Synonym of Metadata#read()
160
- *
161
- * @method Metadata#readSync
162
- * @param {String} type - The type of metadata to read
163
- * @param {String|Array.<String>} fullNames - full name(s) of metadata objects to read
164
- * @param {Callback.<Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>>} [callback] - Callback function
165
- * @returns {Promise.<Array.<Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>>>}
166
- */
167
- /**
168
- * Synchronously read specified metadata components in the organization.
169
- *
170
- * @method Metadata#read
171
- * @param {String} type - The type of metadata to read
172
- * @param {String|Array.<String>} fullNames - full name(s) of metadata objects to read
173
- * @param {Callback.<Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>>} [callback] - Callback function
174
- * @returns {Promise.<Array.<Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>>>}
175
- */
176
- Metadata.prototype.readSync =
177
- Metadata.prototype.read = function(type, fullNames, callback) {
178
- return this._invoke("readMetadata", { type: type, fullNames: fullNames }).then(function(res) {
179
- return _.isArray(res.records) ? _.map(res.records, convertToMetadataInfo) : convertToMetadataInfo(res.records);
180
- }).thenCall(callback);
181
- };
182
-
183
- /**
184
- * @typedef {Object} Metadata~UpdateMetadataInfo
185
- * @prop {String} currentName - The API name of the component or field before the update
186
- * @prop {Metadata~MetadataInfo} metadata - Full specification of the component or field you wish to update
187
- */
188
-
189
- /**
190
- * Asynchronously updates one or more metadata components in the organization.
191
- *
192
- * @param {String} type - The type of metadata to update
193
- * @param {Metadata~UpdateMetadataInfo|Array.<Metadata~UpdateMetadataInfo>} updateMetadata - Updating metadata
194
- * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function
195
- * @returns {Metadata~AsyncResultLocator}
196
- */
197
- Metadata.prototype.updateAsync = function(type, updateMetadata, callback) {
198
- if (Number(this._conn.version) > 30) {
199
- throw new Error("Async metadata CRUD calls are not supported on ver 31.0 or later.");
200
- }
201
- var convert = function(umd) {
202
- umd.metadata["@xsi:type"] = type;
203
- return umd;
204
- };
205
- var isArray = _.isArray(updateMetadata);
206
- updateMetadata = isArray ? _.map(updateMetadata, convert) : convert(updateMetadata);
207
- var res = this._invoke("update", { updateMetadata: updateMetadata });
208
- return new AsyncResultLocator(this, res, isArray).thenCall(callback);
209
- };
210
-
211
- /**
212
- * Synonym of Metadata#update().
213
- *
214
- * @method Metadata#updateSync
215
- * @param {String} type - The type of metadata to update
216
- * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} updateMetadata - Updating metadata
217
- * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function
218
- * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>}
219
- */
220
- /**
221
- * Synchronously updates one or more metadata components in the organization.
222
- *
223
- * @method Metadata#update
224
- * @param {String} type - The type of metadata to update
225
- * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} updateMetadata - Updating metadata
226
- * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function
227
- * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>}
228
- */
229
- Metadata.prototype.updateSync =
230
- Metadata.prototype.update = function(type, metadata, callback) {
231
- var convert = function(md) {
232
- md["@xsi:type"] = type;
233
- return md;
234
- };
235
- var isArray = _.isArray(metadata);
236
- metadata = isArray ? _.map(metadata, convert) : convert(metadata);
237
- return this._invoke("updateMetadata", { metadata: metadata }).then(function(results) {
238
- return _.isArray(results) ? _.map(results, convertToSaveResult) : convertToSaveResult(results);
239
- }).thenCall(callback);
240
- };
241
-
242
- /**
243
- * Synonym of Metadata#upsert().
244
- *
245
- * @method Metadata#upsertSync
246
- * @param {String} type - The type of metadata to upsert
247
- * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Upserting metadata
248
- * @param {Callback.<Metadata~UpsertResult|Array.<Metadata~UpsertResult>>} [callback] - Callback function
249
- * @returns {Promise.<Metadata~UpsertResult|Array.<Metadata~UpsertResult>>}
250
- */
251
- /**
252
- * Upserts one or more components in your organization's data.
253
- *
254
- * @method Metadata#upsert
255
- * @param {String} type - The type of metadata to upsert
256
- * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Upserting metadata
257
- * @param {Callback.<Metadata~UpsertResult|Array.<Metadata~UpsertResult>>} [callback] - Callback function
258
- * @returns {Promise.<Metadata~UpsertResult|Array.<Metadata~UpsertResult>>}
259
- */
260
- Metadata.prototype.upsertSync =
261
- Metadata.prototype.upsert = function(type, metadata, callback) {
262
- var convert = function(md) {
263
- md["@xsi:type"] = type;
264
- return md;
265
- };
266
- var isArray = _.isArray(metadata);
267
- metadata = isArray ? _.map(metadata, convert) : convert(metadata);
268
- return this._invoke("upsertMetadata", { metadata: metadata }).then(function(results) {
269
- return _.isArray(results) ? _.map(results, convertToUpsertResult) : convertToUpsertResult(results);
270
- }).thenCall(callback);
271
- };
272
-
273
- /**
274
- * Asynchronously deletes specified metadata components in the organization.
275
- *
276
- * @param {String} type - The type of metadata to delete
277
- * @param {String|Metadata~MetadataInfo|Array.<String>|Array.<Metadata~MetadataInfo>} metadata - The fullName of metadata or metadata info to delete. If it is passed in fullName, the type parameter should not be empty.
278
- * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function
279
- * @returns {Metadata~AsyncResultLocator}
280
- */
281
- Metadata.prototype.deleteAsync = function(type, metadata, callback) {
282
- if (Number(this._conn.version) > 30) {
283
- throw new Error("Async metadata CRUD calls are not supported on ver 31.0 or later.");
284
- }
285
- var convert = function(md) {
286
- if (_.isString(md)) {
287
- md = { fullName : md };
288
- }
289
- md["@xsi:type"] = type;
290
- return md;
291
- };
292
- var isArray = _.isArray(metadata);
293
- metadata = isArray ? _.map(metadata, convert) : convert(metadata);
294
- var res = this._invoke("delete", { metadata: metadata });
295
- return new AsyncResultLocator(this, res, isArray).thenCall(callback);
296
- };
297
-
298
- /**
299
- * Synonym of Metadata#delete().
300
- *
301
- * @deprecated
302
- * @method Metadata#del
303
- * @param {String} [type] - The type of metadata to delete
304
- * @param {String|Metadata~MetadataInfo|Array.<String>|Array.<Metadata~MetadataInfo>} metadata - The fullName of metadata or metadata info to delete. If it is passed in fullName, the type parameter should not be empty.
305
- * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function
306
- * @returns {Metadata~AsyncResultLocator}
307
- */
308
- /**
309
- * Synonym of Metadata#delete().
310
- *
311
- * @method Metadata#deleteSync
312
- * @param {String} type - The type of metadata to delete
313
- * @param {String|Array.<String>} fullNames - The fullName of metadata to delete.
314
- * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function
315
- * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>}
316
- */
317
-
318
- /**
319
- * Synchronously deletes specified metadata components in the organization.
320
- *
321
- * @method Metadata#delete
322
- * @param {String} type - The type of metadata to delete
323
- * @param {String|Array.<String>} fullNames - The fullName of metadata to delete.
324
- * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function
325
- * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>}
326
- */
327
- Metadata.prototype.del =
328
- Metadata.prototype.deleteSync =
329
- Metadata.prototype["delete"] = function(type, fullNames, callback) {
330
- return this._invoke("deleteMetadata", { type: type, fullNames: fullNames }).then(function(results) {
331
- return _.isArray(results) ? _.map(results, convertToSaveResult) : convertToSaveResult(results);
332
- }).thenCall(callback);
333
- };
334
-
335
- /**
336
- * Rename fullname of a metadata component in the organization
337
- *
338
- * @param {String} type - The type of metadata to delete
339
- * @param {String} oldFullName - The original fullName of metadata
340
- * @param {String} newFullName - The new fullName of metadata
341
- * @param {Callback.<Metadata~SaveResult>} [callback] - Callback function
342
- * @returns {Promise.<Metadata~SaveResult>}
343
- */
344
- Metadata.prototype.rename = function(type, oldFullName, newFullName, callback) {
345
- return this._invoke("renameMetadata", { type: type, oldFullName: oldFullName, newFullName: newFullName }).then(function(result) {
346
- return convertToSaveResult(result);
347
- }).thenCall(callback);
348
- };
349
-
350
- /**
351
- * Checks the status of asynchronous metadata calls
352
- *
353
- * @param {String|Array.<String>} ids - The asynchronous process ID(s)
354
- * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function
355
- * @returns {Metadata~AsyncResultLocator}
356
- */
357
- Metadata.prototype.checkStatus = function(ids, callback) {
358
- var isArray = _.isArray(ids);
359
- var res = this._invoke("checkStatus", { asyncProcessId: ids });
360
- return new AsyncResultLocator(this, res, isArray).thenCall(callback);
361
- };
362
-
363
- /**
364
- * @typedef {Object} Metadata~DescribeMetadataResult
365
- * @prop {Array.<Object>} metadataObjects - One or more metadata components and their attributes
366
- * @prop {Array.<String>} metadataObjects.childXmlNames - List of child sub-components for this component
367
- * @prop {String} metadataObjects.directoryName - The name of the directory in the .zip file that contains this component
368
- * @prop {Boolean} metadataObjects.inFolder - Indicates whether the component is in a folder or not
369
- * @prop {Boolean} metadataObjects.metaFile - Indicates whether the component requires an accompanying metadata file
370
- * @prop {String} metadataObjects.suffix - The file suffix for this component
371
- * @prop {String} metadataObjects.xmlName - The name of the root element in the metadata file for this component
372
- * @prop {String} organizationNamespace - The namespace of the organization
373
- * @prop {Boolean} partialSaveAllowed - Indicates whether rollbackOnError is allowed or not
374
- * @prop {Boolean} testRequired - Indicates whether tests are required or not
375
- */
376
-
377
- /**
378
- * Retrieves the metadata which describes your organization, including Apex classes and triggers,
379
- * custom objects, custom fields on standard objects, tab sets that define an app,
380
- * and many other components.
381
- *
382
- * @param {String} [version] - The API version for which you want metadata; for example, 29.0
383
- * @param {Callback.<Metadata~DescribeMetadataResult>} [callback] - Callback function
384
- * @returns {Promise.<Metadata~DescribeMetadataResult>}
385
- */
386
- Metadata.prototype.describe = function(version, callback) {
387
- if (!_.isString(version)) {
388
- callback = version;
389
- version = this._conn.version;
390
- }
391
- return this._invoke("describeMetadata", { asOfVersion: version }).then(function(res) {
392
- res.metadataObjects = _.isArray(res.metadataObjects) ? res.metadataObjects : [ res.metadataObjects ];
393
- res.metadataObjects = _.map(res.metadataObjects, function(mo) {
394
- if (mo.childXmlNames) {
395
- mo.childXmlNames = _.isArray(mo.childXmlNames) ? mo.childXmlNames: [ mo.childXmlNames ];
396
- }
397
- mo.inFolder = mo.inFolder === 'true';
398
- mo.metaFile = mo.metaFile === 'true';
399
- return mo;
400
- });
401
- res.partialSaveAllowed = res.partialSaveAllowed === 'true';
402
- res.testRequired = res.testRequired === 'true';
403
- return res;
404
- }).thenCall(callback);
405
- };
406
-
407
- /**
408
- * @typedef {Object} Metadata~ListMetadataQuery
409
- * @prop {String} type - The metadata type, such as CustomObject, CustomField, or ApexClass
410
- * @prop {String} [folder] - The folder associated with the component.
411
- */
412
-
413
- /**
414
- * @typedef {Object} Metadata~FileProperties
415
- * @prop {String} type - The metadata type, such as CustomObject, CustomField, or ApexClass
416
- * @prop {String} createdById - ID of the user who created the file
417
- * @prop {String} createdByName - Name of the user who created the file
418
- * @prop {String} createdDate - Date and time when the file was created
419
- * @prop {String} fileName - Name of the file
420
- * @prop {String} fullName - The file developer name used as a unique identifier for API access
421
- * @prop {String} id - ID of the file
422
- * @prop {String} lastModifiedById - ID of the user who last modified the file
423
- * @prop {String} lastModifiedByName - Name of the user who last modified the file
424
- * @prop {String} lastModifiedDate - Date and time that the file was last modified
425
- * @prop {String} [manageableState] - Indicates the manageable state of the specified component if it is contained in a package
426
- * @prop {String} [namespacePrefix] - The namespace prefix of the component
427
- */
428
-
429
- /**
430
- * Retrieves property information about metadata components in your organization
431
- *
432
- * @param {Metadata~ListMetadataQuery|Array.<Metadata~ListMetadataQuery>} queries - The criteria object(s) specifing metadata to list
433
- * @param {String} [version] - The API version for which you want metadata; for example, 29.0
434
- * @param {Callback.<Array.<Metadata~FileProperties>>} [callback] - Callback function
435
- * @returns {Promise.<Array.<Metadata~FileProperties>>}
436
- */
437
- Metadata.prototype.list = function(queries, version, callback) {
438
- if (!_.isString(version)) {
439
- callback = version;
440
- version = this._conn.version;
441
- }
442
- if (!_.isArray(queries)) {
443
- queries = [ queries ];
444
- }
445
- return this._invoke("listMetadata", { queries: queries, asOfVersion: version }, callback);
446
- };
447
-
448
- /**
449
- * @typedef {Object} Metadata~RetrieveRequest
450
- */
451
-
452
- /**
453
- * Retrieves XML file representations of components in an organization
454
- *
455
- * @param {Metadata~RetrieveRequest} request - Options for determining which packages or files are retrieved
456
- * @param {Callback.<Metadata~AsyncResult>} [callback] - Callback function
457
- * @returns {Metadata~RetrieveResultLocator}
458
- */
459
- Metadata.prototype.retrieve = function(request, callback) {
460
- var res = this._invoke("retrieve", { request: request });
461
- return new RetrieveResultLocator(this, res).thenCall(callback);
462
- };
463
-
464
- /**
465
- * Checks the status of declarative metadata call retrieve() and returns the zip file contents
466
- *
467
- * @param {String} id - Async process id returned from previous retrieve request
468
- * @param {Callback.<Metadata~RetrieveResult>} [callback] - Callback function
469
- * @returns {Promise.<Metadata~RetrieveResult>}
470
- */
471
- Metadata.prototype.checkRetrieveStatus = function(id, callback) {
472
- return this._invoke("checkRetrieveStatus", { asyncProcessId: id }, callback);
473
- };
474
-
475
- /**
476
- * Deploy components into an organization using zipped file representations
477
- *
478
- * @param {stream.Stream|Buffer|String} zipInput - Zipped file input source in readable stream, binary buffer or Base64-encoded string
479
- * @param {Object} [options] - Options used in deployment
480
- * @param {Boolean} [options.allowMissingFiles] - Specifies whether a deploy succeeds even if files that are specified in package.xml but are not in the .zip file or not.
481
- * @param {Boolean} [options.autoUpdatePackage] - If a file is in the .zip file but not specified in package.xml, specifies whether the file should be automatically added to the package or not.
482
- * @param {Boolean} [options.checkOnly] - Indicates whether Apex classes and triggers are saved to the organization as part of the deployment (false) or not (true).
483
- * @param {Boolean} [options.ignoreWarnings] - Indicates whether a warning should allow a deployment to complete successfully (true) or not (false). Defaults to false.
484
- * @param {Boolean} [options.performRetrieve] - Indicates whether a retrieve() call is performed immediately after the deployment (true) or not (false).
485
- * @param {Boolean} [options.purgeOnDelete] - If true, the deleted components in the destructiveChanges.xml manifest file aren't stored in the Recycle Bin.
486
- * @param {Boolean} [options.rollbackOnError] - Indicates whether any failure causes a complete rollback (true) or not (false).
487
- * @param {Boolean} [options.runAllTests] - If true, all Apex tests defined in the organization are run.
488
- * @param {Array.<String>} [options.runTests] - A list of Apex tests to be run during deployment.
489
- * @param {Boolean} [options.singlePackage] - Indicates whether the specified .zip file points to a directory structure with a single package (true) or a set of packages (false).
490
- * @param {Callback.<Metadata~AsyncResult>} [callback] - Callback function
491
- * @returns {Metadata~DeployResultLocator}
492
- */
493
- Metadata.prototype.deploy = function(zipInput, options, callback) {
494
- if (!options || _.isFunction(options)) {
495
- callback = options;
496
- options = {};
497
- }
498
- var deferred = Promise.defer();
499
- if (_.isObject(zipInput) && _.isFunction(zipInput.pipe)) {
500
- var bufs = [];
501
- zipInput.on('data', function(d) {
502
- bufs.push(d);
503
- });
504
- zipInput.on('end', function() {
505
- deferred.resolve(Buffer.concat(bufs).toString('base64'));
506
- });
507
- // zipInput.resume();
508
- } else if (zipInput instanceof Buffer) {
509
- deferred.resolve(zipInput.toString('base64'));
510
- } else if (zipInput instanceof String || typeof zipInput === 'string') {
511
- deferred.resolve(zipInput);
512
- } else {
513
- throw "Unexpected zipInput type";
514
- }
515
-
516
- var self = this;
517
- var res = deferred.promise.then(function(zipContentB64) {
518
- return self._invoke("deploy", {
519
- ZipFile: zipContentB64,
520
- DeployOptions: options
521
- }, callback);
522
- });
523
- return new DeployResultLocator(this, res).thenCall(callback);
524
- };
525
-
526
- /**
527
- * Checks the status of declarative metadata call deploy()
528
- *
529
- * @param {String} id - Async process id returned from previous deploy request
530
- * @param {Boolean} [includeDetails] - Sets the DeployResult object to include details information (default: false)
531
- * @param {Callback.<Metadata~DeployResult>} [callback] - Callback function
532
- * @returns {Promise.<Metadata~DeployResult>}
533
- */
534
- Metadata.prototype.checkDeployStatus = function(id, includeDetails, callback) {
535
- if (_.isObject(includeDetails) || _.isBoolean(includeDetails)) {
536
- includeDetails = !!includeDetails;
537
- } else {
538
- callback = includeDetails;
539
- includeDetails = false;
540
- }
541
- return this._invoke("checkDeployStatus", {
542
- asyncProcessId: id,
543
- includeDetails : includeDetails
544
- }).then(function(res) {
545
- res.done = res.done === 'true';
546
- res.success = res.success === 'true';
547
- res.checkOnly = res.checkOnly === 'true';
548
- res.runTestsEnabled = res.runTestsEnabled === 'true';
549
- if (res.ignoreWarnings) {
550
- res.ignoreWarnings = res.ignoreWarnings === 'true';
551
- }
552
- if (res.rollbackOnError) {
553
- res.rollbackOnError = res.rollbackOnError === 'true';
554
- }
555
- res.numberComponentErrors = Number(res.numberComponentErrors);
556
- res.numberComponentsDeployed = Number(res.numberComponentsDeployed);
557
- res.numberComponentsTotal = Number(res.numberComponentsTotal);
558
- res.numberTestErrors = Number(res.numberTestErrors);
559
- res.numberTestsCompleted = Number(res.numberTestsCompleted);
560
- res.numberTestsTotal = Number(res.numberTestsTotal);
561
-
562
- return res;
563
- }).thenCall(callback);
564
- };
565
-
566
-
567
- /*--------------------------------------------*/
568
-
569
- /**
570
- * @typedef {Object} Metadata~AsyncResult
571
- * @prop {Boolean} done - Indicates whether the call has completed or not
572
- * @prop {String} id - ID of the component being created, updated, deleted, deployed, or retrieved
573
- * @prop {String} state - The state four possible values: Queued, InProgress, Completed, and Error.
574
- * @prop {String} [statusCode] - If an error occurred during the create(), update(), or delete() call, a status code is returned
575
- * @prop {String} [message] - Message corresponding to the statusCode field returned
576
- */
577
-
578
- /**
579
- * The locator class for Metadata API asynchronous call result
580
- *
581
- * @protected
582
- * @class Metadata~AsyncResultLocator
583
- * @extends events.EventEmitter
584
- * @implements Promise.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>
585
- * @param {Metadata} meta - Metadata API object
586
- * @param {Promise.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} results - Promise object for async result info
587
- * @param {Boolean} [isArray] - Indicates whether the async request is given in array or single object
588
- */
589
- var AsyncResultLocator = function(meta, results, isArray) {
590
- this._meta = meta;
591
- this._results = results;
592
- this._isArray = isArray;
593
- };
594
-
595
- inherits(AsyncResultLocator, events.EventEmitter);
596
-
597
- /**
598
- * Promise/A+ interface
599
- * http://promises-aplus.github.io/promises-spec/
600
- *
601
- * Delegate to deferred promise, return promise instance for batch result
602
- *
603
- * @method Metadata~AsyncResultLocator#then
604
- */
605
- AsyncResultLocator.prototype.then = function(onResolve, onReject) {
606
- var self = this;
607
- return this._results.then(function(results) {
608
- var convertType = function(res) {
609
- if (res.$ && res.$["xsi:nil"] === 'true') {
610
- return null;
611
- }
612
- res.done = res.done === 'true';
613
- return res;
614
- };
615
- results = _.isArray(results) ? _.map(results, convertType) : convertType(results);
616
- if (self._isArray && !_.isArray(results)) {
617
- results = [ results ];
618
- }
619
- return onResolve(results);
620
- }, onReject);
621
- };
622
-
623
- /**
624
- * Promise/A+ extension
625
- * Call "then" using given node-style callback function
626
- *
627
- * @method Metadata~AsyncResultLocator#thenCall
628
- */
629
- AsyncResultLocator.prototype.thenCall = function(callback) {
630
- return _.isFunction(callback) ? this.then(function(res) {
631
- process.nextTick(function() {
632
- callback(null, res);
633
- });
634
- }, function(err) {
635
- process.nextTick(function() {
636
- callback(err);
637
- });
638
- }) : this;
639
- };
640
-
641
- /**
642
- * Check the status of async request
643
- *
644
- * @method Metadata~AsyncResultLocator#check
645
- * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function
646
- * @returns {Promise.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>}
647
- */
648
- AsyncResultLocator.prototype.check = function(callback) {
649
- var self = this;
650
- var meta = this._meta;
651
- return this.then(function(results) {
652
- var ids = _.isArray(results) ? _.map(results, function(res){ return res.id; }) : results.id;
653
- self._ids = ids;
654
- return meta.checkStatus(ids);
655
- }).thenCall(callback);
656
- };
657
-
658
- /**
659
- * Polling until async call status becomes complete or error
660
- *
661
- * @method Metadata~AsyncResultLocator#poll
662
- * @param {Number} interval - Polling interval in milliseconds
663
- * @param {Number} timeout - Polling timeout in milliseconds
664
- */
665
- AsyncResultLocator.prototype.poll = function(interval, timeout) {
666
- var self = this;
667
- var startTime = new Date().getTime();
668
- var poll = function() {
669
- var now = new Date().getTime();
670
- if (startTime + timeout < now) {
671
- var errMsg = "Polling time out.";
672
- if (self._ids) {
673
- errMsg += " Process Id = " + self._ids;
674
- }
675
- self.emit('error', new Error(errMsg));
676
- return;
677
- }
678
- self.check().then(function(results) {
679
- var done = true;
680
- var resultArr = _.isArray(results) ? results : [ results ];
681
- for (var i=0, len=resultArr.length; i<len; i++) {
682
- var result = resultArr[i];
683
- if (result && !result.done) {
684
- self.emit('progress', result);
685
- done = false;
686
- }
687
- }
688
- if (done) {
689
- self.emit('complete', results);
690
- } else {
691
- setTimeout(poll, interval);
692
- }
693
- }, function(err) {
694
- self.emit('error', err);
695
- });
696
- };
697
- setTimeout(poll, interval);
698
- };
699
-
700
- /**
701
- * Check and wait until the async requests become in completed status
702
- *
703
- * @method Metadata~AsyncResultLocator#complete
704
- * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function
705
- * @returns {Promise.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>}
706
- */
707
- AsyncResultLocator.prototype.complete = function(callback) {
708
- var deferred = Promise.defer();
709
- this.on('complete', function(results) {
710
- deferred.resolve(results);
711
- });
712
- this.on('error', function(err) {
713
- deferred.reject(err);
714
- });
715
- var meta = this._meta;
716
- this.poll(meta.pollInterval, meta.pollTimeout);
717
- return deferred.promise.thenCall(callback);
718
- };
719
-
720
- /*--------------------------------------------*/
721
- /**
722
- * The locator class to track retreive() Metadata API call result
723
- *
724
- * @protected
725
- * @class Metadata~RetrieveResultLocator
726
- * @extends Metadata~AsyncResultLocator
727
- * @param {Metadata} meta - Metadata API object
728
- * @param {Promise.<Metadata~AsyncResult>} result - Promise object for async result of retrieve call()
729
- */
730
- var RetrieveResultLocator = function(meta, result) {
731
- RetrieveResultLocator.super_.call(this, meta, result);
732
- };
733
-
734
- inherits(RetrieveResultLocator, AsyncResultLocator);
735
-
736
- /**
737
- * @typedef {Object} Metadata~RetrieveResult
738
- * @prop {Array.<Metadata~FileProperties>} fileProperties - Contains information about the properties of each component in the .zip file, and the manifest file package.xml
739
- * @prop {String} id - ID of the component being retrieved
740
- * @prop {Array.<Object>} messages - Contains information about the success or failure of the retrieve() call
741
- * @prop {String} zipFile - The zip file returned by the retrieve request. Base 64-encoded binary data
742
- */
743
-
744
- /**
745
- * Check and wait until the async request becomes in completed status,
746
- * and retrieve the result data.
747
- *
748
- * @memthod Metadata~RetrieveResultLocator#complete
749
- * @param {Callback.<Metadata~RetrieveResult>} [callback] - Callback function
750
- * @returns {Promise.<Metadata~RetrieveResult>}
751
- */
752
- RetrieveResultLocator.prototype.complete = function(callback) {
753
- var meta = this._meta;
754
- return RetrieveResultLocator.super_.prototype.complete.call(this).then(function(result) {
755
- return meta.checkRetrieveStatus(result.id);
756
- }).thenCall(callback);
757
- };
758
-
759
- /**
760
- * Change the retrieved result to Node.js readable stream
761
- *
762
- * @method Metadata~RetrieveResultLocator#stream
763
- * @returns {stream.Readable}
764
- */
765
- RetrieveResultLocator.prototype.stream = function() {
766
- var self = this;
767
- var resultStream = new stream.Readable();
768
- var reading = false;
769
- resultStream._read = function() {
770
- if (reading) { return; }
771
- reading = true;
772
- self.complete(function(err, result) {
773
- if (err) {
774
- resultStream.emit('error', err);
775
- } else {
776
- resultStream.push(Buffer.from(result.zipFile, 'base64'));
777
- resultStream.push(null);
778
- }
779
- });
780
- };
781
- return resultStream;
782
- };
783
-
784
- /*--------------------------------------------*/
785
- /**
786
- * The locator class to track deploy() Metadata API call result
787
- *
788
- * @protected
789
- * @class Metadata~DeployResultLocator
790
- * @extends Metadata~AsyncResultLocator
791
- * @param {Metadata} meta - Metadata API object
792
- * @param {Promise.<Metadata~AsyncResult>} result - Promise object for async result of deploy() call
793
- */
794
- var DeployResultLocator = function(meta, result) {
795
- DeployResultLocator.super_.call(this, meta, result);
796
- };
797
-
798
- inherits(DeployResultLocator, AsyncResultLocator);
799
-
800
- /**
801
- * @typedef {Object} Metadata~DeployResult
802
- * @prop {String} id - ID of the component being deployed
803
- * @prop {Boolean} checkOnly - Indicates whether this deployment is being used to check the validity of the deployed files without making any changes in the organization or not
804
- * @prop {String} completedDate - Timestamp for when the deployment process ended
805
- * @prop {String} createdDate - Timestamp for when the deploy() call was received
806
- * @prop {Array.<Object>} [details] - Provides the details of a deployment that is in-progress or ended, if includeDetails is set to true in checkDeployStatus() call
807
- * @prop {Boolean} done - Indicates whether the server finished processing the deploy() call for the specified id
808
- * @prop {String} [errorMessage] - Message corresponding to the values in the errorStatusCode field
809
- * @prop {String} [errorStatusCode] - If an error occurred during the deploy() call, a status code is returned, and the message corresponding to the status code is returned in the errorMessagefield
810
- * @prop {Boolean} [ignoreWarnings] - Specifies whether a deployment should continue even if the deployment generates warnings
811
- * @prop {String} lastModifiedDate - Timestamp of the last update for the deployment process
812
- * @prop {Number} numberComponentErrors - The number of components that generated errors during this deployment
813
- * @prop {Number} numberComponentsDeployed - The number of components deployed in the deployment process
814
- * @prop {Number} numberComponentsTotal - The total number of components in the deployment
815
- * @prop {Number} numberTestErrors - The number of Apex tests that have generated errors during this deployment
816
- * @prop {Number} numberTestsCompleted - The number of completedApex tests for this deployment
817
- * @prop {Number} numberTestsTotal - The total number of Apex tests for this deployment
818
- * @prop {Boolean} [rollbackOnError] - Indicates whether any failure causes a complete rollback or not. Default is true.
819
- * @prop {String} startDate - Timestamp for when the deployment process began
820
- * @prop {String} status - Indicates the current state of the deployment
821
- * @prop {Boolean} success - Indicates whether the deployment was successful or not
822
- */
823
-
824
- /**
825
- * Check and wait until the async request becomes in completed status,
826
- * and retrieve the result data.
827
- *
828
- * @method Metadata~DeployResultLocator#complete
829
- * @param {Callback.<Metadata~DeployResult>} [callback] - Callback function
830
- * @returns {Promise.<Metadata~DeployResult>}
831
- */
832
- DeployResultLocator.prototype.complete = function(includeDetails, callback) {
833
- if (_.isFunction(includeDetails)) {
834
- callback = includeDetails;
835
- includeDetails = false;
836
- }
837
- var meta = this._meta;
838
- return DeployResultLocator.super_.prototype.complete.call(this).then(function(result) {
839
- return meta.checkDeployStatus(result.id, includeDetails);
840
- }).thenCall(callback);
841
- };
842
-
843
-
844
- /*--------------------------------------------*/
845
- /*
846
- * Register hook in connection instantiation for dynamically adding this API module features
847
- */
848
- jsforce.on('connection:new', function(conn) {
849
- conn.metadata = new Metadata(conn);
850
- });
851
-
852
- }).call(this,require('_process'),require("buffer").Buffer)
853
-
854
- },{"_process":5,"buffer":3}],2:[function(require,module,exports){
855
- 'use strict'
856
-
857
- exports.byteLength = byteLength
858
- exports.toByteArray = toByteArray
859
- exports.fromByteArray = fromByteArray
860
-
861
- var lookup = []
862
- var revLookup = []
863
- var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
864
-
865
- var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
866
- for (var i = 0, len = code.length; i < len; ++i) {
867
- lookup[i] = code[i]
868
- revLookup[code.charCodeAt(i)] = i
869
- }
870
-
871
- // Support decoding URL-safe base64 strings, as Node.js does.
872
- // See: https://en.wikipedia.org/wiki/Base64#URL_applications
873
- revLookup['-'.charCodeAt(0)] = 62
874
- revLookup['_'.charCodeAt(0)] = 63
875
-
876
- function getLens (b64) {
877
- var len = b64.length
878
-
879
- if (len % 4 > 0) {
880
- throw new Error('Invalid string. Length must be a multiple of 4')
881
- }
882
-
883
- // Trim off extra bytes after placeholder bytes are found
884
- // See: https://github.com/beatgammit/base64-js/issues/42
885
- var validLen = b64.indexOf('=')
886
- if (validLen === -1) validLen = len
887
-
888
- var placeHoldersLen = validLen === len
889
- ? 0
890
- : 4 - (validLen % 4)
891
-
892
- return [validLen, placeHoldersLen]
893
- }
894
-
895
- // base64 is 4/3 + up to two characters of the original data
896
- function byteLength (b64) {
897
- var lens = getLens(b64)
898
- var validLen = lens[0]
899
- var placeHoldersLen = lens[1]
900
- return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
901
- }
902
-
903
- function _byteLength (b64, validLen, placeHoldersLen) {
904
- return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
905
- }
906
-
907
- function toByteArray (b64) {
908
- var tmp
909
- var lens = getLens(b64)
910
- var validLen = lens[0]
911
- var placeHoldersLen = lens[1]
912
-
913
- var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
914
-
915
- var curByte = 0
916
-
917
- // if there are placeholders, only get up to the last complete 4 chars
918
- var len = placeHoldersLen > 0
919
- ? validLen - 4
920
- : validLen
921
-
922
- for (var i = 0; i < len; i += 4) {
923
- tmp =
924
- (revLookup[b64.charCodeAt(i)] << 18) |
925
- (revLookup[b64.charCodeAt(i + 1)] << 12) |
926
- (revLookup[b64.charCodeAt(i + 2)] << 6) |
927
- revLookup[b64.charCodeAt(i + 3)]
928
- arr[curByte++] = (tmp >> 16) & 0xFF
929
- arr[curByte++] = (tmp >> 8) & 0xFF
930
- arr[curByte++] = tmp & 0xFF
931
- }
932
-
933
- if (placeHoldersLen === 2) {
934
- tmp =
935
- (revLookup[b64.charCodeAt(i)] << 2) |
936
- (revLookup[b64.charCodeAt(i + 1)] >> 4)
937
- arr[curByte++] = tmp & 0xFF
938
- }
939
-
940
- if (placeHoldersLen === 1) {
941
- tmp =
942
- (revLookup[b64.charCodeAt(i)] << 10) |
943
- (revLookup[b64.charCodeAt(i + 1)] << 4) |
944
- (revLookup[b64.charCodeAt(i + 2)] >> 2)
945
- arr[curByte++] = (tmp >> 8) & 0xFF
946
- arr[curByte++] = tmp & 0xFF
947
- }
948
-
949
- return arr
950
- }
951
-
952
- function tripletToBase64 (num) {
953
- return lookup[num >> 18 & 0x3F] +
954
- lookup[num >> 12 & 0x3F] +
955
- lookup[num >> 6 & 0x3F] +
956
- lookup[num & 0x3F]
957
- }
958
-
959
- function encodeChunk (uint8, start, end) {
960
- var tmp
961
- var output = []
962
- for (var i = start; i < end; i += 3) {
963
- tmp =
964
- ((uint8[i] << 16) & 0xFF0000) +
965
- ((uint8[i + 1] << 8) & 0xFF00) +
966
- (uint8[i + 2] & 0xFF)
967
- output.push(tripletToBase64(tmp))
968
- }
969
- return output.join('')
970
- }
971
-
972
- function fromByteArray (uint8) {
973
- var tmp
974
- var len = uint8.length
975
- var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
976
- var parts = []
977
- var maxChunkLength = 16383 // must be multiple of 3
978
-
979
- // go through the array every three bytes, we'll deal with trailing stuff later
980
- for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
981
- parts.push(encodeChunk(
982
- uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
983
- ))
984
- }
985
-
986
- // pad the end with zeros, but make sure to not forget the extra bytes
987
- if (extraBytes === 1) {
988
- tmp = uint8[len - 1]
989
- parts.push(
990
- lookup[tmp >> 2] +
991
- lookup[(tmp << 4) & 0x3F] +
992
- '=='
993
- )
994
- } else if (extraBytes === 2) {
995
- tmp = (uint8[len - 2] << 8) + uint8[len - 1]
996
- parts.push(
997
- lookup[tmp >> 10] +
998
- lookup[(tmp >> 4) & 0x3F] +
999
- lookup[(tmp << 2) & 0x3F] +
1000
- '='
1001
- )
1002
- }
1003
-
1004
- return parts.join('')
1005
- }
1006
-
1007
- },{}],3:[function(require,module,exports){
1008
- /*!
1009
- * The buffer module from node.js, for the browser.
1010
- *
1011
- * @author Feross Aboukhadijeh <https://feross.org>
1012
- * @license MIT
1013
- */
1014
- /* eslint-disable no-proto */
1015
-
1016
- 'use strict'
1017
-
1018
- var base64 = require('base64-js')
1019
- var ieee754 = require('ieee754')
1020
-
1021
- exports.Buffer = Buffer
1022
- exports.SlowBuffer = SlowBuffer
1023
- exports.INSPECT_MAX_BYTES = 50
1024
-
1025
- var K_MAX_LENGTH = 0x7fffffff
1026
- exports.kMaxLength = K_MAX_LENGTH
1027
-
1028
- /**
1029
- * If `Buffer.TYPED_ARRAY_SUPPORT`:
1030
- * === true Use Uint8Array implementation (fastest)
1031
- * === false Print warning and recommend using `buffer` v4.x which has an Object
1032
- * implementation (most compatible, even IE6)
1033
- *
1034
- * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
1035
- * Opera 11.6+, iOS 4.2+.
1036
- *
1037
- * We report that the browser does not support typed arrays if the are not subclassable
1038
- * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
1039
- * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
1040
- * for __proto__ and has a buggy typed array implementation.
1041
- */
1042
- Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
1043
-
1044
- if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
1045
- typeof console.error === 'function') {
1046
- console.error(
1047
- 'This browser lacks typed array (Uint8Array) support which is required by ' +
1048
- '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
1049
- )
1050
- }
1051
-
1052
- function typedArraySupport () {
1053
- // Can typed array instances can be augmented?
1054
- try {
1055
- var arr = new Uint8Array(1)
1056
- arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
1057
- return arr.foo() === 42
1058
- } catch (e) {
1059
- return false
1060
- }
1061
- }
1062
-
1063
- Object.defineProperty(Buffer.prototype, 'parent', {
1064
- get: function () {
1065
- if (!(this instanceof Buffer)) {
1066
- return undefined
1067
- }
1068
- return this.buffer
1069
- }
1070
- })
1071
-
1072
- Object.defineProperty(Buffer.prototype, 'offset', {
1073
- get: function () {
1074
- if (!(this instanceof Buffer)) {
1075
- return undefined
1076
- }
1077
- return this.byteOffset
1078
- }
1079
- })
1080
-
1081
- function createBuffer (length) {
1082
- if (length > K_MAX_LENGTH) {
1083
- throw new RangeError('Invalid typed array length')
1084
- }
1085
- // Return an augmented `Uint8Array` instance
1086
- var buf = new Uint8Array(length)
1087
- buf.__proto__ = Buffer.prototype
1088
- return buf
1089
- }
1090
-
1091
- /**
1092
- * The Buffer constructor returns instances of `Uint8Array` that have their
1093
- * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
1094
- * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
1095
- * and the `Uint8Array` methods. Square bracket notation works as expected -- it
1096
- * returns a single octet.
1097
- *
1098
- * The `Uint8Array` prototype remains unmodified.
1099
- */
1100
-
1101
- function Buffer (arg, encodingOrOffset, length) {
1102
- // Common case.
1103
- if (typeof arg === 'number') {
1104
- if (typeof encodingOrOffset === 'string') {
1105
- throw new Error(
1106
- 'If encoding is specified then the first argument must be a string'
1107
- )
1108
- }
1109
- return allocUnsafe(arg)
1110
- }
1111
- return from(arg, encodingOrOffset, length)
1112
- }
1113
-
1114
- // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
1115
- if (typeof Symbol !== 'undefined' && Symbol.species &&
1116
- Buffer[Symbol.species] === Buffer) {
1117
- Object.defineProperty(Buffer, Symbol.species, {
1118
- value: null,
1119
- configurable: true,
1120
- enumerable: false,
1121
- writable: false
1122
- })
1123
- }
1124
-
1125
- Buffer.poolSize = 8192 // not used by this implementation
1126
-
1127
- function from (value, encodingOrOffset, length) {
1128
- if (typeof value === 'number') {
1129
- throw new TypeError('"value" argument must not be a number')
1130
- }
1131
-
1132
- if (isArrayBuffer(value) || (value && isArrayBuffer(value.buffer))) {
1133
- return fromArrayBuffer(value, encodingOrOffset, length)
1134
- }
1135
-
1136
- if (typeof value === 'string') {
1137
- return fromString(value, encodingOrOffset)
1138
- }
1139
-
1140
- return fromObject(value)
1141
- }
1142
-
1143
- /**
1144
- * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
1145
- * if value is a number.
1146
- * Buffer.from(str[, encoding])
1147
- * Buffer.from(array)
1148
- * Buffer.from(buffer)
1149
- * Buffer.from(arrayBuffer[, byteOffset[, length]])
1150
- **/
1151
- Buffer.from = function (value, encodingOrOffset, length) {
1152
- return from(value, encodingOrOffset, length)
1153
- }
1154
-
1155
- // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
1156
- // https://github.com/feross/buffer/pull/148
1157
- Buffer.prototype.__proto__ = Uint8Array.prototype
1158
- Buffer.__proto__ = Uint8Array
1159
-
1160
- function assertSize (size) {
1161
- if (typeof size !== 'number') {
1162
- throw new TypeError('"size" argument must be of type number')
1163
- } else if (size < 0) {
1164
- throw new RangeError('"size" argument must not be negative')
1165
- }
1166
- }
1167
-
1168
- function alloc (size, fill, encoding) {
1169
- assertSize(size)
1170
- if (size <= 0) {
1171
- return createBuffer(size)
1172
- }
1173
- if (fill !== undefined) {
1174
- // Only pay attention to encoding if it's a string. This
1175
- // prevents accidentally sending in a number that would
1176
- // be interpretted as a start offset.
1177
- return typeof encoding === 'string'
1178
- ? createBuffer(size).fill(fill, encoding)
1179
- : createBuffer(size).fill(fill)
1180
- }
1181
- return createBuffer(size)
1182
- }
1183
-
1184
- /**
1185
- * Creates a new filled Buffer instance.
1186
- * alloc(size[, fill[, encoding]])
1187
- **/
1188
- Buffer.alloc = function (size, fill, encoding) {
1189
- return alloc(size, fill, encoding)
1190
- }
1191
-
1192
- function allocUnsafe (size) {
1193
- assertSize(size)
1194
- return createBuffer(size < 0 ? 0 : checked(size) | 0)
1195
- }
1196
-
1197
- /**
1198
- * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
1199
- * */
1200
- Buffer.allocUnsafe = function (size) {
1201
- return allocUnsafe(size)
1202
- }
1203
- /**
1204
- * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
1205
- */
1206
- Buffer.allocUnsafeSlow = function (size) {
1207
- return allocUnsafe(size)
1208
- }
1209
-
1210
- function fromString (string, encoding) {
1211
- if (typeof encoding !== 'string' || encoding === '') {
1212
- encoding = 'utf8'
1213
- }
1214
-
1215
- if (!Buffer.isEncoding(encoding)) {
1216
- throw new TypeError('Unknown encoding: ' + encoding)
1217
- }
1218
-
1219
- var length = byteLength(string, encoding) | 0
1220
- var buf = createBuffer(length)
1221
-
1222
- var actual = buf.write(string, encoding)
1223
-
1224
- if (actual !== length) {
1225
- // Writing a hex string, for example, that contains invalid characters will
1226
- // cause everything after the first invalid character to be ignored. (e.g.
1227
- // 'abxxcd' will be treated as 'ab')
1228
- buf = buf.slice(0, actual)
1229
- }
1230
-
1231
- return buf
1232
- }
1233
-
1234
- function fromArrayLike (array) {
1235
- var length = array.length < 0 ? 0 : checked(array.length) | 0
1236
- var buf = createBuffer(length)
1237
- for (var i = 0; i < length; i += 1) {
1238
- buf[i] = array[i] & 255
1239
- }
1240
- return buf
1241
- }
1242
-
1243
- function fromArrayBuffer (array, byteOffset, length) {
1244
- if (byteOffset < 0 || array.byteLength < byteOffset) {
1245
- throw new RangeError('"offset" is outside of buffer bounds')
1246
- }
1247
-
1248
- if (array.byteLength < byteOffset + (length || 0)) {
1249
- throw new RangeError('"length" is outside of buffer bounds')
1250
- }
1251
-
1252
- var buf
1253
- if (byteOffset === undefined && length === undefined) {
1254
- buf = new Uint8Array(array)
1255
- } else if (length === undefined) {
1256
- buf = new Uint8Array(array, byteOffset)
1257
- } else {
1258
- buf = new Uint8Array(array, byteOffset, length)
1259
- }
1260
-
1261
- // Return an augmented `Uint8Array` instance
1262
- buf.__proto__ = Buffer.prototype
1263
- return buf
1264
- }
1265
-
1266
- function fromObject (obj) {
1267
- if (Buffer.isBuffer(obj)) {
1268
- var len = checked(obj.length) | 0
1269
- var buf = createBuffer(len)
1270
-
1271
- if (buf.length === 0) {
1272
- return buf
1273
- }
1274
-
1275
- obj.copy(buf, 0, 0, len)
1276
- return buf
1277
- }
1278
-
1279
- if (obj) {
1280
- if (ArrayBuffer.isView(obj) || 'length' in obj) {
1281
- if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
1282
- return createBuffer(0)
1283
- }
1284
- return fromArrayLike(obj)
1285
- }
1286
-
1287
- if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
1288
- return fromArrayLike(obj.data)
1289
- }
1290
- }
1291
-
1292
- throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object.')
1293
- }
1294
-
1295
- function checked (length) {
1296
- // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
1297
- // length is NaN (which is otherwise coerced to zero.)
1298
- if (length >= K_MAX_LENGTH) {
1299
- throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
1300
- 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
1301
- }
1302
- return length | 0
1303
- }
1304
-
1305
- function SlowBuffer (length) {
1306
- if (+length != length) { // eslint-disable-line eqeqeq
1307
- length = 0
1308
- }
1309
- return Buffer.alloc(+length)
1310
- }
1311
-
1312
- Buffer.isBuffer = function isBuffer (b) {
1313
- return b != null && b._isBuffer === true
1314
- }
1315
-
1316
- Buffer.compare = function compare (a, b) {
1317
- if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
1318
- throw new TypeError('Arguments must be Buffers')
1319
- }
1320
-
1321
- if (a === b) return 0
1322
-
1323
- var x = a.length
1324
- var y = b.length
1325
-
1326
- for (var i = 0, len = Math.min(x, y); i < len; ++i) {
1327
- if (a[i] !== b[i]) {
1328
- x = a[i]
1329
- y = b[i]
1330
- break
1331
- }
1332
- }
1333
-
1334
- if (x < y) return -1
1335
- if (y < x) return 1
1336
- return 0
1337
- }
1338
-
1339
- Buffer.isEncoding = function isEncoding (encoding) {
1340
- switch (String(encoding).toLowerCase()) {
1341
- case 'hex':
1342
- case 'utf8':
1343
- case 'utf-8':
1344
- case 'ascii':
1345
- case 'latin1':
1346
- case 'binary':
1347
- case 'base64':
1348
- case 'ucs2':
1349
- case 'ucs-2':
1350
- case 'utf16le':
1351
- case 'utf-16le':
1352
- return true
1353
- default:
1354
- return false
1355
- }
1356
- }
1357
-
1358
- Buffer.concat = function concat (list, length) {
1359
- if (!Array.isArray(list)) {
1360
- throw new TypeError('"list" argument must be an Array of Buffers')
1361
- }
1362
-
1363
- if (list.length === 0) {
1364
- return Buffer.alloc(0)
1365
- }
1366
-
1367
- var i
1368
- if (length === undefined) {
1369
- length = 0
1370
- for (i = 0; i < list.length; ++i) {
1371
- length += list[i].length
1372
- }
1373
- }
1374
-
1375
- var buffer = Buffer.allocUnsafe(length)
1376
- var pos = 0
1377
- for (i = 0; i < list.length; ++i) {
1378
- var buf = list[i]
1379
- if (ArrayBuffer.isView(buf)) {
1380
- buf = Buffer.from(buf)
1381
- }
1382
- if (!Buffer.isBuffer(buf)) {
1383
- throw new TypeError('"list" argument must be an Array of Buffers')
1384
- }
1385
- buf.copy(buffer, pos)
1386
- pos += buf.length
1387
- }
1388
- return buffer
1389
- }
1390
-
1391
- function byteLength (string, encoding) {
1392
- if (Buffer.isBuffer(string)) {
1393
- return string.length
1394
- }
1395
- if (ArrayBuffer.isView(string) || isArrayBuffer(string)) {
1396
- return string.byteLength
1397
- }
1398
- if (typeof string !== 'string') {
1399
- string = '' + string
1400
- }
1401
-
1402
- var len = string.length
1403
- if (len === 0) return 0
1404
-
1405
- // Use a for loop to avoid recursion
1406
- var loweredCase = false
1407
- for (;;) {
1408
- switch (encoding) {
1409
- case 'ascii':
1410
- case 'latin1':
1411
- case 'binary':
1412
- return len
1413
- case 'utf8':
1414
- case 'utf-8':
1415
- case undefined:
1416
- return utf8ToBytes(string).length
1417
- case 'ucs2':
1418
- case 'ucs-2':
1419
- case 'utf16le':
1420
- case 'utf-16le':
1421
- return len * 2
1422
- case 'hex':
1423
- return len >>> 1
1424
- case 'base64':
1425
- return base64ToBytes(string).length
1426
- default:
1427
- if (loweredCase) return utf8ToBytes(string).length // assume utf8
1428
- encoding = ('' + encoding).toLowerCase()
1429
- loweredCase = true
1430
- }
1431
- }
1432
- }
1433
- Buffer.byteLength = byteLength
1434
-
1435
- function slowToString (encoding, start, end) {
1436
- var loweredCase = false
1437
-
1438
- // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
1439
- // property of a typed array.
1440
-
1441
- // This behaves neither like String nor Uint8Array in that we set start/end
1442
- // to their upper/lower bounds if the value passed is out of range.
1443
- // undefined is handled specially as per ECMA-262 6th Edition,
1444
- // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
1445
- if (start === undefined || start < 0) {
1446
- start = 0
1447
- }
1448
- // Return early if start > this.length. Done here to prevent potential uint32
1449
- // coercion fail below.
1450
- if (start > this.length) {
1451
- return ''
1452
- }
1453
-
1454
- if (end === undefined || end > this.length) {
1455
- end = this.length
1456
- }
1457
-
1458
- if (end <= 0) {
1459
- return ''
1460
- }
1461
-
1462
- // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
1463
- end >>>= 0
1464
- start >>>= 0
1465
-
1466
- if (end <= start) {
1467
- return ''
1468
- }
1469
-
1470
- if (!encoding) encoding = 'utf8'
1471
-
1472
- while (true) {
1473
- switch (encoding) {
1474
- case 'hex':
1475
- return hexSlice(this, start, end)
1476
-
1477
- case 'utf8':
1478
- case 'utf-8':
1479
- return utf8Slice(this, start, end)
1480
-
1481
- case 'ascii':
1482
- return asciiSlice(this, start, end)
1483
-
1484
- case 'latin1':
1485
- case 'binary':
1486
- return latin1Slice(this, start, end)
1487
-
1488
- case 'base64':
1489
- return base64Slice(this, start, end)
1490
-
1491
- case 'ucs2':
1492
- case 'ucs-2':
1493
- case 'utf16le':
1494
- case 'utf-16le':
1495
- return utf16leSlice(this, start, end)
1496
-
1497
- default:
1498
- if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
1499
- encoding = (encoding + '').toLowerCase()
1500
- loweredCase = true
1501
- }
1502
- }
1503
- }
1504
-
1505
- // This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
1506
- // to detect a Buffer instance. It's not possible to use `instanceof Buffer`
1507
- // reliably in a browserify context because there could be multiple different
1508
- // copies of the 'buffer' package in use. This method works even for Buffer
1509
- // instances that were created from another copy of the `buffer` package.
1510
- // See: https://github.com/feross/buffer/issues/154
1511
- Buffer.prototype._isBuffer = true
1512
-
1513
- function swap (b, n, m) {
1514
- var i = b[n]
1515
- b[n] = b[m]
1516
- b[m] = i
1517
- }
1518
-
1519
- Buffer.prototype.swap16 = function swap16 () {
1520
- var len = this.length
1521
- if (len % 2 !== 0) {
1522
- throw new RangeError('Buffer size must be a multiple of 16-bits')
1523
- }
1524
- for (var i = 0; i < len; i += 2) {
1525
- swap(this, i, i + 1)
1526
- }
1527
- return this
1528
- }
1529
-
1530
- Buffer.prototype.swap32 = function swap32 () {
1531
- var len = this.length
1532
- if (len % 4 !== 0) {
1533
- throw new RangeError('Buffer size must be a multiple of 32-bits')
1534
- }
1535
- for (var i = 0; i < len; i += 4) {
1536
- swap(this, i, i + 3)
1537
- swap(this, i + 1, i + 2)
1538
- }
1539
- return this
1540
- }
1541
-
1542
- Buffer.prototype.swap64 = function swap64 () {
1543
- var len = this.length
1544
- if (len % 8 !== 0) {
1545
- throw new RangeError('Buffer size must be a multiple of 64-bits')
1546
- }
1547
- for (var i = 0; i < len; i += 8) {
1548
- swap(this, i, i + 7)
1549
- swap(this, i + 1, i + 6)
1550
- swap(this, i + 2, i + 5)
1551
- swap(this, i + 3, i + 4)
1552
- }
1553
- return this
1554
- }
1555
-
1556
- Buffer.prototype.toString = function toString () {
1557
- var length = this.length
1558
- if (length === 0) return ''
1559
- if (arguments.length === 0) return utf8Slice(this, 0, length)
1560
- return slowToString.apply(this, arguments)
1561
- }
1562
-
1563
- Buffer.prototype.toLocaleString = Buffer.prototype.toString
1564
-
1565
- Buffer.prototype.equals = function equals (b) {
1566
- if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
1567
- if (this === b) return true
1568
- return Buffer.compare(this, b) === 0
1569
- }
1570
-
1571
- Buffer.prototype.inspect = function inspect () {
1572
- var str = ''
1573
- var max = exports.INSPECT_MAX_BYTES
1574
- if (this.length > 0) {
1575
- str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
1576
- if (this.length > max) str += ' ... '
1577
- }
1578
- return '<Buffer ' + str + '>'
1579
- }
1580
-
1581
- Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
1582
- if (!Buffer.isBuffer(target)) {
1583
- throw new TypeError('Argument must be a Buffer')
1584
- }
1585
-
1586
- if (start === undefined) {
1587
- start = 0
1588
- }
1589
- if (end === undefined) {
1590
- end = target ? target.length : 0
1591
- }
1592
- if (thisStart === undefined) {
1593
- thisStart = 0
1594
- }
1595
- if (thisEnd === undefined) {
1596
- thisEnd = this.length
1597
- }
1598
-
1599
- if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
1600
- throw new RangeError('out of range index')
1601
- }
1602
-
1603
- if (thisStart >= thisEnd && start >= end) {
1604
- return 0
1605
- }
1606
- if (thisStart >= thisEnd) {
1607
- return -1
1608
- }
1609
- if (start >= end) {
1610
- return 1
1611
- }
1612
-
1613
- start >>>= 0
1614
- end >>>= 0
1615
- thisStart >>>= 0
1616
- thisEnd >>>= 0
1617
-
1618
- if (this === target) return 0
1619
-
1620
- var x = thisEnd - thisStart
1621
- var y = end - start
1622
- var len = Math.min(x, y)
1623
-
1624
- var thisCopy = this.slice(thisStart, thisEnd)
1625
- var targetCopy = target.slice(start, end)
1626
-
1627
- for (var i = 0; i < len; ++i) {
1628
- if (thisCopy[i] !== targetCopy[i]) {
1629
- x = thisCopy[i]
1630
- y = targetCopy[i]
1631
- break
1632
- }
1633
- }
1634
-
1635
- if (x < y) return -1
1636
- if (y < x) return 1
1637
- return 0
1638
- }
1639
-
1640
- // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
1641
- // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
1642
- //
1643
- // Arguments:
1644
- // - buffer - a Buffer to search
1645
- // - val - a string, Buffer, or number
1646
- // - byteOffset - an index into `buffer`; will be clamped to an int32
1647
- // - encoding - an optional encoding, relevant is val is a string
1648
- // - dir - true for indexOf, false for lastIndexOf
1649
- function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
1650
- // Empty buffer means no match
1651
- if (buffer.length === 0) return -1
1652
-
1653
- // Normalize byteOffset
1654
- if (typeof byteOffset === 'string') {
1655
- encoding = byteOffset
1656
- byteOffset = 0
1657
- } else if (byteOffset > 0x7fffffff) {
1658
- byteOffset = 0x7fffffff
1659
- } else if (byteOffset < -0x80000000) {
1660
- byteOffset = -0x80000000
1661
- }
1662
- byteOffset = +byteOffset // Coerce to Number.
1663
- if (numberIsNaN(byteOffset)) {
1664
- // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
1665
- byteOffset = dir ? 0 : (buffer.length - 1)
1666
- }
1667
-
1668
- // Normalize byteOffset: negative offsets start from the end of the buffer
1669
- if (byteOffset < 0) byteOffset = buffer.length + byteOffset
1670
- if (byteOffset >= buffer.length) {
1671
- if (dir) return -1
1672
- else byteOffset = buffer.length - 1
1673
- } else if (byteOffset < 0) {
1674
- if (dir) byteOffset = 0
1675
- else return -1
1676
- }
1677
-
1678
- // Normalize val
1679
- if (typeof val === 'string') {
1680
- val = Buffer.from(val, encoding)
1681
- }
1682
-
1683
- // Finally, search either indexOf (if dir is true) or lastIndexOf
1684
- if (Buffer.isBuffer(val)) {
1685
- // Special case: looking for empty string/buffer always fails
1686
- if (val.length === 0) {
1687
- return -1
1688
- }
1689
- return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
1690
- } else if (typeof val === 'number') {
1691
- val = val & 0xFF // Search for a byte value [0-255]
1692
- if (typeof Uint8Array.prototype.indexOf === 'function') {
1693
- if (dir) {
1694
- return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
1695
- } else {
1696
- return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
1697
- }
1698
- }
1699
- return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
1700
- }
1701
-
1702
- throw new TypeError('val must be string, number or Buffer')
1703
- }
1704
-
1705
- function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
1706
- var indexSize = 1
1707
- var arrLength = arr.length
1708
- var valLength = val.length
1709
-
1710
- if (encoding !== undefined) {
1711
- encoding = String(encoding).toLowerCase()
1712
- if (encoding === 'ucs2' || encoding === 'ucs-2' ||
1713
- encoding === 'utf16le' || encoding === 'utf-16le') {
1714
- if (arr.length < 2 || val.length < 2) {
1715
- return -1
1716
- }
1717
- indexSize = 2
1718
- arrLength /= 2
1719
- valLength /= 2
1720
- byteOffset /= 2
1721
- }
1722
- }
1723
-
1724
- function read (buf, i) {
1725
- if (indexSize === 1) {
1726
- return buf[i]
1727
- } else {
1728
- return buf.readUInt16BE(i * indexSize)
1729
- }
1730
- }
1731
-
1732
- var i
1733
- if (dir) {
1734
- var foundIndex = -1
1735
- for (i = byteOffset; i < arrLength; i++) {
1736
- if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
1737
- if (foundIndex === -1) foundIndex = i
1738
- if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
1739
- } else {
1740
- if (foundIndex !== -1) i -= i - foundIndex
1741
- foundIndex = -1
1742
- }
1743
- }
1744
- } else {
1745
- if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
1746
- for (i = byteOffset; i >= 0; i--) {
1747
- var found = true
1748
- for (var j = 0; j < valLength; j++) {
1749
- if (read(arr, i + j) !== read(val, j)) {
1750
- found = false
1751
- break
1752
- }
1753
- }
1754
- if (found) return i
1755
- }
1756
- }
1757
-
1758
- return -1
1759
- }
1760
-
1761
- Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
1762
- return this.indexOf(val, byteOffset, encoding) !== -1
1763
- }
1764
-
1765
- Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
1766
- return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
1767
- }
1768
-
1769
- Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
1770
- return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
1771
- }
1772
-
1773
- function hexWrite (buf, string, offset, length) {
1774
- offset = Number(offset) || 0
1775
- var remaining = buf.length - offset
1776
- if (!length) {
1777
- length = remaining
1778
- } else {
1779
- length = Number(length)
1780
- if (length > remaining) {
1781
- length = remaining
1782
- }
1783
- }
1784
-
1785
- var strLen = string.length
1786
-
1787
- if (length > strLen / 2) {
1788
- length = strLen / 2
1789
- }
1790
- for (var i = 0; i < length; ++i) {
1791
- var parsed = parseInt(string.substr(i * 2, 2), 16)
1792
- if (numberIsNaN(parsed)) return i
1793
- buf[offset + i] = parsed
1794
- }
1795
- return i
1796
- }
1797
-
1798
- function utf8Write (buf, string, offset, length) {
1799
- return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
1800
- }
1801
-
1802
- function asciiWrite (buf, string, offset, length) {
1803
- return blitBuffer(asciiToBytes(string), buf, offset, length)
1804
- }
1805
-
1806
- function latin1Write (buf, string, offset, length) {
1807
- return asciiWrite(buf, string, offset, length)
1808
- }
1809
-
1810
- function base64Write (buf, string, offset, length) {
1811
- return blitBuffer(base64ToBytes(string), buf, offset, length)
1812
- }
1813
-
1814
- function ucs2Write (buf, string, offset, length) {
1815
- return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
1816
- }
1817
-
1818
- Buffer.prototype.write = function write (string, offset, length, encoding) {
1819
- // Buffer#write(string)
1820
- if (offset === undefined) {
1821
- encoding = 'utf8'
1822
- length = this.length
1823
- offset = 0
1824
- // Buffer#write(string, encoding)
1825
- } else if (length === undefined && typeof offset === 'string') {
1826
- encoding = offset
1827
- length = this.length
1828
- offset = 0
1829
- // Buffer#write(string, offset[, length][, encoding])
1830
- } else if (isFinite(offset)) {
1831
- offset = offset >>> 0
1832
- if (isFinite(length)) {
1833
- length = length >>> 0
1834
- if (encoding === undefined) encoding = 'utf8'
1835
- } else {
1836
- encoding = length
1837
- length = undefined
1838
- }
1839
- } else {
1840
- throw new Error(
1841
- 'Buffer.write(string, encoding, offset[, length]) is no longer supported'
1842
- )
1843
- }
1844
-
1845
- var remaining = this.length - offset
1846
- if (length === undefined || length > remaining) length = remaining
1847
-
1848
- if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
1849
- throw new RangeError('Attempt to write outside buffer bounds')
1850
- }
1851
-
1852
- if (!encoding) encoding = 'utf8'
1853
-
1854
- var loweredCase = false
1855
- for (;;) {
1856
- switch (encoding) {
1857
- case 'hex':
1858
- return hexWrite(this, string, offset, length)
1859
-
1860
- case 'utf8':
1861
- case 'utf-8':
1862
- return utf8Write(this, string, offset, length)
1863
-
1864
- case 'ascii':
1865
- return asciiWrite(this, string, offset, length)
1866
-
1867
- case 'latin1':
1868
- case 'binary':
1869
- return latin1Write(this, string, offset, length)
1870
-
1871
- case 'base64':
1872
- // Warning: maxLength not taken into account in base64Write
1873
- return base64Write(this, string, offset, length)
1874
-
1875
- case 'ucs2':
1876
- case 'ucs-2':
1877
- case 'utf16le':
1878
- case 'utf-16le':
1879
- return ucs2Write(this, string, offset, length)
1880
-
1881
- default:
1882
- if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
1883
- encoding = ('' + encoding).toLowerCase()
1884
- loweredCase = true
1885
- }
1886
- }
1887
- }
1888
-
1889
- Buffer.prototype.toJSON = function toJSON () {
1890
- return {
1891
- type: 'Buffer',
1892
- data: Array.prototype.slice.call(this._arr || this, 0)
1893
- }
1894
- }
1895
-
1896
- function base64Slice (buf, start, end) {
1897
- if (start === 0 && end === buf.length) {
1898
- return base64.fromByteArray(buf)
1899
- } else {
1900
- return base64.fromByteArray(buf.slice(start, end))
1901
- }
1902
- }
1903
-
1904
- function utf8Slice (buf, start, end) {
1905
- end = Math.min(buf.length, end)
1906
- var res = []
1907
-
1908
- var i = start
1909
- while (i < end) {
1910
- var firstByte = buf[i]
1911
- var codePoint = null
1912
- var bytesPerSequence = (firstByte > 0xEF) ? 4
1913
- : (firstByte > 0xDF) ? 3
1914
- : (firstByte > 0xBF) ? 2
1915
- : 1
1916
-
1917
- if (i + bytesPerSequence <= end) {
1918
- var secondByte, thirdByte, fourthByte, tempCodePoint
1919
-
1920
- switch (bytesPerSequence) {
1921
- case 1:
1922
- if (firstByte < 0x80) {
1923
- codePoint = firstByte
1924
- }
1925
- break
1926
- case 2:
1927
- secondByte = buf[i + 1]
1928
- if ((secondByte & 0xC0) === 0x80) {
1929
- tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
1930
- if (tempCodePoint > 0x7F) {
1931
- codePoint = tempCodePoint
1932
- }
1933
- }
1934
- break
1935
- case 3:
1936
- secondByte = buf[i + 1]
1937
- thirdByte = buf[i + 2]
1938
- if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
1939
- tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
1940
- if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
1941
- codePoint = tempCodePoint
1942
- }
1943
- }
1944
- break
1945
- case 4:
1946
- secondByte = buf[i + 1]
1947
- thirdByte = buf[i + 2]
1948
- fourthByte = buf[i + 3]
1949
- if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
1950
- tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
1951
- if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
1952
- codePoint = tempCodePoint
1953
- }
1954
- }
1955
- }
1956
- }
1957
-
1958
- if (codePoint === null) {
1959
- // we did not generate a valid codePoint so insert a
1960
- // replacement char (U+FFFD) and advance only 1 byte
1961
- codePoint = 0xFFFD
1962
- bytesPerSequence = 1
1963
- } else if (codePoint > 0xFFFF) {
1964
- // encode to utf16 (surrogate pair dance)
1965
- codePoint -= 0x10000
1966
- res.push(codePoint >>> 10 & 0x3FF | 0xD800)
1967
- codePoint = 0xDC00 | codePoint & 0x3FF
1968
- }
1969
-
1970
- res.push(codePoint)
1971
- i += bytesPerSequence
1972
- }
1973
-
1974
- return decodeCodePointsArray(res)
1975
- }
1976
-
1977
- // Based on http://stackoverflow.com/a/22747272/680742, the browser with
1978
- // the lowest limit is Chrome, with 0x10000 args.
1979
- // We go 1 magnitude less, for safety
1980
- var MAX_ARGUMENTS_LENGTH = 0x1000
1981
-
1982
- function decodeCodePointsArray (codePoints) {
1983
- var len = codePoints.length
1984
- if (len <= MAX_ARGUMENTS_LENGTH) {
1985
- return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
1986
- }
1987
-
1988
- // Decode in chunks to avoid "call stack size exceeded".
1989
- var res = ''
1990
- var i = 0
1991
- while (i < len) {
1992
- res += String.fromCharCode.apply(
1993
- String,
1994
- codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
1995
- )
1996
- }
1997
- return res
1998
- }
1999
-
2000
- function asciiSlice (buf, start, end) {
2001
- var ret = ''
2002
- end = Math.min(buf.length, end)
2003
-
2004
- for (var i = start; i < end; ++i) {
2005
- ret += String.fromCharCode(buf[i] & 0x7F)
2006
- }
2007
- return ret
2008
- }
2009
-
2010
- function latin1Slice (buf, start, end) {
2011
- var ret = ''
2012
- end = Math.min(buf.length, end)
2013
-
2014
- for (var i = start; i < end; ++i) {
2015
- ret += String.fromCharCode(buf[i])
2016
- }
2017
- return ret
2018
- }
2019
-
2020
- function hexSlice (buf, start, end) {
2021
- var len = buf.length
2022
-
2023
- if (!start || start < 0) start = 0
2024
- if (!end || end < 0 || end > len) end = len
2025
-
2026
- var out = ''
2027
- for (var i = start; i < end; ++i) {
2028
- out += toHex(buf[i])
2029
- }
2030
- return out
2031
- }
2032
-
2033
- function utf16leSlice (buf, start, end) {
2034
- var bytes = buf.slice(start, end)
2035
- var res = ''
2036
- for (var i = 0; i < bytes.length; i += 2) {
2037
- res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
2038
- }
2039
- return res
2040
- }
2041
-
2042
- Buffer.prototype.slice = function slice (start, end) {
2043
- var len = this.length
2044
- start = ~~start
2045
- end = end === undefined ? len : ~~end
2046
-
2047
- if (start < 0) {
2048
- start += len
2049
- if (start < 0) start = 0
2050
- } else if (start > len) {
2051
- start = len
2052
- }
2053
-
2054
- if (end < 0) {
2055
- end += len
2056
- if (end < 0) end = 0
2057
- } else if (end > len) {
2058
- end = len
2059
- }
2060
-
2061
- if (end < start) end = start
2062
-
2063
- var newBuf = this.subarray(start, end)
2064
- // Return an augmented `Uint8Array` instance
2065
- newBuf.__proto__ = Buffer.prototype
2066
- return newBuf
2067
- }
2068
-
2069
- /*
2070
- * Need to make sure that buffer isn't trying to write out of bounds.
2071
- */
2072
- function checkOffset (offset, ext, length) {
2073
- if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
2074
- if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
2075
- }
2076
-
2077
- Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
2078
- offset = offset >>> 0
2079
- byteLength = byteLength >>> 0
2080
- if (!noAssert) checkOffset(offset, byteLength, this.length)
2081
-
2082
- var val = this[offset]
2083
- var mul = 1
2084
- var i = 0
2085
- while (++i < byteLength && (mul *= 0x100)) {
2086
- val += this[offset + i] * mul
2087
- }
2088
-
2089
- return val
2090
- }
2091
-
2092
- Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
2093
- offset = offset >>> 0
2094
- byteLength = byteLength >>> 0
2095
- if (!noAssert) {
2096
- checkOffset(offset, byteLength, this.length)
2097
- }
2098
-
2099
- var val = this[offset + --byteLength]
2100
- var mul = 1
2101
- while (byteLength > 0 && (mul *= 0x100)) {
2102
- val += this[offset + --byteLength] * mul
2103
- }
2104
-
2105
- return val
2106
- }
2107
-
2108
- Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
2109
- offset = offset >>> 0
2110
- if (!noAssert) checkOffset(offset, 1, this.length)
2111
- return this[offset]
2112
- }
2113
-
2114
- Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
2115
- offset = offset >>> 0
2116
- if (!noAssert) checkOffset(offset, 2, this.length)
2117
- return this[offset] | (this[offset + 1] << 8)
2118
- }
2119
-
2120
- Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
2121
- offset = offset >>> 0
2122
- if (!noAssert) checkOffset(offset, 2, this.length)
2123
- return (this[offset] << 8) | this[offset + 1]
2124
- }
2125
-
2126
- Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
2127
- offset = offset >>> 0
2128
- if (!noAssert) checkOffset(offset, 4, this.length)
2129
-
2130
- return ((this[offset]) |
2131
- (this[offset + 1] << 8) |
2132
- (this[offset + 2] << 16)) +
2133
- (this[offset + 3] * 0x1000000)
2134
- }
2135
-
2136
- Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
2137
- offset = offset >>> 0
2138
- if (!noAssert) checkOffset(offset, 4, this.length)
2139
-
2140
- return (this[offset] * 0x1000000) +
2141
- ((this[offset + 1] << 16) |
2142
- (this[offset + 2] << 8) |
2143
- this[offset + 3])
2144
- }
2145
-
2146
- Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
2147
- offset = offset >>> 0
2148
- byteLength = byteLength >>> 0
2149
- if (!noAssert) checkOffset(offset, byteLength, this.length)
2150
-
2151
- var val = this[offset]
2152
- var mul = 1
2153
- var i = 0
2154
- while (++i < byteLength && (mul *= 0x100)) {
2155
- val += this[offset + i] * mul
2156
- }
2157
- mul *= 0x80
2158
-
2159
- if (val >= mul) val -= Math.pow(2, 8 * byteLength)
2160
-
2161
- return val
2162
- }
2163
-
2164
- Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
2165
- offset = offset >>> 0
2166
- byteLength = byteLength >>> 0
2167
- if (!noAssert) checkOffset(offset, byteLength, this.length)
2168
-
2169
- var i = byteLength
2170
- var mul = 1
2171
- var val = this[offset + --i]
2172
- while (i > 0 && (mul *= 0x100)) {
2173
- val += this[offset + --i] * mul
2174
- }
2175
- mul *= 0x80
2176
-
2177
- if (val >= mul) val -= Math.pow(2, 8 * byteLength)
2178
-
2179
- return val
2180
- }
2181
-
2182
- Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
2183
- offset = offset >>> 0
2184
- if (!noAssert) checkOffset(offset, 1, this.length)
2185
- if (!(this[offset] & 0x80)) return (this[offset])
2186
- return ((0xff - this[offset] + 1) * -1)
2187
- }
2188
-
2189
- Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
2190
- offset = offset >>> 0
2191
- if (!noAssert) checkOffset(offset, 2, this.length)
2192
- var val = this[offset] | (this[offset + 1] << 8)
2193
- return (val & 0x8000) ? val | 0xFFFF0000 : val
2194
- }
2195
-
2196
- Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
2197
- offset = offset >>> 0
2198
- if (!noAssert) checkOffset(offset, 2, this.length)
2199
- var val = this[offset + 1] | (this[offset] << 8)
2200
- return (val & 0x8000) ? val | 0xFFFF0000 : val
2201
- }
2202
-
2203
- Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
2204
- offset = offset >>> 0
2205
- if (!noAssert) checkOffset(offset, 4, this.length)
2206
-
2207
- return (this[offset]) |
2208
- (this[offset + 1] << 8) |
2209
- (this[offset + 2] << 16) |
2210
- (this[offset + 3] << 24)
2211
- }
2212
-
2213
- Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
2214
- offset = offset >>> 0
2215
- if (!noAssert) checkOffset(offset, 4, this.length)
2216
-
2217
- return (this[offset] << 24) |
2218
- (this[offset + 1] << 16) |
2219
- (this[offset + 2] << 8) |
2220
- (this[offset + 3])
2221
- }
2222
-
2223
- Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
2224
- offset = offset >>> 0
2225
- if (!noAssert) checkOffset(offset, 4, this.length)
2226
- return ieee754.read(this, offset, true, 23, 4)
2227
- }
2228
-
2229
- Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
2230
- offset = offset >>> 0
2231
- if (!noAssert) checkOffset(offset, 4, this.length)
2232
- return ieee754.read(this, offset, false, 23, 4)
2233
- }
2234
-
2235
- Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
2236
- offset = offset >>> 0
2237
- if (!noAssert) checkOffset(offset, 8, this.length)
2238
- return ieee754.read(this, offset, true, 52, 8)
2239
- }
2240
-
2241
- Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
2242
- offset = offset >>> 0
2243
- if (!noAssert) checkOffset(offset, 8, this.length)
2244
- return ieee754.read(this, offset, false, 52, 8)
2245
- }
2246
-
2247
- function checkInt (buf, value, offset, ext, max, min) {
2248
- if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
2249
- if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
2250
- if (offset + ext > buf.length) throw new RangeError('Index out of range')
2251
- }
2252
-
2253
- Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
2254
- value = +value
2255
- offset = offset >>> 0
2256
- byteLength = byteLength >>> 0
2257
- if (!noAssert) {
2258
- var maxBytes = Math.pow(2, 8 * byteLength) - 1
2259
- checkInt(this, value, offset, byteLength, maxBytes, 0)
2260
- }
2261
-
2262
- var mul = 1
2263
- var i = 0
2264
- this[offset] = value & 0xFF
2265
- while (++i < byteLength && (mul *= 0x100)) {
2266
- this[offset + i] = (value / mul) & 0xFF
2267
- }
2268
-
2269
- return offset + byteLength
2270
- }
2271
-
2272
- Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
2273
- value = +value
2274
- offset = offset >>> 0
2275
- byteLength = byteLength >>> 0
2276
- if (!noAssert) {
2277
- var maxBytes = Math.pow(2, 8 * byteLength) - 1
2278
- checkInt(this, value, offset, byteLength, maxBytes, 0)
2279
- }
2280
-
2281
- var i = byteLength - 1
2282
- var mul = 1
2283
- this[offset + i] = value & 0xFF
2284
- while (--i >= 0 && (mul *= 0x100)) {
2285
- this[offset + i] = (value / mul) & 0xFF
2286
- }
2287
-
2288
- return offset + byteLength
2289
- }
2290
-
2291
- Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
2292
- value = +value
2293
- offset = offset >>> 0
2294
- if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
2295
- this[offset] = (value & 0xff)
2296
- return offset + 1
2297
- }
2298
-
2299
- Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
2300
- value = +value
2301
- offset = offset >>> 0
2302
- if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
2303
- this[offset] = (value & 0xff)
2304
- this[offset + 1] = (value >>> 8)
2305
- return offset + 2
2306
- }
2307
-
2308
- Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
2309
- value = +value
2310
- offset = offset >>> 0
2311
- if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
2312
- this[offset] = (value >>> 8)
2313
- this[offset + 1] = (value & 0xff)
2314
- return offset + 2
2315
- }
2316
-
2317
- Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
2318
- value = +value
2319
- offset = offset >>> 0
2320
- if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
2321
- this[offset + 3] = (value >>> 24)
2322
- this[offset + 2] = (value >>> 16)
2323
- this[offset + 1] = (value >>> 8)
2324
- this[offset] = (value & 0xff)
2325
- return offset + 4
2326
- }
2327
-
2328
- Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
2329
- value = +value
2330
- offset = offset >>> 0
2331
- if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
2332
- this[offset] = (value >>> 24)
2333
- this[offset + 1] = (value >>> 16)
2334
- this[offset + 2] = (value >>> 8)
2335
- this[offset + 3] = (value & 0xff)
2336
- return offset + 4
2337
- }
2338
-
2339
- Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
2340
- value = +value
2341
- offset = offset >>> 0
2342
- if (!noAssert) {
2343
- var limit = Math.pow(2, (8 * byteLength) - 1)
2344
-
2345
- checkInt(this, value, offset, byteLength, limit - 1, -limit)
2346
- }
2347
-
2348
- var i = 0
2349
- var mul = 1
2350
- var sub = 0
2351
- this[offset] = value & 0xFF
2352
- while (++i < byteLength && (mul *= 0x100)) {
2353
- if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
2354
- sub = 1
2355
- }
2356
- this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
2357
- }
2358
-
2359
- return offset + byteLength
2360
- }
2361
-
2362
- Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
2363
- value = +value
2364
- offset = offset >>> 0
2365
- if (!noAssert) {
2366
- var limit = Math.pow(2, (8 * byteLength) - 1)
2367
-
2368
- checkInt(this, value, offset, byteLength, limit - 1, -limit)
2369
- }
2370
-
2371
- var i = byteLength - 1
2372
- var mul = 1
2373
- var sub = 0
2374
- this[offset + i] = value & 0xFF
2375
- while (--i >= 0 && (mul *= 0x100)) {
2376
- if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
2377
- sub = 1
2378
- }
2379
- this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
2380
- }
2381
-
2382
- return offset + byteLength
2383
- }
2384
-
2385
- Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
2386
- value = +value
2387
- offset = offset >>> 0
2388
- if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
2389
- if (value < 0) value = 0xff + value + 1
2390
- this[offset] = (value & 0xff)
2391
- return offset + 1
2392
- }
2393
-
2394
- Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
2395
- value = +value
2396
- offset = offset >>> 0
2397
- if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
2398
- this[offset] = (value & 0xff)
2399
- this[offset + 1] = (value >>> 8)
2400
- return offset + 2
2401
- }
2402
-
2403
- Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
2404
- value = +value
2405
- offset = offset >>> 0
2406
- if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
2407
- this[offset] = (value >>> 8)
2408
- this[offset + 1] = (value & 0xff)
2409
- return offset + 2
2410
- }
2411
-
2412
- Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
2413
- value = +value
2414
- offset = offset >>> 0
2415
- if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
2416
- this[offset] = (value & 0xff)
2417
- this[offset + 1] = (value >>> 8)
2418
- this[offset + 2] = (value >>> 16)
2419
- this[offset + 3] = (value >>> 24)
2420
- return offset + 4
2421
- }
2422
-
2423
- Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
2424
- value = +value
2425
- offset = offset >>> 0
2426
- if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
2427
- if (value < 0) value = 0xffffffff + value + 1
2428
- this[offset] = (value >>> 24)
2429
- this[offset + 1] = (value >>> 16)
2430
- this[offset + 2] = (value >>> 8)
2431
- this[offset + 3] = (value & 0xff)
2432
- return offset + 4
2433
- }
2434
-
2435
- function checkIEEE754 (buf, value, offset, ext, max, min) {
2436
- if (offset + ext > buf.length) throw new RangeError('Index out of range')
2437
- if (offset < 0) throw new RangeError('Index out of range')
2438
- }
2439
-
2440
- function writeFloat (buf, value, offset, littleEndian, noAssert) {
2441
- value = +value
2442
- offset = offset >>> 0
2443
- if (!noAssert) {
2444
- checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
2445
- }
2446
- ieee754.write(buf, value, offset, littleEndian, 23, 4)
2447
- return offset + 4
2448
- }
2449
-
2450
- Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
2451
- return writeFloat(this, value, offset, true, noAssert)
2452
- }
2453
-
2454
- Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
2455
- return writeFloat(this, value, offset, false, noAssert)
2456
- }
2457
-
2458
- function writeDouble (buf, value, offset, littleEndian, noAssert) {
2459
- value = +value
2460
- offset = offset >>> 0
2461
- if (!noAssert) {
2462
- checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
2463
- }
2464
- ieee754.write(buf, value, offset, littleEndian, 52, 8)
2465
- return offset + 8
2466
- }
2467
-
2468
- Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
2469
- return writeDouble(this, value, offset, true, noAssert)
2470
- }
2471
-
2472
- Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
2473
- return writeDouble(this, value, offset, false, noAssert)
2474
- }
2475
-
2476
- // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
2477
- Buffer.prototype.copy = function copy (target, targetStart, start, end) {
2478
- if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
2479
- if (!start) start = 0
2480
- if (!end && end !== 0) end = this.length
2481
- if (targetStart >= target.length) targetStart = target.length
2482
- if (!targetStart) targetStart = 0
2483
- if (end > 0 && end < start) end = start
2484
-
2485
- // Copy 0 bytes; we're done
2486
- if (end === start) return 0
2487
- if (target.length === 0 || this.length === 0) return 0
2488
-
2489
- // Fatal error conditions
2490
- if (targetStart < 0) {
2491
- throw new RangeError('targetStart out of bounds')
2492
- }
2493
- if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
2494
- if (end < 0) throw new RangeError('sourceEnd out of bounds')
2495
-
2496
- // Are we oob?
2497
- if (end > this.length) end = this.length
2498
- if (target.length - targetStart < end - start) {
2499
- end = target.length - targetStart + start
2500
- }
2501
-
2502
- var len = end - start
2503
-
2504
- if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
2505
- // Use built-in when available, missing from IE11
2506
- this.copyWithin(targetStart, start, end)
2507
- } else if (this === target && start < targetStart && targetStart < end) {
2508
- // descending copy from end
2509
- for (var i = len - 1; i >= 0; --i) {
2510
- target[i + targetStart] = this[i + start]
2511
- }
2512
- } else {
2513
- Uint8Array.prototype.set.call(
2514
- target,
2515
- this.subarray(start, end),
2516
- targetStart
2517
- )
2518
- }
2519
-
2520
- return len
2521
- }
2522
-
2523
- // Usage:
2524
- // buffer.fill(number[, offset[, end]])
2525
- // buffer.fill(buffer[, offset[, end]])
2526
- // buffer.fill(string[, offset[, end]][, encoding])
2527
- Buffer.prototype.fill = function fill (val, start, end, encoding) {
2528
- // Handle string cases:
2529
- if (typeof val === 'string') {
2530
- if (typeof start === 'string') {
2531
- encoding = start
2532
- start = 0
2533
- end = this.length
2534
- } else if (typeof end === 'string') {
2535
- encoding = end
2536
- end = this.length
2537
- }
2538
- if (encoding !== undefined && typeof encoding !== 'string') {
2539
- throw new TypeError('encoding must be a string')
2540
- }
2541
- if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
2542
- throw new TypeError('Unknown encoding: ' + encoding)
2543
- }
2544
- if (val.length === 1) {
2545
- var code = val.charCodeAt(0)
2546
- if ((encoding === 'utf8' && code < 128) ||
2547
- encoding === 'latin1') {
2548
- // Fast path: If `val` fits into a single byte, use that numeric value.
2549
- val = code
2550
- }
2551
- }
2552
- } else if (typeof val === 'number') {
2553
- val = val & 255
2554
- }
2555
-
2556
- // Invalid ranges are not set to a default, so can range check early.
2557
- if (start < 0 || this.length < start || this.length < end) {
2558
- throw new RangeError('Out of range index')
2559
- }
2560
-
2561
- if (end <= start) {
2562
- return this
2563
- }
2564
-
2565
- start = start >>> 0
2566
- end = end === undefined ? this.length : end >>> 0
2567
-
2568
- if (!val) val = 0
2569
-
2570
- var i
2571
- if (typeof val === 'number') {
2572
- for (i = start; i < end; ++i) {
2573
- this[i] = val
2574
- }
2575
- } else {
2576
- var bytes = Buffer.isBuffer(val)
2577
- ? val
2578
- : new Buffer(val, encoding)
2579
- var len = bytes.length
2580
- if (len === 0) {
2581
- throw new TypeError('The value "' + val +
2582
- '" is invalid for argument "value"')
2583
- }
2584
- for (i = 0; i < end - start; ++i) {
2585
- this[i + start] = bytes[i % len]
2586
- }
2587
- }
2588
-
2589
- return this
2590
- }
2591
-
2592
- // HELPER FUNCTIONS
2593
- // ================
2594
-
2595
- var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
2596
-
2597
- function base64clean (str) {
2598
- // Node takes equal signs as end of the Base64 encoding
2599
- str = str.split('=')[0]
2600
- // Node strips out invalid characters like \n and \t from the string, base64-js does not
2601
- str = str.trim().replace(INVALID_BASE64_RE, '')
2602
- // Node converts strings with length < 2 to ''
2603
- if (str.length < 2) return ''
2604
- // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
2605
- while (str.length % 4 !== 0) {
2606
- str = str + '='
2607
- }
2608
- return str
2609
- }
2610
-
2611
- function toHex (n) {
2612
- if (n < 16) return '0' + n.toString(16)
2613
- return n.toString(16)
2614
- }
2615
-
2616
- function utf8ToBytes (string, units) {
2617
- units = units || Infinity
2618
- var codePoint
2619
- var length = string.length
2620
- var leadSurrogate = null
2621
- var bytes = []
2622
-
2623
- for (var i = 0; i < length; ++i) {
2624
- codePoint = string.charCodeAt(i)
2625
-
2626
- // is surrogate component
2627
- if (codePoint > 0xD7FF && codePoint < 0xE000) {
2628
- // last char was a lead
2629
- if (!leadSurrogate) {
2630
- // no lead yet
2631
- if (codePoint > 0xDBFF) {
2632
- // unexpected trail
2633
- if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
2634
- continue
2635
- } else if (i + 1 === length) {
2636
- // unpaired lead
2637
- if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
2638
- continue
2639
- }
2640
-
2641
- // valid lead
2642
- leadSurrogate = codePoint
2643
-
2644
- continue
2645
- }
2646
-
2647
- // 2 leads in a row
2648
- if (codePoint < 0xDC00) {
2649
- if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
2650
- leadSurrogate = codePoint
2651
- continue
2652
- }
2653
-
2654
- // valid surrogate pair
2655
- codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
2656
- } else if (leadSurrogate) {
2657
- // valid bmp char, but last char was a lead
2658
- if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
2659
- }
2660
-
2661
- leadSurrogate = null
2662
-
2663
- // encode utf8
2664
- if (codePoint < 0x80) {
2665
- if ((units -= 1) < 0) break
2666
- bytes.push(codePoint)
2667
- } else if (codePoint < 0x800) {
2668
- if ((units -= 2) < 0) break
2669
- bytes.push(
2670
- codePoint >> 0x6 | 0xC0,
2671
- codePoint & 0x3F | 0x80
2672
- )
2673
- } else if (codePoint < 0x10000) {
2674
- if ((units -= 3) < 0) break
2675
- bytes.push(
2676
- codePoint >> 0xC | 0xE0,
2677
- codePoint >> 0x6 & 0x3F | 0x80,
2678
- codePoint & 0x3F | 0x80
2679
- )
2680
- } else if (codePoint < 0x110000) {
2681
- if ((units -= 4) < 0) break
2682
- bytes.push(
2683
- codePoint >> 0x12 | 0xF0,
2684
- codePoint >> 0xC & 0x3F | 0x80,
2685
- codePoint >> 0x6 & 0x3F | 0x80,
2686
- codePoint & 0x3F | 0x80
2687
- )
2688
- } else {
2689
- throw new Error('Invalid code point')
2690
- }
2691
- }
2692
-
2693
- return bytes
2694
- }
2695
-
2696
- function asciiToBytes (str) {
2697
- var byteArray = []
2698
- for (var i = 0; i < str.length; ++i) {
2699
- // Node's code seems to be doing this and not & 0x7F..
2700
- byteArray.push(str.charCodeAt(i) & 0xFF)
2701
- }
2702
- return byteArray
2703
- }
2704
-
2705
- function utf16leToBytes (str, units) {
2706
- var c, hi, lo
2707
- var byteArray = []
2708
- for (var i = 0; i < str.length; ++i) {
2709
- if ((units -= 2) < 0) break
2710
-
2711
- c = str.charCodeAt(i)
2712
- hi = c >> 8
2713
- lo = c % 256
2714
- byteArray.push(lo)
2715
- byteArray.push(hi)
2716
- }
2717
-
2718
- return byteArray
2719
- }
2720
-
2721
- function base64ToBytes (str) {
2722
- return base64.toByteArray(base64clean(str))
2723
- }
2724
-
2725
- function blitBuffer (src, dst, offset, length) {
2726
- for (var i = 0; i < length; ++i) {
2727
- if ((i + offset >= dst.length) || (i >= src.length)) break
2728
- dst[i + offset] = src[i]
2729
- }
2730
- return i
2731
- }
2732
-
2733
- // ArrayBuffers from another context (i.e. an iframe) do not pass the `instanceof` check
2734
- // but they should be treated as valid. See: https://github.com/feross/buffer/issues/166
2735
- function isArrayBuffer (obj) {
2736
- return obj instanceof ArrayBuffer ||
2737
- (obj != null && obj.constructor != null && obj.constructor.name === 'ArrayBuffer' &&
2738
- typeof obj.byteLength === 'number')
2739
- }
2740
-
2741
- function numberIsNaN (obj) {
2742
- return obj !== obj // eslint-disable-line no-self-compare
2743
- }
2744
-
2745
- },{"base64-js":2,"ieee754":4}],4:[function(require,module,exports){
2746
- exports.read = function (buffer, offset, isLE, mLen, nBytes) {
2747
- var e, m
2748
- var eLen = (nBytes * 8) - mLen - 1
2749
- var eMax = (1 << eLen) - 1
2750
- var eBias = eMax >> 1
2751
- var nBits = -7
2752
- var i = isLE ? (nBytes - 1) : 0
2753
- var d = isLE ? -1 : 1
2754
- var s = buffer[offset + i]
2755
-
2756
- i += d
2757
-
2758
- e = s & ((1 << (-nBits)) - 1)
2759
- s >>= (-nBits)
2760
- nBits += eLen
2761
- for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
2762
-
2763
- m = e & ((1 << (-nBits)) - 1)
2764
- e >>= (-nBits)
2765
- nBits += mLen
2766
- for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
2767
-
2768
- if (e === 0) {
2769
- e = 1 - eBias
2770
- } else if (e === eMax) {
2771
- return m ? NaN : ((s ? -1 : 1) * Infinity)
2772
- } else {
2773
- m = m + Math.pow(2, mLen)
2774
- e = e - eBias
2775
- }
2776
- return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
2777
- }
2778
-
2779
- exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
2780
- var e, m, c
2781
- var eLen = (nBytes * 8) - mLen - 1
2782
- var eMax = (1 << eLen) - 1
2783
- var eBias = eMax >> 1
2784
- var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
2785
- var i = isLE ? 0 : (nBytes - 1)
2786
- var d = isLE ? 1 : -1
2787
- var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
2788
-
2789
- value = Math.abs(value)
2790
-
2791
- if (isNaN(value) || value === Infinity) {
2792
- m = isNaN(value) ? 1 : 0
2793
- e = eMax
2794
- } else {
2795
- e = Math.floor(Math.log(value) / Math.LN2)
2796
- if (value * (c = Math.pow(2, -e)) < 1) {
2797
- e--
2798
- c *= 2
2799
- }
2800
- if (e + eBias >= 1) {
2801
- value += rt / c
2802
- } else {
2803
- value += rt * Math.pow(2, 1 - eBias)
2804
- }
2805
- if (value * c >= 2) {
2806
- e++
2807
- c /= 2
2808
- }
2809
-
2810
- if (e + eBias >= eMax) {
2811
- m = 0
2812
- e = eMax
2813
- } else if (e + eBias >= 1) {
2814
- m = ((value * c) - 1) * Math.pow(2, mLen)
2815
- e = e + eBias
2816
- } else {
2817
- m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
2818
- e = 0
2819
- }
2820
- }
2821
-
2822
- for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
2823
-
2824
- e = (e << mLen) | m
2825
- eLen += mLen
2826
- for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
2827
-
2828
- buffer[offset + i - d] |= s * 128
2829
- }
2830
-
2831
- },{}],5:[function(require,module,exports){
2832
- // shim for using process in browser
2833
- var process = module.exports = {};
2834
-
2835
- // cached from whatever global is present so that test runners that stub it
2836
- // don't break things. But we need to wrap it in a try catch in case it is
2837
- // wrapped in strict mode code which doesn't define any globals. It's inside a
2838
- // function because try/catches deoptimize in certain engines.
2839
-
2840
- var cachedSetTimeout;
2841
- var cachedClearTimeout;
2842
-
2843
- function defaultSetTimout() {
2844
- throw new Error('setTimeout has not been defined');
2845
- }
2846
- function defaultClearTimeout () {
2847
- throw new Error('clearTimeout has not been defined');
2848
- }
2849
- (function () {
2850
- try {
2851
- if (typeof setTimeout === 'function') {
2852
- cachedSetTimeout = setTimeout;
2853
- } else {
2854
- cachedSetTimeout = defaultSetTimout;
2855
- }
2856
- } catch (e) {
2857
- cachedSetTimeout = defaultSetTimout;
2858
- }
2859
- try {
2860
- if (typeof clearTimeout === 'function') {
2861
- cachedClearTimeout = clearTimeout;
2862
- } else {
2863
- cachedClearTimeout = defaultClearTimeout;
2864
- }
2865
- } catch (e) {
2866
- cachedClearTimeout = defaultClearTimeout;
2867
- }
2868
- } ())
2869
- function runTimeout(fun) {
2870
- if (cachedSetTimeout === setTimeout) {
2871
- //normal enviroments in sane situations
2872
- return setTimeout(fun, 0);
2873
- }
2874
- // if setTimeout wasn't available but was latter defined
2875
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
2876
- cachedSetTimeout = setTimeout;
2877
- return setTimeout(fun, 0);
2878
- }
2879
- try {
2880
- // when when somebody has screwed with setTimeout but no I.E. maddness
2881
- return cachedSetTimeout(fun, 0);
2882
- } catch(e){
2883
- try {
2884
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
2885
- return cachedSetTimeout.call(null, fun, 0);
2886
- } catch(e){
2887
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
2888
- return cachedSetTimeout.call(this, fun, 0);
2889
- }
2890
- }
2891
-
2892
-
2893
- }
2894
- function runClearTimeout(marker) {
2895
- if (cachedClearTimeout === clearTimeout) {
2896
- //normal enviroments in sane situations
2897
- return clearTimeout(marker);
2898
- }
2899
- // if clearTimeout wasn't available but was latter defined
2900
- if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
2901
- cachedClearTimeout = clearTimeout;
2902
- return clearTimeout(marker);
2903
- }
2904
- try {
2905
- // when when somebody has screwed with setTimeout but no I.E. maddness
2906
- return cachedClearTimeout(marker);
2907
- } catch (e){
2908
- try {
2909
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
2910
- return cachedClearTimeout.call(null, marker);
2911
- } catch (e){
2912
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
2913
- // Some versions of I.E. have different rules for clearTimeout vs setTimeout
2914
- return cachedClearTimeout.call(this, marker);
2915
- }
2916
- }
2917
-
2918
-
2919
-
2920
- }
2921
- var queue = [];
2922
- var draining = false;
2923
- var currentQueue;
2924
- var queueIndex = -1;
2925
-
2926
- function cleanUpNextTick() {
2927
- if (!draining || !currentQueue) {
2928
- return;
2929
- }
2930
- draining = false;
2931
- if (currentQueue.length) {
2932
- queue = currentQueue.concat(queue);
2933
- } else {
2934
- queueIndex = -1;
2935
- }
2936
- if (queue.length) {
2937
- drainQueue();
2938
- }
2939
- }
2940
-
2941
- function drainQueue() {
2942
- if (draining) {
2943
- return;
2944
- }
2945
- var timeout = runTimeout(cleanUpNextTick);
2946
- draining = true;
2947
-
2948
- var len = queue.length;
2949
- while(len) {
2950
- currentQueue = queue;
2951
- queue = [];
2952
- while (++queueIndex < len) {
2953
- if (currentQueue) {
2954
- currentQueue[queueIndex].run();
2955
- }
2956
- }
2957
- queueIndex = -1;
2958
- len = queue.length;
2959
- }
2960
- currentQueue = null;
2961
- draining = false;
2962
- runClearTimeout(timeout);
2963
- }
2964
-
2965
- process.nextTick = function (fun) {
2966
- var args = new Array(arguments.length - 1);
2967
- if (arguments.length > 1) {
2968
- for (var i = 1; i < arguments.length; i++) {
2969
- args[i - 1] = arguments[i];
2970
- }
2971
- }
2972
- queue.push(new Item(fun, args));
2973
- if (queue.length === 1 && !draining) {
2974
- runTimeout(drainQueue);
2975
- }
2976
- };
2977
-
2978
- // v8 likes predictible objects
2979
- function Item(fun, array) {
2980
- this.fun = fun;
2981
- this.array = array;
2982
- }
2983
- Item.prototype.run = function () {
2984
- this.fun.apply(null, this.array);
2985
- };
2986
- process.title = 'browser';
2987
- process.browser = true;
2988
- process.env = {};
2989
- process.argv = [];
2990
- process.version = ''; // empty string to avoid regexp issues
2991
- process.versions = {};
2992
-
2993
- function noop() {}
2994
-
2995
- process.on = noop;
2996
- process.addListener = noop;
2997
- process.once = noop;
2998
- process.off = noop;
2999
- process.removeListener = noop;
3000
- process.removeAllListeners = noop;
3001
- process.emit = noop;
3002
- process.prependListener = noop;
3003
- process.prependOnceListener = noop;
3004
-
3005
- process.listeners = function (name) { return [] }
3006
-
3007
- process.binding = function (name) {
3008
- throw new Error('process.binding is not supported');
3009
- };
3010
-
3011
- process.cwd = function () { return '/' };
3012
- process.chdir = function (dir) {
3013
- throw new Error('process.chdir is not supported');
3014
- };
3015
- process.umask = function() { return 0; };
3016
-
3017
- },{}]},{},[1])(1)
3018
- });
3019
-
3020
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvYXBpL21ldGFkYXRhLmpzIiwibm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaDFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeHNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8qZ2xvYmFsIHByb2Nlc3MsIEJ1ZmZlciAqL1xuLyoqXG4gKiBAZmlsZSBNYW5hZ2VzIFNhbGVzZm9yY2UgTWV0YWRhdGEgQVBJXG4gKiBAYXV0aG9yIFNoaW5pY2hpIFRvbWl0YSA8c2hpbmljaGkudG9taXRhQGdtYWlsLmNvbT5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBpbmhlcml0cyA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJ2luaGVyaXRzJyksXG4gICAgZXZlbnRzICA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJ2V2ZW50cycpLFxuICAgIHN0cmVhbSAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0nKSxcbiAgICBfICAgICAgID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnbG9kYXNoL2NvcmUnKSxcbiAgICBqc2ZvcmNlID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnLi9jb3JlJyksXG4gICAgUHJvbWlzZSA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJy4vcHJvbWlzZScpLFxuICAgIFNPQVAgICAgPSB3aW5kb3cuanNmb3JjZS5yZXF1aXJlKCcuL3NvYXAnKTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKipcbiAqIENsYXNzIGZvciBTYWxlc2ZvcmNlIE1ldGFkYXRhIEFQSVxuICpcbiAqIEBjbGFzc1xuICogQHBhcmFtIHtDb25uZWN0aW9ufSBjb25uIC0gQ29ubmVjdGlvbiBvYmplY3RcbiAqL1xudmFyIE1ldGFkYXRhID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihjb25uKSB7XG4gIHRoaXMuX2Nvbm4gPSBjb25uO1xufTtcblxuXG4vKipcbiAqIFBvbGxpbmcgaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzXG4gKiBAdHlwZSB7TnVtYmVyfVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUucG9sbEludGVydmFsID0gMTAwMDtcblxuLyoqXG4gKiBQb2xsaW5nIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKiBAdHlwZSB7TnVtYmVyfVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUucG9sbFRpbWVvdXQgPSAxMDAwMDtcblxuXG4vKipcbiAqIENhbGwgTWV0YWRhdGEgQVBJIFNPQVAgZW5kcG9pbnRcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUuX2ludm9rZSA9IGZ1bmN0aW9uKG1ldGhvZCwgbWVzc2FnZSwgY2FsbGJhY2spIHtcbiAgdmFyIHNvYXBFbmRwb2ludCA9IG5ldyBTT0FQKHRoaXMuX2Nvbm4sIHtcbiAgICB4bWxuczogXCJodHRwOi8vc29hcC5zZm9yY2UuY29tLzIwMDYvMDQvbWV0YWRhdGFcIixcbiAgICBlbmRwb2ludFVybDogdGhpcy5fY29ubi5pbnN0YW5jZVVybCArIFwiL3NlcnZpY2VzL1NvYXAvbS9cIiArIHRoaXMuX2Nvbm4udmVyc2lvblxuICB9KTtcbiAgcmV0dXJuIHNvYXBFbmRwb2ludC5pbnZva2UobWV0aG9kLCBtZXNzYWdlKS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgIHJldHVybiByZXMucmVzdWx0O1xuICB9KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTWV0YWRhdGF+TWV0YWRhdGFJbmZvXG4gKiBAcHJvcCB7U3RyaW5nfSBmdWxsTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBjb21wb25lbnRcbiAqL1xuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IGFkZHMgb25lIG9yIG1vcmUgbmV3IG1ldGFkYXRhIGNvbXBvbmVudHMgdG8gdGhlIG9yZ2FuaXphdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIG1ldGFkYXRhIHRvIGNyZWF0ZVxuICogQHBhcmFtIHtNZXRhZGF0YX5NZXRhZGF0YUluZm98QXJyYXkuPE1ldGFkYXRhfk1ldGFkYXRhSW5mbz59IG1ldGFkYXRhIC0gTWV0YWRhdGEgdG8gY3JlYXRlXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxNZXRhZGF0YX5Bc3luY1Jlc3VsdHxBcnJheS48TWV0YWRhdGF+QXN5bmNSZXN1bHQ+Pn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7TWV0YWRhdGF+QXN5bmNSZXN1bHRMb2NhdG9yfVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUuY3JlYXRlQXN5bmMgPSBmdW5jdGlvbih0eXBlLCBtZXRhZGF0YSwgY2FsbGJhY2spIHtcbiAgaWYgKE51bWJlcih0aGlzLl9jb25uLnZlcnNpb24pID4gMzApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJBc3luYyBtZXRhZGF0YSBDUlVEIGNhbGxzIGFyZSBub3Qgc3VwcG9ydGVkIG9uIHZlciAzMS4wIG9yIGxhdGVyLlwiKTtcbiAgfVxuICB2YXIgY29udmVydCA9IGZ1bmN0aW9uKG1kKSB7XG4gICAgbWRbXCJAeHNpOnR5cGVcIl0gPSB0eXBlO1xuICAgIHJldHVybiBtZDtcbiAgfTtcbiAgdmFyIGlzQXJyYXkgPSBfLmlzQXJyYXkobWV0YWRhdGEpO1xuICBtZXRhZGF0YSA9IGlzQXJyYXkgPyBfLm1hcChtZXRhZGF0YSwgY29udmVydCkgOiBjb252ZXJ0KG1ldGFkYXRhKTtcbiAgdmFyIHJlcyA9IHRoaXMuX2ludm9rZShcImNyZWF0ZVwiLCB7IG1ldGFkYXRhOiBtZXRhZGF0YSB9KTtcbiAgcmV0dXJuIG5ldyBBc3luY1Jlc3VsdExvY2F0b3IodGhpcywgcmVzLCBpc0FycmF5KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1ldGFkYXRhflNhdmVSZXN1bHRcbiAqIEBwcm9wIHtCb29sZWFufSBzdWNjZXNzIC0gVHJ1ZSBpZiBtZXRhZGF0YSBpcyBzdWNjZXNzZnVsbHkgc2F2ZWRcbiAqIEBwcm9wIHtTdHJpbmd9IGZ1bGxOYW1lIC0gRnVsbCBuYW1lIG9mIG1ldGFkYXRhIG9iamVjdFxuICovXG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY29udmVydFRvU2F2ZVJlc3VsdChyZXN1bHQpIHtcbiAgdmFyIHNhdmVSZXN1bHQgPSBfLmNsb25lKHJlc3VsdCk7XG4gIHNhdmVSZXN1bHQuc3VjY2VzcyA9IHNhdmVSZXN1bHQuc3VjY2VzcyA9PT0gJ3RydWUnO1xuICByZXR1cm4gc2F2ZVJlc3VsdDtcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZXRhZGF0YX5VcHNlcnRSZXN1bHRcbiAqIEBwcm9wIHtCb29sZWFufSBzdWNjZXNzIC0gVHJ1ZSBpZiBtZXRhZGF0YSBpcyBzdWNjZXNzZnVsbHkgc2F2ZWRcbiAqIEBwcm9wIHtTdHJpbmd9IGZ1bGxOYW1lIC0gRnVsbCBuYW1lIG9mIG1ldGFkYXRhIG9iamVjdFxuICogQHByb3Age0Jvb2xlYW59IGNyZWF0ZWQgLSBUcnVlIGlmIG1ldGFkYXRhIGlzIG5ld2x5IGNyZWF0ZWRcbiAqL1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRUb1Vwc2VydFJlc3VsdChyZXN1bHQpIHtcbiAgdmFyIHVwc2VydFJlc3VsdCA9IGNvbnZlcnRUb1NhdmVSZXN1bHQocmVzdWx0KTtcbiAgdXBzZXJ0UmVzdWx0LmNyZWF0ZWQgPSB1cHNlcnRSZXN1bHQuY3JlYXRlZCA9PT0gJ3RydWUnO1xuICByZXR1cm4gdXBzZXJ0UmVzdWx0O1xufVxuXG4vKipcbiAqIFN5bm9ueW0gb2YgTWV0YWRhdGEjY3JlYXRlKCkuXG4gKlxuICogQG1ldGhvZCBNZXRhZGF0YSNjcmVhdGVTeW5jXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIG1ldGFkYXRhIHRvIGNyZWF0ZVxuICogQHBhcmFtIHtNZXRhZGF0YX5NZXRhZGF0YUluZm98QXJyYXkuPE1ldGFkYXRhfk1ldGFkYXRhSW5mbz59IG1ldGFkYXRhIC0gTWV0YWRhdGEgdG8gY3JlYXRlXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxNZXRhZGF0YX5TYXZlUmVzdWx0fEFycmF5LjxNZXRhZGF0YX5TYXZlUmVzdWx0Pj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPE1ldGFkYXRhflNhdmVSZXN1bHR8QXJyYXkuPE1ldGFkYXRhflNhdmVSZXN1bHQ+Pn1cbiAqL1xuLyoqXG4gKiBTeW5jaHJvbm91c2x5IGFkZHMgb25lIG9yIG1vcmUgbmV3IG1ldGFkYXRhIGNvbXBvbmVudHMgdG8gdGhlIG9yZ2FuaXphdGlvbi5cbiAqXG4gKiBAbWV0aG9kIE1ldGFkYXRhI2NyZWF0ZVxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBtZXRhZGF0YSB0byBjcmVhdGVcbiAqIEBwYXJhbSB7TWV0YWRhdGF+TWV0YWRhdGFJbmZvfEFycmF5LjxNZXRhZGF0YX5NZXRhZGF0YUluZm8+fSBtZXRhZGF0YSAtIE1ldGFkYXRhIHRvIGNyZWF0ZVxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+U2F2ZVJlc3VsdHxBcnJheS48TWV0YWRhdGF+U2F2ZVJlc3VsdD4+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtQcm9taXNlLjxNZXRhZGF0YX5TYXZlUmVzdWx0fEFycmF5LjxNZXRhZGF0YX5TYXZlUmVzdWx0Pj59XG4gKi9cbk1ldGFkYXRhLnByb3RvdHlwZS5jcmVhdGVTeW5jID1cbk1ldGFkYXRhLnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbih0eXBlLCBtZXRhZGF0YSwgY2FsbGJhY2spIHtcbiAgdmFyIGNvbnZlcnQgPSBmdW5jdGlvbihtZCkge1xuICAgIG1kW1wiQHhzaTp0eXBlXCJdID0gdHlwZTtcbiAgICByZXR1cm4gbWQ7XG4gIH07XG4gIHZhciBpc0FycmF5ID0gXy5pc0FycmF5KG1ldGFkYXRhKTtcbiAgbWV0YWRhdGEgPSBpc0FycmF5ID8gXy5tYXAobWV0YWRhdGEsIGNvbnZlcnQpIDogY29udmVydChtZXRhZGF0YSk7XG4gIHJldHVybiB0aGlzLl9pbnZva2UoXCJjcmVhdGVNZXRhZGF0YVwiLCB7IG1ldGFkYXRhOiBtZXRhZGF0YSB9KS50aGVuKGZ1bmN0aW9uKHJlc3VsdHMpIHtcbiAgICByZXR1cm4gXy5pc0FycmF5KHJlc3VsdHMpID8gXy5tYXAocmVzdWx0cywgY29udmVydFRvU2F2ZVJlc3VsdCkgOiBjb252ZXJ0VG9TYXZlUmVzdWx0KHJlc3VsdHMpO1xuICB9KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRUb01ldGFkYXRhSW5mbyhyZWMpIHtcbiAgdmFyIG1ldGFkYXRhSW5mbyA9IF8uY2xvbmUocmVjKTtcbiAgZGVsZXRlIG1ldGFkYXRhSW5mby4kO1xuICByZXR1cm4gbWV0YWRhdGFJbmZvO1xufVxuXG4vKipcbiAqIFN5bm9ueW0gb2YgTWV0YWRhdGEjcmVhZCgpXG4gKlxuICogQG1ldGhvZCBNZXRhZGF0YSNyZWFkU3luY1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBtZXRhZGF0YSB0byByZWFkXG4gKiBAcGFyYW0ge1N0cmluZ3xBcnJheS48U3RyaW5nPn0gZnVsbE5hbWVzIC0gZnVsbCBuYW1lKHMpIG9mIG1ldGFkYXRhIG9iamVjdHMgdG8gcmVhZFxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+TWV0YWRhdGFJbmZvfEFycmF5LjxNZXRhZGF0YX5NZXRhZGF0YUluZm8+Pn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48QXJyYXkuPE1ldGFkYXRhfk1ldGFkYXRhSW5mb3xBcnJheS48TWV0YWRhdGF+TWV0YWRhdGFJbmZvPj4+fVxuICovXG4vKipcbiAqIFN5bmNocm9ub3VzbHkgcmVhZCBzcGVjaWZpZWQgbWV0YWRhdGEgY29tcG9uZW50cyBpbiB0aGUgb3JnYW5pemF0aW9uLlxuICpcbiAqIEBtZXRob2QgTWV0YWRhdGEjcmVhZFxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBtZXRhZGF0YSB0byByZWFkXG4gKiBAcGFyYW0ge1N0cmluZ3xBcnJheS48U3RyaW5nPn0gZnVsbE5hbWVzIC0gZnVsbCBuYW1lKHMpIG9mIG1ldGFkYXRhIG9iamVjdHMgdG8gcmVhZFxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+TWV0YWRhdGFJbmZvfEFycmF5LjxNZXRhZGF0YX5NZXRhZGF0YUluZm8+Pn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48QXJyYXkuPE1ldGFkYXRhfk1ldGFkYXRhSW5mb3xBcnJheS48TWV0YWRhdGF+TWV0YWRhdGFJbmZvPj4+fVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUucmVhZFN5bmMgPVxuTWV0YWRhdGEucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbih0eXBlLCBmdWxsTmFtZXMsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB0aGlzLl9pbnZva2UoXCJyZWFkTWV0YWRhdGFcIiwgeyB0eXBlOiB0eXBlLCBmdWxsTmFtZXM6IGZ1bGxOYW1lcyB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgIHJldHVybiBfLmlzQXJyYXkocmVzLnJlY29yZHMpID8gXy5tYXAocmVzLnJlY29yZHMsIGNvbnZlcnRUb01ldGFkYXRhSW5mbykgOiBjb252ZXJ0VG9NZXRhZGF0YUluZm8ocmVzLnJlY29yZHMpO1xuICB9KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1ldGFkYXRhflVwZGF0ZU1ldGFkYXRhSW5mb1xuICogQHByb3Age1N0cmluZ30gY3VycmVudE5hbWUgLSBUaGUgQVBJIG5hbWUgb2YgdGhlIGNvbXBvbmVudCBvciBmaWVsZCBiZWZvcmUgdGhlIHVwZGF0ZVxuICogQHByb3Age01ldGFkYXRhfk1ldGFkYXRhSW5mb30gbWV0YWRhdGEgLSBGdWxsIHNwZWNpZmljYXRpb24gb2YgdGhlIGNvbXBvbmVudCBvciBmaWVsZCB5b3Ugd2lzaCB0byB1cGRhdGVcbiAqL1xuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IHVwZGF0ZXMgb25lIG9yIG1vcmUgbWV0YWRhdGEgY29tcG9uZW50cyBpbiB0aGUgb3JnYW5pemF0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIC0gVGhlIHR5cGUgb2YgbWV0YWRhdGEgdG8gdXBkYXRlXG4gKiBAcGFyYW0ge01ldGFkYXRhflVwZGF0ZU1ldGFkYXRhSW5mb3xBcnJheS48TWV0YWRhdGF+VXBkYXRlTWV0YWRhdGFJbmZvPn0gdXBkYXRlTWV0YWRhdGEgLSBVcGRhdGluZyBtZXRhZGF0YVxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+QXN5bmNSZXN1bHR8QXJyYXkuPE1ldGFkYXRhfkFzeW5jUmVzdWx0Pj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge01ldGFkYXRhfkFzeW5jUmVzdWx0TG9jYXRvcn1cbiAqL1xuTWV0YWRhdGEucHJvdG90eXBlLnVwZGF0ZUFzeW5jID0gZnVuY3Rpb24odHlwZSwgdXBkYXRlTWV0YWRhdGEsIGNhbGxiYWNrKSB7XG4gIGlmIChOdW1iZXIodGhpcy5fY29ubi52ZXJzaW9uKSA+IDMwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQXN5bmMgbWV0YWRhdGEgQ1JVRCBjYWxscyBhcmUgbm90IHN1cHBvcnRlZCBvbiB2ZXIgMzEuMCBvciBsYXRlci5cIik7XG4gIH1cbiAgdmFyIGNvbnZlcnQgPSBmdW5jdGlvbih1bWQpIHtcbiAgICB1bWQubWV0YWRhdGFbXCJAeHNpOnR5cGVcIl0gPSB0eXBlO1xuICAgIHJldHVybiB1bWQ7XG4gIH07XG4gIHZhciBpc0FycmF5ID0gXy5pc0FycmF5KHVwZGF0ZU1ldGFkYXRhKTtcbiAgdXBkYXRlTWV0YWRhdGEgPSBpc0FycmF5ID8gXy5tYXAodXBkYXRlTWV0YWRhdGEsIGNvbnZlcnQpIDogY29udmVydCh1cGRhdGVNZXRhZGF0YSk7XG4gIHZhciByZXMgPSB0aGlzLl9pbnZva2UoXCJ1cGRhdGVcIiwgeyB1cGRhdGVNZXRhZGF0YTogdXBkYXRlTWV0YWRhdGEgfSk7XG4gIHJldHVybiBuZXcgQXN5bmNSZXN1bHRMb2NhdG9yKHRoaXMsIHJlcywgaXNBcnJheSkudGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBTeW5vbnltIG9mIE1ldGFkYXRhI3VwZGF0ZSgpLlxuICpcbiAqIEBtZXRob2QgTWV0YWRhdGEjdXBkYXRlU3luY1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBtZXRhZGF0YSB0byB1cGRhdGVcbiAqIEBwYXJhbSB7TWV0YWRhdGF+TWV0YWRhdGFJbmZvfEFycmF5LjxNZXRhZGF0YX5NZXRhZGF0YUluZm8+fSB1cGRhdGVNZXRhZGF0YSAtIFVwZGF0aW5nIG1ldGFkYXRhXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxNZXRhZGF0YX5TYXZlUmVzdWx0fEFycmF5LjxNZXRhZGF0YX5TYXZlUmVzdWx0Pj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPE1ldGFkYXRhflNhdmVSZXN1bHR8QXJyYXkuPE1ldGFkYXRhflNhdmVSZXN1bHQ+Pn1cbiAqL1xuLyoqXG4gKiBTeW5jaHJvbm91c2x5IHVwZGF0ZXMgb25lIG9yIG1vcmUgbWV0YWRhdGEgY29tcG9uZW50cyBpbiB0aGUgb3JnYW5pemF0aW9uLlxuICpcbiAqIEBtZXRob2QgTWV0YWRhdGEjdXBkYXRlXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIG1ldGFkYXRhIHRvIHVwZGF0ZVxuICogQHBhcmFtIHtNZXRhZGF0YX5NZXRhZGF0YUluZm98QXJyYXkuPE1ldGFkYXRhfk1ldGFkYXRhSW5mbz59IHVwZGF0ZU1ldGFkYXRhIC0gVXBkYXRpbmcgbWV0YWRhdGFcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPE1ldGFkYXRhflNhdmVSZXN1bHR8QXJyYXkuPE1ldGFkYXRhflNhdmVSZXN1bHQ+Pn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48TWV0YWRhdGF+U2F2ZVJlc3VsdHxBcnJheS48TWV0YWRhdGF+U2F2ZVJlc3VsdD4+fVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUudXBkYXRlU3luYyA9XG5NZXRhZGF0YS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24odHlwZSwgbWV0YWRhdGEsIGNhbGxiYWNrKSB7XG4gIHZhciBjb252ZXJ0ID0gZnVuY3Rpb24obWQpIHtcbiAgICBtZFtcIkB4c2k6dHlwZVwiXSA9IHR5cGU7XG4gICAgcmV0dXJuIG1kO1xuICB9O1xuICB2YXIgaXNBcnJheSA9IF8uaXNBcnJheShtZXRhZGF0YSk7XG4gIG1ldGFkYXRhID0gaXNBcnJheSA/IF8ubWFwKG1ldGFkYXRhLCBjb252ZXJ0KSA6IGNvbnZlcnQobWV0YWRhdGEpO1xuICByZXR1cm4gdGhpcy5faW52b2tlKFwidXBkYXRlTWV0YWRhdGFcIiwgeyBtZXRhZGF0YTogbWV0YWRhdGEgfSkudGhlbihmdW5jdGlvbihyZXN1bHRzKSB7XG4gICAgcmV0dXJuIF8uaXNBcnJheShyZXN1bHRzKSA/IF8ubWFwKHJlc3VsdHMsIGNvbnZlcnRUb1NhdmVSZXN1bHQpIDogY29udmVydFRvU2F2ZVJlc3VsdChyZXN1bHRzKTtcbiAgfSkudGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBTeW5vbnltIG9mIE1ldGFkYXRhI3Vwc2VydCgpLlxuICpcbiAqIEBtZXRob2QgTWV0YWRhdGEjdXBzZXJ0U3luY1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBtZXRhZGF0YSB0byB1cHNlcnRcbiAqIEBwYXJhbSB7TWV0YWRhdGF+TWV0YWRhdGFJbmZvfEFycmF5LjxNZXRhZGF0YX5NZXRhZGF0YUluZm8+fSBtZXRhZGF0YSAtIFVwc2VydGluZyBtZXRhZGF0YVxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+VXBzZXJ0UmVzdWx0fEFycmF5LjxNZXRhZGF0YX5VcHNlcnRSZXN1bHQ+Pn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48TWV0YWRhdGF+VXBzZXJ0UmVzdWx0fEFycmF5LjxNZXRhZGF0YX5VcHNlcnRSZXN1bHQ+Pn1cbiAqL1xuLyoqXG4gKiBVcHNlcnRzIG9uZSBvciBtb3JlIGNvbXBvbmVudHMgaW4geW91ciBvcmdhbml6YXRpb24ncyBkYXRhLlxuICpcbiAqIEBtZXRob2QgTWV0YWRhdGEjdXBzZXJ0XG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIG1ldGFkYXRhIHRvIHVwc2VydFxuICogQHBhcmFtIHtNZXRhZGF0YX5NZXRhZGF0YUluZm98QXJyYXkuPE1ldGFkYXRhfk1ldGFkYXRhSW5mbz59IG1ldGFkYXRhIC0gVXBzZXJ0aW5nIG1ldGFkYXRhXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxNZXRhZGF0YX5VcHNlcnRSZXN1bHR8QXJyYXkuPE1ldGFkYXRhflVwc2VydFJlc3VsdD4+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtQcm9taXNlLjxNZXRhZGF0YX5VcHNlcnRSZXN1bHR8QXJyYXkuPE1ldGFkYXRhflVwc2VydFJlc3VsdD4+fVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUudXBzZXJ0U3luYyA9XG5NZXRhZGF0YS5wcm90b3R5cGUudXBzZXJ0ID0gZnVuY3Rpb24odHlwZSwgbWV0YWRhdGEsIGNhbGxiYWNrKSB7XG4gIHZhciBjb252ZXJ0ID0gZnVuY3Rpb24obWQpIHtcbiAgICBtZFtcIkB4c2k6dHlwZVwiXSA9IHR5cGU7XG4gICAgcmV0dXJuIG1kO1xuICB9O1xuICB2YXIgaXNBcnJheSA9IF8uaXNBcnJheShtZXRhZGF0YSk7XG4gIG1ldGFkYXRhID0gaXNBcnJheSA/IF8ubWFwKG1ldGFkYXRhLCBjb252ZXJ0KSA6IGNvbnZlcnQobWV0YWRhdGEpO1xuICByZXR1cm4gdGhpcy5faW52b2tlKFwidXBzZXJ0TWV0YWRhdGFcIiwgeyBtZXRhZGF0YTogbWV0YWRhdGEgfSkudGhlbihmdW5jdGlvbihyZXN1bHRzKSB7XG4gICAgcmV0dXJuIF8uaXNBcnJheShyZXN1bHRzKSA/IF8ubWFwKHJlc3VsdHMsIGNvbnZlcnRUb1Vwc2VydFJlc3VsdCkgOiBjb252ZXJ0VG9VcHNlcnRSZXN1bHQocmVzdWx0cyk7XG4gIH0pLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogQXN5bmNocm9ub3VzbHkgZGVsZXRlcyBzcGVjaWZpZWQgbWV0YWRhdGEgY29tcG9uZW50cyBpbiB0aGUgb3JnYW5pemF0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIC0gVGhlIHR5cGUgb2YgbWV0YWRhdGEgdG8gZGVsZXRlXG4gKiBAcGFyYW0ge1N0cmluZ3xNZXRhZGF0YX5NZXRhZGF0YUluZm98QXJyYXkuPFN0cmluZz58QXJyYXkuPE1ldGFkYXRhfk1ldGFkYXRhSW5mbz59IG1ldGFkYXRhIC0gVGhlIGZ1bGxOYW1lIG9mIG1ldGFkYXRhIG9yIG1ldGFkYXRhIGluZm8gdG8gZGVsZXRlLiBJZiBpdCBpcyBwYXNzZWQgaW4gZnVsbE5hbWUsIHRoZSB0eXBlIHBhcmFtZXRlciBzaG91bGQgbm90IGJlIGVtcHR5LlxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+QXN5bmNSZXN1bHR8QXJyYXkuPE1ldGFkYXRhfkFzeW5jUmVzdWx0Pj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge01ldGFkYXRhfkFzeW5jUmVzdWx0TG9jYXRvcn1cbiAqL1xuTWV0YWRhdGEucHJvdG90eXBlLmRlbGV0ZUFzeW5jID0gZnVuY3Rpb24odHlwZSwgbWV0YWRhdGEsIGNhbGxiYWNrKSB7XG4gIGlmIChOdW1iZXIodGhpcy5fY29ubi52ZXJzaW9uKSA+IDMwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQXN5bmMgbWV0YWRhdGEgQ1JVRCBjYWxscyBhcmUgbm90IHN1cHBvcnRlZCBvbiB2ZXIgMzEuMCBvciBsYXRlci5cIik7XG4gIH1cbiAgdmFyIGNvbnZlcnQgPSBmdW5jdGlvbihtZCkge1xuICAgIGlmIChfLmlzU3RyaW5nKG1kKSkge1xuICAgICAgbWQgPSB7IGZ1bGxOYW1lIDogbWQgfTtcbiAgICB9XG4gICAgbWRbXCJAeHNpOnR5cGVcIl0gPSB0eXBlO1xuICAgIHJldHVybiBtZDtcbiAgfTtcbiAgdmFyIGlzQXJyYXkgPSBfLmlzQXJyYXkobWV0YWRhdGEpO1xuICBtZXRhZGF0YSA9IGlzQXJyYXkgPyBfLm1hcChtZXRhZGF0YSwgY29udmVydCkgOiBjb252ZXJ0KG1ldGFkYXRhKTtcbiAgdmFyIHJlcyA9IHRoaXMuX2ludm9rZShcImRlbGV0ZVwiLCB7IG1ldGFkYXRhOiBtZXRhZGF0YSB9KTtcbiAgcmV0dXJuIG5ldyBBc3luY1Jlc3VsdExvY2F0b3IodGhpcywgcmVzLCBpc0FycmF5KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFN5bm9ueW0gb2YgTWV0YWRhdGEjZGVsZXRlKCkuXG4gKlxuICogQGRlcHJlY2F0ZWRcbiAqIEBtZXRob2QgTWV0YWRhdGEjZGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gW3R5cGVdIC0gVGhlIHR5cGUgb2YgbWV0YWRhdGEgdG8gZGVsZXRlXG4gKiBAcGFyYW0ge1N0cmluZ3xNZXRhZGF0YX5NZXRhZGF0YUluZm98QXJyYXkuPFN0cmluZz58QXJyYXkuPE1ldGFkYXRhfk1ldGFkYXRhSW5mbz59IG1ldGFkYXRhIC0gVGhlIGZ1bGxOYW1lIG9mIG1ldGFkYXRhIG9yIG1ldGFkYXRhIGluZm8gdG8gZGVsZXRlLiBJZiBpdCBpcyBwYXNzZWQgaW4gZnVsbE5hbWUsIHRoZSB0eXBlIHBhcmFtZXRlciBzaG91bGQgbm90IGJlIGVtcHR5LlxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+QXN5bmNSZXN1bHR8QXJyYXkuPE1ldGFkYXRhfkFzeW5jUmVzdWx0Pj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge01ldGFkYXRhfkFzeW5jUmVzdWx0TG9jYXRvcn1cbiAqL1xuLyoqXG4gKiBTeW5vbnltIG9mIE1ldGFkYXRhI2RlbGV0ZSgpLlxuICpcbiAqIEBtZXRob2QgTWV0YWRhdGEjZGVsZXRlU3luY1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBtZXRhZGF0YSB0byBkZWxldGVcbiAqIEBwYXJhbSB7U3RyaW5nfEFycmF5LjxTdHJpbmc+fSBmdWxsTmFtZXMgLSBUaGUgZnVsbE5hbWUgb2YgbWV0YWRhdGEgdG8gZGVsZXRlLlxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+U2F2ZVJlc3VsdHxBcnJheS48TWV0YWRhdGF+U2F2ZVJlc3VsdD4+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtQcm9taXNlLjxNZXRhZGF0YX5TYXZlUmVzdWx0fEFycmF5LjxNZXRhZGF0YX5TYXZlUmVzdWx0Pj59XG4gKi9cblxuLyoqXG4gKiBTeW5jaHJvbm91c2x5IGRlbGV0ZXMgc3BlY2lmaWVkIG1ldGFkYXRhIGNvbXBvbmVudHMgaW4gdGhlIG9yZ2FuaXphdGlvbi5cbiAqXG4gKiBAbWV0aG9kIE1ldGFkYXRhI2RlbGV0ZVxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBtZXRhZGF0YSB0byBkZWxldGVcbiAqIEBwYXJhbSB7U3RyaW5nfEFycmF5LjxTdHJpbmc+fSBmdWxsTmFtZXMgLSBUaGUgZnVsbE5hbWUgb2YgbWV0YWRhdGEgdG8gZGVsZXRlLlxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+U2F2ZVJlc3VsdHxBcnJheS48TWV0YWRhdGF+U2F2ZVJlc3VsdD4+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtQcm9taXNlLjxNZXRhZGF0YX5TYXZlUmVzdWx0fEFycmF5LjxNZXRhZGF0YX5TYXZlUmVzdWx0Pj59XG4gKi9cbk1ldGFkYXRhLnByb3RvdHlwZS5kZWwgPVxuTWV0YWRhdGEucHJvdG90eXBlLmRlbGV0ZVN5bmMgPVxuTWV0YWRhdGEucHJvdG90eXBlW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24odHlwZSwgZnVsbE5hbWVzLCBjYWxsYmFjaykge1xuICByZXR1cm4gdGhpcy5faW52b2tlKFwiZGVsZXRlTWV0YWRhdGFcIiwgeyB0eXBlOiB0eXBlLCBmdWxsTmFtZXM6IGZ1bGxOYW1lcyB9KS50aGVuKGZ1bmN0aW9uKHJlc3VsdHMpIHtcbiAgICByZXR1cm4gXy5pc0FycmF5KHJlc3VsdHMpID8gXy5tYXAocmVzdWx0cywgY29udmVydFRvU2F2ZVJlc3VsdCkgOiBjb252ZXJ0VG9TYXZlUmVzdWx0KHJlc3VsdHMpO1xuICB9KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFJlbmFtZSBmdWxsbmFtZSBvZiBhIG1ldGFkYXRhIGNvbXBvbmVudCBpbiB0aGUgb3JnYW5pemF0aW9uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgLSBUaGUgdHlwZSBvZiBtZXRhZGF0YSB0byBkZWxldGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBvbGRGdWxsTmFtZSAtIFRoZSBvcmlnaW5hbCBmdWxsTmFtZSBvZiBtZXRhZGF0YVxuICogQHBhcmFtIHtTdHJpbmd9IG5ld0Z1bGxOYW1lIC0gVGhlIG5ldyBmdWxsTmFtZSBvZiBtZXRhZGF0YVxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+U2F2ZVJlc3VsdD59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPE1ldGFkYXRhflNhdmVSZXN1bHQ+fVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUucmVuYW1lID0gZnVuY3Rpb24odHlwZSwgb2xkRnVsbE5hbWUsIG5ld0Z1bGxOYW1lLCBjYWxsYmFjaykge1xuICByZXR1cm4gdGhpcy5faW52b2tlKFwicmVuYW1lTWV0YWRhdGFcIiwgeyB0eXBlOiB0eXBlLCBvbGRGdWxsTmFtZTogb2xkRnVsbE5hbWUsIG5ld0Z1bGxOYW1lOiBuZXdGdWxsTmFtZSB9KS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgIHJldHVybiBjb252ZXJ0VG9TYXZlUmVzdWx0KHJlc3VsdCk7XG4gIH0pLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHRoZSBzdGF0dXMgb2YgYXN5bmNocm9ub3VzIG1ldGFkYXRhIGNhbGxzXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXkuPFN0cmluZz59IGlkcyAtIFRoZSBhc3luY2hyb25vdXMgcHJvY2VzcyBJRChzKVxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+QXN5bmNSZXN1bHR8QXJyYXkuPE1ldGFkYXRhfkFzeW5jUmVzdWx0Pj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge01ldGFkYXRhfkFzeW5jUmVzdWx0TG9jYXRvcn1cbiAqL1xuTWV0YWRhdGEucHJvdG90eXBlLmNoZWNrU3RhdHVzID0gZnVuY3Rpb24oaWRzLCBjYWxsYmFjaykge1xuICB2YXIgaXNBcnJheSA9IF8uaXNBcnJheShpZHMpO1xuICB2YXIgcmVzID0gdGhpcy5faW52b2tlKFwiY2hlY2tTdGF0dXNcIiwgeyBhc3luY1Byb2Nlc3NJZDogaWRzIH0pO1xuICByZXR1cm4gbmV3IEFzeW5jUmVzdWx0TG9jYXRvcih0aGlzLCByZXMsIGlzQXJyYXkpLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTWV0YWRhdGF+RGVzY3JpYmVNZXRhZGF0YVJlc3VsdFxuICogQHByb3Age0FycmF5LjxPYmplY3Q+fSBtZXRhZGF0YU9iamVjdHMgLSBPbmUgb3IgbW9yZSBtZXRhZGF0YSBjb21wb25lbnRzIGFuZCB0aGVpciBhdHRyaWJ1dGVzXG4gKiBAcHJvcCB7QXJyYXkuPFN0cmluZz59IG1ldGFkYXRhT2JqZWN0cy5jaGlsZFhtbE5hbWVzIC0gTGlzdCBvZiBjaGlsZCBzdWItY29tcG9uZW50cyBmb3IgdGhpcyBjb21wb25lbnRcbiAqIEBwcm9wIHtTdHJpbmd9IG1ldGFkYXRhT2JqZWN0cy5kaXJlY3RvcnlOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGRpcmVjdG9yeSBpbiB0aGUgLnppcCBmaWxlIHRoYXQgY29udGFpbnMgdGhpcyBjb21wb25lbnRcbiAqIEBwcm9wIHtCb29sZWFufSBtZXRhZGF0YU9iamVjdHMuaW5Gb2xkZXIgLSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgY29tcG9uZW50IGlzIGluIGEgZm9sZGVyIG9yIG5vdFxuICogQHByb3Age0Jvb2xlYW59IG1ldGFkYXRhT2JqZWN0cy5tZXRhRmlsZSAtIEluZGljYXRlcyB3aGV0aGVyIHRoZSBjb21wb25lbnQgcmVxdWlyZXMgYW4gYWNjb21wYW55aW5nIG1ldGFkYXRhIGZpbGVcbiAqIEBwcm9wIHtTdHJpbmd9IG1ldGFkYXRhT2JqZWN0cy5zdWZmaXggLSBUaGUgZmlsZSBzdWZmaXggZm9yIHRoaXMgY29tcG9uZW50XG4gKiBAcHJvcCB7U3RyaW5nfSBtZXRhZGF0YU9iamVjdHMueG1sTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSByb290IGVsZW1lbnQgaW4gdGhlIG1ldGFkYXRhIGZpbGUgZm9yIHRoaXMgY29tcG9uZW50XG4gKiBAcHJvcCB7U3RyaW5nfSBvcmdhbml6YXRpb25OYW1lc3BhY2UgLSBUaGUgbmFtZXNwYWNlIG9mIHRoZSBvcmdhbml6YXRpb25cbiAqIEBwcm9wIHtCb29sZWFufSBwYXJ0aWFsU2F2ZUFsbG93ZWQgLSBJbmRpY2F0ZXMgd2hldGhlciByb2xsYmFja09uRXJyb3IgaXMgYWxsb3dlZCBvciBub3RcbiAqIEBwcm9wIHtCb29sZWFufSB0ZXN0UmVxdWlyZWQgLSBJbmRpY2F0ZXMgd2hldGhlciB0ZXN0cyBhcmUgcmVxdWlyZWQgb3Igbm90XG4gKi9cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIG1ldGFkYXRhIHdoaWNoIGRlc2NyaWJlcyB5b3VyIG9yZ2FuaXphdGlvbiwgaW5jbHVkaW5nIEFwZXggY2xhc3NlcyBhbmQgdHJpZ2dlcnMsXG4gKiBjdXN0b20gb2JqZWN0cywgY3VzdG9tIGZpZWxkcyBvbiBzdGFuZGFyZCBvYmplY3RzLCB0YWIgc2V0cyB0aGF0IGRlZmluZSBhbiBhcHAsXG4gKiBhbmQgbWFueSBvdGhlciBjb21wb25lbnRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBbdmVyc2lvbl0gLSBUaGUgQVBJIHZlcnNpb24gZm9yIHdoaWNoIHlvdSB3YW50IG1ldGFkYXRhOyBmb3IgZXhhbXBsZSwgMjkuMFxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+RGVzY3JpYmVNZXRhZGF0YVJlc3VsdD59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPE1ldGFkYXRhfkRlc2NyaWJlTWV0YWRhdGFSZXN1bHQ+fVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUuZGVzY3JpYmUgPSBmdW5jdGlvbih2ZXJzaW9uLCBjYWxsYmFjaykge1xuICBpZiAoIV8uaXNTdHJpbmcodmVyc2lvbikpIHtcbiAgICBjYWxsYmFjayA9IHZlcnNpb247XG4gICAgdmVyc2lvbiA9IHRoaXMuX2Nvbm4udmVyc2lvbjtcbiAgfVxuICByZXR1cm4gdGhpcy5faW52b2tlKFwiZGVzY3JpYmVNZXRhZGF0YVwiLCB7IGFzT2ZWZXJzaW9uOiB2ZXJzaW9uIH0pLnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgcmVzLm1ldGFkYXRhT2JqZWN0cyA9IF8uaXNBcnJheShyZXMubWV0YWRhdGFPYmplY3RzKSA/IHJlcy5tZXRhZGF0YU9iamVjdHMgOiBbIHJlcy5tZXRhZGF0YU9iamVjdHMgXTtcbiAgICByZXMubWV0YWRhdGFPYmplY3RzID0gXy5tYXAocmVzLm1ldGFkYXRhT2JqZWN0cywgZnVuY3Rpb24obW8pIHtcbiAgICAgIGlmIChtby5jaGlsZFhtbE5hbWVzKSB7XG4gICAgICAgIG1vLmNoaWxkWG1sTmFtZXMgPSBfLmlzQXJyYXkobW8uY2hpbGRYbWxOYW1lcykgPyBtby5jaGlsZFhtbE5hbWVzOiBbIG1vLmNoaWxkWG1sTmFtZXMgXTtcbiAgICAgIH1cbiAgICAgIG1vLmluRm9sZGVyID0gbW8uaW5Gb2xkZXIgPT09ICd0cnVlJztcbiAgICAgIG1vLm1ldGFGaWxlID0gbW8ubWV0YUZpbGUgPT09ICd0cnVlJztcbiAgICAgIHJldHVybiBtbztcbiAgICB9KTtcbiAgICByZXMucGFydGlhbFNhdmVBbGxvd2VkID0gcmVzLnBhcnRpYWxTYXZlQWxsb3dlZCA9PT0gJ3RydWUnO1xuICAgIHJlcy50ZXN0UmVxdWlyZWQgPSByZXMudGVzdFJlcXVpcmVkID09PSAndHJ1ZSc7XG4gICAgcmV0dXJuIHJlcztcbiAgfSkudGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZXRhZGF0YX5MaXN0TWV0YWRhdGFRdWVyeVxuICogQHByb3Age1N0cmluZ30gdHlwZSAtIFRoZSBtZXRhZGF0YSB0eXBlLCBzdWNoIGFzIEN1c3RvbU9iamVjdCwgQ3VzdG9tRmllbGQsIG9yIEFwZXhDbGFzc1xuICogQHByb3Age1N0cmluZ30gW2ZvbGRlcl0gLSBUaGUgZm9sZGVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29tcG9uZW50LlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTWV0YWRhdGF+RmlsZVByb3BlcnRpZXNcbiAqIEBwcm9wIHtTdHJpbmd9IHR5cGUgLSBUaGUgbWV0YWRhdGEgdHlwZSwgc3VjaCBhcyBDdXN0b21PYmplY3QsIEN1c3RvbUZpZWxkLCBvciBBcGV4Q2xhc3NcbiAqIEBwcm9wIHtTdHJpbmd9IGNyZWF0ZWRCeUlkIC0gSUQgb2YgdGhlIHVzZXIgd2hvIGNyZWF0ZWQgdGhlIGZpbGVcbiAqIEBwcm9wIHtTdHJpbmd9IGNyZWF0ZWRCeU5hbWUgLSBOYW1lIG9mIHRoZSB1c2VyIHdobyBjcmVhdGVkIHRoZSBmaWxlXG4gKiBAcHJvcCB7U3RyaW5nfSBjcmVhdGVkRGF0ZSAtIERhdGUgYW5kIHRpbWUgd2hlbiB0aGUgZmlsZSB3YXMgY3JlYXRlZFxuICogQHByb3Age1N0cmluZ30gZmlsZU5hbWUgLSBOYW1lIG9mIHRoZSBmaWxlXG4gKiBAcHJvcCB7U3RyaW5nfSBmdWxsTmFtZSAtIFRoZSBmaWxlIGRldmVsb3BlciBuYW1lIHVzZWQgYXMgYSB1bmlxdWUgaWRlbnRpZmllciBmb3IgQVBJIGFjY2Vzc1xuICogQHByb3Age1N0cmluZ30gaWQgLSBJRCBvZiB0aGUgZmlsZVxuICogQHByb3Age1N0cmluZ30gbGFzdE1vZGlmaWVkQnlJZCAtIElEIG9mIHRoZSB1c2VyIHdobyBsYXN0IG1vZGlmaWVkIHRoZSBmaWxlXG4gKiBAcHJvcCB7U3RyaW5nfSBsYXN0TW9kaWZpZWRCeU5hbWUgLSBOYW1lIG9mIHRoZSB1c2VyIHdobyBsYXN0IG1vZGlmaWVkIHRoZSBmaWxlXG4gKiBAcHJvcCB7U3RyaW5nfSBsYXN0TW9kaWZpZWREYXRlIC0gRGF0ZSBhbmQgdGltZSB0aGF0IHRoZSBmaWxlIHdhcyBsYXN0IG1vZGlmaWVkXG4gKiBAcHJvcCB7U3RyaW5nfSBbbWFuYWdlYWJsZVN0YXRlXSAtIEluZGljYXRlcyB0aGUgbWFuYWdlYWJsZSBzdGF0ZSBvZiB0aGUgc3BlY2lmaWVkIGNvbXBvbmVudCBpZiBpdCBpcyBjb250YWluZWQgaW4gYSBwYWNrYWdlXG4gKiBAcHJvcCB7U3RyaW5nfSBbbmFtZXNwYWNlUHJlZml4XSAtIFRoZSBuYW1lc3BhY2UgcHJlZml4IG9mIHRoZSBjb21wb25lbnRcbiAqL1xuXG4vKipcbiAqIFJldHJpZXZlcyBwcm9wZXJ0eSBpbmZvcm1hdGlvbiBhYm91dCBtZXRhZGF0YSBjb21wb25lbnRzIGluIHlvdXIgb3JnYW5pemF0aW9uXG4gKlxuICogQHBhcmFtIHtNZXRhZGF0YX5MaXN0TWV0YWRhdGFRdWVyeXxBcnJheS48TWV0YWRhdGF+TGlzdE1ldGFkYXRhUXVlcnk+fSBxdWVyaWVzIC0gVGhlIGNyaXRlcmlhIG9iamVjdChzKSBzcGVjaWZpbmcgbWV0YWRhdGEgdG8gbGlzdFxuICogQHBhcmFtIHtTdHJpbmd9IFt2ZXJzaW9uXSAtIFRoZSBBUEkgdmVyc2lvbiBmb3Igd2hpY2ggeW91IHdhbnQgbWV0YWRhdGE7IGZvciBleGFtcGxlLCAyOS4wXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxBcnJheS48TWV0YWRhdGF+RmlsZVByb3BlcnRpZXM+Pn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48QXJyYXkuPE1ldGFkYXRhfkZpbGVQcm9wZXJ0aWVzPj59XG4gKi9cbk1ldGFkYXRhLnByb3RvdHlwZS5saXN0ID0gZnVuY3Rpb24ocXVlcmllcywgdmVyc2lvbiwgY2FsbGJhY2spIHtcbiAgaWYgKCFfLmlzU3RyaW5nKHZlcnNpb24pKSB7XG4gICAgY2FsbGJhY2sgPSB2ZXJzaW9uO1xuICAgIHZlcnNpb24gPSB0aGlzLl9jb25uLnZlcnNpb247XG4gIH1cbiAgaWYgKCFfLmlzQXJyYXkocXVlcmllcykpIHtcbiAgICBxdWVyaWVzID0gWyBxdWVyaWVzIF07XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2ludm9rZShcImxpc3RNZXRhZGF0YVwiLCB7IHF1ZXJpZXM6IHF1ZXJpZXMsIGFzT2ZWZXJzaW9uOiB2ZXJzaW9uIH0sIGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTWV0YWRhdGF+UmV0cmlldmVSZXF1ZXN0XG4gKi9cblxuLyoqXG4gKiBSZXRyaWV2ZXMgWE1MIGZpbGUgcmVwcmVzZW50YXRpb25zIG9mIGNvbXBvbmVudHMgaW4gYW4gb3JnYW5pemF0aW9uXG4gKlxuICogQHBhcmFtIHtNZXRhZGF0YX5SZXRyaWV2ZVJlcXVlc3R9IHJlcXVlc3QgLSBPcHRpb25zIGZvciBkZXRlcm1pbmluZyB3aGljaCBwYWNrYWdlcyBvciBmaWxlcyBhcmUgcmV0cmlldmVkXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxNZXRhZGF0YX5Bc3luY1Jlc3VsdD59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge01ldGFkYXRhflJldHJpZXZlUmVzdWx0TG9jYXRvcn1cbiAqL1xuTWV0YWRhdGEucHJvdG90eXBlLnJldHJpZXZlID0gZnVuY3Rpb24ocmVxdWVzdCwgY2FsbGJhY2spIHtcbiAgdmFyIHJlcyA9IHRoaXMuX2ludm9rZShcInJldHJpZXZlXCIsIHsgcmVxdWVzdDogcmVxdWVzdCB9KTtcbiAgcmV0dXJuIG5ldyBSZXRyaWV2ZVJlc3VsdExvY2F0b3IodGhpcywgcmVzKS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB0aGUgc3RhdHVzIG9mIGRlY2xhcmF0aXZlIG1ldGFkYXRhIGNhbGwgcmV0cmlldmUoKSBhbmQgcmV0dXJucyB0aGUgemlwIGZpbGUgY29udGVudHNcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaWQgLSBBc3luYyBwcm9jZXNzIGlkIHJldHVybmVkIGZyb20gcHJldmlvdXMgcmV0cmlldmUgcmVxdWVzdFxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+UmV0cmlldmVSZXN1bHQ+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtQcm9taXNlLjxNZXRhZGF0YX5SZXRyaWV2ZVJlc3VsdD59XG4gKi9cbk1ldGFkYXRhLnByb3RvdHlwZS5jaGVja1JldHJpZXZlU3RhdHVzID0gZnVuY3Rpb24oaWQsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB0aGlzLl9pbnZva2UoXCJjaGVja1JldHJpZXZlU3RhdHVzXCIsIHsgYXN5bmNQcm9jZXNzSWQ6IGlkIH0sIGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogRGVwbG95IGNvbXBvbmVudHMgaW50byBhbiBvcmdhbml6YXRpb24gdXNpbmcgemlwcGVkIGZpbGUgcmVwcmVzZW50YXRpb25zXG4gKlxuICogQHBhcmFtIHtzdHJlYW0uU3RyZWFtfEJ1ZmZlcnxTdHJpbmd9IHppcElucHV0IC0gWmlwcGVkIGZpbGUgaW5wdXQgc291cmNlIGluIHJlYWRhYmxlIHN0cmVhbSwgYmluYXJ5IGJ1ZmZlciBvciBCYXNlNjQtZW5jb2RlZCBzdHJpbmdcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSBPcHRpb25zIHVzZWQgaW4gZGVwbG95bWVudFxuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5hbGxvd01pc3NpbmdGaWxlc10gLSBTcGVjaWZpZXMgd2hldGhlciBhIGRlcGxveSBzdWNjZWVkcyBldmVuIGlmIGZpbGVzIHRoYXQgYXJlIHNwZWNpZmllZCBpbiBwYWNrYWdlLnhtbCBidXQgYXJlIG5vdCBpbiB0aGUgLnppcCBmaWxlIG9yIG5vdC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuYXV0b1VwZGF0ZVBhY2thZ2VdIC0gSWYgYSBmaWxlIGlzIGluIHRoZSAuemlwIGZpbGUgYnV0IG5vdCBzcGVjaWZpZWQgaW4gcGFja2FnZS54bWwsIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBmaWxlIHNob3VsZCBiZSBhdXRvbWF0aWNhbGx5IGFkZGVkIHRvIHRoZSBwYWNrYWdlIG9yIG5vdC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuY2hlY2tPbmx5XSAtIEluZGljYXRlcyB3aGV0aGVyIEFwZXggY2xhc3NlcyBhbmQgdHJpZ2dlcnMgYXJlIHNhdmVkIHRvIHRoZSBvcmdhbml6YXRpb24gYXMgcGFydCBvZiB0aGUgZGVwbG95bWVudCAoZmFsc2UpIG9yIG5vdCAodHJ1ZSkuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmlnbm9yZVdhcm5pbmdzXSAtIEluZGljYXRlcyB3aGV0aGVyIGEgd2FybmluZyBzaG91bGQgYWxsb3cgYSBkZXBsb3ltZW50IHRvIGNvbXBsZXRlIHN1Y2Nlc3NmdWxseSAodHJ1ZSkgb3Igbm90IChmYWxzZSkuIERlZmF1bHRzIHRvIGZhbHNlLlxuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5wZXJmb3JtUmV0cmlldmVdIC0gSW5kaWNhdGVzIHdoZXRoZXIgYSByZXRyaWV2ZSgpIGNhbGwgaXMgcGVyZm9ybWVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBkZXBsb3ltZW50ICh0cnVlKSBvciBub3QgKGZhbHNlKS5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMucHVyZ2VPbkRlbGV0ZV0gLSBJZiB0cnVlLCB0aGUgZGVsZXRlZCBjb21wb25lbnRzIGluIHRoZSBkZXN0cnVjdGl2ZUNoYW5nZXMueG1sIG1hbmlmZXN0IGZpbGUgYXJlbid0IHN0b3JlZCBpbiB0aGUgUmVjeWNsZSBCaW4uXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnJvbGxiYWNrT25FcnJvcl0gLSBJbmRpY2F0ZXMgd2hldGhlciBhbnkgZmFpbHVyZSBjYXVzZXMgYSBjb21wbGV0ZSByb2xsYmFjayAodHJ1ZSkgb3Igbm90IChmYWxzZSkuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnJ1bkFsbFRlc3RzXSAtIElmIHRydWUsIGFsbCBBcGV4IHRlc3RzIGRlZmluZWQgaW4gdGhlIG9yZ2FuaXphdGlvbiBhcmUgcnVuLlxuICogQHBhcmFtIHtBcnJheS48U3RyaW5nPn0gW29wdGlvbnMucnVuVGVzdHNdIC0gQSBsaXN0IG9mIEFwZXggdGVzdHMgdG8gYmUgcnVuIGR1cmluZyBkZXBsb3ltZW50LlxuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zaW5nbGVQYWNrYWdlXSAtIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgLnppcCBmaWxlIHBvaW50cyB0byBhIGRpcmVjdG9yeSBzdHJ1Y3R1cmUgd2l0aCBhIHNpbmdsZSBwYWNrYWdlICh0cnVlKSBvciBhIHNldCBvZiBwYWNrYWdlcyAoZmFsc2UpLlxuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+QXN5bmNSZXN1bHQ+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtNZXRhZGF0YX5EZXBsb3lSZXN1bHRMb2NhdG9yfVxuICovXG5NZXRhZGF0YS5wcm90b3R5cGUuZGVwbG95ID0gZnVuY3Rpb24oemlwSW5wdXQsIG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghb3B0aW9ucyB8fCBfLmlzRnVuY3Rpb24ob3B0aW9ucykpIHtcbiAgICBjYWxsYmFjayA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIHZhciBkZWZlcnJlZCA9IFByb21pc2UuZGVmZXIoKTtcbiAgaWYgKF8uaXNPYmplY3QoemlwSW5wdXQpICYmIF8uaXNGdW5jdGlvbih6aXBJbnB1dC5waXBlKSkge1xuICAgIHZhciBidWZzID0gW107XG4gICAgemlwSW5wdXQub24oJ2RhdGEnLCBmdW5jdGlvbihkKSB7XG4gICAgICBidWZzLnB1c2goZCk7XG4gICAgfSk7XG4gICAgemlwSW5wdXQub24oJ2VuZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgZGVmZXJyZWQucmVzb2x2ZShCdWZmZXIuY29uY2F0KGJ1ZnMpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgfSk7XG4gICAgLy8gemlwSW5wdXQucmVzdW1lKCk7XG4gIH0gZWxzZSBpZiAoemlwSW5wdXQgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICBkZWZlcnJlZC5yZXNvbHZlKHppcElucHV0LnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gIH0gZWxzZSBpZiAoemlwSW5wdXQgaW5zdGFuY2VvZiBTdHJpbmcgfHwgdHlwZW9mIHppcElucHV0ID09PSAnc3RyaW5nJykge1xuICAgIGRlZmVycmVkLnJlc29sdmUoemlwSW5wdXQpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IFwiVW5leHBlY3RlZCB6aXBJbnB1dCB0eXBlXCI7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciByZXMgPSBkZWZlcnJlZC5wcm9taXNlLnRoZW4oZnVuY3Rpb24oemlwQ29udGVudEI2NCkge1xuICAgIHJldHVybiBzZWxmLl9pbnZva2UoXCJkZXBsb3lcIiwge1xuICAgICAgWmlwRmlsZTogemlwQ29udGVudEI2NCxcbiAgICAgIERlcGxveU9wdGlvbnM6IG9wdGlvbnNcbiAgICB9LCBjYWxsYmFjayk7XG4gIH0pO1xuICByZXR1cm4gbmV3IERlcGxveVJlc3VsdExvY2F0b3IodGhpcywgcmVzKS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB0aGUgc3RhdHVzIG9mIGRlY2xhcmF0aXZlIG1ldGFkYXRhIGNhbGwgZGVwbG95KClcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaWQgLSBBc3luYyBwcm9jZXNzIGlkIHJldHVybmVkIGZyb20gcHJldmlvdXMgZGVwbG95IHJlcXVlc3RcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2luY2x1ZGVEZXRhaWxzXSAtIFNldHMgdGhlIERlcGxveVJlc3VsdCBvYmplY3QgdG8gaW5jbHVkZSBkZXRhaWxzIGluZm9ybWF0aW9uIChkZWZhdWx0OiBmYWxzZSlcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPE1ldGFkYXRhfkRlcGxveVJlc3VsdD59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPE1ldGFkYXRhfkRlcGxveVJlc3VsdD59XG4gKi9cbk1ldGFkYXRhLnByb3RvdHlwZS5jaGVja0RlcGxveVN0YXR1cyA9IGZ1bmN0aW9uKGlkLCBpbmNsdWRlRGV0YWlscywgY2FsbGJhY2spIHtcbiAgaWYgKF8uaXNPYmplY3QoaW5jbHVkZURldGFpbHMpIHx8IF8uaXNCb29sZWFuKGluY2x1ZGVEZXRhaWxzKSkge1xuICAgIGluY2x1ZGVEZXRhaWxzID0gISFpbmNsdWRlRGV0YWlscztcbiAgfSBlbHNlIHtcbiAgICBjYWxsYmFjayA9IGluY2x1ZGVEZXRhaWxzO1xuICAgIGluY2x1ZGVEZXRhaWxzID0gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2ludm9rZShcImNoZWNrRGVwbG95U3RhdHVzXCIsIHtcbiAgICBhc3luY1Byb2Nlc3NJZDogaWQsXG4gICAgaW5jbHVkZURldGFpbHMgOiBpbmNsdWRlRGV0YWlsc1xuICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgIHJlcy5kb25lID0gcmVzLmRvbmUgPT09ICd0cnVlJztcbiAgICByZXMuc3VjY2VzcyA9IHJlcy5zdWNjZXNzID09PSAndHJ1ZSc7XG4gICAgcmVzLmNoZWNrT25seSA9IHJlcy5jaGVja09ubHkgPT09ICd0cnVlJztcbiAgICByZXMucnVuVGVzdHNFbmFibGVkID0gcmVzLnJ1blRlc3RzRW5hYmxlZCA9PT0gJ3RydWUnO1xuICAgIGlmIChyZXMuaWdub3JlV2FybmluZ3MpIHtcbiAgICAgIHJlcy5pZ25vcmVXYXJuaW5ncyA9IHJlcy5pZ25vcmVXYXJuaW5ncyA9PT0gJ3RydWUnO1xuICAgIH1cbiAgICBpZiAocmVzLnJvbGxiYWNrT25FcnJvcikge1xuICAgICAgcmVzLnJvbGxiYWNrT25FcnJvciA9IHJlcy5yb2xsYmFja09uRXJyb3IgPT09ICd0cnVlJztcbiAgICB9XG4gICAgcmVzLm51bWJlckNvbXBvbmVudEVycm9ycyA9IE51bWJlcihyZXMubnVtYmVyQ29tcG9uZW50RXJyb3JzKTtcbiAgICByZXMubnVtYmVyQ29tcG9uZW50c0RlcGxveWVkID0gTnVtYmVyKHJlcy5udW1iZXJDb21wb25lbnRzRGVwbG95ZWQpO1xuICAgIHJlcy5udW1iZXJDb21wb25lbnRzVG90YWwgPSBOdW1iZXIocmVzLm51bWJlckNvbXBvbmVudHNUb3RhbCk7XG4gICAgcmVzLm51bWJlclRlc3RFcnJvcnMgPSBOdW1iZXIocmVzLm51bWJlclRlc3RFcnJvcnMpO1xuICAgIHJlcy5udW1iZXJUZXN0c0NvbXBsZXRlZCA9IE51bWJlcihyZXMubnVtYmVyVGVzdHNDb21wbGV0ZWQpO1xuICAgIHJlcy5udW1iZXJUZXN0c1RvdGFsID0gTnVtYmVyKHJlcy5udW1iZXJUZXN0c1RvdGFsKTtcblxuICAgIHJldHVybiByZXM7XG4gIH0pLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTWV0YWRhdGF+QXN5bmNSZXN1bHRcbiAqIEBwcm9wIHtCb29sZWFufSBkb25lIC0gSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGNhbGwgaGFzIGNvbXBsZXRlZCBvciBub3RcbiAqIEBwcm9wIHtTdHJpbmd9IGlkIC0gSUQgb2YgdGhlIGNvbXBvbmVudCBiZWluZyBjcmVhdGVkLCB1cGRhdGVkLCBkZWxldGVkLCBkZXBsb3llZCwgb3IgcmV0cmlldmVkXG4gKiBAcHJvcCB7U3RyaW5nfSBzdGF0ZSAtIFRoZSBzdGF0ZSBmb3VyIHBvc3NpYmxlIHZhbHVlczogUXVldWVkLCBJblByb2dyZXNzLCBDb21wbGV0ZWQsIGFuZCBFcnJvci5cbiAqIEBwcm9wIHtTdHJpbmd9IFtzdGF0dXNDb2RlXSAtIElmIGFuIGVycm9yIG9jY3VycmVkIGR1cmluZyB0aGUgY3JlYXRlKCksIHVwZGF0ZSgpLCBvciBkZWxldGUoKSBjYWxsLCBhIHN0YXR1cyBjb2RlIGlzIHJldHVybmVkXG4gKiBAcHJvcCB7U3RyaW5nfSBbbWVzc2FnZV0gLSBNZXNzYWdlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHN0YXR1c0NvZGUgZmllbGQgcmV0dXJuZWRcbiAqL1xuXG4vKipcbiAqIFRoZSBsb2NhdG9yIGNsYXNzIGZvciBNZXRhZGF0YSBBUEkgYXN5bmNocm9ub3VzIGNhbGwgcmVzdWx0XG4gKlxuICogQHByb3RlY3RlZFxuICogQGNsYXNzIE1ldGFkYXRhfkFzeW5jUmVzdWx0TG9jYXRvclxuICogQGV4dGVuZHMgZXZlbnRzLkV2ZW50RW1pdHRlclxuICogQGltcGxlbWVudHMgUHJvbWlzZS48TWV0YWRhdGF+QXN5bmNSZXN1bHR8QXJyYXkuPE1ldGFkYXRhfkFzeW5jUmVzdWx0Pj5cbiAqIEBwYXJhbSB7TWV0YWRhdGF9IG1ldGEgLSBNZXRhZGF0YSBBUEkgb2JqZWN0XG4gKiBAcGFyYW0ge1Byb21pc2UuPE1ldGFkYXRhfkFzeW5jUmVzdWx0fEFycmF5LjxNZXRhZGF0YX5Bc3luY1Jlc3VsdD4+fSByZXN1bHRzIC0gUHJvbWlzZSBvYmplY3QgZm9yIGFzeW5jIHJlc3VsdCBpbmZvXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtpc0FycmF5XSAtIEluZGljYXRlcyB3aGV0aGVyIHRoZSBhc3luYyByZXF1ZXN0IGlzIGdpdmVuIGluIGFycmF5IG9yIHNpbmdsZSBvYmplY3RcbiAqL1xudmFyIEFzeW5jUmVzdWx0TG9jYXRvciA9IGZ1bmN0aW9uKG1ldGEsIHJlc3VsdHMsIGlzQXJyYXkpIHtcbiAgdGhpcy5fbWV0YSA9IG1ldGE7XG4gIHRoaXMuX3Jlc3VsdHMgPSByZXN1bHRzO1xuICB0aGlzLl9pc0FycmF5ID0gaXNBcnJheTtcbn07XG5cbmluaGVyaXRzKEFzeW5jUmVzdWx0TG9jYXRvciwgZXZlbnRzLkV2ZW50RW1pdHRlcik7XG5cbi8qKlxuICogUHJvbWlzZS9BKyBpbnRlcmZhY2VcbiAqIGh0dHA6Ly9wcm9taXNlcy1hcGx1cy5naXRodWIuaW8vcHJvbWlzZXMtc3BlYy9cbiAqXG4gKiBEZWxlZ2F0ZSB0byBkZWZlcnJlZCBwcm9taXNlLCByZXR1cm4gcHJvbWlzZSBpbnN0YW5jZSBmb3IgYmF0Y2ggcmVzdWx0XG4gKlxuICogQG1ldGhvZCBNZXRhZGF0YX5Bc3luY1Jlc3VsdExvY2F0b3IjdGhlblxuICovXG5Bc3luY1Jlc3VsdExvY2F0b3IucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbihvblJlc29sdmUsIG9uUmVqZWN0KSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmV0dXJuIHRoaXMuX3Jlc3VsdHMudGhlbihmdW5jdGlvbihyZXN1bHRzKSB7XG4gICAgdmFyIGNvbnZlcnRUeXBlID0gZnVuY3Rpb24ocmVzKSB7XG4gICAgICBpZiAocmVzLiQgJiYgcmVzLiRbXCJ4c2k6bmlsXCJdID09PSAndHJ1ZScpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXMuZG9uZSA9IHJlcy5kb25lID09PSAndHJ1ZSc7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH07XG4gICAgcmVzdWx0cyA9IF8uaXNBcnJheShyZXN1bHRzKSA/IF8ubWFwKHJlc3VsdHMsIGNvbnZlcnRUeXBlKSA6IGNvbnZlcnRUeXBlKHJlc3VsdHMpO1xuICAgIGlmIChzZWxmLl9pc0FycmF5ICYmICFfLmlzQXJyYXkocmVzdWx0cykpIHtcbiAgICAgIHJlc3VsdHMgPSBbIHJlc3VsdHMgXTtcbiAgICB9XG4gICAgcmV0dXJuIG9uUmVzb2x2ZShyZXN1bHRzKTtcbiAgfSwgb25SZWplY3QpO1xufTtcblxuLyoqXG4gKiBQcm9taXNlL0ErIGV4dGVuc2lvblxuICogQ2FsbCBcInRoZW5cIiB1c2luZyBnaXZlbiBub2RlLXN0eWxlIGNhbGxiYWNrIGZ1bmN0aW9uXG4gKlxuICogQG1ldGhvZCBNZXRhZGF0YX5Bc3luY1Jlc3VsdExvY2F0b3IjdGhlbkNhbGxcbiAqL1xuQXN5bmNSZXN1bHRMb2NhdG9yLnByb3RvdHlwZS50aGVuQ2FsbCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHJldHVybiBfLmlzRnVuY3Rpb24oY2FsbGJhY2spID8gdGhpcy50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24oKSB7XG4gICAgICBjYWxsYmFjayhudWxsLCByZXMpO1xuICAgIH0pO1xuICB9LCBmdW5jdGlvbihlcnIpIHtcbiAgICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uKCkge1xuICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICB9KTtcbiAgfSkgOiB0aGlzO1xufTtcblxuLyoqXG4gKiBDaGVjayB0aGUgc3RhdHVzIG9mIGFzeW5jIHJlcXVlc3RcbiAqXG4gKiBAbWV0aG9kIE1ldGFkYXRhfkFzeW5jUmVzdWx0TG9jYXRvciNjaGVja1xuICogQHBhcmFtIHtDYWxsYmFjay48TWV0YWRhdGF+QXN5bmNSZXN1bHR8QXJyYXkuPE1ldGFkYXRhfkFzeW5jUmVzdWx0Pj59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPE1ldGFkYXRhfkFzeW5jUmVzdWx0fEFycmF5LjxNZXRhZGF0YX5Bc3luY1Jlc3VsdD4+fVxuICovXG5Bc3luY1Jlc3VsdExvY2F0b3IucHJvdG90eXBlLmNoZWNrID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgbWV0YSA9IHRoaXMuX21ldGE7XG4gIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24ocmVzdWx0cykge1xuICAgIHZhciBpZHMgPSBfLmlzQXJyYXkocmVzdWx0cykgPyBfLm1hcChyZXN1bHRzLCBmdW5jdGlvbihyZXMpeyByZXR1cm4gcmVzLmlkOyB9KSA6IHJlc3VsdHMuaWQ7XG4gICAgc2VsZi5faWRzID0gaWRzO1xuICAgIHJldHVybiBtZXRhLmNoZWNrU3RhdHVzKGlkcyk7XG4gIH0pLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogUG9sbGluZyB1bnRpbCBhc3luYyBjYWxsIHN0YXR1cyBiZWNvbWVzIGNvbXBsZXRlIG9yIGVycm9yXG4gKlxuICogQG1ldGhvZCBNZXRhZGF0YX5Bc3luY1Jlc3VsdExvY2F0b3IjcG9sbFxuICogQHBhcmFtIHtOdW1iZXJ9IGludGVydmFsIC0gUG9sbGluZyBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lb3V0IC0gUG9sbGluZyB0aW1lb3V0IGluIG1pbGxpc2Vjb25kc1xuICovXG5Bc3luY1Jlc3VsdExvY2F0b3IucHJvdG90eXBlLnBvbGwgPSBmdW5jdGlvbihpbnRlcnZhbCwgdGltZW91dCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBzdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgdmFyIHBvbGwgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgbm93ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgaWYgKHN0YXJ0VGltZSArIHRpbWVvdXQgPCBub3cpIHtcbiAgICAgIHZhciBlcnJNc2cgPSBcIlBvbGxpbmcgdGltZSBvdXQuXCI7XG4gICAgICBpZiAoc2VsZi5faWRzKSB7XG4gICAgICAgIGVyck1zZyArPSBcIiBQcm9jZXNzIElkID0gXCIgKyBzZWxmLl9pZHM7XG4gICAgICB9XG4gICAgICBzZWxmLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKGVyck1zZykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZWxmLmNoZWNrKCkudGhlbihmdW5jdGlvbihyZXN1bHRzKSB7XG4gICAgICB2YXIgZG9uZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0QXJyID0gXy5pc0FycmF5KHJlc3VsdHMpID8gcmVzdWx0cyA6IFsgcmVzdWx0cyBdO1xuICAgICAgZm9yICh2YXIgaT0wLCBsZW49cmVzdWx0QXJyLmxlbmd0aDsgaTxsZW47IGkrKykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gcmVzdWx0QXJyW2ldO1xuICAgICAgICBpZiAocmVzdWx0ICYmICFyZXN1bHQuZG9uZSkge1xuICAgICAgICAgIHNlbGYuZW1pdCgncHJvZ3Jlc3MnLCByZXN1bHQpO1xuICAgICAgICAgIGRvbmUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgc2VsZi5lbWl0KCdjb21wbGV0ZScsIHJlc3VsdHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChwb2xsLCBpbnRlcnZhbCk7XG4gICAgICB9XG4gICAgfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICBzZWxmLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICB9KTtcbiAgfTtcbiAgc2V0VGltZW91dChwb2xsLCBpbnRlcnZhbCk7XG59O1xuXG4vKipcbiAqIENoZWNrIGFuZCB3YWl0IHVudGlsIHRoZSBhc3luYyByZXF1ZXN0cyBiZWNvbWUgaW4gY29tcGxldGVkIHN0YXR1c1xuICpcbiAqIEBtZXRob2QgTWV0YWRhdGF+QXN5bmNSZXN1bHRMb2NhdG9yI2NvbXBsZXRlXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxNZXRhZGF0YX5Bc3luY1Jlc3VsdHxBcnJheS48TWV0YWRhdGF+QXN5bmNSZXN1bHQ+Pn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7UHJvbWlzZS48TWV0YWRhdGF+QXN5bmNSZXN1bHR8QXJyYXkuPE1ldGFkYXRhfkFzeW5jUmVzdWx0Pj59XG4gKi9cbkFzeW5jUmVzdWx0TG9jYXRvci5wcm90b3R5cGUuY29tcGxldGUgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgZGVmZXJyZWQgPSBQcm9taXNlLmRlZmVyKCk7XG4gIHRoaXMub24oJ2NvbXBsZXRlJywgZnVuY3Rpb24ocmVzdWx0cykge1xuICAgIGRlZmVycmVkLnJlc29sdmUocmVzdWx0cyk7XG4gIH0pO1xuICB0aGlzLm9uKCdlcnJvcicsIGZ1bmN0aW9uKGVycikge1xuICAgIGRlZmVycmVkLnJlamVjdChlcnIpO1xuICB9KTtcbiAgdmFyIG1ldGEgPSB0aGlzLl9tZXRhO1xuICB0aGlzLnBvbGwobWV0YS5wb2xsSW50ZXJ2YWwsIG1ldGEucG9sbFRpbWVvdXQpO1xuICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbi8qKlxuICogVGhlIGxvY2F0b3IgY2xhc3MgdG8gdHJhY2sgcmV0cmVpdmUoKSBNZXRhZGF0YSBBUEkgY2FsbCByZXN1bHRcbiAqXG4gKiBAcHJvdGVjdGVkXG4gKiBAY2xhc3MgTWV0YWRhdGF+UmV0cmlldmVSZXN1bHRMb2NhdG9yXG4gKiBAZXh0ZW5kcyBNZXRhZGF0YX5Bc3luY1Jlc3VsdExvY2F0b3JcbiAqIEBwYXJhbSB7TWV0YWRhdGF9IG1ldGEgLSBNZXRhZGF0YSBBUEkgb2JqZWN0XG4gKiBAcGFyYW0ge1Byb21pc2UuPE1ldGFkYXRhfkFzeW5jUmVzdWx0Pn0gcmVzdWx0IC0gUHJvbWlzZSBvYmplY3QgZm9yIGFzeW5jIHJlc3VsdCBvZiByZXRyaWV2ZSBjYWxsKClcbiAqL1xudmFyIFJldHJpZXZlUmVzdWx0TG9jYXRvciA9IGZ1bmN0aW9uKG1ldGEsIHJlc3VsdCkge1xuICBSZXRyaWV2ZVJlc3VsdExvY2F0b3Iuc3VwZXJfLmNhbGwodGhpcywgbWV0YSwgcmVzdWx0KTtcbn07XG5cbmluaGVyaXRzKFJldHJpZXZlUmVzdWx0TG9jYXRvciwgQXN5bmNSZXN1bHRMb2NhdG9yKTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZXRhZGF0YX5SZXRyaWV2ZVJlc3VsdFxuICogQHByb3Age0FycmF5LjxNZXRhZGF0YX5GaWxlUHJvcGVydGllcz59IGZpbGVQcm9wZXJ0aWVzIC0gQ29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHByb3BlcnRpZXMgb2YgZWFjaCBjb21wb25lbnQgaW4gdGhlIC56aXAgZmlsZSwgYW5kIHRoZSBtYW5pZmVzdCBmaWxlIHBhY2thZ2UueG1sXG4gKiBAcHJvcCB7U3RyaW5nfSBpZCAtIElEIG9mIHRoZSBjb21wb25lbnQgYmVpbmcgcmV0cmlldmVkXG4gKiBAcHJvcCB7QXJyYXkuPE9iamVjdD59IG1lc3NhZ2VzIC0gQ29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHN1Y2Nlc3Mgb3IgZmFpbHVyZSBvZiB0aGUgcmV0cmlldmUoKSBjYWxsXG4gKiBAcHJvcCB7U3RyaW5nfSB6aXBGaWxlIC0gVGhlIHppcCBmaWxlIHJldHVybmVkIGJ5IHRoZSByZXRyaWV2ZSByZXF1ZXN0LiBCYXNlIDY0LWVuY29kZWQgYmluYXJ5IGRhdGFcbiAqL1xuXG4vKipcbiAqIENoZWNrIGFuZCB3YWl0IHVudGlsIHRoZSBhc3luYyByZXF1ZXN0IGJlY29tZXMgaW4gY29tcGxldGVkIHN0YXR1cyxcbiAqIGFuZCByZXRyaWV2ZSB0aGUgcmVzdWx0IGRhdGEuXG4gKlxuICogQG1lbXRob2QgTWV0YWRhdGF+UmV0cmlldmVSZXN1bHRMb2NhdG9yI2NvbXBsZXRlXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxNZXRhZGF0YX5SZXRyaWV2ZVJlc3VsdD59IFtjYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2UuPE1ldGFkYXRhflJldHJpZXZlUmVzdWx0Pn1cbiAqL1xuUmV0cmlldmVSZXN1bHRMb2NhdG9yLnByb3RvdHlwZS5jb21wbGV0ZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHZhciBtZXRhID0gdGhpcy5fbWV0YTtcbiAgcmV0dXJuIFJldHJpZXZlUmVzdWx0TG9jYXRvci5zdXBlcl8ucHJvdG90eXBlLmNvbXBsZXRlLmNhbGwodGhpcykudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICByZXR1cm4gbWV0YS5jaGVja1JldHJpZXZlU3RhdHVzKHJlc3VsdC5pZCk7XG4gIH0pLnRoZW5DYWxsKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogQ2hhbmdlIHRoZSByZXRyaWV2ZWQgcmVzdWx0IHRvIE5vZGUuanMgcmVhZGFibGUgc3RyZWFtXG4gKlxuICogQG1ldGhvZCBNZXRhZGF0YX5SZXRyaWV2ZVJlc3VsdExvY2F0b3Ijc3RyZWFtXG4gKiBAcmV0dXJucyB7c3RyZWFtLlJlYWRhYmxlfVxuICovXG5SZXRyaWV2ZVJlc3VsdExvY2F0b3IucHJvdG90eXBlLnN0cmVhbSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciByZXN1bHRTdHJlYW0gPSBuZXcgc3RyZWFtLlJlYWRhYmxlKCk7XG4gIHZhciByZWFkaW5nID0gZmFsc2U7XG4gIHJlc3VsdFN0cmVhbS5fcmVhZCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmIChyZWFkaW5nKSB7IHJldHVybjsgfVxuICAgIHJlYWRpbmcgPSB0cnVlO1xuICAgIHNlbGYuY29tcGxldGUoZnVuY3Rpb24oZXJyLCByZXN1bHQpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmVzdWx0U3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdFN0cmVhbS5wdXNoKEJ1ZmZlci5mcm9tKHJlc3VsdC56aXBGaWxlLCAnYmFzZTY0JykpO1xuICAgICAgICByZXN1bHRTdHJlYW0ucHVzaChudWxsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbiAgcmV0dXJuIHJlc3VsdFN0cmVhbTtcbn07XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLyoqXG4gKiBUaGUgbG9jYXRvciBjbGFzcyB0byB0cmFjayBkZXBsb3koKSBNZXRhZGF0YSBBUEkgY2FsbCByZXN1bHRcbiAqXG4gKiBAcHJvdGVjdGVkXG4gKiBAY2xhc3MgTWV0YWRhdGF+RGVwbG95UmVzdWx0TG9jYXRvclxuICogQGV4dGVuZHMgTWV0YWRhdGF+QXN5bmNSZXN1bHRMb2NhdG9yXG4gKiBAcGFyYW0ge01ldGFkYXRhfSBtZXRhIC0gTWV0YWRhdGEgQVBJIG9iamVjdFxuICogQHBhcmFtIHtQcm9taXNlLjxNZXRhZGF0YX5Bc3luY1Jlc3VsdD59IHJlc3VsdCAtIFByb21pc2Ugb2JqZWN0IGZvciBhc3luYyByZXN1bHQgb2YgZGVwbG95KCkgY2FsbFxuICovXG52YXIgRGVwbG95UmVzdWx0TG9jYXRvciA9IGZ1bmN0aW9uKG1ldGEsIHJlc3VsdCkge1xuICBEZXBsb3lSZXN1bHRMb2NhdG9yLnN1cGVyXy5jYWxsKHRoaXMsIG1ldGEsIHJlc3VsdCk7XG59O1xuXG5pbmhlcml0cyhEZXBsb3lSZXN1bHRMb2NhdG9yLCBBc3luY1Jlc3VsdExvY2F0b3IpO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1ldGFkYXRhfkRlcGxveVJlc3VsdFxuICogQHByb3Age1N0cmluZ30gaWQgLSBJRCBvZiB0aGUgY29tcG9uZW50IGJlaW5nIGRlcGxveWVkXG4gKiBAcHJvcCB7Qm9vbGVhbn0gY2hlY2tPbmx5IC0gSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBkZXBsb3ltZW50IGlzIGJlaW5nIHVzZWQgdG8gY2hlY2sgdGhlIHZhbGlkaXR5IG9mIHRoZSBkZXBsb3llZCBmaWxlcyB3aXRob3V0IG1ha2luZyBhbnkgY2hhbmdlcyBpbiB0aGUgb3JnYW5pemF0aW9uIG9yIG5vdFxuICogQHByb3Age1N0cmluZ30gY29tcGxldGVkRGF0ZSAtIFRpbWVzdGFtcCBmb3Igd2hlbiB0aGUgZGVwbG95bWVudCBwcm9jZXNzIGVuZGVkXG4gKiBAcHJvcCB7U3RyaW5nfSBjcmVhdGVkRGF0ZSAtIFRpbWVzdGFtcCBmb3Igd2hlbiB0aGUgZGVwbG95KCkgY2FsbCB3YXMgcmVjZWl2ZWRcbiAqIEBwcm9wIHtBcnJheS48T2JqZWN0Pn0gW2RldGFpbHNdIC0gUHJvdmlkZXMgdGhlIGRldGFpbHMgb2YgYSBkZXBsb3ltZW50IHRoYXQgaXMgaW4tcHJvZ3Jlc3Mgb3IgZW5kZWQsIGlmIGluY2x1ZGVEZXRhaWxzIGlzIHNldCB0byB0cnVlIGluIGNoZWNrRGVwbG95U3RhdHVzKCkgY2FsbFxuICogQHByb3Age0Jvb2xlYW59IGRvbmUgLSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc2VydmVyIGZpbmlzaGVkIHByb2Nlc3NpbmcgdGhlIGRlcGxveSgpIGNhbGwgZm9yIHRoZSBzcGVjaWZpZWQgaWRcbiAqIEBwcm9wIHtTdHJpbmd9IFtlcnJvck1lc3NhZ2VdIC0gTWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIHRoZSB2YWx1ZXMgaW4gdGhlIGVycm9yU3RhdHVzQ29kZSBmaWVsZFxuICogQHByb3Age1N0cmluZ30gW2Vycm9yU3RhdHVzQ29kZV0gLSBJZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgdGhlIGRlcGxveSgpIGNhbGwsIGEgc3RhdHVzIGNvZGUgaXMgcmV0dXJuZWQsIGFuZCB0aGUgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBzdGF0dXMgY29kZSBpcyByZXR1cm5lZCBpbiB0aGUgZXJyb3JNZXNzYWdlZmllbGRcbiAqIEBwcm9wIHtCb29sZWFufSBbaWdub3JlV2FybmluZ3NdIC0gU3BlY2lmaWVzIHdoZXRoZXIgYSBkZXBsb3ltZW50IHNob3VsZCBjb250aW51ZSBldmVuIGlmIHRoZSBkZXBsb3ltZW50IGdlbmVyYXRlcyB3YXJuaW5nc1xuICogQHByb3Age1N0cmluZ30gbGFzdE1vZGlmaWVkRGF0ZSAtIFRpbWVzdGFtcCBvZiB0aGUgbGFzdCB1cGRhdGUgZm9yIHRoZSBkZXBsb3ltZW50IHByb2Nlc3NcbiAqIEBwcm9wIHtOdW1iZXJ9IG51bWJlckNvbXBvbmVudEVycm9ycyAtIFRoZSBudW1iZXIgb2YgY29tcG9uZW50cyB0aGF0IGdlbmVyYXRlZCBlcnJvcnMgZHVyaW5nIHRoaXMgZGVwbG95bWVudFxuICogQHByb3Age051bWJlcn0gbnVtYmVyQ29tcG9uZW50c0RlcGxveWVkIC0gVGhlIG51bWJlciBvZiBjb21wb25lbnRzIGRlcGxveWVkIGluIHRoZSBkZXBsb3ltZW50IHByb2Nlc3NcbiAqIEBwcm9wIHtOdW1iZXJ9IG51bWJlckNvbXBvbmVudHNUb3RhbCAtIFRoZSB0b3RhbCBudW1iZXIgb2YgY29tcG9uZW50cyBpbiB0aGUgZGVwbG95bWVudFxuICogQHByb3Age051bWJlcn0gbnVtYmVyVGVzdEVycm9ycyAtIFRoZSBudW1iZXIgb2YgQXBleCB0ZXN0cyB0aGF0IGhhdmUgZ2VuZXJhdGVkIGVycm9ycyBkdXJpbmcgdGhpcyBkZXBsb3ltZW50XG4gKiBAcHJvcCB7TnVtYmVyfSBudW1iZXJUZXN0c0NvbXBsZXRlZCAtIFRoZSBudW1iZXIgb2YgY29tcGxldGVkQXBleCB0ZXN0cyBmb3IgdGhpcyBkZXBsb3ltZW50XG4gKiBAcHJvcCB7TnVtYmVyfSBudW1iZXJUZXN0c1RvdGFsIC0gVGhlIHRvdGFsIG51bWJlciBvZiBBcGV4IHRlc3RzIGZvciB0aGlzIGRlcGxveW1lbnRcbiAqIEBwcm9wIHtCb29sZWFufSBbcm9sbGJhY2tPbkVycm9yXSAtIEluZGljYXRlcyB3aGV0aGVyIGFueSBmYWlsdXJlIGNhdXNlcyBhIGNvbXBsZXRlIHJvbGxiYWNrIG9yIG5vdC4gRGVmYXVsdCBpcyB0cnVlLlxuICogQHByb3Age1N0cmluZ30gc3RhcnREYXRlIC0gVGltZXN0YW1wIGZvciB3aGVuIHRoZSBkZXBsb3ltZW50IHByb2Nlc3MgYmVnYW5cbiAqIEBwcm9wIHtTdHJpbmd9IHN0YXR1cyAtIEluZGljYXRlcyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgZGVwbG95bWVudFxuICogQHByb3Age0Jvb2xlYW59IHN1Y2Nlc3MgLSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZGVwbG95bWVudCB3YXMgc3VjY2Vzc2Z1bCBvciBub3RcbiAqL1xuXG4vKipcbiAqIENoZWNrIGFuZCB3YWl0IHVudGlsIHRoZSBhc3luYyByZXF1ZXN0IGJlY29tZXMgaW4gY29tcGxldGVkIHN0YXR1cyxcbiAqIGFuZCByZXRyaWV2ZSB0aGUgcmVzdWx0IGRhdGEuXG4gKlxuICogQG1ldGhvZCBNZXRhZGF0YX5EZXBsb3lSZXN1bHRMb2NhdG9yI2NvbXBsZXRlXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxNZXRhZGF0YX5EZXBsb3lSZXN1bHQ+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtQcm9taXNlLjxNZXRhZGF0YX5EZXBsb3lSZXN1bHQ+fVxuICovXG5EZXBsb3lSZXN1bHRMb2NhdG9yLnByb3RvdHlwZS5jb21wbGV0ZSA9IGZ1bmN0aW9uKGluY2x1ZGVEZXRhaWxzLCBjYWxsYmFjaykge1xuICBpZiAoXy5pc0Z1bmN0aW9uKGluY2x1ZGVEZXRhaWxzKSkge1xuICAgIGNhbGxiYWNrID0gaW5jbHVkZURldGFpbHM7XG4gICAgaW5jbHVkZURldGFpbHMgPSBmYWxzZTtcbiAgfVxuICB2YXIgbWV0YSA9IHRoaXMuX21ldGE7XG4gIHJldHVybiBEZXBsb3lSZXN1bHRMb2NhdG9yLnN1cGVyXy5wcm90b3R5cGUuY29tcGxldGUuY2FsbCh0aGlzKS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgIHJldHVybiBtZXRhLmNoZWNrRGVwbG95U3RhdHVzKHJlc3VsdC5pZCwgaW5jbHVkZURldGFpbHMpO1xuICB9KS50aGVuQ2FsbChjYWxsYmFjayk7XG59O1xuXG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLypcbiAqIFJlZ2lzdGVyIGhvb2sgaW4gY29ubmVjdGlvbiBpbnN0YW50aWF0aW9uIGZvciBkeW5hbWljYWxseSBhZGRpbmcgdGhpcyBBUEkgbW9kdWxlIGZlYXR1cmVzXG4gKi9cbmpzZm9yY2Uub24oJ2Nvbm5lY3Rpb246bmV3JywgZnVuY3Rpb24oY29ubikge1xuICBjb25uLm1ldGFkYXRhID0gbmV3IE1ldGFkYXRhKGNvbm4pO1xufSk7XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKFxuICAgICAgdWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKVxuICAgICkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG52YXIgS19NQVhfTEVOR1RIID0gMHg3ZmZmZmZmZlxuZXhwb3J0cy5rTWF4TGVuZ3RoID0gS19NQVhfTEVOR1RIXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFByaW50IHdhcm5pbmcgYW5kIHJlY29tbWVuZCB1c2luZyBgYnVmZmVyYCB2NC54IHdoaWNoIGhhcyBhbiBPYmplY3RcbiAqICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIFdlIHJlcG9ydCB0aGF0IHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGlmIHRoZSBhcmUgbm90IHN1YmNsYXNzYWJsZVxuICogdXNpbmcgX19wcm90b19fLiBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YFxuICogKFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4KS4gSUUgMTAgbGFja3Mgc3VwcG9ydFxuICogZm9yIF9fcHJvdG9fXyBhbmQgaGFzIGEgYnVnZ3kgdHlwZWQgYXJyYXkgaW1wbGVtZW50YXRpb24uXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gdHlwZWRBcnJheVN1cHBvcnQoKVxuXG5pZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJlxuICAgIHR5cGVvZiBjb25zb2xlLmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gIGNvbnNvbGUuZXJyb3IoXG4gICAgJ1RoaXMgYnJvd3NlciBsYWNrcyB0eXBlZCBhcnJheSAoVWludDhBcnJheSkgc3VwcG9ydCB3aGljaCBpcyByZXF1aXJlZCBieSAnICtcbiAgICAnYGJ1ZmZlcmAgdjUueC4gVXNlIGBidWZmZXJgIHY0LnggaWYgeW91IHJlcXVpcmUgb2xkIGJyb3dzZXIgc3VwcG9ydC4nXG4gIClcbn1cblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICAvLyBDYW4gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWQ/XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHtfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLCBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH19XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDJcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIucHJvdG90eXBlLCAncGFyZW50Jywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5idWZmZXJcbiAgfVxufSlcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlci5wcm90b3R5cGUsICdvZmZzZXQnLCB7XG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmJ5dGVPZmZzZXRcbiAgfVxufSlcblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKGxlbmd0aCA+IEtfTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aCcpXG4gIH1cbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgYnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGJ1ZlxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUoYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG4vLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICYmXG4gICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgdmFsdWU6IG51bGwsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuZnVuY3Rpb24gZnJvbSAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAoaXNBcnJheUJ1ZmZlcih2YWx1ZSkgfHwgKHZhbHVlICYmIGlzQXJyYXlCdWZmZXIodmFsdWUuYnVmZmVyKSkpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgcmV0dXJuIGZyb21PYmplY3QodmFsdWUpXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20odmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuLy8gTm90ZTogQ2hhbmdlIHByb3RvdHlwZSAqYWZ0ZXIqIEJ1ZmZlci5mcm9tIGlzIGRlZmluZWQgdG8gd29ya2Fyb3VuZCBDaHJvbWUgYnVnOlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC8xNDhcbkJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbkJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcihzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2Moc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlIChzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIEJ1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShzaXplKVxufVxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIFNsb3dCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShzaXplKVxufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnIHx8IGVuY29kaW5nID09PSAnJykge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBieXRlTGVuZ3RoKHN0cmluZywgZW5jb2RpbmcpIHwgMFxuICB2YXIgYnVmID0gY3JlYXRlQnVmZmVyKGxlbmd0aClcblxuICB2YXIgYWN0dWFsID0gYnVmLndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICBidWYgPSBidWYuc2xpY2UoMCwgYWN0dWFsKVxuICB9XG5cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlIChhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgYnVmW2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJvZmZzZXRcIiBpcyBvdXRzaWRlIG9mIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcImxlbmd0aFwiIGlzIG91dHNpZGUgb2YgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICB2YXIgYnVmXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShhcnJheSlcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICBidWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKG9iaikge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iaikpIHtcbiAgICB2YXIgbGVuID0gY2hlY2tlZChvYmoubGVuZ3RoKSB8IDBcbiAgICB2YXIgYnVmID0gY3JlYXRlQnVmZmVyKGxlbilcblxuICAgIGlmIChidWYubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gYnVmXG4gICAgfVxuXG4gICAgb2JqLmNvcHkoYnVmLCAwLCAwLCBsZW4pXG4gICAgcmV0dXJuIGJ1ZlxuICB9XG5cbiAgaWYgKG9iaikge1xuICAgIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcob2JqKSB8fCAnbGVuZ3RoJyBpbiBvYmopIHtcbiAgICAgIGlmICh0eXBlb2Ygb2JqLmxlbmd0aCAhPT0gJ251bWJlcicgfHwgbnVtYmVySXNOYU4ob2JqLmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcigwKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2Uob2JqKVxuICAgIH1cblxuICAgIGlmIChvYmoudHlwZSA9PT0gJ0J1ZmZlcicgJiYgQXJyYXkuaXNBcnJheShvYmouZGF0YSkpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKG9iai5kYXRhKVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB0eXBlIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIEFycmF5LWxpa2UgT2JqZWN0LicpXG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBLX01BWF9MRU5HVEhgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0gS19NQVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIEtfTUFYX0xFTkdUSC50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuIGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlciA9PT0gdHJ1ZVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhidWYpKSB7XG4gICAgICBidWYgPSBCdWZmZXIuZnJvbShidWYpXG4gICAgfVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IGlzQXJyYXlCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHN0cmluZyA9ICcnICsgc3RyaW5nXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICAvLyBObyBuZWVkIHRvIHZlcmlmeSB0aGF0IFwidGhpcy5sZW5ndGggPD0gTUFYX1VJTlQzMlwiIHNpbmNlIGl0J3MgYSByZWFkLW9ubHlcbiAgLy8gcHJvcGVydHkgb2YgYSB0eXBlZCBhcnJheS5cblxuICAvLyBUaGlzIGJlaGF2ZXMgbmVpdGhlciBsaWtlIFN0cmluZyBub3IgVWludDhBcnJheSBpbiB0aGF0IHdlIHNldCBzdGFydC9lbmRcbiAgLy8gdG8gdGhlaXIgdXBwZXIvbG93ZXIgYm91bmRzIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgb3V0IG9mIHJhbmdlLlxuICAvLyB1bmRlZmluZWQgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYXMgcGVyIEVDTUEtMjYyIDZ0aCBFZGl0aW9uLFxuICAvLyBTZWN0aW9uIDEzLjMuMy43IFJ1bnRpbWUgU2VtYW50aWNzOiBLZXllZEJpbmRpbmdJbml0aWFsaXphdGlvbi5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQgfHwgc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgLy8gUmV0dXJuIGVhcmx5IGlmIHN0YXJ0ID4gdGhpcy5sZW5ndGguIERvbmUgaGVyZSB0byBwcmV2ZW50IHBvdGVudGlhbCB1aW50MzJcbiAgLy8gY29lcmNpb24gZmFpbCBiZWxvdy5cbiAgaWYgKHN0YXJ0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoZW5kIDw9IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEZvcmNlIGNvZXJzaW9uIHRvIHVpbnQzMi4gVGhpcyB3aWxsIGFsc28gY29lcmNlIGZhbHNleS9OYU4gdmFsdWVzIHRvIDAuXG4gIGVuZCA+Pj49IDBcbiAgc3RhcnQgPj4+PSAwXG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoaXMgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCAoYW5kIHRoZSBgaXMtYnVmZmVyYCBucG0gcGFja2FnZSlcbi8vIHRvIGRldGVjdCBhIEJ1ZmZlciBpbnN0YW5jZS4gSXQncyBub3QgcG9zc2libGUgdG8gdXNlIGBpbnN0YW5jZW9mIEJ1ZmZlcmBcbi8vIHJlbGlhYmx5IGluIGEgYnJvd3NlcmlmeSBjb250ZXh0IGJlY2F1c2UgdGhlcmUgY291bGQgYmUgbXVsdGlwbGUgZGlmZmVyZW50XG4vLyBjb3BpZXMgb2YgdGhlICdidWZmZXInIHBhY2thZ2UgaW4gdXNlLiBUaGlzIG1ldGhvZCB3b3JrcyBldmVuIGZvciBCdWZmZXJcbi8vIGluc3RhbmNlcyB0aGF0IHdlcmUgY3JlYXRlZCBmcm9tIGFub3RoZXIgY29weSBvZiB0aGUgYGJ1ZmZlcmAgcGFja2FnZS5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvaXNzdWVzLzE1NFxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbmZ1bmN0aW9uIHN3YXAgKGIsIG4sIG0pIHtcbiAgdmFyIGkgPSBiW25dXG4gIGJbbl0gPSBiW21dXG4gIGJbbV0gPSBpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2ID0gZnVuY3Rpb24gc3dhcDE2ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMSlcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAzMiA9IGZ1bmN0aW9uIHN3YXAzMiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDMpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDIpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwNjQgPSBmdW5jdGlvbiBzd2FwNjQgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDgpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyA3KVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyA2KVxuICAgIHN3YXAodGhpcywgaSArIDIsIGkgKyA1KVxuICAgIHN3YXAodGhpcywgaSArIDMsIGkgKyA0KVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0xvY2FsZVN0cmluZyA9IEJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmdcblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpc1N0YXJ0LCB0aGlzRW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgIC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChudW1iZXJJc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChudW1iZXJJc05hTihwYXJzZWQpKSByZXR1cm4gaVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gbGF0aW4xV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCA+Pj4gMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIChieXRlc1tpICsgMV0gKiAyNTYpKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgKDggKiBieXRlTGVuZ3RoKSAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsICg4ICogYnl0ZUxlbmd0aCkgLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpICsgMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdhcmd1bWVudCBzaG91bGQgYmUgYSBCdWZmZXInKVxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuY29weVdpdGhpbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIFVzZSBidWlsdC1pbiB3aGVuIGF2YWlsYWJsZSwgbWlzc2luZyBmcm9tIElFMTFcbiAgICB0aGlzLmNvcHlXaXRoaW4odGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpXG4gIH0gZWxzZSBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKHZhciBpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmICgoZW5jb2RpbmcgPT09ICd1dGY4JyAmJiBjb2RlIDwgMTI4KSB8fFxuICAgICAgICAgIGVuY29kaW5nID09PSAnbGF0aW4xJykge1xuICAgICAgICAvLyBGYXN0IHBhdGg6IElmIGB2YWxgIGZpdHMgaW50byBhIHNpbmdsZSBieXRlLCB1c2UgdGhhdCBudW1lcmljIHZhbHVlLlxuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogbmV3IEJ1ZmZlcih2YWwsIGVuY29kaW5nKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBpZiAobGVuID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgdmFsdWUgXCInICsgdmFsICtcbiAgICAgICAgJ1wiIGlzIGludmFsaWQgZm9yIGFyZ3VtZW50IFwidmFsdWVcIicpXG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teKy8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgdGFrZXMgZXF1YWwgc2lnbnMgYXMgZW5kIG9mIHRoZSBCYXNlNjQgZW5jb2RpbmdcbiAgc3RyID0gc3RyLnNwbGl0KCc9JylbMF1cbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0ci50cmltKCkucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG4vLyBBcnJheUJ1ZmZlcnMgZnJvbSBhbm90aGVyIGNvbnRleHQgKGkuZS4gYW4gaWZyYW1lKSBkbyBub3QgcGFzcyB0aGUgYGluc3RhbmNlb2ZgIGNoZWNrXG4vLyBidXQgdGhleSBzaG91bGQgYmUgdHJlYXRlZCBhcyB2YWxpZC4gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9pc3N1ZXMvMTY2XG5mdW5jdGlvbiBpc0FycmF5QnVmZmVyIChvYmopIHtcbiAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8XG4gICAgKG9iaiAhPSBudWxsICYmIG9iai5jb25zdHJ1Y3RvciAhPSBudWxsICYmIG9iai5jb25zdHJ1Y3Rvci5uYW1lID09PSAnQXJyYXlCdWZmZXInICYmXG4gICAgICB0eXBlb2Ygb2JqLmJ5dGVMZW5ndGggPT09ICdudW1iZXInKVxufVxuXG5mdW5jdGlvbiBudW1iZXJJc05hTiAob2JqKSB7XG4gIHJldHVybiBvYmogIT09IG9iaiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuIiwiZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiJdfQ==