@cartanova/qgrid-cli 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +9 -0
  2. package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +6 -0
  3. package/bundle/dist/dist/_virtual/_rolldown/runtime.js +15 -0
  4. package/bundle/dist/dist/application/qgrid/oauth.js +140 -0
  5. package/bundle/dist/dist/application/qgrid/pool.js +100 -0
  6. package/bundle/dist/dist/application/qgrid/qgrid.frame.js +280 -0
  7. package/bundle/dist/dist/application/qgrid/qgrid.types.js +79 -0
  8. package/bundle/dist/dist/application/qgrid/worker.js +183 -0
  9. package/bundle/dist/dist/application/queries.generated.js +31 -0
  10. package/bundle/dist/dist/application/request-log/request-log.model.js +113 -0
  11. package/bundle/dist/dist/application/request-log/request-log.types.js +13 -0
  12. package/bundle/dist/dist/application/sonamu.generated.js +99 -0
  13. package/bundle/dist/dist/application/sonamu.generated.sso.js +34 -0
  14. package/bundle/dist/dist/application/token/token.model.js +157 -0
  15. package/bundle/dist/dist/application/token/token.types.js +22 -0
  16. package/bundle/dist/dist/i18n/en.js +63 -0
  17. package/bundle/dist/dist/i18n/ko.js +62 -0
  18. package/bundle/dist/dist/i18n/sd.generated.js +272 -0
  19. package/bundle/dist/dist/index.js +11 -0
  20. package/bundle/dist/dist/migrations/20260410171405_create__request_logs.js +26 -0
  21. package/bundle/dist/dist/migrations/20260410171406_create__tokens.js +24 -0
  22. package/bundle/dist/dist/migrations/20260411120624_alter_tokens_alter2.js +16 -0
  23. package/bundle/dist/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +155 -0
  24. package/bundle/dist/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +1484 -0
  25. package/bundle/dist/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +887 -0
  26. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +2746 -0
  27. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +8 -0
  28. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +8 -0
  29. package/bundle/dist/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +662 -0
  30. package/bundle/dist/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +386 -0
  31. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +82 -0
  32. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +48 -0
  33. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +1307 -0
  34. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +558 -0
  35. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +33 -0
  36. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +226 -0
  37. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +27 -0
  38. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +77 -0
  39. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +374 -0
  40. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +37 -0
  41. package/bundle/dist/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +2886 -0
  42. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +10 -0
  43. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +109 -0
  44. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +10 -0
  45. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +10 -0
  46. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +10 -0
  47. package/bundle/dist/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +1127 -0
  48. package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +21 -0
  49. package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +432 -0
  50. package/bundle/dist/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +506 -0
  51. package/bundle/dist/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +86 -0
  52. package/bundle/dist/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.9.2_@emnapi_runtime@1.9.2_@types_node@25.0.7_esbuild@0.27.4_jiti@2.6.1_sass@1.98.0_tsx@4.21.0/node_modules/vite/dist/node/module-runner.js +426 -0
  53. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +6 -0
  54. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +41 -0
  55. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +19 -0
  56. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +202 -0
  57. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.DOa3dzoN.js +16 -0
  58. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +59 -0
  59. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/test.p_J6dB8a.js +2910 -0
  60. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +44 -0
  61. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/index.js +28 -0
  62. package/bundle/dist/dist/sonamu.config.js +196 -0
  63. package/bundle/dist/dist/testing/fixture.js +8 -0
  64. package/bundle/dist/dist/testing/global.js +9 -0
  65. package/bundle/dist/dist/testing/setup-mocks.js +17 -0
  66. package/bundle/dist/dist/utils/subset-loaders.js +12 -0
  67. package/bundle/src/src/application/qgrid/oauth.ts +181 -0
  68. package/bundle/src/src/application/qgrid/pool.ts +132 -0
  69. package/bundle/src/src/application/qgrid/qgrid.frame.ts +275 -0
  70. package/bundle/src/src/application/qgrid/qgrid.types.ts +117 -0
  71. package/bundle/src/src/application/qgrid/worker.ts +234 -0
  72. package/bundle/src/src/application/queries.generated.ts +59 -0
  73. package/bundle/src/src/application/request-log/request-log.entity.json +75 -0
  74. package/bundle/src/src/application/request-log/request-log.model.ts +155 -0
  75. package/bundle/src/src/application/request-log/request-log.types.ts +15 -0
  76. package/bundle/src/src/application/sonamu.generated.http +187 -0
  77. package/bundle/src/src/application/sonamu.generated.sso.ts +66 -0
  78. package/bundle/src/src/application/sonamu.generated.ts +135 -0
  79. package/bundle/src/src/application/token/token.entity.json +37 -0
  80. package/bundle/src/src/application/token/token.model.ts +160 -0
  81. package/bundle/src/src/application/token/token.types.ts +26 -0
  82. package/bundle/src/src/i18n/en.ts +59 -0
  83. package/bundle/src/src/i18n/ko.ts +59 -0
  84. package/bundle/src/src/i18n/sd.generated.ts +384 -0
  85. package/bundle/src/src/index.ts +6 -0
  86. package/bundle/src/src/migrations/20260410171405_create__request_logs.ts +23 -0
  87. package/bundle/src/src/migrations/20260410171406_create__tokens.ts +21 -0
  88. package/bundle/src/src/migrations/20260411120624_alter_tokens_alter2.ts +15 -0
  89. package/bundle/src/src/sonamu.config.ts +248 -0
  90. package/bundle/src/src/testing/fixture.ts +6 -0
  91. package/bundle/src/src/testing/global.ts +6 -0
  92. package/bundle/src/src/testing/setup-mocks.ts +44 -0
  93. package/bundle/src/src/typings/fastify.d.ts +8 -0
  94. package/bundle/src/src/typings/sonamu.d.ts +17 -0
  95. package/bundle/src/src/utils/subset-loaders.ts +11 -0
  96. package/bundle/web-dist/web-dist/client/assets/index-DlPchHBY.js +116 -0
  97. package/bundle/web-dist/web-dist/client/assets/index-vZsvyuFn.css +1 -0
  98. package/bundle/web-dist/web-dist/client/assets/rolldown-runtime-Dw2cE7zH.js +1 -0
  99. package/bundle/web-dist/web-dist/client/assets/routes-CagDz23B.js +1 -0
  100. package/bundle/web-dist/web-dist/client/assets/sd.generated-BrQoQXvv.js +47 -0
  101. package/bundle/web-dist/web-dist/client/assets/services.generated-BspO2L0j.js +1 -0
  102. package/bundle/web-dist/web-dist/client/assets/show-aXUGa0gm.js +29 -0
  103. package/bundle/web-dist/web-dist/client/assets/tokens-DRkXtZ3Q.js +1 -0
  104. package/bundle/web-dist/web-dist/client/assets/vendor-react-DH4kUfK2.js +9 -0
  105. package/bundle/web-dist/web-dist/client/assets/vendor-tanstack-CUxlo6YN.js +1 -0
  106. package/bundle/web-dist/web-dist/client/index.html +18 -0
  107. package/bundle/web-dist/web-dist/server/assets/react-dom-CGIzOSuj.js +335 -0
  108. package/bundle/web-dist/web-dist/server/assets/routes-ClzReRep.js +490 -0
  109. package/bundle/web-dist/web-dist/server/assets/sd.generated-BnonqqKr.js +21694 -0
  110. package/bundle/web-dist/web-dist/server/assets/services.generated-D5ABD5fr.js +836 -0
  111. package/bundle/web-dist/web-dist/server/assets/show-C9pcdSxc.js +23364 -0
  112. package/bundle/web-dist/web-dist/server/assets/tokens-JH6FsnWZ.js +860 -0
  113. package/bundle/web-dist/web-dist/server/entry-server.generated.js +44646 -0
  114. package/package.json +11 -10
@@ -0,0 +1,1307 @@
1
+ import { y } from "../../../../../tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js";
2
+ import { format, plugins } from "../../../../../@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js";
3
+ import { stringify } from "./display.js";
4
+ import "./constants.js";
5
+ import { deepClone, getOwnProperties, getType as getType$1 } from "./helpers.js";
6
+ /**
7
+ * Class representing one diff tuple.
8
+ * Attempts to look like a two-element array (which is what this used to be).
9
+ * @param {number} op Operation, one of: DIFF_DELETE, DIFF_INSERT, DIFF_EQUAL.
10
+ * @param {string} text Text to be deleted, inserted, or retained.
11
+ * @constructor
12
+ */
13
+ var Diff = class {
14
+ 0;
15
+ 1;
16
+ constructor(op, text) {
17
+ this[0] = op;
18
+ this[1] = text;
19
+ }
20
+ };
21
+ /**
22
+ * Determine the common prefix of two strings.
23
+ * @param {string} text1 First string.
24
+ * @param {string} text2 Second string.
25
+ * @return {number} The number of characters common to the start of each
26
+ * string.
27
+ */
28
+ function diff_commonPrefix(text1, text2) {
29
+ if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) return 0;
30
+ let pointermin = 0;
31
+ let pointermax = Math.min(text1.length, text2.length);
32
+ let pointermid = pointermax;
33
+ let pointerstart = 0;
34
+ while (pointermin < pointermid) {
35
+ if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) {
36
+ pointermin = pointermid;
37
+ pointerstart = pointermin;
38
+ } else pointermax = pointermid;
39
+ pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
40
+ }
41
+ return pointermid;
42
+ }
43
+ /**
44
+ * Determine the common suffix of two strings.
45
+ * @param {string} text1 First string.
46
+ * @param {string} text2 Second string.
47
+ * @return {number} The number of characters common to the end of each string.
48
+ */
49
+ function diff_commonSuffix(text1, text2) {
50
+ if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) return 0;
51
+ let pointermin = 0;
52
+ let pointermax = Math.min(text1.length, text2.length);
53
+ let pointermid = pointermax;
54
+ let pointerend = 0;
55
+ while (pointermin < pointermid) {
56
+ if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) {
57
+ pointermin = pointermid;
58
+ pointerend = pointermin;
59
+ } else pointermax = pointermid;
60
+ pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
61
+ }
62
+ return pointermid;
63
+ }
64
+ /**
65
+ * Determine if the suffix of one string is the prefix of another.
66
+ * @param {string} text1 First string.
67
+ * @param {string} text2 Second string.
68
+ * @return {number} The number of characters common to the end of the first
69
+ * string and the start of the second string.
70
+ * @private
71
+ */
72
+ function diff_commonOverlap_(text1, text2) {
73
+ const text1_length = text1.length;
74
+ const text2_length = text2.length;
75
+ if (text1_length === 0 || text2_length === 0) return 0;
76
+ if (text1_length > text2_length) text1 = text1.substring(text1_length - text2_length);
77
+ else if (text1_length < text2_length) text2 = text2.substring(0, text1_length);
78
+ const text_length = Math.min(text1_length, text2_length);
79
+ if (text1 === text2) return text_length;
80
+ let best = 0;
81
+ let length = 1;
82
+ while (true) {
83
+ const pattern = text1.substring(text_length - length);
84
+ const found = text2.indexOf(pattern);
85
+ if (found === -1) return best;
86
+ length += found;
87
+ if (found === 0 || text1.substring(text_length - length) === text2.substring(0, length)) {
88
+ best = length;
89
+ length++;
90
+ }
91
+ }
92
+ }
93
+ /**
94
+ * Reduce the number of edits by eliminating semantically trivial equalities.
95
+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
96
+ */
97
+ function diff_cleanupSemantic(diffs) {
98
+ let changes = false;
99
+ const equalities = [];
100
+ let equalitiesLength = 0;
101
+ /** @type {?string} */
102
+ let lastEquality = null;
103
+ let pointer = 0;
104
+ let length_insertions1 = 0;
105
+ let length_deletions1 = 0;
106
+ let length_insertions2 = 0;
107
+ let length_deletions2 = 0;
108
+ while (pointer < diffs.length) {
109
+ if (diffs[pointer][0] === 0) {
110
+ equalities[equalitiesLength++] = pointer;
111
+ length_insertions1 = length_insertions2;
112
+ length_deletions1 = length_deletions2;
113
+ length_insertions2 = 0;
114
+ length_deletions2 = 0;
115
+ lastEquality = diffs[pointer][1];
116
+ } else {
117
+ if (diffs[pointer][0] === 1) length_insertions2 += diffs[pointer][1].length;
118
+ else length_deletions2 += diffs[pointer][1].length;
119
+ if (lastEquality && lastEquality.length <= Math.max(length_insertions1, length_deletions1) && lastEquality.length <= Math.max(length_insertions2, length_deletions2)) {
120
+ diffs.splice(equalities[equalitiesLength - 1], 0, new Diff(-1, lastEquality));
121
+ diffs[equalities[equalitiesLength - 1] + 1][0] = 1;
122
+ equalitiesLength--;
123
+ equalitiesLength--;
124
+ pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
125
+ length_insertions1 = 0;
126
+ length_deletions1 = 0;
127
+ length_insertions2 = 0;
128
+ length_deletions2 = 0;
129
+ lastEquality = null;
130
+ changes = true;
131
+ }
132
+ }
133
+ pointer++;
134
+ }
135
+ if (changes) diff_cleanupMerge(diffs);
136
+ diff_cleanupSemanticLossless(diffs);
137
+ pointer = 1;
138
+ while (pointer < diffs.length) {
139
+ if (diffs[pointer - 1][0] === -1 && diffs[pointer][0] === 1) {
140
+ const deletion = diffs[pointer - 1][1];
141
+ const insertion = diffs[pointer][1];
142
+ const overlap_length1 = diff_commonOverlap_(deletion, insertion);
143
+ const overlap_length2 = diff_commonOverlap_(insertion, deletion);
144
+ if (overlap_length1 >= overlap_length2) {
145
+ if (overlap_length1 >= deletion.length / 2 || overlap_length1 >= insertion.length / 2) {
146
+ diffs.splice(pointer, 0, new Diff(0, insertion.substring(0, overlap_length1)));
147
+ diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlap_length1);
148
+ diffs[pointer + 1][1] = insertion.substring(overlap_length1);
149
+ pointer++;
150
+ }
151
+ } else if (overlap_length2 >= deletion.length / 2 || overlap_length2 >= insertion.length / 2) {
152
+ diffs.splice(pointer, 0, new Diff(0, deletion.substring(0, overlap_length2)));
153
+ diffs[pointer - 1][0] = 1;
154
+ diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlap_length2);
155
+ diffs[pointer + 1][0] = -1;
156
+ diffs[pointer + 1][1] = deletion.substring(overlap_length2);
157
+ pointer++;
158
+ }
159
+ pointer++;
160
+ }
161
+ pointer++;
162
+ }
163
+ }
164
+ const nonAlphaNumericRegex_ = /[^a-z0-9]/i;
165
+ const whitespaceRegex_ = /\s/;
166
+ const linebreakRegex_ = /[\r\n]/;
167
+ const blanklineEndRegex_ = /\n\r?\n$/;
168
+ const blanklineStartRegex_ = /^\r?\n\r?\n/;
169
+ /**
170
+ * Look for single edits surrounded on both sides by equalities
171
+ * which can be shifted sideways to align the edit to a word boundary.
172
+ * e.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came.
173
+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
174
+ */
175
+ function diff_cleanupSemanticLossless(diffs) {
176
+ let pointer = 1;
177
+ while (pointer < diffs.length - 1) {
178
+ if (diffs[pointer - 1][0] === 0 && diffs[pointer + 1][0] === 0) {
179
+ let equality1 = diffs[pointer - 1][1];
180
+ let edit = diffs[pointer][1];
181
+ let equality2 = diffs[pointer + 1][1];
182
+ const commonOffset = diff_commonSuffix(equality1, edit);
183
+ if (commonOffset) {
184
+ const commonString = edit.substring(edit.length - commonOffset);
185
+ equality1 = equality1.substring(0, equality1.length - commonOffset);
186
+ edit = commonString + edit.substring(0, edit.length - commonOffset);
187
+ equality2 = commonString + equality2;
188
+ }
189
+ let bestEquality1 = equality1;
190
+ let bestEdit = edit;
191
+ let bestEquality2 = equality2;
192
+ let bestScore = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2);
193
+ while (edit.charAt(0) === equality2.charAt(0)) {
194
+ equality1 += edit.charAt(0);
195
+ edit = edit.substring(1) + equality2.charAt(0);
196
+ equality2 = equality2.substring(1);
197
+ const score = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2);
198
+ if (score >= bestScore) {
199
+ bestScore = score;
200
+ bestEquality1 = equality1;
201
+ bestEdit = edit;
202
+ bestEquality2 = equality2;
203
+ }
204
+ }
205
+ if (diffs[pointer - 1][1] !== bestEquality1) {
206
+ if (bestEquality1) diffs[pointer - 1][1] = bestEquality1;
207
+ else {
208
+ diffs.splice(pointer - 1, 1);
209
+ pointer--;
210
+ }
211
+ diffs[pointer][1] = bestEdit;
212
+ if (bestEquality2) diffs[pointer + 1][1] = bestEquality2;
213
+ else {
214
+ diffs.splice(pointer + 1, 1);
215
+ pointer--;
216
+ }
217
+ }
218
+ }
219
+ pointer++;
220
+ }
221
+ }
222
+ /**
223
+ * Reorder and merge like edit sections. Merge equalities.
224
+ * Any edit section can move as long as it doesn't cross an equality.
225
+ * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
226
+ */
227
+ function diff_cleanupMerge(diffs) {
228
+ diffs.push(new Diff(0, ""));
229
+ let pointer = 0;
230
+ let count_delete = 0;
231
+ let count_insert = 0;
232
+ let text_delete = "";
233
+ let text_insert = "";
234
+ let commonlength;
235
+ while (pointer < diffs.length) switch (diffs[pointer][0]) {
236
+ case 1:
237
+ count_insert++;
238
+ text_insert += diffs[pointer][1];
239
+ pointer++;
240
+ break;
241
+ case -1:
242
+ count_delete++;
243
+ text_delete += diffs[pointer][1];
244
+ pointer++;
245
+ break;
246
+ case 0:
247
+ if (count_delete + count_insert > 1) {
248
+ if (count_delete !== 0 && count_insert !== 0) {
249
+ commonlength = diff_commonPrefix(text_insert, text_delete);
250
+ if (commonlength !== 0) {
251
+ if (pointer - count_delete - count_insert > 0 && diffs[pointer - count_delete - count_insert - 1][0] === 0) diffs[pointer - count_delete - count_insert - 1][1] += text_insert.substring(0, commonlength);
252
+ else {
253
+ diffs.splice(0, 0, new Diff(0, text_insert.substring(0, commonlength)));
254
+ pointer++;
255
+ }
256
+ text_insert = text_insert.substring(commonlength);
257
+ text_delete = text_delete.substring(commonlength);
258
+ }
259
+ commonlength = diff_commonSuffix(text_insert, text_delete);
260
+ if (commonlength !== 0) {
261
+ diffs[pointer][1] = text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1];
262
+ text_insert = text_insert.substring(0, text_insert.length - commonlength);
263
+ text_delete = text_delete.substring(0, text_delete.length - commonlength);
264
+ }
265
+ }
266
+ pointer -= count_delete + count_insert;
267
+ diffs.splice(pointer, count_delete + count_insert);
268
+ if (text_delete.length) {
269
+ diffs.splice(pointer, 0, new Diff(-1, text_delete));
270
+ pointer++;
271
+ }
272
+ if (text_insert.length) {
273
+ diffs.splice(pointer, 0, new Diff(1, text_insert));
274
+ pointer++;
275
+ }
276
+ pointer++;
277
+ } else if (pointer !== 0 && diffs[pointer - 1][0] === 0) {
278
+ diffs[pointer - 1][1] += diffs[pointer][1];
279
+ diffs.splice(pointer, 1);
280
+ } else pointer++;
281
+ count_insert = 0;
282
+ count_delete = 0;
283
+ text_delete = "";
284
+ text_insert = "";
285
+ break;
286
+ }
287
+ if (diffs.at(-1)?.[1] === "") diffs.pop();
288
+ let changes = false;
289
+ pointer = 1;
290
+ while (pointer < diffs.length - 1) {
291
+ if (diffs[pointer - 1][0] === 0 && diffs[pointer + 1][0] === 0) {
292
+ if (diffs[pointer][1].substring(diffs[pointer][1].length - diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) {
293
+ diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length);
294
+ diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
295
+ diffs.splice(pointer - 1, 1);
296
+ changes = true;
297
+ } else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) {
298
+ diffs[pointer - 1][1] += diffs[pointer + 1][1];
299
+ diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1];
300
+ diffs.splice(pointer + 1, 1);
301
+ changes = true;
302
+ }
303
+ }
304
+ pointer++;
305
+ }
306
+ if (changes) diff_cleanupMerge(diffs);
307
+ }
308
+ /**
309
+ * Given two strings, compute a score representing whether the internal
310
+ * boundary falls on logical boundaries.
311
+ * Scores range from 6 (best) to 0 (worst).
312
+ * Closure, but does not reference any external variables.
313
+ * @param {string} one First string.
314
+ * @param {string} two Second string.
315
+ * @return {number} The score.
316
+ * @private
317
+ */
318
+ function diff_cleanupSemanticScore_(one, two) {
319
+ if (!one || !two) return 6;
320
+ const char1 = one.charAt(one.length - 1);
321
+ const char2 = two.charAt(0);
322
+ const nonAlphaNumeric1 = char1.match(nonAlphaNumericRegex_);
323
+ const nonAlphaNumeric2 = char2.match(nonAlphaNumericRegex_);
324
+ const whitespace1 = nonAlphaNumeric1 && char1.match(whitespaceRegex_);
325
+ const whitespace2 = nonAlphaNumeric2 && char2.match(whitespaceRegex_);
326
+ const lineBreak1 = whitespace1 && char1.match(linebreakRegex_);
327
+ const lineBreak2 = whitespace2 && char2.match(linebreakRegex_);
328
+ const blankLine1 = lineBreak1 && one.match(blanklineEndRegex_);
329
+ const blankLine2 = lineBreak2 && two.match(blanklineStartRegex_);
330
+ if (blankLine1 || blankLine2) return 5;
331
+ else if (lineBreak1 || lineBreak2) return 4;
332
+ else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) return 3;
333
+ else if (whitespace1 || whitespace2) return 2;
334
+ else if (nonAlphaNumeric1 || nonAlphaNumeric2) return 1;
335
+ return 0;
336
+ }
337
+ /**
338
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
339
+ *
340
+ * This source code is licensed under the MIT license found in the
341
+ * LICENSE file in the root directory of this source tree.
342
+ */
343
+ const NO_DIFF_MESSAGE = "Compared values have no visual difference.";
344
+ const SIMILAR_MESSAGE = "Compared values serialize to the same structure.\nPrinting internal object structure without calling `toJSON` instead.";
345
+ function getDefaultExportFromCjs(x) {
346
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
347
+ }
348
+ var build = {};
349
+ var hasRequiredBuild;
350
+ function requireBuild() {
351
+ if (hasRequiredBuild) return build;
352
+ hasRequiredBuild = 1;
353
+ Object.defineProperty(build, "__esModule", { value: true });
354
+ build.default = diffSequence;
355
+ /**
356
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
357
+ *
358
+ * This source code is licensed under the MIT license found in the
359
+ * LICENSE file in the root directory of this source tree.
360
+ *
361
+ */
362
+ const pkg = "diff-sequences";
363
+ const NOT_YET_SET = 0;
364
+ const countCommonItemsF = (aIndex, aEnd, bIndex, bEnd, isCommon) => {
365
+ let nCommon = 0;
366
+ while (aIndex < aEnd && bIndex < bEnd && isCommon(aIndex, bIndex)) {
367
+ aIndex += 1;
368
+ bIndex += 1;
369
+ nCommon += 1;
370
+ }
371
+ return nCommon;
372
+ };
373
+ const countCommonItemsR = (aStart, aIndex, bStart, bIndex, isCommon) => {
374
+ let nCommon = 0;
375
+ while (aStart <= aIndex && bStart <= bIndex && isCommon(aIndex, bIndex)) {
376
+ aIndex -= 1;
377
+ bIndex -= 1;
378
+ nCommon += 1;
379
+ }
380
+ return nCommon;
381
+ };
382
+ const extendPathsF = (d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF) => {
383
+ let iF = 0;
384
+ let kF = -d;
385
+ let aFirst = aIndexesF[iF];
386
+ let aIndexPrev1 = aFirst;
387
+ aIndexesF[iF] += countCommonItemsF(aFirst + 1, aEnd, bF + aFirst - kF + 1, bEnd, isCommon);
388
+ const nF = d < iMaxF ? d : iMaxF;
389
+ for (iF += 1, kF += 2; iF <= nF; iF += 1, kF += 2) {
390
+ if (iF !== d && aIndexPrev1 < aIndexesF[iF]) aFirst = aIndexesF[iF];
391
+ else {
392
+ aFirst = aIndexPrev1 + 1;
393
+ if (aEnd <= aFirst) return iF - 1;
394
+ }
395
+ aIndexPrev1 = aIndexesF[iF];
396
+ aIndexesF[iF] = aFirst + countCommonItemsF(aFirst + 1, aEnd, bF + aFirst - kF + 1, bEnd, isCommon);
397
+ }
398
+ return iMaxF;
399
+ };
400
+ const extendPathsR = (d, aStart, bStart, bR, isCommon, aIndexesR, iMaxR) => {
401
+ let iR = 0;
402
+ let kR = d;
403
+ let aFirst = aIndexesR[iR];
404
+ let aIndexPrev1 = aFirst;
405
+ aIndexesR[iR] -= countCommonItemsR(aStart, aFirst - 1, bStart, bR + aFirst - kR - 1, isCommon);
406
+ const nR = d < iMaxR ? d : iMaxR;
407
+ for (iR += 1, kR -= 2; iR <= nR; iR += 1, kR -= 2) {
408
+ if (iR !== d && aIndexesR[iR] < aIndexPrev1) aFirst = aIndexesR[iR];
409
+ else {
410
+ aFirst = aIndexPrev1 - 1;
411
+ if (aFirst < aStart) return iR - 1;
412
+ }
413
+ aIndexPrev1 = aIndexesR[iR];
414
+ aIndexesR[iR] = aFirst - countCommonItemsR(aStart, aFirst - 1, bStart, bR + aFirst - kR - 1, isCommon);
415
+ }
416
+ return iMaxR;
417
+ };
418
+ const extendOverlappablePathsF = (d, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, iMaxF, aIndexesR, iMaxR, division) => {
419
+ const bF = bStart - aStart;
420
+ const aLength = aEnd - aStart;
421
+ const baDeltaLength = bEnd - bStart - aLength;
422
+ const kMinOverlapF = -baDeltaLength - (d - 1);
423
+ const kMaxOverlapF = -baDeltaLength + (d - 1);
424
+ let aIndexPrev1 = NOT_YET_SET;
425
+ const nF = d < iMaxF ? d : iMaxF;
426
+ for (let iF = 0, kF = -d; iF <= nF; iF += 1, kF += 2) {
427
+ const insert = iF === 0 || iF !== d && aIndexPrev1 < aIndexesF[iF];
428
+ const aLastPrev = insert ? aIndexesF[iF] : aIndexPrev1;
429
+ const aFirst = insert ? aLastPrev : aLastPrev + 1;
430
+ const bFirst = bF + aFirst - kF;
431
+ const nCommonF = countCommonItemsF(aFirst + 1, aEnd, bFirst + 1, bEnd, isCommon);
432
+ const aLast = aFirst + nCommonF;
433
+ aIndexPrev1 = aIndexesF[iF];
434
+ aIndexesF[iF] = aLast;
435
+ if (kMinOverlapF <= kF && kF <= kMaxOverlapF) {
436
+ const iR = (d - 1 - (kF + baDeltaLength)) / 2;
437
+ if (iR <= iMaxR && aIndexesR[iR] - 1 <= aLast) {
438
+ const bLastPrev = bF + aLastPrev - (insert ? kF + 1 : kF - 1);
439
+ const nCommonR = countCommonItemsR(aStart, aLastPrev, bStart, bLastPrev, isCommon);
440
+ const aIndexPrevFirst = aLastPrev - nCommonR;
441
+ const bIndexPrevFirst = bLastPrev - nCommonR;
442
+ const aEndPreceding = aIndexPrevFirst + 1;
443
+ const bEndPreceding = bIndexPrevFirst + 1;
444
+ division.nChangePreceding = d - 1;
445
+ if (d - 1 === aEndPreceding + bEndPreceding - aStart - bStart) {
446
+ division.aEndPreceding = aStart;
447
+ division.bEndPreceding = bStart;
448
+ } else {
449
+ division.aEndPreceding = aEndPreceding;
450
+ division.bEndPreceding = bEndPreceding;
451
+ }
452
+ division.nCommonPreceding = nCommonR;
453
+ if (nCommonR !== 0) {
454
+ division.aCommonPreceding = aEndPreceding;
455
+ division.bCommonPreceding = bEndPreceding;
456
+ }
457
+ division.nCommonFollowing = nCommonF;
458
+ if (nCommonF !== 0) {
459
+ division.aCommonFollowing = aFirst + 1;
460
+ division.bCommonFollowing = bFirst + 1;
461
+ }
462
+ const aStartFollowing = aLast + 1;
463
+ const bStartFollowing = bFirst + nCommonF + 1;
464
+ division.nChangeFollowing = d - 1;
465
+ if (d - 1 === aEnd + bEnd - aStartFollowing - bStartFollowing) {
466
+ division.aStartFollowing = aEnd;
467
+ division.bStartFollowing = bEnd;
468
+ } else {
469
+ division.aStartFollowing = aStartFollowing;
470
+ division.bStartFollowing = bStartFollowing;
471
+ }
472
+ return true;
473
+ }
474
+ }
475
+ }
476
+ return false;
477
+ };
478
+ const extendOverlappablePathsR = (d, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, iMaxF, aIndexesR, iMaxR, division) => {
479
+ const bR = bEnd - aEnd;
480
+ const aLength = aEnd - aStart;
481
+ const baDeltaLength = bEnd - bStart - aLength;
482
+ const kMinOverlapR = baDeltaLength - d;
483
+ const kMaxOverlapR = baDeltaLength + d;
484
+ let aIndexPrev1 = NOT_YET_SET;
485
+ const nR = d < iMaxR ? d : iMaxR;
486
+ for (let iR = 0, kR = d; iR <= nR; iR += 1, kR -= 2) {
487
+ const insert = iR === 0 || iR !== d && aIndexesR[iR] < aIndexPrev1;
488
+ const aLastPrev = insert ? aIndexesR[iR] : aIndexPrev1;
489
+ const aFirst = insert ? aLastPrev : aLastPrev - 1;
490
+ const bFirst = bR + aFirst - kR;
491
+ const nCommonR = countCommonItemsR(aStart, aFirst - 1, bStart, bFirst - 1, isCommon);
492
+ const aLast = aFirst - nCommonR;
493
+ aIndexPrev1 = aIndexesR[iR];
494
+ aIndexesR[iR] = aLast;
495
+ if (kMinOverlapR <= kR && kR <= kMaxOverlapR) {
496
+ const iF = (d + (kR - baDeltaLength)) / 2;
497
+ if (iF <= iMaxF && aLast - 1 <= aIndexesF[iF]) {
498
+ const bLast = bFirst - nCommonR;
499
+ division.nChangePreceding = d;
500
+ if (d === aLast + bLast - aStart - bStart) {
501
+ division.aEndPreceding = aStart;
502
+ division.bEndPreceding = bStart;
503
+ } else {
504
+ division.aEndPreceding = aLast;
505
+ division.bEndPreceding = bLast;
506
+ }
507
+ division.nCommonPreceding = nCommonR;
508
+ if (nCommonR !== 0) {
509
+ division.aCommonPreceding = aLast;
510
+ division.bCommonPreceding = bLast;
511
+ }
512
+ division.nChangeFollowing = d - 1;
513
+ if (d === 1) {
514
+ division.nCommonFollowing = 0;
515
+ division.aStartFollowing = aEnd;
516
+ division.bStartFollowing = bEnd;
517
+ } else {
518
+ const bLastPrev = bR + aLastPrev - (insert ? kR - 1 : kR + 1);
519
+ const nCommonF = countCommonItemsF(aLastPrev, aEnd, bLastPrev, bEnd, isCommon);
520
+ division.nCommonFollowing = nCommonF;
521
+ if (nCommonF !== 0) {
522
+ division.aCommonFollowing = aLastPrev;
523
+ division.bCommonFollowing = bLastPrev;
524
+ }
525
+ const aStartFollowing = aLastPrev + nCommonF;
526
+ const bStartFollowing = bLastPrev + nCommonF;
527
+ if (d - 1 === aEnd + bEnd - aStartFollowing - bStartFollowing) {
528
+ division.aStartFollowing = aEnd;
529
+ division.bStartFollowing = bEnd;
530
+ } else {
531
+ division.aStartFollowing = aStartFollowing;
532
+ division.bStartFollowing = bStartFollowing;
533
+ }
534
+ }
535
+ return true;
536
+ }
537
+ }
538
+ }
539
+ return false;
540
+ };
541
+ const divide = (nChange, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, aIndexesR, division) => {
542
+ const bF = bStart - aStart;
543
+ const bR = bEnd - aEnd;
544
+ const aLength = aEnd - aStart;
545
+ const bLength = bEnd - bStart;
546
+ const baDeltaLength = bLength - aLength;
547
+ let iMaxF = aLength;
548
+ let iMaxR = aLength;
549
+ aIndexesF[0] = aStart - 1;
550
+ aIndexesR[0] = aEnd;
551
+ if (baDeltaLength % 2 === 0) {
552
+ const dMin = (nChange || baDeltaLength) / 2;
553
+ const dMax = (aLength + bLength) / 2;
554
+ for (let d = 1; d <= dMax; d += 1) {
555
+ iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF);
556
+ if (d < dMin) iMaxR = extendPathsR(d, aStart, bStart, bR, isCommon, aIndexesR, iMaxR);
557
+ else if (extendOverlappablePathsR(d, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, iMaxF, aIndexesR, iMaxR, division)) return;
558
+ }
559
+ } else {
560
+ const dMin = ((nChange || baDeltaLength) + 1) / 2;
561
+ const dMax = (aLength + bLength + 1) / 2;
562
+ let d = 1;
563
+ iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF);
564
+ for (d += 1; d <= dMax; d += 1) {
565
+ iMaxR = extendPathsR(d - 1, aStart, bStart, bR, isCommon, aIndexesR, iMaxR);
566
+ if (d < dMin) iMaxF = extendPathsF(d, aEnd, bEnd, bF, isCommon, aIndexesF, iMaxF);
567
+ else if (extendOverlappablePathsF(d, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, iMaxF, aIndexesR, iMaxR, division)) return;
568
+ }
569
+ }
570
+ /* istanbul ignore next */
571
+ throw new Error(`${pkg}: no overlap aStart=${aStart} aEnd=${aEnd} bStart=${bStart} bEnd=${bEnd}`);
572
+ };
573
+ const findSubsequences = (nChange, aStart, aEnd, bStart, bEnd, transposed, callbacks, aIndexesF, aIndexesR, division) => {
574
+ if (bEnd - bStart < aEnd - aStart) {
575
+ transposed = !transposed;
576
+ if (transposed && callbacks.length === 1) {
577
+ const { foundSubsequence, isCommon } = callbacks[0];
578
+ callbacks[1] = {
579
+ foundSubsequence: (nCommon, bCommon, aCommon) => {
580
+ foundSubsequence(nCommon, aCommon, bCommon);
581
+ },
582
+ isCommon: (bIndex, aIndex) => isCommon(aIndex, bIndex)
583
+ };
584
+ }
585
+ const tStart = aStart;
586
+ const tEnd = aEnd;
587
+ aStart = bStart;
588
+ aEnd = bEnd;
589
+ bStart = tStart;
590
+ bEnd = tEnd;
591
+ }
592
+ const { foundSubsequence, isCommon } = callbacks[transposed ? 1 : 0];
593
+ divide(nChange, aStart, aEnd, bStart, bEnd, isCommon, aIndexesF, aIndexesR, division);
594
+ const { nChangePreceding, aEndPreceding, bEndPreceding, nCommonPreceding, aCommonPreceding, bCommonPreceding, nCommonFollowing, aCommonFollowing, bCommonFollowing, nChangeFollowing, aStartFollowing, bStartFollowing } = division;
595
+ if (aStart < aEndPreceding && bStart < bEndPreceding) findSubsequences(nChangePreceding, aStart, aEndPreceding, bStart, bEndPreceding, transposed, callbacks, aIndexesF, aIndexesR, division);
596
+ if (nCommonPreceding !== 0) foundSubsequence(nCommonPreceding, aCommonPreceding, bCommonPreceding);
597
+ if (nCommonFollowing !== 0) foundSubsequence(nCommonFollowing, aCommonFollowing, bCommonFollowing);
598
+ if (aStartFollowing < aEnd && bStartFollowing < bEnd) findSubsequences(nChangeFollowing, aStartFollowing, aEnd, bStartFollowing, bEnd, transposed, callbacks, aIndexesF, aIndexesR, division);
599
+ };
600
+ const validateLength = (name, arg) => {
601
+ if (typeof arg !== "number") throw new TypeError(`${pkg}: ${name} typeof ${typeof arg} is not a number`);
602
+ if (!Number.isSafeInteger(arg)) throw new RangeError(`${pkg}: ${name} value ${arg} is not a safe integer`);
603
+ if (arg < 0) throw new RangeError(`${pkg}: ${name} value ${arg} is a negative integer`);
604
+ };
605
+ const validateCallback = (name, arg) => {
606
+ const type = typeof arg;
607
+ if (type !== "function") throw new TypeError(`${pkg}: ${name} typeof ${type} is not a function`);
608
+ };
609
+ function diffSequence(aLength, bLength, isCommon, foundSubsequence) {
610
+ validateLength("aLength", aLength);
611
+ validateLength("bLength", bLength);
612
+ validateCallback("isCommon", isCommon);
613
+ validateCallback("foundSubsequence", foundSubsequence);
614
+ const nCommonF = countCommonItemsF(0, aLength, 0, bLength, isCommon);
615
+ if (nCommonF !== 0) foundSubsequence(nCommonF, 0, 0);
616
+ if (aLength !== nCommonF || bLength !== nCommonF) {
617
+ const aStart = nCommonF;
618
+ const bStart = nCommonF;
619
+ const nCommonR = countCommonItemsR(aStart, aLength - 1, bStart, bLength - 1, isCommon);
620
+ const aEnd = aLength - nCommonR;
621
+ const bEnd = bLength - nCommonR;
622
+ const nCommonFR = nCommonF + nCommonR;
623
+ if (aLength !== nCommonFR && bLength !== nCommonFR) findSubsequences(0, aStart, aEnd, bStart, bEnd, false, [{
624
+ foundSubsequence,
625
+ isCommon
626
+ }], [NOT_YET_SET], [NOT_YET_SET], {
627
+ aCommonFollowing: NOT_YET_SET,
628
+ aCommonPreceding: NOT_YET_SET,
629
+ aEndPreceding: NOT_YET_SET,
630
+ aStartFollowing: NOT_YET_SET,
631
+ bCommonFollowing: NOT_YET_SET,
632
+ bCommonPreceding: NOT_YET_SET,
633
+ bEndPreceding: NOT_YET_SET,
634
+ bStartFollowing: NOT_YET_SET,
635
+ nChangeFollowing: NOT_YET_SET,
636
+ nChangePreceding: NOT_YET_SET,
637
+ nCommonFollowing: NOT_YET_SET,
638
+ nCommonPreceding: NOT_YET_SET
639
+ });
640
+ if (nCommonR !== 0) foundSubsequence(nCommonR, aEnd, bEnd);
641
+ }
642
+ }
643
+ return build;
644
+ }
645
+ var diffSequences = /* @__PURE__ */ getDefaultExportFromCjs(/* @__PURE__ */ requireBuild());
646
+ function formatTrailingSpaces(line, trailingSpaceFormatter) {
647
+ return line.replace(/\s+$/, (match) => trailingSpaceFormatter(match));
648
+ }
649
+ function printDiffLine(line, isFirstOrLast, color, indicator, trailingSpaceFormatter, emptyFirstOrLastLinePlaceholder) {
650
+ return line.length !== 0 ? color(`${indicator} ${formatTrailingSpaces(line, trailingSpaceFormatter)}`) : indicator !== " " ? color(indicator) : isFirstOrLast && emptyFirstOrLastLinePlaceholder.length !== 0 ? color(`${indicator} ${emptyFirstOrLastLinePlaceholder}`) : "";
651
+ }
652
+ function printDeleteLine(line, isFirstOrLast, { aColor, aIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) {
653
+ return printDiffLine(line, isFirstOrLast, aColor, aIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder);
654
+ }
655
+ function printInsertLine(line, isFirstOrLast, { bColor, bIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) {
656
+ return printDiffLine(line, isFirstOrLast, bColor, bIndicator, changeLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder);
657
+ }
658
+ function printCommonLine(line, isFirstOrLast, { commonColor, commonIndicator, commonLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder }) {
659
+ return printDiffLine(line, isFirstOrLast, commonColor, commonIndicator, commonLineTrailingSpaceColor, emptyFirstOrLastLinePlaceholder);
660
+ }
661
+ function createPatchMark(aStart, aEnd, bStart, bEnd, { patchColor }) {
662
+ return patchColor(`@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@`);
663
+ }
664
+ function joinAlignedDiffsNoExpand(diffs, options) {
665
+ const iLength = diffs.length;
666
+ const nContextLines = options.contextLines;
667
+ const nContextLines2 = nContextLines + nContextLines;
668
+ let jLength = iLength;
669
+ let hasExcessAtStartOrEnd = false;
670
+ let nExcessesBetweenChanges = 0;
671
+ let i = 0;
672
+ while (i !== iLength) {
673
+ const iStart = i;
674
+ while (i !== iLength && diffs[i][0] === 0) i += 1;
675
+ if (iStart !== i) if (iStart === 0) {
676
+ if (i > nContextLines) {
677
+ jLength -= i - nContextLines;
678
+ hasExcessAtStartOrEnd = true;
679
+ }
680
+ } else if (i === iLength) {
681
+ const n = i - iStart;
682
+ if (n > nContextLines) {
683
+ jLength -= n - nContextLines;
684
+ hasExcessAtStartOrEnd = true;
685
+ }
686
+ } else {
687
+ const n = i - iStart;
688
+ if (n > nContextLines2) {
689
+ jLength -= n - nContextLines2;
690
+ nExcessesBetweenChanges += 1;
691
+ }
692
+ }
693
+ while (i !== iLength && diffs[i][0] !== 0) i += 1;
694
+ }
695
+ const hasPatch = nExcessesBetweenChanges !== 0 || hasExcessAtStartOrEnd;
696
+ if (nExcessesBetweenChanges !== 0) jLength += nExcessesBetweenChanges + 1;
697
+ else if (hasExcessAtStartOrEnd) jLength += 1;
698
+ const jLast = jLength - 1;
699
+ const lines = [];
700
+ let jPatchMark = 0;
701
+ if (hasPatch) lines.push("");
702
+ let aStart = 0;
703
+ let bStart = 0;
704
+ let aEnd = 0;
705
+ let bEnd = 0;
706
+ const pushCommonLine = (line) => {
707
+ const j = lines.length;
708
+ lines.push(printCommonLine(line, j === 0 || j === jLast, options));
709
+ aEnd += 1;
710
+ bEnd += 1;
711
+ };
712
+ const pushDeleteLine = (line) => {
713
+ const j = lines.length;
714
+ lines.push(printDeleteLine(line, j === 0 || j === jLast, options));
715
+ aEnd += 1;
716
+ };
717
+ const pushInsertLine = (line) => {
718
+ const j = lines.length;
719
+ lines.push(printInsertLine(line, j === 0 || j === jLast, options));
720
+ bEnd += 1;
721
+ };
722
+ i = 0;
723
+ while (i !== iLength) {
724
+ let iStart = i;
725
+ while (i !== iLength && diffs[i][0] === 0) i += 1;
726
+ if (iStart !== i) if (iStart === 0) {
727
+ if (i > nContextLines) {
728
+ iStart = i - nContextLines;
729
+ aStart = iStart;
730
+ bStart = iStart;
731
+ aEnd = aStart;
732
+ bEnd = bStart;
733
+ }
734
+ for (let iCommon = iStart; iCommon !== i; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
735
+ } else if (i === iLength) {
736
+ const iEnd = i - iStart > nContextLines ? iStart + nContextLines : i;
737
+ for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
738
+ } else {
739
+ const nCommon = i - iStart;
740
+ if (nCommon > nContextLines2) {
741
+ const iEnd = iStart + nContextLines;
742
+ for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
743
+ lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options);
744
+ jPatchMark = lines.length;
745
+ lines.push("");
746
+ const nOmit = nCommon - nContextLines2;
747
+ aStart = aEnd + nOmit;
748
+ bStart = bEnd + nOmit;
749
+ aEnd = aStart;
750
+ bEnd = bStart;
751
+ for (let iCommon = i - nContextLines; iCommon !== i; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
752
+ } else for (let iCommon = iStart; iCommon !== i; iCommon += 1) pushCommonLine(diffs[iCommon][1]);
753
+ }
754
+ while (i !== iLength && diffs[i][0] === -1) {
755
+ pushDeleteLine(diffs[i][1]);
756
+ i += 1;
757
+ }
758
+ while (i !== iLength && diffs[i][0] === 1) {
759
+ pushInsertLine(diffs[i][1]);
760
+ i += 1;
761
+ }
762
+ }
763
+ if (hasPatch) lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options);
764
+ return lines.join("\n");
765
+ }
766
+ function joinAlignedDiffsExpand(diffs, options) {
767
+ return diffs.map((diff, i, diffs) => {
768
+ const line = diff[1];
769
+ const isFirstOrLast = i === 0 || i === diffs.length - 1;
770
+ switch (diff[0]) {
771
+ case -1: return printDeleteLine(line, isFirstOrLast, options);
772
+ case 1: return printInsertLine(line, isFirstOrLast, options);
773
+ default: return printCommonLine(line, isFirstOrLast, options);
774
+ }
775
+ }).join("\n");
776
+ }
777
+ const noColor = (string) => string;
778
+ const DIFF_CONTEXT_DEFAULT = 5;
779
+ const DIFF_TRUNCATE_THRESHOLD_DEFAULT = 0;
780
+ function getDefaultOptions() {
781
+ return {
782
+ aAnnotation: "Expected",
783
+ aColor: y.green,
784
+ aIndicator: "-",
785
+ bAnnotation: "Received",
786
+ bColor: y.red,
787
+ bIndicator: "+",
788
+ changeColor: y.inverse,
789
+ changeLineTrailingSpaceColor: noColor,
790
+ commonColor: y.dim,
791
+ commonIndicator: " ",
792
+ commonLineTrailingSpaceColor: noColor,
793
+ compareKeys: void 0,
794
+ contextLines: DIFF_CONTEXT_DEFAULT,
795
+ emptyFirstOrLastLinePlaceholder: "",
796
+ expand: false,
797
+ includeChangeCounts: false,
798
+ omitAnnotationLines: false,
799
+ patchColor: y.yellow,
800
+ printBasicPrototype: false,
801
+ truncateThreshold: DIFF_TRUNCATE_THRESHOLD_DEFAULT,
802
+ truncateAnnotation: "... Diff result is truncated",
803
+ truncateAnnotationColor: noColor
804
+ };
805
+ }
806
+ function getCompareKeys(compareKeys) {
807
+ return compareKeys && typeof compareKeys === "function" ? compareKeys : void 0;
808
+ }
809
+ function getContextLines(contextLines) {
810
+ return typeof contextLines === "number" && Number.isSafeInteger(contextLines) && contextLines >= 0 ? contextLines : DIFF_CONTEXT_DEFAULT;
811
+ }
812
+ function normalizeDiffOptions(options = {}) {
813
+ return {
814
+ ...getDefaultOptions(),
815
+ ...options,
816
+ compareKeys: getCompareKeys(options.compareKeys),
817
+ contextLines: getContextLines(options.contextLines)
818
+ };
819
+ }
820
+ function isEmptyString(lines) {
821
+ return lines.length === 1 && lines[0].length === 0;
822
+ }
823
+ function countChanges(diffs) {
824
+ let a = 0;
825
+ let b = 0;
826
+ diffs.forEach((diff) => {
827
+ switch (diff[0]) {
828
+ case -1:
829
+ a += 1;
830
+ break;
831
+ case 1:
832
+ b += 1;
833
+ break;
834
+ }
835
+ });
836
+ return {
837
+ a,
838
+ b
839
+ };
840
+ }
841
+ function printAnnotation({ aAnnotation, aColor, aIndicator, bAnnotation, bColor, bIndicator, includeChangeCounts, omitAnnotationLines }, changeCounts) {
842
+ if (omitAnnotationLines) return "";
843
+ let aRest = "";
844
+ let bRest = "";
845
+ if (includeChangeCounts) {
846
+ const aCount = String(changeCounts.a);
847
+ const bCount = String(changeCounts.b);
848
+ const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length;
849
+ const aAnnotationPadding = " ".repeat(Math.max(0, baAnnotationLengthDiff));
850
+ const bAnnotationPadding = " ".repeat(Math.max(0, -baAnnotationLengthDiff));
851
+ const baCountLengthDiff = bCount.length - aCount.length;
852
+ const aCountPadding = " ".repeat(Math.max(0, baCountLengthDiff));
853
+ const bCountPadding = " ".repeat(Math.max(0, -baCountLengthDiff));
854
+ aRest = `${aAnnotationPadding} ${aIndicator} ${aCountPadding}${aCount}`;
855
+ bRest = `${bAnnotationPadding} ${bIndicator} ${bCountPadding}${bCount}`;
856
+ }
857
+ const a = `${aIndicator} ${aAnnotation}${aRest}`;
858
+ const b = `${bIndicator} ${bAnnotation}${bRest}`;
859
+ return `${aColor(a)}\n${bColor(b)}\n\n`;
860
+ }
861
+ function printDiffLines(diffs, truncated, options) {
862
+ return printAnnotation(options, countChanges(diffs)) + (options.expand ? joinAlignedDiffsExpand(diffs, options) : joinAlignedDiffsNoExpand(diffs, options)) + (truncated ? options.truncateAnnotationColor(`\n${options.truncateAnnotation}`) : "");
863
+ }
864
+ function diffLinesUnified(aLines, bLines, options) {
865
+ const normalizedOptions = normalizeDiffOptions(options);
866
+ const [diffs, truncated] = diffLinesRaw(isEmptyString(aLines) ? [] : aLines, isEmptyString(bLines) ? [] : bLines, normalizedOptions);
867
+ return printDiffLines(diffs, truncated, normalizedOptions);
868
+ }
869
+ function diffLinesUnified2(aLinesDisplay, bLinesDisplay, aLinesCompare, bLinesCompare, options) {
870
+ if (isEmptyString(aLinesDisplay) && isEmptyString(aLinesCompare)) {
871
+ aLinesDisplay = [];
872
+ aLinesCompare = [];
873
+ }
874
+ if (isEmptyString(bLinesDisplay) && isEmptyString(bLinesCompare)) {
875
+ bLinesDisplay = [];
876
+ bLinesCompare = [];
877
+ }
878
+ if (aLinesDisplay.length !== aLinesCompare.length || bLinesDisplay.length !== bLinesCompare.length) return diffLinesUnified(aLinesDisplay, bLinesDisplay, options);
879
+ const [diffs, truncated] = diffLinesRaw(aLinesCompare, bLinesCompare, options);
880
+ let aIndex = 0;
881
+ let bIndex = 0;
882
+ diffs.forEach((diff) => {
883
+ switch (diff[0]) {
884
+ case -1:
885
+ diff[1] = aLinesDisplay[aIndex];
886
+ aIndex += 1;
887
+ break;
888
+ case 1:
889
+ diff[1] = bLinesDisplay[bIndex];
890
+ bIndex += 1;
891
+ break;
892
+ default:
893
+ diff[1] = bLinesDisplay[bIndex];
894
+ aIndex += 1;
895
+ bIndex += 1;
896
+ }
897
+ });
898
+ return printDiffLines(diffs, truncated, normalizeDiffOptions(options));
899
+ }
900
+ function diffLinesRaw(aLines, bLines, options) {
901
+ const truncate = options?.truncateThreshold ?? false;
902
+ const truncateThreshold = Math.max(Math.floor(options?.truncateThreshold ?? 0), 0);
903
+ const aLength = truncate ? Math.min(aLines.length, truncateThreshold) : aLines.length;
904
+ const bLength = truncate ? Math.min(bLines.length, truncateThreshold) : bLines.length;
905
+ const truncated = aLength !== aLines.length || bLength !== bLines.length;
906
+ const isCommon = (aIndex, bIndex) => aLines[aIndex] === bLines[bIndex];
907
+ const diffs = [];
908
+ let aIndex = 0;
909
+ let bIndex = 0;
910
+ const foundSubsequence = (nCommon, aCommon, bCommon) => {
911
+ for (; aIndex !== aCommon; aIndex += 1) diffs.push(new Diff(-1, aLines[aIndex]));
912
+ for (; bIndex !== bCommon; bIndex += 1) diffs.push(new Diff(1, bLines[bIndex]));
913
+ for (; nCommon !== 0; nCommon -= 1, aIndex += 1, bIndex += 1) diffs.push(new Diff(0, bLines[bIndex]));
914
+ };
915
+ diffSequences(aLength, bLength, isCommon, foundSubsequence);
916
+ for (; aIndex !== aLength; aIndex += 1) diffs.push(new Diff(-1, aLines[aIndex]));
917
+ for (; bIndex !== bLength; bIndex += 1) diffs.push(new Diff(1, bLines[bIndex]));
918
+ return [diffs, truncated];
919
+ }
920
+ function getType(value) {
921
+ if (value === void 0) return "undefined";
922
+ else if (value === null) return "null";
923
+ else if (Array.isArray(value)) return "array";
924
+ else if (typeof value === "boolean") return "boolean";
925
+ else if (typeof value === "function") return "function";
926
+ else if (typeof value === "number") return "number";
927
+ else if (typeof value === "string") return "string";
928
+ else if (typeof value === "bigint") return "bigint";
929
+ else if (typeof value === "object") {
930
+ if (value != null) {
931
+ if (value.constructor === RegExp) return "regexp";
932
+ else if (value.constructor === Map) return "map";
933
+ else if (value.constructor === Set) return "set";
934
+ else if (value.constructor === Date) return "date";
935
+ }
936
+ return "object";
937
+ } else if (typeof value === "symbol") return "symbol";
938
+ throw new Error(`value of unknown type: ${value}`);
939
+ }
940
+ function getNewLineSymbol(string) {
941
+ return string.includes("\r\n") ? "\r\n" : "\n";
942
+ }
943
+ function diffStrings(a, b, options) {
944
+ const truncate = options?.truncateThreshold ?? false;
945
+ const truncateThreshold = Math.max(Math.floor(options?.truncateThreshold ?? 0), 0);
946
+ let aLength = a.length;
947
+ let bLength = b.length;
948
+ if (truncate) {
949
+ const aMultipleLines = a.includes("\n");
950
+ const bMultipleLines = b.includes("\n");
951
+ const aNewLineSymbol = getNewLineSymbol(a);
952
+ const bNewLineSymbol = getNewLineSymbol(b);
953
+ const _a = aMultipleLines ? `${a.split(aNewLineSymbol, truncateThreshold).join(aNewLineSymbol)}\n` : a;
954
+ const _b = bMultipleLines ? `${b.split(bNewLineSymbol, truncateThreshold).join(bNewLineSymbol)}\n` : b;
955
+ aLength = _a.length;
956
+ bLength = _b.length;
957
+ }
958
+ const truncated = aLength !== a.length || bLength !== b.length;
959
+ const isCommon = (aIndex, bIndex) => a[aIndex] === b[bIndex];
960
+ let aIndex = 0;
961
+ let bIndex = 0;
962
+ const diffs = [];
963
+ const foundSubsequence = (nCommon, aCommon, bCommon) => {
964
+ if (aIndex !== aCommon) diffs.push(new Diff(-1, a.slice(aIndex, aCommon)));
965
+ if (bIndex !== bCommon) diffs.push(new Diff(1, b.slice(bIndex, bCommon)));
966
+ aIndex = aCommon + nCommon;
967
+ bIndex = bCommon + nCommon;
968
+ diffs.push(new Diff(0, b.slice(bCommon, bIndex)));
969
+ };
970
+ diffSequences(aLength, bLength, isCommon, foundSubsequence);
971
+ if (aIndex !== aLength) diffs.push(new Diff(-1, a.slice(aIndex)));
972
+ if (bIndex !== bLength) diffs.push(new Diff(1, b.slice(bIndex)));
973
+ return [diffs, truncated];
974
+ }
975
+ function concatenateRelevantDiffs(op, diffs, changeColor) {
976
+ return diffs.reduce((reduced, diff) => reduced + (diff[0] === 0 ? diff[1] : diff[0] === op && diff[1].length !== 0 ? changeColor(diff[1]) : ""), "");
977
+ }
978
+ var ChangeBuffer = class {
979
+ op;
980
+ line;
981
+ lines;
982
+ changeColor;
983
+ constructor(op, changeColor) {
984
+ this.op = op;
985
+ this.line = [];
986
+ this.lines = [];
987
+ this.changeColor = changeColor;
988
+ }
989
+ pushSubstring(substring) {
990
+ this.pushDiff(new Diff(this.op, substring));
991
+ }
992
+ pushLine() {
993
+ this.lines.push(this.line.length !== 1 ? new Diff(this.op, concatenateRelevantDiffs(this.op, this.line, this.changeColor)) : this.line[0][0] === this.op ? this.line[0] : new Diff(this.op, this.line[0][1]));
994
+ this.line.length = 0;
995
+ }
996
+ isLineEmpty() {
997
+ return this.line.length === 0;
998
+ }
999
+ pushDiff(diff) {
1000
+ this.line.push(diff);
1001
+ }
1002
+ align(diff) {
1003
+ const string = diff[1];
1004
+ if (string.includes("\n")) {
1005
+ const substrings = string.split("\n");
1006
+ const iLast = substrings.length - 1;
1007
+ substrings.forEach((substring, i) => {
1008
+ if (i < iLast) {
1009
+ this.pushSubstring(substring);
1010
+ this.pushLine();
1011
+ } else if (substring.length !== 0) this.pushSubstring(substring);
1012
+ });
1013
+ } else this.pushDiff(diff);
1014
+ }
1015
+ moveLinesTo(lines) {
1016
+ if (!this.isLineEmpty()) this.pushLine();
1017
+ lines.push(...this.lines);
1018
+ this.lines.length = 0;
1019
+ }
1020
+ };
1021
+ var CommonBuffer = class {
1022
+ deleteBuffer;
1023
+ insertBuffer;
1024
+ lines;
1025
+ constructor(deleteBuffer, insertBuffer) {
1026
+ this.deleteBuffer = deleteBuffer;
1027
+ this.insertBuffer = insertBuffer;
1028
+ this.lines = [];
1029
+ }
1030
+ pushDiffCommonLine(diff) {
1031
+ this.lines.push(diff);
1032
+ }
1033
+ pushDiffChangeLines(diff) {
1034
+ const isDiffEmpty = diff[1].length === 0;
1035
+ if (!isDiffEmpty || this.deleteBuffer.isLineEmpty()) this.deleteBuffer.pushDiff(diff);
1036
+ if (!isDiffEmpty || this.insertBuffer.isLineEmpty()) this.insertBuffer.pushDiff(diff);
1037
+ }
1038
+ flushChangeLines() {
1039
+ this.deleteBuffer.moveLinesTo(this.lines);
1040
+ this.insertBuffer.moveLinesTo(this.lines);
1041
+ }
1042
+ align(diff) {
1043
+ const op = diff[0];
1044
+ const string = diff[1];
1045
+ if (string.includes("\n")) {
1046
+ const substrings = string.split("\n");
1047
+ const iLast = substrings.length - 1;
1048
+ substrings.forEach((substring, i) => {
1049
+ if (i === 0) {
1050
+ const subdiff = new Diff(op, substring);
1051
+ if (this.deleteBuffer.isLineEmpty() && this.insertBuffer.isLineEmpty()) {
1052
+ this.flushChangeLines();
1053
+ this.pushDiffCommonLine(subdiff);
1054
+ } else {
1055
+ this.pushDiffChangeLines(subdiff);
1056
+ this.flushChangeLines();
1057
+ }
1058
+ } else if (i < iLast) this.pushDiffCommonLine(new Diff(op, substring));
1059
+ else if (substring.length !== 0) this.pushDiffChangeLines(new Diff(op, substring));
1060
+ });
1061
+ } else this.pushDiffChangeLines(diff);
1062
+ }
1063
+ getLines() {
1064
+ this.flushChangeLines();
1065
+ return this.lines;
1066
+ }
1067
+ };
1068
+ function getAlignedDiffs(diffs, changeColor) {
1069
+ const deleteBuffer = new ChangeBuffer(-1, changeColor);
1070
+ const insertBuffer = new ChangeBuffer(1, changeColor);
1071
+ const commonBuffer = new CommonBuffer(deleteBuffer, insertBuffer);
1072
+ diffs.forEach((diff) => {
1073
+ switch (diff[0]) {
1074
+ case -1:
1075
+ deleteBuffer.align(diff);
1076
+ break;
1077
+ case 1:
1078
+ insertBuffer.align(diff);
1079
+ break;
1080
+ default: commonBuffer.align(diff);
1081
+ }
1082
+ });
1083
+ return commonBuffer.getLines();
1084
+ }
1085
+ function hasCommonDiff(diffs, isMultiline) {
1086
+ if (isMultiline) {
1087
+ const iLast = diffs.length - 1;
1088
+ return diffs.some((diff, i) => diff[0] === 0 && (i !== iLast || diff[1] !== "\n"));
1089
+ }
1090
+ return diffs.some((diff) => diff[0] === 0);
1091
+ }
1092
+ function diffStringsUnified(a, b, options) {
1093
+ if (a !== b && a.length !== 0 && b.length !== 0) {
1094
+ const isMultiline = a.includes("\n") || b.includes("\n");
1095
+ const [diffs, truncated] = diffStringsRaw(isMultiline ? `${a}\n` : a, isMultiline ? `${b}\n` : b, true, options);
1096
+ if (hasCommonDiff(diffs, isMultiline)) {
1097
+ const optionsNormalized = normalizeDiffOptions(options);
1098
+ return printDiffLines(getAlignedDiffs(diffs, optionsNormalized.changeColor), truncated, optionsNormalized);
1099
+ }
1100
+ }
1101
+ return diffLinesUnified(a.split("\n"), b.split("\n"), options);
1102
+ }
1103
+ function diffStringsRaw(a, b, cleanup, options) {
1104
+ const [diffs, truncated] = diffStrings(a, b, options);
1105
+ if (cleanup) diff_cleanupSemantic(diffs);
1106
+ return [diffs, truncated];
1107
+ }
1108
+ function getCommonMessage(message, options) {
1109
+ const { commonColor } = normalizeDiffOptions(options);
1110
+ return commonColor(message);
1111
+ }
1112
+ const { AsymmetricMatcher, DOMCollection, DOMElement, Immutable, ReactElement, ReactTestComponent } = plugins;
1113
+ const PLUGINS = [
1114
+ ReactTestComponent,
1115
+ ReactElement,
1116
+ DOMElement,
1117
+ DOMCollection,
1118
+ Immutable,
1119
+ AsymmetricMatcher,
1120
+ plugins.Error
1121
+ ];
1122
+ const FORMAT_OPTIONS = {
1123
+ maxDepth: 20,
1124
+ plugins: PLUGINS
1125
+ };
1126
+ const FALLBACK_FORMAT_OPTIONS = {
1127
+ callToJSON: false,
1128
+ maxDepth: 8,
1129
+ plugins: PLUGINS
1130
+ };
1131
+ /**
1132
+ * @param a Expected value
1133
+ * @param b Received value
1134
+ * @param options Diff options
1135
+ * @returns {string | null} a string diff
1136
+ */
1137
+ function diff(a, b, options) {
1138
+ if (Object.is(a, b)) return "";
1139
+ const aType = getType(a);
1140
+ let expectedType = aType;
1141
+ let omitDifference = false;
1142
+ if (aType === "object" && typeof a.asymmetricMatch === "function") {
1143
+ if (a.$$typeof !== Symbol.for("jest.asymmetricMatcher")) return;
1144
+ if (typeof a.getExpectedType !== "function") return;
1145
+ expectedType = a.getExpectedType();
1146
+ omitDifference = expectedType === "string";
1147
+ }
1148
+ if (expectedType !== getType(b)) {
1149
+ const { aAnnotation, aColor, aIndicator, bAnnotation, bColor, bIndicator } = normalizeDiffOptions(options);
1150
+ const formatOptions = getFormatOptions(FALLBACK_FORMAT_OPTIONS, options);
1151
+ let aDisplay = format(a, formatOptions);
1152
+ let bDisplay = format(b, formatOptions);
1153
+ const MAX_LENGTH = 1e5;
1154
+ function truncate(s) {
1155
+ return s.length <= MAX_LENGTH ? s : `${s.slice(0, MAX_LENGTH)}...`;
1156
+ }
1157
+ aDisplay = truncate(aDisplay);
1158
+ bDisplay = truncate(bDisplay);
1159
+ return `${`${aColor(`${aIndicator} ${aAnnotation}:`)}\n${aDisplay}`}\n\n${`${bColor(`${bIndicator} ${bAnnotation}:`)}\n${bDisplay}`}`;
1160
+ }
1161
+ if (omitDifference) return;
1162
+ switch (aType) {
1163
+ case "string": return diffLinesUnified(a.split("\n"), b.split("\n"), options);
1164
+ case "boolean":
1165
+ case "number": return comparePrimitive(a, b, options);
1166
+ case "map": return compareObjects(sortMap(a), sortMap(b), options);
1167
+ case "set": return compareObjects(sortSet(a), sortSet(b), options);
1168
+ default: return compareObjects(a, b, options);
1169
+ }
1170
+ }
1171
+ function comparePrimitive(a, b, options) {
1172
+ const aFormat = format(a, FORMAT_OPTIONS);
1173
+ const bFormat = format(b, FORMAT_OPTIONS);
1174
+ return aFormat === bFormat ? "" : diffLinesUnified(aFormat.split("\n"), bFormat.split("\n"), options);
1175
+ }
1176
+ function sortMap(map) {
1177
+ return new Map(Array.from(map.entries()).sort());
1178
+ }
1179
+ function sortSet(set) {
1180
+ return new Set(Array.from(set.values()).sort());
1181
+ }
1182
+ function compareObjects(a, b, options) {
1183
+ let difference;
1184
+ let hasThrown = false;
1185
+ try {
1186
+ difference = getObjectsDifference(a, b, getFormatOptions(FORMAT_OPTIONS, options), options);
1187
+ } catch {
1188
+ hasThrown = true;
1189
+ }
1190
+ const noDiffMessage = getCommonMessage(NO_DIFF_MESSAGE, options);
1191
+ if (difference === void 0 || difference === noDiffMessage) {
1192
+ difference = getObjectsDifference(a, b, getFormatOptions(FALLBACK_FORMAT_OPTIONS, options), options);
1193
+ if (difference !== noDiffMessage && !hasThrown) difference = `${getCommonMessage(SIMILAR_MESSAGE, options)}\n\n${difference}`;
1194
+ }
1195
+ return difference;
1196
+ }
1197
+ function getFormatOptions(formatOptions, options) {
1198
+ const { compareKeys, printBasicPrototype, maxDepth } = normalizeDiffOptions(options);
1199
+ return {
1200
+ ...formatOptions,
1201
+ compareKeys,
1202
+ printBasicPrototype,
1203
+ maxDepth: maxDepth ?? formatOptions.maxDepth
1204
+ };
1205
+ }
1206
+ function getObjectsDifference(a, b, formatOptions, options) {
1207
+ const formatOptionsZeroIndent = {
1208
+ ...formatOptions,
1209
+ indent: 0
1210
+ };
1211
+ const aCompare = format(a, formatOptionsZeroIndent);
1212
+ const bCompare = format(b, formatOptionsZeroIndent);
1213
+ if (aCompare === bCompare) return getCommonMessage(NO_DIFF_MESSAGE, options);
1214
+ else {
1215
+ const aDisplay = format(a, formatOptions);
1216
+ const bDisplay = format(b, formatOptions);
1217
+ return diffLinesUnified2(aDisplay.split("\n"), bDisplay.split("\n"), aCompare.split("\n"), bCompare.split("\n"), options);
1218
+ }
1219
+ }
1220
+ const MAX_DIFF_STRING_LENGTH = 2e4;
1221
+ function isAsymmetricMatcher(data) {
1222
+ return getType$1(data) === "Object" && typeof data.asymmetricMatch === "function";
1223
+ }
1224
+ function isReplaceable(obj1, obj2) {
1225
+ const obj1Type = getType$1(obj1);
1226
+ return obj1Type === getType$1(obj2) && (obj1Type === "Object" || obj1Type === "Array");
1227
+ }
1228
+ function printDiffOrStringify(received, expected, options) {
1229
+ const { aAnnotation, bAnnotation } = normalizeDiffOptions(options);
1230
+ if (typeof expected === "string" && typeof received === "string" && expected.length > 0 && received.length > 0 && expected.length <= MAX_DIFF_STRING_LENGTH && received.length <= MAX_DIFF_STRING_LENGTH && expected !== received) {
1231
+ if (expected.includes("\n") || received.includes("\n")) return diffStringsUnified(expected, received, options);
1232
+ const [diffs] = diffStringsRaw(expected, received, true);
1233
+ const hasCommonDiff = diffs.some((diff) => diff[0] === 0);
1234
+ const printLabel = getLabelPrinter(aAnnotation, bAnnotation);
1235
+ return `${printLabel(aAnnotation) + printExpected(getCommonAndChangedSubstrings(diffs, -1, hasCommonDiff))}\n${printLabel(bAnnotation) + printReceived(getCommonAndChangedSubstrings(diffs, 1, hasCommonDiff))}`;
1236
+ }
1237
+ const clonedExpected = deepClone(expected, { forceWritable: true });
1238
+ const { replacedExpected, replacedActual } = replaceAsymmetricMatcher(deepClone(received, { forceWritable: true }), clonedExpected);
1239
+ return diff(replacedExpected, replacedActual, options);
1240
+ }
1241
+ function replaceAsymmetricMatcher(actual, expected, actualReplaced = /* @__PURE__ */ new WeakSet(), expectedReplaced = /* @__PURE__ */ new WeakSet()) {
1242
+ if (actual instanceof Error && expected instanceof Error && typeof actual.cause !== "undefined" && typeof expected.cause === "undefined") {
1243
+ delete actual.cause;
1244
+ return {
1245
+ replacedActual: actual,
1246
+ replacedExpected: expected
1247
+ };
1248
+ }
1249
+ if (!isReplaceable(actual, expected)) return {
1250
+ replacedActual: actual,
1251
+ replacedExpected: expected
1252
+ };
1253
+ if (actualReplaced.has(actual) || expectedReplaced.has(expected)) return {
1254
+ replacedActual: actual,
1255
+ replacedExpected: expected
1256
+ };
1257
+ actualReplaced.add(actual);
1258
+ expectedReplaced.add(expected);
1259
+ getOwnProperties(expected).forEach((key) => {
1260
+ const expectedValue = expected[key];
1261
+ const actualValue = actual[key];
1262
+ if (isAsymmetricMatcher(expectedValue)) {
1263
+ if (expectedValue.asymmetricMatch(actualValue)) expected[key] = actualValue;
1264
+ else if ("sample" in expectedValue && expectedValue.sample !== void 0 && isReplaceable(actualValue, expectedValue.sample)) {
1265
+ const replaced = replaceAsymmetricMatcher(actualValue, expectedValue.sample, actualReplaced, expectedReplaced);
1266
+ actual[key] = replaced.replacedActual;
1267
+ expected[key] = replaced.replacedExpected;
1268
+ }
1269
+ } else if (isAsymmetricMatcher(actualValue)) {
1270
+ if (actualValue.asymmetricMatch(expectedValue)) actual[key] = expectedValue;
1271
+ else if ("sample" in actualValue && actualValue.sample !== void 0 && isReplaceable(actualValue.sample, expectedValue)) {
1272
+ const replaced = replaceAsymmetricMatcher(actualValue.sample, expectedValue, actualReplaced, expectedReplaced);
1273
+ actual[key] = replaced.replacedActual;
1274
+ expected[key] = replaced.replacedExpected;
1275
+ }
1276
+ } else if (isReplaceable(actualValue, expectedValue)) {
1277
+ const replaced = replaceAsymmetricMatcher(actualValue, expectedValue, actualReplaced, expectedReplaced);
1278
+ actual[key] = replaced.replacedActual;
1279
+ expected[key] = replaced.replacedExpected;
1280
+ }
1281
+ });
1282
+ return {
1283
+ replacedActual: actual,
1284
+ replacedExpected: expected
1285
+ };
1286
+ }
1287
+ function getLabelPrinter(...strings) {
1288
+ const maxLength = strings.reduce((max, string) => string.length > max ? string.length : max, 0);
1289
+ return (string) => `${string}: ${" ".repeat(maxLength - string.length)}`;
1290
+ }
1291
+ const SPACE_SYMBOL = "·";
1292
+ function replaceTrailingSpaces(text) {
1293
+ return text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
1294
+ }
1295
+ function printReceived(object) {
1296
+ return y.red(replaceTrailingSpaces(stringify(object)));
1297
+ }
1298
+ function printExpected(value) {
1299
+ return y.green(replaceTrailingSpaces(stringify(value)));
1300
+ }
1301
+ function getCommonAndChangedSubstrings(diffs, op, hasCommonDiff) {
1302
+ return diffs.reduce((reduced, diff) => reduced + (diff[0] === 0 ? diff[1] : diff[0] === op ? hasCommonDiff ? y.inverse(diff[1]) : diff[1] : ""), "");
1303
+ }
1304
+ //#endregion
1305
+ export { diff, printDiffOrStringify };
1306
+
1307
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi5qcyIsIm5hbWVzIjpbImMiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHZpdGVzdCt1dGlsc0A0LjEuMi9ub2RlX21vZHVsZXMvQHZpdGVzdC91dGlscy9kaXN0L2RpZmYuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcGx1Z2lucywgZm9ybWF0IH0gZnJvbSAnQHZpdGVzdC9wcmV0dHktZm9ybWF0JztcbmltcG9ydCBjIGZyb20gJ3RpbnlyYWluYm93JztcbmltcG9ydCB7IHN0cmluZ2lmeSB9IGZyb20gJy4vZGlzcGxheS5qcyc7XG5pbXBvcnQgeyBkZWVwQ2xvbmUsIGdldE93blByb3BlcnRpZXMsIGdldFR5cGUgYXMgZ2V0VHlwZSQxIH0gZnJvbSAnLi9oZWxwZXJzLmpzJztcbmltcG9ydCAnLi9jb25zdGFudHMuanMnO1xuXG4vKipcbiogRGlmZiBNYXRjaCBhbmQgUGF0Y2hcbiogQ29weXJpZ2h0IDIwMTggVGhlIGRpZmYtbWF0Y2gtcGF0Y2ggQXV0aG9ycy5cbiogaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9kaWZmLW1hdGNoLXBhdGNoXG4qXG4qIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4qIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4qXG4qICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4qXG4qIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG4vKipcbiogQGZpbGVvdmVydmlldyBDb21wdXRlcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byB0ZXh0cyB0byBjcmVhdGUgYSBwYXRjaC5cbiogQXBwbGllcyB0aGUgcGF0Y2ggb250byBhbm90aGVyIHRleHQsIGFsbG93aW5nIGZvciBlcnJvcnMuXG4qIEBhdXRob3IgZnJhc2VyQGdvb2dsZS5jb20gKE5laWwgRnJhc2VyKVxuKi9cbi8qKlxuKiBDSEFOR0VTIGJ5IHBlZHJvdHRpbWFyayB0byBkaWZmX21hdGNoX3BhdGNoX3VuY29tcHJlc3NlZC50cyBmaWxlOlxuKlxuKiAxLiBEZWxldGUgYW55dGhpbmcgbm90IG5lZWRlZCB0byB1c2UgZGlmZl9jbGVhbnVwU2VtYW50aWMgbWV0aG9kXG4qIDIuIENvbnZlcnQgZnJvbSBwcm90b3R5cGUgcHJvcGVydGllcyB0byB2YXIgZGVjbGFyYXRpb25zXG4qIDMuIENvbnZlcnQgRGlmZiB0byBjbGFzcyBmcm9tIGNvbnN0cnVjdG9yIGFuZCBwcm90b3R5cGVcbiogNC4gQWRkIHR5cGUgYW5ub3RhdGlvbnMgZm9yIGFyZ3VtZW50cyBhbmQgcmV0dXJuIHZhbHVlc1xuKiA1LiBBZGQgZXhwb3J0c1xuKi9cbi8qKlxuKiBUaGUgZGF0YSBzdHJ1Y3R1cmUgcmVwcmVzZW50aW5nIGEgZGlmZiBpcyBhbiBhcnJheSBvZiB0dXBsZXM6XG4qIFtbRElGRl9ERUxFVEUsICdIZWxsbyddLCBbRElGRl9JTlNFUlQsICdHb29kYnllJ10sIFtESUZGX0VRVUFMLCAnIHdvcmxkLiddXVxuKiB3aGljaCBtZWFuczogZGVsZXRlICdIZWxsbycsIGFkZCAnR29vZGJ5ZScgYW5kIGtlZXAgJyB3b3JsZC4nXG4qL1xuY29uc3QgRElGRl9ERUxFVEUgPSAtMTtcbmNvbnN0IERJRkZfSU5TRVJUID0gMTtcbmNvbnN0IERJRkZfRVFVQUwgPSAwO1xuLyoqXG4qIENsYXNzIHJlcHJlc2VudGluZyBvbmUgZGlmZiB0dXBsZS5cbiogQXR0ZW1wdHMgdG8gbG9vayBsaWtlIGEgdHdvLWVsZW1lbnQgYXJyYXkgKHdoaWNoIGlzIHdoYXQgdGhpcyB1c2VkIHRvIGJlKS5cbiogQHBhcmFtIHtudW1iZXJ9IG9wIE9wZXJhdGlvbiwgb25lIG9mOiBESUZGX0RFTEVURSwgRElGRl9JTlNFUlQsIERJRkZfRVFVQUwuXG4qIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRleHQgdG8gYmUgZGVsZXRlZCwgaW5zZXJ0ZWQsIG9yIHJldGFpbmVkLlxuKiBAY29uc3RydWN0b3JcbiovXG5jbGFzcyBEaWZmIHtcblx0MDtcblx0MTtcblx0Y29uc3RydWN0b3Iob3AsIHRleHQpIHtcblx0XHR0aGlzWzBdID0gb3A7XG5cdFx0dGhpc1sxXSA9IHRleHQ7XG5cdH1cbn1cbi8qKlxuKiBEZXRlcm1pbmUgdGhlIGNvbW1vbiBwcmVmaXggb2YgdHdvIHN0cmluZ3MuXG4qIEBwYXJhbSB7c3RyaW5nfSB0ZXh0MSBGaXJzdCBzdHJpbmcuXG4qIEBwYXJhbSB7c3RyaW5nfSB0ZXh0MiBTZWNvbmQgc3RyaW5nLlxuKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBjb21tb24gdG8gdGhlIHN0YXJ0IG9mIGVhY2hcbiogICAgIHN0cmluZy5cbiovXG5mdW5jdGlvbiBkaWZmX2NvbW1vblByZWZpeCh0ZXh0MSwgdGV4dDIpIHtcblx0Ly8gUXVpY2sgY2hlY2sgZm9yIGNvbW1vbiBudWxsIGNhc2VzLlxuXHRpZiAoIXRleHQxIHx8ICF0ZXh0MiB8fCB0ZXh0MS5jaGFyQXQoMCkgIT09IHRleHQyLmNoYXJBdCgwKSkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cdC8vIEJpbmFyeSBzZWFyY2guXG5cdC8vIFBlcmZvcm1hbmNlIGFuYWx5c2lzOiBodHRwczovL25laWwuZnJhc2VyLm5hbWUvbmV3cy8yMDA3LzEwLzA5L1xuXHRsZXQgcG9pbnRlcm1pbiA9IDA7XG5cdGxldCBwb2ludGVybWF4ID0gTWF0aC5taW4odGV4dDEubGVuZ3RoLCB0ZXh0Mi5sZW5ndGgpO1xuXHRsZXQgcG9pbnRlcm1pZCA9IHBvaW50ZXJtYXg7XG5cdGxldCBwb2ludGVyc3RhcnQgPSAwO1xuXHR3aGlsZSAocG9pbnRlcm1pbiA8IHBvaW50ZXJtaWQpIHtcblx0XHRpZiAodGV4dDEuc3Vic3RyaW5nKHBvaW50ZXJzdGFydCwgcG9pbnRlcm1pZCkgPT09IHRleHQyLnN1YnN0cmluZyhwb2ludGVyc3RhcnQsIHBvaW50ZXJtaWQpKSB7XG5cdFx0XHRwb2ludGVybWluID0gcG9pbnRlcm1pZDtcblx0XHRcdHBvaW50ZXJzdGFydCA9IHBvaW50ZXJtaW47XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBvaW50ZXJtYXggPSBwb2ludGVybWlkO1xuXHRcdH1cblx0XHRwb2ludGVybWlkID0gTWF0aC5mbG9vcigocG9pbnRlcm1heCAtIHBvaW50ZXJtaW4pIC8gMiArIHBvaW50ZXJtaW4pO1xuXHR9XG5cdHJldHVybiBwb2ludGVybWlkO1xufVxuLyoqXG4qIERldGVybWluZSB0aGUgY29tbW9uIHN1ZmZpeCBvZiB0d28gc3RyaW5ncy5cbiogQHBhcmFtIHtzdHJpbmd9IHRleHQxIEZpcnN0IHN0cmluZy5cbiogQHBhcmFtIHtzdHJpbmd9IHRleHQyIFNlY29uZCBzdHJpbmcuXG4qIEByZXR1cm4ge251bWJlcn0gVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGNvbW1vbiB0byB0aGUgZW5kIG9mIGVhY2ggc3RyaW5nLlxuKi9cbmZ1bmN0aW9uIGRpZmZfY29tbW9uU3VmZml4KHRleHQxLCB0ZXh0Mikge1xuXHQvLyBRdWljayBjaGVjayBmb3IgY29tbW9uIG51bGwgY2FzZXMuXG5cdGlmICghdGV4dDEgfHwgIXRleHQyIHx8IHRleHQxLmNoYXJBdCh0ZXh0MS5sZW5ndGggLSAxKSAhPT0gdGV4dDIuY2hhckF0KHRleHQyLmxlbmd0aCAtIDEpKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblx0Ly8gQmluYXJ5IHNlYXJjaC5cblx0Ly8gUGVyZm9ybWFuY2UgYW5hbHlzaXM6IGh0dHBzOi8vbmVpbC5mcmFzZXIubmFtZS9uZXdzLzIwMDcvMTAvMDkvXG5cdGxldCBwb2ludGVybWluID0gMDtcblx0bGV0IHBvaW50ZXJtYXggPSBNYXRoLm1pbih0ZXh0MS5sZW5ndGgsIHRleHQyLmxlbmd0aCk7XG5cdGxldCBwb2ludGVybWlkID0gcG9pbnRlcm1heDtcblx0bGV0IHBvaW50ZXJlbmQgPSAwO1xuXHR3aGlsZSAocG9pbnRlcm1pbiA8IHBvaW50ZXJtaWQpIHtcblx0XHRpZiAodGV4dDEuc3Vic3RyaW5nKHRleHQxLmxlbmd0aCAtIHBvaW50ZXJtaWQsIHRleHQxLmxlbmd0aCAtIHBvaW50ZXJlbmQpID09PSB0ZXh0Mi5zdWJzdHJpbmcodGV4dDIubGVuZ3RoIC0gcG9pbnRlcm1pZCwgdGV4dDIubGVuZ3RoIC0gcG9pbnRlcmVuZCkpIHtcblx0XHRcdHBvaW50ZXJtaW4gPSBwb2ludGVybWlkO1xuXHRcdFx0cG9pbnRlcmVuZCA9IHBvaW50ZXJtaW47XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBvaW50ZXJtYXggPSBwb2ludGVybWlkO1xuXHRcdH1cblx0XHRwb2ludGVybWlkID0gTWF0aC5mbG9vcigocG9pbnRlcm1heCAtIHBvaW50ZXJtaW4pIC8gMiArIHBvaW50ZXJtaW4pO1xuXHR9XG5cdHJldHVybiBwb2ludGVybWlkO1xufVxuLyoqXG4qIERldGVybWluZSBpZiB0aGUgc3VmZml4IG9mIG9uZSBzdHJpbmcgaXMgdGhlIHByZWZpeCBvZiBhbm90aGVyLlxuKiBAcGFyYW0ge3N0cmluZ30gdGV4dDEgRmlyc3Qgc3RyaW5nLlxuKiBAcGFyYW0ge3N0cmluZ30gdGV4dDIgU2Vjb25kIHN0cmluZy5cbiogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgY29tbW9uIHRvIHRoZSBlbmQgb2YgdGhlIGZpcnN0XG4qICAgICBzdHJpbmcgYW5kIHRoZSBzdGFydCBvZiB0aGUgc2Vjb25kIHN0cmluZy5cbiogQHByaXZhdGVcbiovXG5mdW5jdGlvbiBkaWZmX2NvbW1vbk92ZXJsYXBfKHRleHQxLCB0ZXh0Mikge1xuXHQvLyBDYWNoZSB0aGUgdGV4dCBsZW5ndGhzIHRvIHByZXZlbnQgbXVsdGlwbGUgY2FsbHMuXG5cdGNvbnN0IHRleHQxX2xlbmd0aCA9IHRleHQxLmxlbmd0aDtcblx0Y29uc3QgdGV4dDJfbGVuZ3RoID0gdGV4dDIubGVuZ3RoO1xuXHQvLyBFbGltaW5hdGUgdGhlIG51bGwgY2FzZS5cblx0aWYgKHRleHQxX2xlbmd0aCA9PT0gMCB8fCB0ZXh0Ml9sZW5ndGggPT09IDApIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXHQvLyBUcnVuY2F0ZSB0aGUgbG9uZ2VyIHN0cmluZy5cblx0aWYgKHRleHQxX2xlbmd0aCA+IHRleHQyX2xlbmd0aCkge1xuXHRcdHRleHQxID0gdGV4dDEuc3Vic3RyaW5nKHRleHQxX2xlbmd0aCAtIHRleHQyX2xlbmd0aCk7XG5cdH0gZWxzZSBpZiAodGV4dDFfbGVuZ3RoIDwgdGV4dDJfbGVuZ3RoKSB7XG5cdFx0dGV4dDIgPSB0ZXh0Mi5zdWJzdHJpbmcoMCwgdGV4dDFfbGVuZ3RoKTtcblx0fVxuXHRjb25zdCB0ZXh0X2xlbmd0aCA9IE1hdGgubWluKHRleHQxX2xlbmd0aCwgdGV4dDJfbGVuZ3RoKTtcblx0Ly8gUXVpY2sgY2hlY2sgZm9yIHRoZSB3b3JzdCBjYXNlLlxuXHRpZiAodGV4dDEgPT09IHRleHQyKSB7XG5cdFx0cmV0dXJuIHRleHRfbGVuZ3RoO1xuXHR9XG5cdC8vIFN0YXJ0IGJ5IGxvb2tpbmcgZm9yIGEgc2luZ2xlIGNoYXJhY3RlciBtYXRjaFxuXHQvLyBhbmQgaW5jcmVhc2UgbGVuZ3RoIHVudGlsIG5vIG1hdGNoIGlzIGZvdW5kLlxuXHQvLyBQZXJmb3JtYW5jZSBhbmFseXNpczogaHR0cHM6Ly9uZWlsLmZyYXNlci5uYW1lL25ld3MvMjAxMC8xMS8wNC9cblx0bGV0IGJlc3QgPSAwO1xuXHRsZXQgbGVuZ3RoID0gMTtcblx0d2hpbGUgKHRydWUpIHtcblx0XHRjb25zdCBwYXR0ZXJuID0gdGV4dDEuc3Vic3RyaW5nKHRleHRfbGVuZ3RoIC0gbGVuZ3RoKTtcblx0XHRjb25zdCBmb3VuZCA9IHRleHQyLmluZGV4T2YocGF0dGVybik7XG5cdFx0aWYgKGZvdW5kID09PSAtMSkge1xuXHRcdFx0cmV0dXJuIGJlc3Q7XG5cdFx0fVxuXHRcdGxlbmd0aCArPSBmb3VuZDtcblx0XHRpZiAoZm91bmQgPT09IDAgfHwgdGV4dDEuc3Vic3RyaW5nKHRleHRfbGVuZ3RoIC0gbGVuZ3RoKSA9PT0gdGV4dDIuc3Vic3RyaW5nKDAsIGxlbmd0aCkpIHtcblx0XHRcdGJlc3QgPSBsZW5ndGg7XG5cdFx0XHRsZW5ndGgrKztcblx0XHR9XG5cdH1cbn1cbi8qKlxuKiBSZWR1Y2UgdGhlIG51bWJlciBvZiBlZGl0cyBieSBlbGltaW5hdGluZyBzZW1hbnRpY2FsbHkgdHJpdmlhbCBlcXVhbGl0aWVzLlxuKiBAcGFyYW0geyFBcnJheS48IWRpZmZfbWF0Y2hfcGF0Y2guRGlmZj59IGRpZmZzIEFycmF5IG9mIGRpZmYgdHVwbGVzLlxuKi9cbmZ1bmN0aW9uIGRpZmZfY2xlYW51cFNlbWFudGljKGRpZmZzKSB7XG5cdGxldCBjaGFuZ2VzID0gZmFsc2U7XG5cdGNvbnN0IGVxdWFsaXRpZXMgPSBbXTtcblx0bGV0IGVxdWFsaXRpZXNMZW5ndGggPSAwO1xuXHQvKiogQHR5cGUgez9zdHJpbmd9ICovXG5cdGxldCBsYXN0RXF1YWxpdHkgPSBudWxsO1xuXHQvLyBBbHdheXMgZXF1YWwgdG8gZGlmZnNbZXF1YWxpdGllc1tlcXVhbGl0aWVzTGVuZ3RoIC0gMV1dWzFdXG5cdGxldCBwb2ludGVyID0gMDtcblx0Ly8gTnVtYmVyIG9mIGNoYXJhY3RlcnMgdGhhdCBjaGFuZ2VkIHByaW9yIHRvIHRoZSBlcXVhbGl0eS5cblx0bGV0IGxlbmd0aF9pbnNlcnRpb25zMSA9IDA7XG5cdGxldCBsZW5ndGhfZGVsZXRpb25zMSA9IDA7XG5cdC8vIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRoYXQgY2hhbmdlZCBhZnRlciB0aGUgZXF1YWxpdHkuXG5cdGxldCBsZW5ndGhfaW5zZXJ0aW9uczIgPSAwO1xuXHRsZXQgbGVuZ3RoX2RlbGV0aW9uczIgPSAwO1xuXHR3aGlsZSAocG9pbnRlciA8IGRpZmZzLmxlbmd0aCkge1xuXHRcdGlmIChkaWZmc1twb2ludGVyXVswXSA9PT0gRElGRl9FUVVBTCkge1xuXHRcdFx0Ly8gRXF1YWxpdHkgZm91bmQuXG5cdFx0XHRlcXVhbGl0aWVzW2VxdWFsaXRpZXNMZW5ndGgrK10gPSBwb2ludGVyO1xuXHRcdFx0bGVuZ3RoX2luc2VydGlvbnMxID0gbGVuZ3RoX2luc2VydGlvbnMyO1xuXHRcdFx0bGVuZ3RoX2RlbGV0aW9uczEgPSBsZW5ndGhfZGVsZXRpb25zMjtcblx0XHRcdGxlbmd0aF9pbnNlcnRpb25zMiA9IDA7XG5cdFx0XHRsZW5ndGhfZGVsZXRpb25zMiA9IDA7XG5cdFx0XHRsYXN0RXF1YWxpdHkgPSBkaWZmc1twb2ludGVyXVsxXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gQW4gaW5zZXJ0aW9uIG9yIGRlbGV0aW9uLlxuXHRcdFx0aWYgKGRpZmZzW3BvaW50ZXJdWzBdID09PSBESUZGX0lOU0VSVCkge1xuXHRcdFx0XHRsZW5ndGhfaW5zZXJ0aW9uczIgKz0gZGlmZnNbcG9pbnRlcl1bMV0ubGVuZ3RoO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGVuZ3RoX2RlbGV0aW9uczIgKz0gZGlmZnNbcG9pbnRlcl1bMV0ubGVuZ3RoO1xuXHRcdFx0fVxuXHRcdFx0Ly8gRWxpbWluYXRlIGFuIGVxdWFsaXR5IHRoYXQgaXMgc21hbGxlciBvciBlcXVhbCB0byB0aGUgZWRpdHMgb24gYm90aFxuXHRcdFx0Ly8gc2lkZXMgb2YgaXQuXG5cdFx0XHRpZiAobGFzdEVxdWFsaXR5ICYmIGxhc3RFcXVhbGl0eS5sZW5ndGggPD0gTWF0aC5tYXgobGVuZ3RoX2luc2VydGlvbnMxLCBsZW5ndGhfZGVsZXRpb25zMSkgJiYgbGFzdEVxdWFsaXR5Lmxlbmd0aCA8PSBNYXRoLm1heChsZW5ndGhfaW5zZXJ0aW9uczIsIGxlbmd0aF9kZWxldGlvbnMyKSkge1xuXHRcdFx0XHQvLyBEdXBsaWNhdGUgcmVjb3JkLlxuXHRcdFx0XHRkaWZmcy5zcGxpY2UoZXF1YWxpdGllc1tlcXVhbGl0aWVzTGVuZ3RoIC0gMV0sIDAsIG5ldyBEaWZmKERJRkZfREVMRVRFLCBsYXN0RXF1YWxpdHkpKTtcblx0XHRcdFx0Ly8gQ2hhbmdlIHNlY29uZCBjb3B5IHRvIGluc2VydC5cblx0XHRcdFx0ZGlmZnNbZXF1YWxpdGllc1tlcXVhbGl0aWVzTGVuZ3RoIC0gMV0gKyAxXVswXSA9IERJRkZfSU5TRVJUO1xuXHRcdFx0XHQvLyBUaHJvdyBhd2F5IHRoZSBlcXVhbGl0eSB3ZSBqdXN0IGRlbGV0ZWQuXG5cdFx0XHRcdGVxdWFsaXRpZXNMZW5ndGgtLTtcblx0XHRcdFx0Ly8gVGhyb3cgYXdheSB0aGUgcHJldmlvdXMgZXF1YWxpdHkgKGl0IG5lZWRzIHRvIGJlIHJlZXZhbHVhdGVkKS5cblx0XHRcdFx0ZXF1YWxpdGllc0xlbmd0aC0tO1xuXHRcdFx0XHRwb2ludGVyID0gZXF1YWxpdGllc0xlbmd0aCA+IDAgPyBlcXVhbGl0aWVzW2VxdWFsaXRpZXNMZW5ndGggLSAxXSA6IC0xO1xuXHRcdFx0XHRsZW5ndGhfaW5zZXJ0aW9uczEgPSAwO1xuXHRcdFx0XHRsZW5ndGhfZGVsZXRpb25zMSA9IDA7XG5cdFx0XHRcdGxlbmd0aF9pbnNlcnRpb25zMiA9IDA7XG5cdFx0XHRcdGxlbmd0aF9kZWxldGlvbnMyID0gMDtcblx0XHRcdFx0bGFzdEVxdWFsaXR5ID0gbnVsbDtcblx0XHRcdFx0Y2hhbmdlcyA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHBvaW50ZXIrKztcblx0fVxuXHQvLyBOb3JtYWxpemUgdGhlIGRpZmYuXG5cdGlmIChjaGFuZ2VzKSB7XG5cdFx0ZGlmZl9jbGVhbnVwTWVyZ2UoZGlmZnMpO1xuXHR9XG5cdGRpZmZfY2xlYW51cFNlbWFudGljTG9zc2xlc3MoZGlmZnMpO1xuXHQvLyBGaW5kIGFueSBvdmVybGFwcyBiZXR3ZWVuIGRlbGV0aW9ucyBhbmQgaW5zZXJ0aW9ucy5cblx0Ly8gZS5nOiA8ZGVsPmFiY3h4eDwvZGVsPjxpbnM+eHh4ZGVmPC9pbnM+XG5cdC8vICAgLT4gPGRlbD5hYmM8L2RlbD54eHg8aW5zPmRlZjwvaW5zPlxuXHQvLyBlLmc6IDxkZWw+eHh4YWJjPC9kZWw+PGlucz5kZWZ4eHg8L2lucz5cblx0Ly8gICAtPiA8aW5zPmRlZjwvaW5zPnh4eDxkZWw+YWJjPC9kZWw+XG5cdC8vIE9ubHkgZXh0cmFjdCBhbiBvdmVybGFwIGlmIGl0IGlzIGFzIGJpZyBhcyB0aGUgZWRpdCBhaGVhZCBvciBiZWhpbmQgaXQuXG5cdHBvaW50ZXIgPSAxO1xuXHR3aGlsZSAocG9pbnRlciA8IGRpZmZzLmxlbmd0aCkge1xuXHRcdGlmIChkaWZmc1twb2ludGVyIC0gMV1bMF0gPT09IERJRkZfREVMRVRFICYmIGRpZmZzW3BvaW50ZXJdWzBdID09PSBESUZGX0lOU0VSVCkge1xuXHRcdFx0Y29uc3QgZGVsZXRpb24gPSBkaWZmc1twb2ludGVyIC0gMV1bMV07XG5cdFx0XHRjb25zdCBpbnNlcnRpb24gPSBkaWZmc1twb2ludGVyXVsxXTtcblx0XHRcdGNvbnN0IG92ZXJsYXBfbGVuZ3RoMSA9IGRpZmZfY29tbW9uT3ZlcmxhcF8oZGVsZXRpb24sIGluc2VydGlvbik7XG5cdFx0XHRjb25zdCBvdmVybGFwX2xlbmd0aDIgPSBkaWZmX2NvbW1vbk92ZXJsYXBfKGluc2VydGlvbiwgZGVsZXRpb24pO1xuXHRcdFx0aWYgKG92ZXJsYXBfbGVuZ3RoMSA+PSBvdmVybGFwX2xlbmd0aDIpIHtcblx0XHRcdFx0aWYgKG92ZXJsYXBfbGVuZ3RoMSA+PSBkZWxldGlvbi5sZW5ndGggLyAyIHx8IG92ZXJsYXBfbGVuZ3RoMSA+PSBpbnNlcnRpb24ubGVuZ3RoIC8gMikge1xuXHRcdFx0XHRcdC8vIE92ZXJsYXAgZm91bmQuICBJbnNlcnQgYW4gZXF1YWxpdHkgYW5kIHRyaW0gdGhlIHN1cnJvdW5kaW5nIGVkaXRzLlxuXHRcdFx0XHRcdGRpZmZzLnNwbGljZShwb2ludGVyLCAwLCBuZXcgRGlmZihESUZGX0VRVUFMLCBpbnNlcnRpb24uc3Vic3RyaW5nKDAsIG92ZXJsYXBfbGVuZ3RoMSkpKTtcblx0XHRcdFx0XHRkaWZmc1twb2ludGVyIC0gMV1bMV0gPSBkZWxldGlvbi5zdWJzdHJpbmcoMCwgZGVsZXRpb24ubGVuZ3RoIC0gb3ZlcmxhcF9sZW5ndGgxKTtcblx0XHRcdFx0XHRkaWZmc1twb2ludGVyICsgMV1bMV0gPSBpbnNlcnRpb24uc3Vic3RyaW5nKG92ZXJsYXBfbGVuZ3RoMSk7XG5cdFx0XHRcdFx0cG9pbnRlcisrO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAob3ZlcmxhcF9sZW5ndGgyID49IGRlbGV0aW9uLmxlbmd0aCAvIDIgfHwgb3ZlcmxhcF9sZW5ndGgyID49IGluc2VydGlvbi5sZW5ndGggLyAyKSB7XG5cdFx0XHRcdFx0Ly8gUmV2ZXJzZSBvdmVybGFwIGZvdW5kLlxuXHRcdFx0XHRcdC8vIEluc2VydCBhbiBlcXVhbGl0eSBhbmQgc3dhcCBhbmQgdHJpbSB0aGUgc3Vycm91bmRpbmcgZWRpdHMuXG5cdFx0XHRcdFx0ZGlmZnMuc3BsaWNlKHBvaW50ZXIsIDAsIG5ldyBEaWZmKERJRkZfRVFVQUwsIGRlbGV0aW9uLnN1YnN0cmluZygwLCBvdmVybGFwX2xlbmd0aDIpKSk7XG5cdFx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzBdID0gRElGRl9JTlNFUlQ7XG5cdFx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzFdID0gaW5zZXJ0aW9uLnN1YnN0cmluZygwLCBpbnNlcnRpb24ubGVuZ3RoIC0gb3ZlcmxhcF9sZW5ndGgyKTtcblx0XHRcdFx0XHRkaWZmc1twb2ludGVyICsgMV1bMF0gPSBESUZGX0RFTEVURTtcblx0XHRcdFx0XHRkaWZmc1twb2ludGVyICsgMV1bMV0gPSBkZWxldGlvbi5zdWJzdHJpbmcob3ZlcmxhcF9sZW5ndGgyKTtcblx0XHRcdFx0XHRwb2ludGVyKys7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHBvaW50ZXIrKztcblx0XHR9XG5cdFx0cG9pbnRlcisrO1xuXHR9XG59XG4vLyBEZWZpbmUgc29tZSByZWdleCBwYXR0ZXJucyBmb3IgbWF0Y2hpbmcgYm91bmRhcmllcy5cbmNvbnN0IG5vbkFscGhhTnVtZXJpY1JlZ2V4XyA9IC9bXmEtejAtOV0vaTtcbmNvbnN0IHdoaXRlc3BhY2VSZWdleF8gPSAvXFxzLztcbmNvbnN0IGxpbmVicmVha1JlZ2V4XyA9IC9bXFxyXFxuXS87XG5jb25zdCBibGFua2xpbmVFbmRSZWdleF8gPSAvXFxuXFxyP1xcbiQvO1xuY29uc3QgYmxhbmtsaW5lU3RhcnRSZWdleF8gPSAvXlxccj9cXG5cXHI/XFxuLztcbi8qKlxuKiBMb29rIGZvciBzaW5nbGUgZWRpdHMgc3Vycm91bmRlZCBvbiBib3RoIHNpZGVzIGJ5IGVxdWFsaXRpZXNcbiogd2hpY2ggY2FuIGJlIHNoaWZ0ZWQgc2lkZXdheXMgdG8gYWxpZ24gdGhlIGVkaXQgdG8gYSB3b3JkIGJvdW5kYXJ5LlxuKiBlLmc6IFRoZSBjPGlucz5hdCBjPC9pbnM+YW1lLiAtPiBUaGUgPGlucz5jYXQgPC9pbnM+Y2FtZS5cbiogQHBhcmFtIHshQXJyYXkuPCFkaWZmX21hdGNoX3BhdGNoLkRpZmY+fSBkaWZmcyBBcnJheSBvZiBkaWZmIHR1cGxlcy5cbiovXG5mdW5jdGlvbiBkaWZmX2NsZWFudXBTZW1hbnRpY0xvc3NsZXNzKGRpZmZzKSB7XG5cdGxldCBwb2ludGVyID0gMTtcblx0Ly8gSW50ZW50aW9uYWxseSBpZ25vcmUgdGhlIGZpcnN0IGFuZCBsYXN0IGVsZW1lbnQgKGRvbid0IG5lZWQgY2hlY2tpbmcpLlxuXHR3aGlsZSAocG9pbnRlciA8IGRpZmZzLmxlbmd0aCAtIDEpIHtcblx0XHRpZiAoZGlmZnNbcG9pbnRlciAtIDFdWzBdID09PSBESUZGX0VRVUFMICYmIGRpZmZzW3BvaW50ZXIgKyAxXVswXSA9PT0gRElGRl9FUVVBTCkge1xuXHRcdFx0Ly8gVGhpcyBpcyBhIHNpbmdsZSBlZGl0IHN1cnJvdW5kZWQgYnkgZXF1YWxpdGllcy5cblx0XHRcdGxldCBlcXVhbGl0eTEgPSBkaWZmc1twb2ludGVyIC0gMV1bMV07XG5cdFx0XHRsZXQgZWRpdCA9IGRpZmZzW3BvaW50ZXJdWzFdO1xuXHRcdFx0bGV0IGVxdWFsaXR5MiA9IGRpZmZzW3BvaW50ZXIgKyAxXVsxXTtcblx0XHRcdC8vIEZpcnN0LCBzaGlmdCB0aGUgZWRpdCBhcyBmYXIgbGVmdCBhcyBwb3NzaWJsZS5cblx0XHRcdGNvbnN0IGNvbW1vbk9mZnNldCA9IGRpZmZfY29tbW9uU3VmZml4KGVxdWFsaXR5MSwgZWRpdCk7XG5cdFx0XHRpZiAoY29tbW9uT2Zmc2V0KSB7XG5cdFx0XHRcdGNvbnN0IGNvbW1vblN0cmluZyA9IGVkaXQuc3Vic3RyaW5nKGVkaXQubGVuZ3RoIC0gY29tbW9uT2Zmc2V0KTtcblx0XHRcdFx0ZXF1YWxpdHkxID0gZXF1YWxpdHkxLnN1YnN0cmluZygwLCBlcXVhbGl0eTEubGVuZ3RoIC0gY29tbW9uT2Zmc2V0KTtcblx0XHRcdFx0ZWRpdCA9IGNvbW1vblN0cmluZyArIGVkaXQuc3Vic3RyaW5nKDAsIGVkaXQubGVuZ3RoIC0gY29tbW9uT2Zmc2V0KTtcblx0XHRcdFx0ZXF1YWxpdHkyID0gY29tbW9uU3RyaW5nICsgZXF1YWxpdHkyO1xuXHRcdFx0fVxuXHRcdFx0Ly8gU2Vjb25kLCBzdGVwIGNoYXJhY3RlciBieSBjaGFyYWN0ZXIgcmlnaHQsIGxvb2tpbmcgZm9yIHRoZSBiZXN0IGZpdC5cblx0XHRcdGxldCBiZXN0RXF1YWxpdHkxID0gZXF1YWxpdHkxO1xuXHRcdFx0bGV0IGJlc3RFZGl0ID0gZWRpdDtcblx0XHRcdGxldCBiZXN0RXF1YWxpdHkyID0gZXF1YWxpdHkyO1xuXHRcdFx0bGV0IGJlc3RTY29yZSA9IGRpZmZfY2xlYW51cFNlbWFudGljU2NvcmVfKGVxdWFsaXR5MSwgZWRpdCkgKyBkaWZmX2NsZWFudXBTZW1hbnRpY1Njb3JlXyhlZGl0LCBlcXVhbGl0eTIpO1xuXHRcdFx0d2hpbGUgKGVkaXQuY2hhckF0KDApID09PSBlcXVhbGl0eTIuY2hhckF0KDApKSB7XG5cdFx0XHRcdGVxdWFsaXR5MSArPSBlZGl0LmNoYXJBdCgwKTtcblx0XHRcdFx0ZWRpdCA9IGVkaXQuc3Vic3RyaW5nKDEpICsgZXF1YWxpdHkyLmNoYXJBdCgwKTtcblx0XHRcdFx0ZXF1YWxpdHkyID0gZXF1YWxpdHkyLnN1YnN0cmluZygxKTtcblx0XHRcdFx0Y29uc3Qgc2NvcmUgPSBkaWZmX2NsZWFudXBTZW1hbnRpY1Njb3JlXyhlcXVhbGl0eTEsIGVkaXQpICsgZGlmZl9jbGVhbnVwU2VtYW50aWNTY29yZV8oZWRpdCwgZXF1YWxpdHkyKTtcblx0XHRcdFx0Ly8gVGhlID49IGVuY291cmFnZXMgdHJhaWxpbmcgcmF0aGVyIHRoYW4gbGVhZGluZyB3aGl0ZXNwYWNlIG9uIGVkaXRzLlxuXHRcdFx0XHRpZiAoc2NvcmUgPj0gYmVzdFNjb3JlKSB7XG5cdFx0XHRcdFx0YmVzdFNjb3JlID0gc2NvcmU7XG5cdFx0XHRcdFx0YmVzdEVxdWFsaXR5MSA9IGVxdWFsaXR5MTtcblx0XHRcdFx0XHRiZXN0RWRpdCA9IGVkaXQ7XG5cdFx0XHRcdFx0YmVzdEVxdWFsaXR5MiA9IGVxdWFsaXR5Mjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKGRpZmZzW3BvaW50ZXIgLSAxXVsxXSAhPT0gYmVzdEVxdWFsaXR5MSkge1xuXHRcdFx0XHQvLyBXZSBoYXZlIGFuIGltcHJvdmVtZW50LCBzYXZlIGl0IGJhY2sgdG8gdGhlIGRpZmYuXG5cdFx0XHRcdGlmIChiZXN0RXF1YWxpdHkxKSB7XG5cdFx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzFdID0gYmVzdEVxdWFsaXR5MTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkaWZmcy5zcGxpY2UocG9pbnRlciAtIDEsIDEpO1xuXHRcdFx0XHRcdHBvaW50ZXItLTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkaWZmc1twb2ludGVyXVsxXSA9IGJlc3RFZGl0O1xuXHRcdFx0XHRpZiAoYmVzdEVxdWFsaXR5Mikge1xuXHRcdFx0XHRcdGRpZmZzW3BvaW50ZXIgKyAxXVsxXSA9IGJlc3RFcXVhbGl0eTI7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZGlmZnMuc3BsaWNlKHBvaW50ZXIgKyAxLCAxKTtcblx0XHRcdFx0XHRwb2ludGVyLS07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cG9pbnRlcisrO1xuXHR9XG59XG4vKipcbiogUmVvcmRlciBhbmQgbWVyZ2UgbGlrZSBlZGl0IHNlY3Rpb25zLiAgTWVyZ2UgZXF1YWxpdGllcy5cbiogQW55IGVkaXQgc2VjdGlvbiBjYW4gbW92ZSBhcyBsb25nIGFzIGl0IGRvZXNuJ3QgY3Jvc3MgYW4gZXF1YWxpdHkuXG4qIEBwYXJhbSB7IUFycmF5LjwhZGlmZl9tYXRjaF9wYXRjaC5EaWZmPn0gZGlmZnMgQXJyYXkgb2YgZGlmZiB0dXBsZXMuXG4qL1xuZnVuY3Rpb24gZGlmZl9jbGVhbnVwTWVyZ2UoZGlmZnMpIHtcblx0Ly8gQWRkIGEgZHVtbXkgZW50cnkgYXQgdGhlIGVuZC5cblx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0VRVUFMLCBcIlwiKSk7XG5cdGxldCBwb2ludGVyID0gMDtcblx0bGV0IGNvdW50X2RlbGV0ZSA9IDA7XG5cdGxldCBjb3VudF9pbnNlcnQgPSAwO1xuXHRsZXQgdGV4dF9kZWxldGUgPSBcIlwiO1xuXHRsZXQgdGV4dF9pbnNlcnQgPSBcIlwiO1xuXHRsZXQgY29tbW9ubGVuZ3RoO1xuXHR3aGlsZSAocG9pbnRlciA8IGRpZmZzLmxlbmd0aCkge1xuXHRcdHN3aXRjaCAoZGlmZnNbcG9pbnRlcl1bMF0pIHtcblx0XHRcdGNhc2UgRElGRl9JTlNFUlQ6XG5cdFx0XHRcdGNvdW50X2luc2VydCsrO1xuXHRcdFx0XHR0ZXh0X2luc2VydCArPSBkaWZmc1twb2ludGVyXVsxXTtcblx0XHRcdFx0cG9pbnRlcisrO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRElGRl9ERUxFVEU6XG5cdFx0XHRcdGNvdW50X2RlbGV0ZSsrO1xuXHRcdFx0XHR0ZXh0X2RlbGV0ZSArPSBkaWZmc1twb2ludGVyXVsxXTtcblx0XHRcdFx0cG9pbnRlcisrO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRElGRl9FUVVBTDpcblx0XHRcdFx0Ly8gVXBvbiByZWFjaGluZyBhbiBlcXVhbGl0eSwgY2hlY2sgZm9yIHByaW9yIHJlZHVuZGFuY2llcy5cblx0XHRcdFx0aWYgKGNvdW50X2RlbGV0ZSArIGNvdW50X2luc2VydCA+IDEpIHtcblx0XHRcdFx0XHRpZiAoY291bnRfZGVsZXRlICE9PSAwICYmIGNvdW50X2luc2VydCAhPT0gMCkge1xuXHRcdFx0XHRcdFx0Ly8gRmFjdG9yIG91dCBhbnkgY29tbW9uIHByZWZpeGVzLlxuXHRcdFx0XHRcdFx0Y29tbW9ubGVuZ3RoID0gZGlmZl9jb21tb25QcmVmaXgodGV4dF9pbnNlcnQsIHRleHRfZGVsZXRlKTtcblx0XHRcdFx0XHRcdGlmIChjb21tb25sZW5ndGggIT09IDApIHtcblx0XHRcdFx0XHRcdFx0aWYgKHBvaW50ZXIgLSBjb3VudF9kZWxldGUgLSBjb3VudF9pbnNlcnQgPiAwICYmIGRpZmZzW3BvaW50ZXIgLSBjb3VudF9kZWxldGUgLSBjb3VudF9pbnNlcnQgLSAxXVswXSA9PT0gRElGRl9FUVVBTCkge1xuXHRcdFx0XHRcdFx0XHRcdGRpZmZzW3BvaW50ZXIgLSBjb3VudF9kZWxldGUgLSBjb3VudF9pbnNlcnQgLSAxXVsxXSArPSB0ZXh0X2luc2VydC5zdWJzdHJpbmcoMCwgY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRkaWZmcy5zcGxpY2UoMCwgMCwgbmV3IERpZmYoRElGRl9FUVVBTCwgdGV4dF9pbnNlcnQuc3Vic3RyaW5nKDAsIGNvbW1vbmxlbmd0aCkpKTtcblx0XHRcdFx0XHRcdFx0XHRwb2ludGVyKys7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0dGV4dF9pbnNlcnQgPSB0ZXh0X2luc2VydC5zdWJzdHJpbmcoY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdFx0dGV4dF9kZWxldGUgPSB0ZXh0X2RlbGV0ZS5zdWJzdHJpbmcoY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdC8vIEZhY3RvciBvdXQgYW55IGNvbW1vbiBzdWZmaXhlcy5cblx0XHRcdFx0XHRcdGNvbW1vbmxlbmd0aCA9IGRpZmZfY29tbW9uU3VmZml4KHRleHRfaW5zZXJ0LCB0ZXh0X2RlbGV0ZSk7XG5cdFx0XHRcdFx0XHRpZiAoY29tbW9ubGVuZ3RoICE9PSAwKSB7XG5cdFx0XHRcdFx0XHRcdGRpZmZzW3BvaW50ZXJdWzFdID0gdGV4dF9pbnNlcnQuc3Vic3RyaW5nKHRleHRfaW5zZXJ0Lmxlbmd0aCAtIGNvbW1vbmxlbmd0aCkgKyBkaWZmc1twb2ludGVyXVsxXTtcblx0XHRcdFx0XHRcdFx0dGV4dF9pbnNlcnQgPSB0ZXh0X2luc2VydC5zdWJzdHJpbmcoMCwgdGV4dF9pbnNlcnQubGVuZ3RoIC0gY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdFx0dGV4dF9kZWxldGUgPSB0ZXh0X2RlbGV0ZS5zdWJzdHJpbmcoMCwgdGV4dF9kZWxldGUubGVuZ3RoIC0gY29tbW9ubGVuZ3RoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gRGVsZXRlIHRoZSBvZmZlbmRpbmcgcmVjb3JkcyBhbmQgYWRkIHRoZSBtZXJnZWQgb25lcy5cblx0XHRcdFx0XHRwb2ludGVyIC09IGNvdW50X2RlbGV0ZSArIGNvdW50X2luc2VydDtcblx0XHRcdFx0XHRkaWZmcy5zcGxpY2UocG9pbnRlciwgY291bnRfZGVsZXRlICsgY291bnRfaW5zZXJ0KTtcblx0XHRcdFx0XHRpZiAodGV4dF9kZWxldGUubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRkaWZmcy5zcGxpY2UocG9pbnRlciwgMCwgbmV3IERpZmYoRElGRl9ERUxFVEUsIHRleHRfZGVsZXRlKSk7XG5cdFx0XHRcdFx0XHRwb2ludGVyKys7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICh0ZXh0X2luc2VydC5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdGRpZmZzLnNwbGljZShwb2ludGVyLCAwLCBuZXcgRGlmZihESUZGX0lOU0VSVCwgdGV4dF9pbnNlcnQpKTtcblx0XHRcdFx0XHRcdHBvaW50ZXIrKztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9pbnRlcisrO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHBvaW50ZXIgIT09IDAgJiYgZGlmZnNbcG9pbnRlciAtIDFdWzBdID09PSBESUZGX0VRVUFMKSB7XG5cdFx0XHRcdFx0Ly8gTWVyZ2UgdGhpcyBlcXVhbGl0eSB3aXRoIHRoZSBwcmV2aW91cyBvbmUuXG5cdFx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzFdICs9IGRpZmZzW3BvaW50ZXJdWzFdO1xuXHRcdFx0XHRcdGRpZmZzLnNwbGljZShwb2ludGVyLCAxKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRwb2ludGVyKys7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y291bnRfaW5zZXJ0ID0gMDtcblx0XHRcdFx0Y291bnRfZGVsZXRlID0gMDtcblx0XHRcdFx0dGV4dF9kZWxldGUgPSBcIlwiO1xuXHRcdFx0XHR0ZXh0X2luc2VydCA9IFwiXCI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXHRpZiAoZGlmZnMuYXQoLTEpPy5bMV0gPT09IFwiXCIpIHtcblx0XHRkaWZmcy5wb3AoKTtcblx0fVxuXHQvLyBTZWNvbmQgcGFzczogbG9vayBmb3Igc2luZ2xlIGVkaXRzIHN1cnJvdW5kZWQgb24gYm90aCBzaWRlcyBieSBlcXVhbGl0aWVzXG5cdC8vIHdoaWNoIGNhbiBiZSBzaGlmdGVkIHNpZGV3YXlzIHRvIGVsaW1pbmF0ZSBhbiBlcXVhbGl0eS5cblx0Ly8gZS5nOiBBPGlucz5CQTwvaW5zPkMgLT4gPGlucz5BQjwvaW5zPkFDXG5cdGxldCBjaGFuZ2VzID0gZmFsc2U7XG5cdHBvaW50ZXIgPSAxO1xuXHQvLyBJbnRlbnRpb25hbGx5IGlnbm9yZSB0aGUgZmlyc3QgYW5kIGxhc3QgZWxlbWVudCAoZG9uJ3QgbmVlZCBjaGVja2luZykuXG5cdHdoaWxlIChwb2ludGVyIDwgZGlmZnMubGVuZ3RoIC0gMSkge1xuXHRcdGlmIChkaWZmc1twb2ludGVyIC0gMV1bMF0gPT09IERJRkZfRVFVQUwgJiYgZGlmZnNbcG9pbnRlciArIDFdWzBdID09PSBESUZGX0VRVUFMKSB7XG5cdFx0XHQvLyBUaGlzIGlzIGEgc2luZ2xlIGVkaXQgc3Vycm91bmRlZCBieSBlcXVhbGl0aWVzLlxuXHRcdFx0aWYgKGRpZmZzW3BvaW50ZXJdWzFdLnN1YnN0cmluZyhkaWZmc1twb2ludGVyXVsxXS5sZW5ndGggLSBkaWZmc1twb2ludGVyIC0gMV1bMV0ubGVuZ3RoKSA9PT0gZGlmZnNbcG9pbnRlciAtIDFdWzFdKSB7XG5cdFx0XHRcdC8vIFNoaWZ0IHRoZSBlZGl0IG92ZXIgdGhlIHByZXZpb3VzIGVxdWFsaXR5LlxuXHRcdFx0XHRkaWZmc1twb2ludGVyXVsxXSA9IGRpZmZzW3BvaW50ZXIgLSAxXVsxXSArIGRpZmZzW3BvaW50ZXJdWzFdLnN1YnN0cmluZygwLCBkaWZmc1twb2ludGVyXVsxXS5sZW5ndGggLSBkaWZmc1twb2ludGVyIC0gMV1bMV0ubGVuZ3RoKTtcblx0XHRcdFx0ZGlmZnNbcG9pbnRlciArIDFdWzFdID0gZGlmZnNbcG9pbnRlciAtIDFdWzFdICsgZGlmZnNbcG9pbnRlciArIDFdWzFdO1xuXHRcdFx0XHRkaWZmcy5zcGxpY2UocG9pbnRlciAtIDEsIDEpO1xuXHRcdFx0XHRjaGFuZ2VzID0gdHJ1ZTtcblx0XHRcdH0gZWxzZSBpZiAoZGlmZnNbcG9pbnRlcl1bMV0uc3Vic3RyaW5nKDAsIGRpZmZzW3BvaW50ZXIgKyAxXVsxXS5sZW5ndGgpID09PSBkaWZmc1twb2ludGVyICsgMV1bMV0pIHtcblx0XHRcdFx0Ly8gU2hpZnQgdGhlIGVkaXQgb3ZlciB0aGUgbmV4dCBlcXVhbGl0eS5cblx0XHRcdFx0ZGlmZnNbcG9pbnRlciAtIDFdWzFdICs9IGRpZmZzW3BvaW50ZXIgKyAxXVsxXTtcblx0XHRcdFx0ZGlmZnNbcG9pbnRlcl1bMV0gPSBkaWZmc1twb2ludGVyXVsxXS5zdWJzdHJpbmcoZGlmZnNbcG9pbnRlciArIDFdWzFdLmxlbmd0aCkgKyBkaWZmc1twb2ludGVyICsgMV1bMV07XG5cdFx0XHRcdGRpZmZzLnNwbGljZShwb2ludGVyICsgMSwgMSk7XG5cdFx0XHRcdGNoYW5nZXMgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRwb2ludGVyKys7XG5cdH1cblx0Ly8gSWYgc2hpZnRzIHdlcmUgbWFkZSwgdGhlIGRpZmYgbmVlZHMgcmVvcmRlcmluZyBhbmQgYW5vdGhlciBzaGlmdCBzd2VlcC5cblx0aWYgKGNoYW5nZXMpIHtcblx0XHRkaWZmX2NsZWFudXBNZXJnZShkaWZmcyk7XG5cdH1cbn1cbi8qKlxuKiBHaXZlbiB0d28gc3RyaW5ncywgY29tcHV0ZSBhIHNjb3JlIHJlcHJlc2VudGluZyB3aGV0aGVyIHRoZSBpbnRlcm5hbFxuKiBib3VuZGFyeSBmYWxscyBvbiBsb2dpY2FsIGJvdW5kYXJpZXMuXG4qIFNjb3JlcyByYW5nZSBmcm9tIDYgKGJlc3QpIHRvIDAgKHdvcnN0KS5cbiogQ2xvc3VyZSwgYnV0IGRvZXMgbm90IHJlZmVyZW5jZSBhbnkgZXh0ZXJuYWwgdmFyaWFibGVzLlxuKiBAcGFyYW0ge3N0cmluZ30gb25lIEZpcnN0IHN0cmluZy5cbiogQHBhcmFtIHtzdHJpbmd9IHR3byBTZWNvbmQgc3RyaW5nLlxuKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBzY29yZS5cbiogQHByaXZhdGVcbiovXG5mdW5jdGlvbiBkaWZmX2NsZWFudXBTZW1hbnRpY1Njb3JlXyhvbmUsIHR3bykge1xuXHRpZiAoIW9uZSB8fCAhdHdvKSB7XG5cdFx0Ly8gRWRnZXMgYXJlIHRoZSBiZXN0LlxuXHRcdHJldHVybiA2O1xuXHR9XG5cdC8vIEVhY2ggcG9ydCBvZiB0aGlzIGZ1bmN0aW9uIGJlaGF2ZXMgc2xpZ2h0bHkgZGlmZmVyZW50bHkgZHVlIHRvXG5cdC8vIHN1YnRsZSBkaWZmZXJlbmNlcyBpbiBlYWNoIGxhbmd1YWdlJ3MgZGVmaW5pdGlvbiBvZiB0aGluZ3MgbGlrZVxuXHQvLyAnd2hpdGVzcGFjZScuICBTaW5jZSB0aGlzIGZ1bmN0aW9uJ3MgcHVycG9zZSBpcyBsYXJnZWx5IGNvc21ldGljLFxuXHQvLyB0aGUgY2hvaWNlIGhhcyBiZWVuIG1hZGUgdG8gdXNlIGVhY2ggbGFuZ3VhZ2UncyBuYXRpdmUgZmVhdHVyZXNcblx0Ly8gcmF0aGVyIHRoYW4gZm9yY2UgdG90YWwgY29uZm9ybWl0eS5cblx0Y29uc3QgY2hhcjEgPSBvbmUuY2hhckF0KG9uZS5sZW5ndGggLSAxKTtcblx0Y29uc3QgY2hhcjIgPSB0d28uY2hhckF0KDApO1xuXHRjb25zdCBub25BbHBoYU51bWVyaWMxID0gY2hhcjEubWF0Y2gobm9uQWxwaGFOdW1lcmljUmVnZXhfKTtcblx0Y29uc3Qgbm9uQWxwaGFOdW1lcmljMiA9IGNoYXIyLm1hdGNoKG5vbkFscGhhTnVtZXJpY1JlZ2V4Xyk7XG5cdGNvbnN0IHdoaXRlc3BhY2UxID0gbm9uQWxwaGFOdW1lcmljMSAmJiBjaGFyMS5tYXRjaCh3aGl0ZXNwYWNlUmVnZXhfKTtcblx0Y29uc3Qgd2hpdGVzcGFjZTIgPSBub25BbHBoYU51bWVyaWMyICYmIGNoYXIyLm1hdGNoKHdoaXRlc3BhY2VSZWdleF8pO1xuXHRjb25zdCBsaW5lQnJlYWsxID0gd2hpdGVzcGFjZTEgJiYgY2hhcjEubWF0Y2gobGluZWJyZWFrUmVnZXhfKTtcblx0Y29uc3QgbGluZUJyZWFrMiA9IHdoaXRlc3BhY2UyICYmIGNoYXIyLm1hdGNoKGxpbmVicmVha1JlZ2V4Xyk7XG5cdGNvbnN0IGJsYW5rTGluZTEgPSBsaW5lQnJlYWsxICYmIG9uZS5tYXRjaChibGFua2xpbmVFbmRSZWdleF8pO1xuXHRjb25zdCBibGFua0xpbmUyID0gbGluZUJyZWFrMiAmJiB0d28ubWF0Y2goYmxhbmtsaW5lU3RhcnRSZWdleF8pO1xuXHRpZiAoYmxhbmtMaW5lMSB8fCBibGFua0xpbmUyKSB7XG5cdFx0Ly8gRml2ZSBwb2ludHMgZm9yIGJsYW5rIGxpbmVzLlxuXHRcdHJldHVybiA1O1xuXHR9IGVsc2UgaWYgKGxpbmVCcmVhazEgfHwgbGluZUJyZWFrMikge1xuXHRcdC8vIEZvdXIgcG9pbnRzIGZvciBsaW5lIGJyZWFrcy5cblx0XHRyZXR1cm4gNDtcblx0fSBlbHNlIGlmIChub25BbHBoYU51bWVyaWMxICYmICF3aGl0ZXNwYWNlMSAmJiB3aGl0ZXNwYWNlMikge1xuXHRcdC8vIFRocmVlIHBvaW50cyBmb3IgZW5kIG9mIHNlbnRlbmNlcy5cblx0XHRyZXR1cm4gMztcblx0fSBlbHNlIGlmICh3aGl0ZXNwYWNlMSB8fCB3aGl0ZXNwYWNlMikge1xuXHRcdC8vIFR3byBwb2ludHMgZm9yIHdoaXRlc3BhY2UuXG5cdFx0cmV0dXJuIDI7XG5cdH0gZWxzZSBpZiAobm9uQWxwaGFOdW1lcmljMSB8fCBub25BbHBoYU51bWVyaWMyKSB7XG5cdFx0Ly8gT25lIHBvaW50IGZvciBub24tYWxwaGFudW1lcmljLlxuXHRcdHJldHVybiAxO1xuXHR9XG5cdHJldHVybiAwO1xufVxuXG4vKipcbiogQ29weXJpZ2h0IChjKSBNZXRhIFBsYXRmb3JtcywgSW5jLiBhbmQgYWZmaWxpYXRlcy5cbipcbiogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4qIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiovXG5jb25zdCBOT19ESUZGX01FU1NBR0UgPSBcIkNvbXBhcmVkIHZhbHVlcyBoYXZlIG5vIHZpc3VhbCBkaWZmZXJlbmNlLlwiO1xuY29uc3QgU0lNSUxBUl9NRVNTQUdFID0gXCJDb21wYXJlZCB2YWx1ZXMgc2VyaWFsaXplIHRvIHRoZSBzYW1lIHN0cnVjdHVyZS5cXG5cIiArIFwiUHJpbnRpbmcgaW50ZXJuYWwgb2JqZWN0IHN0cnVjdHVyZSB3aXRob3V0IGNhbGxpbmcgYHRvSlNPTmAgaW5zdGVhZC5cIjtcblxuZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoeCkge1xuXHRyZXR1cm4geCAmJiB4Ll9fZXNNb2R1bGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsIFwiZGVmYXVsdFwiKSA/IHhbXCJkZWZhdWx0XCJdIDogeDtcbn1cblxudmFyIGJ1aWxkID0ge307XG5cbnZhciBoYXNSZXF1aXJlZEJ1aWxkO1xuXG5mdW5jdGlvbiByZXF1aXJlQnVpbGQgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRCdWlsZCkgcmV0dXJuIGJ1aWxkO1xuXHRoYXNSZXF1aXJlZEJ1aWxkID0gMTtcblxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoYnVpbGQsICdfX2VzTW9kdWxlJywge1xuXHQgIHZhbHVlOiB0cnVlXG5cdH0pO1xuXHRidWlsZC5kZWZhdWx0ID0gZGlmZlNlcXVlbmNlO1xuXHQvKipcblx0ICogQ29weXJpZ2h0IChjKSBNZXRhIFBsYXRmb3JtcywgSW5jLiBhbmQgYWZmaWxpYXRlcy5cblx0ICpcblx0ICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG5cdCAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cblx0ICpcblx0ICovXG5cblx0Ly8gVGhpcyBkaWZmLXNlcXVlbmNlcyBwYWNrYWdlIGltcGxlbWVudHMgdGhlIGxpbmVhciBzcGFjZSB2YXJpYXRpb24gaW5cblx0Ly8gQW4gTyhORCkgRGlmZmVyZW5jZSBBbGdvcml0aG0gYW5kIEl0cyBWYXJpYXRpb25zIGJ5IEV1Z2VuZSBXLiBNeWVyc1xuXG5cdC8vIFJlbGF0aW9uc2hpcCBpbiBub3RhdGlvbiBiZXR3ZWVuIE15ZXJzIHBhcGVyIGFuZCB0aGlzIHBhY2thZ2U6XG5cdC8vIEEgaXMgYVxuXHQvLyBOIGlzIGFMZW5ndGgsIGFFbmQgLSBhU3RhcnQsIGFuZCBzbyBvblxuXHQvLyB4IGlzIGFJbmRleCwgYUZpcnN0LCBhTGFzdCwgYW5kIHNvIG9uXG5cdC8vIEIgaXMgYlxuXHQvLyBNIGlzIGJMZW5ndGgsIGJFbmQgLSBiU3RhcnQsIGFuZCBzbyBvblxuXHQvLyB5IGlzIGJJbmRleCwgYkZpcnN0LCBiTGFzdCwgYW5kIHNvIG9uXG5cdC8vIM6UID0gTiAtIE0gaXMgbmVnYXRpdmUgb2YgYmFEZWx0YUxlbmd0aCA9IGJMZW5ndGggLSBhTGVuZ3RoXG5cdC8vIEQgaXMgZFxuXHQvLyBrIGlzIGtGXG5cdC8vIGsgKyDOlCBpcyBrRiA9IGtSIC0gYmFEZWx0YUxlbmd0aFxuXHQvLyBWIGlzIGFJbmRleGVzRiBvciBhSW5kZXhlc1IgKHNlZSBjb21tZW50IGJlbG93IGFib3V0IEluZGV4ZXMgdHlwZSlcblx0Ly8gaW5kZXggaW50ZXJ2YWxzIFsxLCBOXSBhbmQgWzEsIE1dIGFyZSBbMCwgYUxlbmd0aCkgYW5kIFswLCBiTGVuZ3RoKVxuXHQvLyBzdGFydGluZyBwb2ludCBpbiBmb3J3YXJkIGRpcmVjdGlvbiAoMCwgMCkgaXMgKC0xLCAtMSlcblx0Ly8gc3RhcnRpbmcgcG9pbnQgaW4gcmV2ZXJzZSBkaXJlY3Rpb24gKE4gKyAxLCBNICsgMSkgaXMgKGFMZW5ndGgsIGJMZW5ndGgpXG5cblx0Ly8gVGhlIOKAnGVkaXQgZ3JhcGjigJ0gZm9yIHNlcXVlbmNlcyBhIGFuZCBiIGNvcnJlc3BvbmRzIHRvIGl0ZW1zOlxuXHQvLyBpbiBhIG9uIHRoZSBob3Jpem9udGFsIGF4aXNcblx0Ly8gaW4gYiBvbiB0aGUgdmVydGljYWwgYXhpc1xuXHQvL1xuXHQvLyBHaXZlbiBhLWNvb3JkaW5hdGUgb2YgYSBwb2ludCBpbiBhIGRpYWdvbmFsLCB5b3UgY2FuIGNvbXB1dGUgYi1jb29yZGluYXRlLlxuXHQvL1xuXHQvLyBGb3J3YXJkIGRpYWdvbmFscyBrRjpcblx0Ly8gemVybyBkaWFnb25hbCBpbnRlcnNlY3RzIHRvcCBsZWZ0IGNvcm5lclxuXHQvLyBwb3NpdGl2ZSBkaWFnb25hbHMgaW50ZXJzZWN0IHRvcCBlZGdlXG5cdC8vIG5lZ2F0aXZlIGRpYWdvbmFscyBpbnNlcnNlY3QgbGVmdCBlZGdlXG5cdC8vXG5cdC8vIFJldmVyc2UgZGlhZ29uYWxzIGtSOlxuXHQvLyB6ZXJvIGRpYWdvbmFsIGludGVyc2VjdHMgYm90dG9tIHJpZ2h0IGNvcm5lclxuXHQvLyBwb3NpdGl2ZSBkaWFnb25hbHMgaW50ZXJzZWN0IHJpZ2h0IGVkZ2Vcblx0Ly8gbmVnYXRpdmUgZGlhZ29uYWxzIGludGVyc2VjdCBib3R0b20gZWRnZVxuXG5cdC8vIFRoZSBncmFwaCBjb250YWlucyBhIGRpcmVjdGVkIGFjeWNsaWMgZ3JhcGggb2YgZWRnZXM6XG5cdC8vIGhvcml6b250YWw6IGRlbGV0ZSBhbiBpdGVtIGZyb20gYVxuXHQvLyB2ZXJ0aWNhbDogaW5zZXJ0IGFuIGl0ZW0gZnJvbSBiXG5cdC8vIGRpYWdvbmFsOiBjb21tb24gaXRlbSBpbiBhIGFuZCBiXG5cdC8vXG5cdC8vIFRoZSBhbGdvcml0aG0gc29sdmVzIGR1YWwgcHJvYmxlbXMgaW4gdGhlIGdyYXBoIGFuYWxvZ3k6XG5cdC8vIEZpbmQgbG9uZ2VzdCBjb21tb24gc3Vic2VxdWVuY2U6IHBhdGggd2l0aCBtYXhpbXVtIG51bWJlciBvZiBkaWFnb25hbCBlZGdlc1xuXHQvLyBGaW5kIHNob3J0ZXN0IGVkaXQgc2NyaXB0OiBwYXRoIHdpdGggbWluaW11bSBudW1iZXIgb2Ygbm9uLWRpYWdvbmFsIGVkZ2VzXG5cblx0Ly8gSW5wdXQgY2FsbGJhY2sgZnVuY3Rpb24gY29tcGFyZXMgaXRlbXMgYXQgaW5kZXhlcyBpbiB0aGUgc2VxdWVuY2VzLlxuXG5cdC8vIE91dHB1dCBjYWxsYmFjayBmdW5jdGlvbiByZWNlaXZlcyB0aGUgbnVtYmVyIG9mIGFkamFjZW50IGl0ZW1zXG5cdC8vIGFuZCBzdGFydGluZyBpbmRleGVzIG9mIGVhY2ggY29tbW9uIHN1YnNlcXVlbmNlLlxuXHQvLyBFaXRoZXIgb3JpZ2luYWwgZnVuY3Rpb25zIG9yIHdyYXBwZWQgdG8gc3dhcCBpbmRleGVzIGlmIGdyYXBoIGlzIHRyYW5zcG9zZWQuXG5cdC8vIEluZGV4ZXMgaW4gc2VxdWVuY2UgYSBvZiBsYXN0IHBvaW50IG9mIGZvcndhcmQgb3IgcmV2ZXJzZSBwYXRocyBpbiBncmFwaC5cblx0Ly8gTXllcnMgYWxnb3JpdGhtIGluZGV4ZXMgYnkgZGlhZ29uYWwgayB3aGljaCBmb3IgbmVnYXRpdmUgaXMgYmFkIGRlb3B0IGluIFY4LlxuXHQvLyBUaGlzIHBhY2thZ2UgaW5kZXhlcyBieSBpRiBhbmQgaVIgd2hpY2ggYXJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB6ZXJvLlxuXHQvLyBhbmQgYWxzbyB1cGRhdGVzIHRoZSBpbmRleCBhcnJheXMgaW4gcGxhY2UgdG8gY3V0IG1lbW9yeSBpbiBoYWxmLlxuXHQvLyBrRiA9IDIgKiBpRiAtIGRcblx0Ly8ga1IgPSBkIC0gMiAqIGlSXG5cdC8vIERpdmlzaW9uIG9mIGluZGV4IGludGVydmFscyBpbiBzZXF1ZW5jZXMgYSBhbmQgYiBhdCB0aGUgbWlkZGxlIGNoYW5nZS5cblx0Ly8gSW52YXJpYW50OiBpbnRlcnZhbHMgZG8gbm90IGhhdmUgY29tbW9uIGl0ZW1zIGF0IHRoZSBzdGFydCBvciBlbmQuXG5cdGNvbnN0IHBrZyA9ICdkaWZmLXNlcXVlbmNlcyc7IC8vIGZvciBlcnJvciBtZXNzYWdlc1xuXHRjb25zdCBOT1RfWUVUX1NFVCA9IDA7IC8vIHNtYWxsIGludCBpbnN0ZWFkIG9mIHVuZGVmaW5lZCB0byBhdm9pZCBkZW9wdCBpbiBWOFxuXG5cdC8vIFJldHVybiB0aGUgbnVtYmVyIG9mIGNvbW1vbiBpdGVtcyB0aGF0IGZvbGxvdyBpbiBmb3J3YXJkIGRpcmVjdGlvbi5cblx0Ly8gVGhlIGxlbmd0aCBvZiB3aGF0IE15ZXJzIHBhcGVyIGNhbGxzIGEg4oCcc25ha2XigJ0gaW4gYSBmb3J3YXJkIHBhdGguXG5cdGNvbnN0IGNvdW50Q29tbW9uSXRlbXNGID0gKGFJbmRleCwgYUVuZCwgYkluZGV4LCBiRW5kLCBpc0NvbW1vbikgPT4ge1xuXHQgIGxldCBuQ29tbW9uID0gMDtcblx0ICB3aGlsZSAoYUluZGV4IDwgYUVuZCAmJiBiSW5kZXggPCBiRW5kICYmIGlzQ29tbW9uKGFJbmRleCwgYkluZGV4KSkge1xuXHQgICAgYUluZGV4ICs9IDE7XG5cdCAgICBiSW5kZXggKz0gMTtcblx0ICAgIG5Db21tb24gKz0gMTtcblx0ICB9XG5cdCAgcmV0dXJuIG5Db21tb247XG5cdH07XG5cblx0Ly8gUmV0dXJuIHRoZSBudW1iZXIgb2YgY29tbW9uIGl0ZW1zIHRoYXQgcHJlY2VkZSBpbiByZXZlcnNlIGRpcmVjdGlvbi5cblx0Ly8gVGhlIGxlbmd0aCBvZiB3aGF0IE15ZXJzIHBhcGVyIGNhbGxzIGEg4oCcc25ha2XigJ0gaW4gYSByZXZlcnNlIHBhdGguXG5cdGNvbnN0IGNvdW50Q29tbW9uSXRlbXNSID0gKGFTdGFydCwgYUluZGV4LCBiU3RhcnQsIGJJbmRleCwgaXNDb21tb24pID0+IHtcblx0ICBsZXQgbkNvbW1vbiA9IDA7XG5cdCAgd2hpbGUgKGFTdGFydCA8PSBhSW5kZXggJiYgYlN0YXJ0IDw9IGJJbmRleCAmJiBpc0NvbW1vbihhSW5kZXgsIGJJbmRleCkpIHtcblx0ICAgIGFJbmRleCAtPSAxO1xuXHQgICAgYkluZGV4IC09IDE7XG5cdCAgICBuQ29tbW9uICs9IDE7XG5cdCAgfVxuXHQgIHJldHVybiBuQ29tbW9uO1xuXHR9O1xuXG5cdC8vIEEgc2ltcGxlIGZ1bmN0aW9uIHRvIGV4dGVuZCBmb3J3YXJkIHBhdGhzIGZyb20gKGQgLSAxKSB0byBkIGNoYW5nZXNcblx0Ly8gd2hlbiBmb3J3YXJkIGFuZCByZXZlcnNlIHBhdGhzIGNhbm5vdCB5ZXQgb3ZlcmxhcC5cblx0Y29uc3QgZXh0ZW5kUGF0aHNGID0gKFxuXHQgIGQsXG5cdCAgYUVuZCxcblx0ICBiRW5kLFxuXHQgIGJGLFxuXHQgIGlzQ29tbW9uLFxuXHQgIGFJbmRleGVzRixcblx0ICBpTWF4RiAvLyByZXR1cm4gdGhlIHZhbHVlIGJlY2F1c2Ugb3B0aW1pemF0aW9uIG1pZ2h0IGRlY3JlYXNlIGl0XG5cdCkgPT4ge1xuXHQgIC8vIFVucm9sbCB0aGUgZmlyc3QgaXRlcmF0aW9uLlxuXHQgIGxldCBpRiA9IDA7XG5cdCAgbGV0IGtGID0gLWQ7IC8vIGtGID0gMiAqIGlGIC0gZFxuXHQgIGxldCBhRmlyc3QgPSBhSW5kZXhlc0ZbaUZdOyAvLyBpbiBmaXJzdCBpdGVyYXRpb24gYWx3YXlzIGluc2VydFxuXHQgIGxldCBhSW5kZXhQcmV2MSA9IGFGaXJzdDsgLy8gcHJldiB2YWx1ZSBvZiBbaUYgLSAxXSBpbiBuZXh0IGl0ZXJhdGlvblxuXHQgIGFJbmRleGVzRltpRl0gKz0gY291bnRDb21tb25JdGVtc0YoXG5cdCAgICBhRmlyc3QgKyAxLFxuXHQgICAgYUVuZCxcblx0ICAgIGJGICsgYUZpcnN0IC0ga0YgKyAxLFxuXHQgICAgYkVuZCxcblx0ICAgIGlzQ29tbW9uXG5cdCAgKTtcblxuXHQgIC8vIE9wdGltaXphdGlvbjogc2tpcCBkaWFnb25hbHMgaW4gd2hpY2ggcGF0aHMgY2Fubm90IGV2ZXIgb3ZlcmxhcC5cblx0ICBjb25zdCBuRiA9IGQgPCBpTWF4RiA/IGQgOiBpTWF4RjtcblxuXHQgIC8vIFRoZSBkaWFnb25hbHMga0YgYXJlIG9kZCB3aGVuIGQgaXMgb2RkIGFuZCBldmVuIHdoZW4gZCBpcyBldmVuLlxuXHQgIGZvciAoaUYgKz0gMSwga0YgKz0gMjsgaUYgPD0gbkY7IGlGICs9IDEsIGtGICs9IDIpIHtcblx0ICAgIC8vIFRvIGdldCBmaXJzdCBwb2ludCBvZiBwYXRoIHNlZ21lbnQsIG1vdmUgb25lIGNoYW5nZSBpbiBmb3J3YXJkIGRpcmVjdGlvblxuXHQgICAgLy8gZnJvbSBsYXN0IHBvaW50IG9mIHByZXZpb3VzIHBhdGggc2VnbWVudCBpbiBhbiBhZGphY2VudCBkaWFnb25hbC5cblx0ICAgIC8vIEluIGxhc3QgcG9zc2libGUgaXRlcmF0aW9uIHdoZW4gaUYgPT09IGQgYW5kIGtGID09PSBkIGFsd2F5cyBkZWxldGUuXG5cdCAgICBpZiAoaUYgIT09IGQgJiYgYUluZGV4UHJldjEgPCBhSW5kZXhlc0ZbaUZdKSB7XG5cdCAgICAgIGFGaXJzdCA9IGFJbmRleGVzRltpRl07IC8vIHZlcnRpY2FsIHRvIGluc2VydCBmcm9tIGJcblx0ICAgIH0gZWxzZSB7XG5cdCAgICAgIGFGaXJzdCA9IGFJbmRleFByZXYxICsgMTsgLy8gaG9yaXpvbnRhbCB0byBkZWxldGUgZnJvbSBhXG5cblx0ICAgICAgaWYgKGFFbmQgPD0gYUZpcnN0KSB7XG5cdCAgICAgICAgLy8gT3B0aW1pemF0aW9uOiBkZWxldGUgbW92ZWQgcGFzdCByaWdodCBvZiBncmFwaC5cblx0ICAgICAgICByZXR1cm4gaUYgLSAxO1xuXHQgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIC8vIFRvIGdldCBsYXN0IHBvaW50IG9mIHBhdGggc2VnbWVudCwgbW92ZSBhbG9uZyBkaWFnb25hbCBvZiBjb21tb24gaXRlbXMuXG5cdCAgICBhSW5kZXhQcmV2MSA9IGFJbmRleGVzRltpRl07XG5cdCAgICBhSW5kZXhlc0ZbaUZdID1cblx0ICAgICAgYUZpcnN0ICtcblx0ICAgICAgY291bnRDb21tb25JdGVtc0YoYUZpcnN0ICsgMSwgYUVuZCwgYkYgKyBhRmlyc3QgLSBrRiArIDEsIGJFbmQsIGlzQ29tbW9uKTtcblx0ICB9XG5cdCAgcmV0dXJuIGlNYXhGO1xuXHR9O1xuXG5cdC8vIEEgc2ltcGxlIGZ1bmN0aW9uIHRvIGV4dGVuZCByZXZlcnNlIHBhdGhzIGZyb20gKGQgLSAxKSB0byBkIGNoYW5nZXNcblx0Ly8gd2hlbiByZXZlcnNlIGFuZCBmb3J3YXJkIHBhdGhzIGNhbm5vdCB5ZXQgb3ZlcmxhcC5cblx0Y29uc3QgZXh0ZW5kUGF0aHNSID0gKFxuXHQgIGQsXG5cdCAgYVN0YXJ0LFxuXHQgIGJTdGFydCxcblx0ICBiUixcblx0ICBpc0NvbW1vbixcblx0ICBhSW5kZXhlc1IsXG5cdCAgaU1heFIgLy8gcmV0dXJuIHRoZSB2YWx1ZSBiZWNhdXNlIG9wdGltaXphdGlvbiBtaWdodCBkZWNyZWFzZSBpdFxuXHQpID0+IHtcblx0ICAvLyBVbnJvbGwgdGhlIGZpcnN0IGl0ZXJhdGlvbi5cblx0ICBsZXQgaVIgPSAwO1xuXHQgIGxldCBrUiA9IGQ7IC8vIGtSID0gZCAtIDIgKiBpUlxuXHQgIGxldCBhRmlyc3QgPSBhSW5kZXhlc1JbaVJdOyAvLyBpbiBmaXJzdCBpdGVyYXRpb24gYWx3YXlzIGluc2VydFxuXHQgIGxldCBhSW5kZXhQcmV2MSA9IGFGaXJzdDsgLy8gcHJldiB2YWx1ZSBvZiBbaVIgLSAxXSBpbiBuZXh0IGl0ZXJhdGlvblxuXHQgIGFJbmRleGVzUltpUl0gLT0gY291bnRDb21tb25JdGVtc1IoXG5cdCAgICBhU3RhcnQsXG5cdCAgICBhRmlyc3QgLSAxLFxuXHQgICAgYlN0YXJ0LFxuXHQgICAgYlIgKyBhRmlyc3QgLSBrUiAtIDEsXG5cdCAgICBpc0NvbW1vblxuXHQgICk7XG5cblx0ICAvLyBPcHRpbWl6YXRpb246IHNraXAgZGlhZ29uYWxzIGluIHdoaWNoIHBhdGhzIGNhbm5vdCBldmVyIG92ZXJsYXAuXG5cdCAgY29uc3QgblIgPSBkIDwgaU1heFIgPyBkIDogaU1heFI7XG5cblx0ICAvLyBUaGUgZGlhZ29uYWxzIGtSIGFyZSBvZGQgd2hlbiBkIGlzIG9kZCBhbmQgZXZlbiB3aGVuIGQgaXMgZXZlbi5cblx0ICBmb3IgKGlSICs9IDEsIGtSIC09IDI7IGlSIDw9IG5SOyBpUiArPSAxLCBrUiAtPSAyKSB7XG5cdCAgICAvLyBUbyBnZXQgZmlyc3QgcG9pbnQgb2YgcGF0aCBzZWdtZW50LCBtb3ZlIG9uZSBjaGFuZ2UgaW4gcmV2ZXJzZSBkaXJlY3Rpb25cblx0ICAgIC8vIGZyb20gbGFzdCBwb2ludCBvZiBwcmV2aW91cyBwYXRoIHNlZ21lbnQgaW4gYW4gYWRqYWNlbnQgZGlhZ29uYWwuXG5cdCAgICAvLyBJbiBsYXN0IHBvc3NpYmxlIGl0ZXJhdGlvbiB3aGVuIGlSID09PSBkIGFuZCBrUiA9PT0gLWQgYWx3YXlzIGRlbGV0ZS5cblx0ICAgIGlmIChpUiAhPT0gZCAmJiBhSW5kZXhlc1JbaVJdIDwgYUluZGV4UHJldjEpIHtcblx0ICAgICAgYUZpcnN0ID0gYUluZGV4ZXNSW2lSXTsgLy8gdmVydGljYWwgdG8gaW5zZXJ0IGZyb20gYlxuXHQgICAgfSBlbHNlIHtcblx0ICAgICAgYUZpcnN0ID0gYUluZGV4UHJldjEgLSAxOyAvLyBob3Jpem9udGFsIHRvIGRlbGV0ZSBmcm9tIGFcblxuXHQgICAgICBpZiAoYUZpcnN0IDwgYVN0YXJ0KSB7XG5cdCAgICAgICAgLy8gT3B0aW1pemF0aW9uOiBkZWxldGUgbW92ZWQgcGFzdCBsZWZ0IG9mIGdyYXBoLlxuXHQgICAgICAgIHJldHVybiBpUiAtIDE7XG5cdCAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgLy8gVG8gZ2V0IGxhc3QgcG9pbnQgb2YgcGF0aCBzZWdtZW50LCBtb3ZlIGFsb25nIGRpYWdvbmFsIG9mIGNvbW1vbiBpdGVtcy5cblx0ICAgIGFJbmRleFByZXYxID0gYUluZGV4ZXNSW2lSXTtcblx0ICAgIGFJbmRleGVzUltpUl0gPVxuXHQgICAgICBhRmlyc3QgLVxuXHQgICAgICBjb3VudENvbW1vbkl0ZW1zUihcblx0ICAgICAgICBhU3RhcnQsXG5cdCAgICAgICAgYUZpcnN0IC0gMSxcblx0ICAgICAgICBiU3RhcnQsXG5cdCAgICAgICAgYlIgKyBhRmlyc3QgLSBrUiAtIDEsXG5cdCAgICAgICAgaXNDb21tb25cblx0ICAgICAgKTtcblx0ICB9XG5cdCAgcmV0dXJuIGlNYXhSO1xuXHR9O1xuXG5cdC8vIEEgY29tcGxldGUgZnVuY3Rpb24gdG8gZXh0ZW5kIGZvcndhcmQgcGF0aHMgZnJvbSAoZCAtIDEpIHRvIGQgY2hhbmdlcy5cblx0Ly8gUmV0dXJuIHRydWUgaWYgYSBwYXRoIG92ZXJsYXBzIHJldmVyc2UgcGF0aCBvZiAoZCAtIDEpIGNoYW5nZXMgaW4gaXRzIGRpYWdvbmFsLlxuXHRjb25zdCBleHRlbmRPdmVybGFwcGFibGVQYXRoc0YgPSAoXG5cdCAgZCxcblx0ICBhU3RhcnQsXG5cdCAgYUVuZCxcblx0ICBiU3RhcnQsXG5cdCAgYkVuZCxcblx0ICBpc0NvbW1vbixcblx0ICBhSW5kZXhlc0YsXG5cdCAgaU1heEYsXG5cdCAgYUluZGV4ZXNSLFxuXHQgIGlNYXhSLFxuXHQgIGRpdmlzaW9uIC8vIHVwZGF0ZSBwcm9wIHZhbHVlcyBpZiByZXR1cm4gdHJ1ZVxuXHQpID0+IHtcblx0ICBjb25zdCBiRiA9IGJTdGFydCAtIGFTdGFydDsgLy8gYkluZGV4ID0gYkYgKyBhSW5kZXggLSBrRlxuXHQgIGNvbnN0IGFMZW5ndGggPSBhRW5kIC0gYVN0YXJ0O1xuXHQgIGNvbnN0IGJMZW5ndGggPSBiRW5kIC0gYlN0YXJ0O1xuXHQgIGNvbnN0IGJhRGVsdGFMZW5ndGggPSBiTGVuZ3RoIC0gYUxlbmd0aDsgLy8ga0YgPSBrUiAtIGJhRGVsdGFMZW5ndGhcblxuXHQgIC8vIFJhbmdlIG9mIGRpYWdvbmFscyBpbiB3aGljaCBmb3J3YXJkIGFuZCByZXZlcnNlIHBhdGhzIG1pZ2h0IG92ZXJsYXAuXG5cdCAgY29uc3Qga01pbk92ZXJsYXBGID0gLWJhRGVsdGFMZW5ndGggLSAoZCAtIDEpOyAvLyAtKGQgLSAxKSA8PSBrUlxuXHQgIGNvbnN0IGtNYXhPdmVybGFwRiA9IC1iYURlbHRhTGVuZ3RoICsgKGQgLSAxKTsgLy8ga1IgPD0gKGQgLSAxKVxuXG5cdCAgbGV0IGFJbmRleFByZXYxID0gTk9UX1lFVF9TRVQ7IC8vIHByZXYgdmFsdWUgb2YgW2lGIC0gMV0gaW4gbmV4dCBpdGVyYXRpb25cblxuXHQgIC8vIE9wdGltaXphdGlvbjogc2tpcCBkaWFnb25hbHMgaW4gd2hpY2ggcGF0aHMgY2Fubm90IGV2ZXIgb3ZlcmxhcC5cblx0ICBjb25zdCBuRiA9IGQgPCBpTWF4RiA/IGQgOiBpTWF4RjtcblxuXHQgIC8vIFRoZSBkaWFnb25hbHMga0YgPSAyICogaUYgLSBkIGFyZSBvZGQgd2hlbiBkIGlzIG9kZCBhbmQgZXZlbiB3aGVuIGQgaXMgZXZlbi5cblx0ICBmb3IgKGxldCBpRiA9IDAsIGtGID0gLWQ7IGlGIDw9IG5GOyBpRiArPSAxLCBrRiArPSAyKSB7XG5cdCAgICAvLyBUbyBnZXQgZmlyc3QgcG9pbnQgb2YgcGF0aCBzZWdtZW50LCBtb3ZlIG9uZSBjaGFuZ2UgaW4gZm9yd2FyZCBkaXJlY3Rpb25cblx0ICAgIC8vIGZyb20gbGFzdCBwb2ludCBvZiBwcmV2aW91cyBwYXRoIHNlZ21lbnQgaW4gYW4gYWRqYWNlbnQgZGlhZ29uYWwuXG5cdCAgICAvLyBJbiBmaXJzdCBpdGVyYXRpb24gd2hlbiBpRiA9PT0gMCBhbmQga0YgPT09IC1kIGFsd2F5cyBpbnNlcnQuXG5cdCAgICAvLyBJbiBsYXN0IHBvc3NpYmxlIGl0ZXJhdGlvbiB3aGVuIGlGID09PSBkIGFuZCBrRiA9PT0gZCBhbHdheXMgZGVsZXRlLlxuXHQgICAgY29uc3QgaW5zZXJ0ID0gaUYgPT09IDAgfHwgKGlGICE9PSBkICYmIGFJbmRleFByZXYxIDwgYUluZGV4ZXNGW2lGXSk7XG5cdCAgICBjb25zdCBhTGFzdFByZXYgPSBpbnNlcnQgPyBhSW5kZXhlc0ZbaUZdIDogYUluZGV4UHJldjE7XG5cdCAgICBjb25zdCBhRmlyc3QgPSBpbnNlcnRcblx0ICAgICAgPyBhTGFzdFByZXYgLy8gdmVydGljYWwgdG8gaW5zZXJ0IGZyb20gYlxuXHQgICAgICA6IGFMYXN0UHJldiArIDE7IC8vIGhvcml6b250YWwgdG8gZGVsZXRlIGZyb20gYVxuXG5cdCAgICAvLyBUbyBnZXQgbGFzdCBwb2ludCBvZiBwYXRoIHNlZ21lbnQsIG1vdmUgYWxvbmcgZGlhZ29uYWwgb2YgY29tbW9uIGl0ZW1zLlxuXHQgICAgY29uc3QgYkZpcnN0ID0gYkYgKyBhRmlyc3QgLSBrRjtcblx0ICAgIGNvbnN0IG5Db21tb25GID0gY291bnRDb21tb25JdGVtc0YoXG5cdCAgICAgIGFGaXJzdCArIDEsXG5cdCAgICAgIGFFbmQsXG5cdCAgICAgIGJGaXJzdCArIDEsXG5cdCAgICAgIGJFbmQsXG5cdCAgICAgIGlzQ29tbW9uXG5cdCAgICApO1xuXHQgICAgY29uc3QgYUxhc3QgPSBhRmlyc3QgKyBuQ29tbW9uRjtcblx0ICAgIGFJbmRleFByZXYxID0gYUluZGV4ZXNGW2lGXTtcblx0ICAgIGFJbmRleGVzRltpRl0gPSBhTGFzdDtcblx0ICAgIGlmIChrTWluT3ZlcmxhcEYgPD0ga0YgJiYga0YgPD0ga01heE92ZXJsYXBGKSB7XG5cdCAgICAgIC8vIFNvbHZlIGZvciBpUiBvZiByZXZlcnNlIHBhdGggd2l0aCAoZCAtIDEpIGNoYW5nZXMgaW4gZGlhZ29uYWwga0Y6XG5cdCAgICAgIC8vIGtSID0ga0YgKyBiYURlbHRhTGVuZ3RoXG5cdCAgICAgIC8vIGtSID0gKGQgLSAxKSAtIDIgKiBpUlxuXHQgICAgICBjb25zdCBpUiA9IChkIC0gMSAtIChrRiArIGJhRGVsdGFMZW5ndGgpKSAvIDI7XG5cblx0ICAgICAgLy8gSWYgdGhpcyBmb3J3YXJkIHBhdGggb3ZlcmxhcHMgdGhlIHJldmVyc2UgcGF0aCBpbiB0aGlzIGRpYWdvbmFsLFxuXHQgICAgICAvLyB0aGVuIHRoaXMgaXMgdGhlIG1pZGRsZSBjaGFuZ2Ugb2YgdGhlIGluZGV4IGludGVydmFscy5cblx0ICAgICAgaWYgKGlSIDw9IGlNYXhSICYmIGFJbmRleGVzUltpUl0gLSAxIDw9IGFMYXN0KSB7XG5cdCAgICAgICAgLy8gVW5saWtlIHRoZSBNeWVycyBhbGdvcml0aG0gd2hpY2ggZmluZHMgb25seSB0aGUgbWlkZGxlIOKAnHNuYWtl4oCdXG5cdCAgICAgICAgLy8gdGhpcyBwYWNrYWdlIGNhbiBmaW5kIHR3byBjb21tb24gc3Vic2VxdWVuY2VzIHBlciBkaXZpc2lvbi5cblx0ICAgICAgICAvLyBMYXN0IHBvaW50IG9mIHByZXZpb3VzIHBhdGggc2VnbWVudCBpcyBvbiBhbiBhZGphY2VudCBkaWFnb25hbC5cblx0ICAgICAgICBjb25zdCBiTGFzdFByZXYgPSBiRiArIGFMYXN0UHJldiAtIChpbnNlcnQgPyBrRiArIDEgOiBrRiAtIDEpO1xuXG5cdCAgICAgICAgLy8gQmVjYXVzZSBvZiBpbnZhcmlhbnQgdGhhdCBpbnRlcnZhbHMgcHJlY2VkaW5nIHRoZSBtaWRkbGUgY2hhbmdlXG5cdCAgICAgICAgLy8gY2Fubm90IGhhdmUgY29tbW9uIGl0ZW1zIGF0IHRoZSBlbmQsXG5cdCAgICAgICAgLy8gbW92ZSBpbiByZXZlcnNlIGRpcmVjdGlvbiBhbG9uZyBhIGRpYWdvbmFsIG9mIGNvbW1vbiBpdGVtcy5cblx0ICAgICAgICBjb25zdCBuQ29tbW9uUiA9IGNvdW50Q29tbW9uSXRlbXNSKFxuXHQgICAgICAgICAgYVN0YXJ0LFxuXHQgICAgICAgICAgYUxhc3RQcmV2LFxuXHQgICAgICAgICAgYlN0YXJ0LFxuXHQgICAgICAgICAgYkxhc3RQcmV2LFxuXHQgICAgICAgICAgaXNDb21tb25cblx0ICAgICAgICApO1xuXHQgICAgICAgIGNvbnN0IGFJbmRleFByZXZGaXJzdCA9IGFMYXN0UHJldiAtIG5Db21tb25SO1xuXHQgICAgICAgIGNvbnN0IGJJbmRleFByZXZGaXJzdCA9IGJMYXN0UHJldiAtIG5Db21tb25SO1xuXHQgICAgICAgIGNvbnN0IGFFbmRQcmVjZWRpbmcgPSBhSW5kZXhQcmV2Rmlyc3QgKyAxO1xuXHQgICAgICAgIGNvbnN0IGJFbmRQcmVjZWRpbmcgPSBiSW5kZXhQcmV2Rmlyc3QgKyAxO1xuXHQgICAgICAgIGRpdmlzaW9uLm5DaGFuZ2VQcmVjZWRpbmcgPSBkIC0gMTtcblx0ICAgICAgICBpZiAoZCAtIDEgPT09IGFFbmRQcmVjZWRpbmcgKyBiRW5kUHJlY2VkaW5nIC0gYVN0YXJ0IC0gYlN0YXJ0KSB7XG5cdCAgICAgICAgICAvLyBPcHRpbWl6YXRpb246IG51bWJlciBvZiBwcmVjZWRpbmcgY2hhbmdlcyBpbiBmb3J3YXJkIGRpcmVjdGlvblxuXHQgICAgICAgICAgLy8gaXMgZXF1YWwgdG8gbnVtYmVyIG9mIGl0ZW1zIGluIHByZWNlZGluZyBpbnRlcnZhbCxcblx0ICAgICAgICAgIC8vIHRoZXJlZm9yZSBpdCBjYW5ub3QgY29udGFpbiBhbnkgY29tbW9uIGl0ZW1zLlxuXHQgICAgICAgICAgZGl2aXNpb24uYUVuZFByZWNlZGluZyA9IGFTdGFydDtcblx0ICAgICAgICAgIGRpdmlzaW9uLmJFbmRQcmVjZWRpbmcgPSBiU3RhcnQ7XG5cdCAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgIGRpdmlzaW9uLmFFbmRQcmVjZWRpbmcgPSBhRW5kUHJlY2VkaW5nO1xuXHQgICAgICAgICAgZGl2aXNpb24uYkVuZFByZWNlZGluZyA9IGJFbmRQcmVjZWRpbmc7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpdmlzaW9uLm5Db21tb25QcmVjZWRpbmcgPSBuQ29tbW9uUjtcblx0ICAgICAgICBpZiAobkNvbW1vblIgIT09IDApIHtcblx0ICAgICAgICAgIGRpdmlzaW9uLmFDb21tb25QcmVjZWRpbmcgPSBhRW5kUHJlY2VkaW5nO1xuXHQgICAgICAgICAgZGl2aXNpb24uYkNvbW1vblByZWNlZGluZyA9IGJFbmRQcmVjZWRpbmc7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpdmlzaW9uLm5Db21tb25Gb2xsb3dpbmcgPSBuQ29tbW9uRjtcblx0ICAgICAgICBpZiAobkNvbW1vbkYgIT09IDApIHtcblx0ICAgICAgICAgIGRpdmlzaW9uLmFDb21tb25Gb2xsb3dpbmcgPSBhRmlyc3QgKyAxO1xuXHQgICAgICAgICAgZGl2aXNpb24uYkNvbW1vbkZvbGxvd2luZyA9IGJGaXJzdCArIDE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnN0IGFTdGFydEZvbGxvd2luZyA9IGFMYXN0ICsgMTtcblx0ICAgICAgICBjb25zdCBiU3RhcnRGb2xsb3dpbmcgPSBiRmlyc3QgKyBuQ29tbW9uRiArIDE7XG5cdCAgICAgICAgZGl2aXNpb24ubkNoYW5nZUZvbGxvd2luZyA9IGQgLSAxO1xuXHQgICAgICAgIGlmIChkIC0gMSA9PT0gYUVuZCArIGJFbmQgLSBhU3RhcnRGb2xsb3dpbmcgLSBiU3RhcnRGb2xsb3dpbmcpIHtcblx0ICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogbnVtYmVyIG9mIGNoYW5nZXMgaW4gcmV2ZXJzZSBkaXJlY3Rpb25cblx0ICAgICAgICAgIC8vIGlzIGVxdWFsIHRvIG51bWJlciBvZiBpdGVtcyBpbiBmb2xsb3dpbmcgaW50ZXJ2YWwsXG5cdCAgICAgICAgICAvLyB0aGVyZWZvcmUgaXQgY2Fubm90IGNvbnRhaW4gYW55IGNvbW1vbiBpdGVtcy5cblx0ICAgICAgICAgIGRpdmlzaW9uLmFTdGFydEZvbGxvd2luZyA9IGFFbmQ7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iU3RhcnRGb2xsb3dpbmcgPSBiRW5kO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBkaXZpc2lvbi5hU3RhcnRGb2xsb3dpbmcgPSBhU3RhcnRGb2xsb3dpbmc7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iU3RhcnRGb2xsb3dpbmcgPSBiU3RhcnRGb2xsb3dpbmc7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfVxuXHQgIHJldHVybiBmYWxzZTtcblx0fTtcblxuXHQvLyBBIGNvbXBsZXRlIGZ1bmN0aW9uIHRvIGV4dGVuZCByZXZlcnNlIHBhdGhzIGZyb20gKGQgLSAxKSB0byBkIGNoYW5nZXMuXG5cdC8vIFJldHVybiB0cnVlIGlmIGEgcGF0aCBvdmVybGFwcyBmb3J3YXJkIHBhdGggb2YgZCBjaGFuZ2VzIGluIGl0cyBkaWFnb25hbC5cblx0Y29uc3QgZXh0ZW5kT3ZlcmxhcHBhYmxlUGF0aHNSID0gKFxuXHQgIGQsXG5cdCAgYVN0YXJ0LFxuXHQgIGFFbmQsXG5cdCAgYlN0YXJ0LFxuXHQgIGJFbmQsXG5cdCAgaXNDb21tb24sXG5cdCAgYUluZGV4ZXNGLFxuXHQgIGlNYXhGLFxuXHQgIGFJbmRleGVzUixcblx0ICBpTWF4Uixcblx0ICBkaXZpc2lvbiAvLyB1cGRhdGUgcHJvcCB2YWx1ZXMgaWYgcmV0dXJuIHRydWVcblx0KSA9PiB7XG5cdCAgY29uc3QgYlIgPSBiRW5kIC0gYUVuZDsgLy8gYkluZGV4ID0gYlIgKyBhSW5kZXggLSBrUlxuXHQgIGNvbnN0IGFMZW5ndGggPSBhRW5kIC0gYVN0YXJ0O1xuXHQgIGNvbnN0IGJMZW5ndGggPSBiRW5kIC0gYlN0YXJ0O1xuXHQgIGNvbnN0IGJhRGVsdGFMZW5ndGggPSBiTGVuZ3RoIC0gYUxlbmd0aDsgLy8ga1IgPSBrRiArIGJhRGVsdGFMZW5ndGhcblxuXHQgIC8vIFJhbmdlIG9mIGRpYWdvbmFscyBpbiB3aGljaCBmb3J3YXJkIGFuZCByZXZlcnNlIHBhdGhzIG1pZ2h0IG92ZXJsYXAuXG5cdCAgY29uc3Qga01pbk92ZXJsYXBSID0gYmFEZWx0YUxlbmd0aCAtIGQ7IC8vIC1kIDw9IGtGXG5cdCAgY29uc3Qga01heE92ZXJsYXBSID0gYmFEZWx0YUxlbmd0aCArIGQ7IC8vIGtGIDw9IGRcblxuXHQgIGxldCBhSW5kZXhQcmV2MSA9IE5PVF9ZRVRfU0VUOyAvLyBwcmV2IHZhbHVlIG9mIFtpUiAtIDFdIGluIG5leHQgaXRlcmF0aW9uXG5cblx0ICAvLyBPcHRpbWl6YXRpb246IHNraXAgZGlhZ29uYWxzIGluIHdoaWNoIHBhdGhzIGNhbm5vdCBldmVyIG92ZXJsYXAuXG5cdCAgY29uc3QgblIgPSBkIDwgaU1heFIgPyBkIDogaU1heFI7XG5cblx0ICAvLyBUaGUgZGlhZ29uYWxzIGtSID0gZCAtIDIgKiBpUiBhcmUgb2RkIHdoZW4gZCBpcyBvZGQgYW5kIGV2ZW4gd2hlbiBkIGlzIGV2ZW4uXG5cdCAgZm9yIChsZXQgaVIgPSAwLCBrUiA9IGQ7IGlSIDw9IG5SOyBpUiArPSAxLCBrUiAtPSAyKSB7XG5cdCAgICAvLyBUbyBnZXQgZmlyc3QgcG9pbnQgb2YgcGF0aCBzZWdtZW50LCBtb3ZlIG9uZSBjaGFuZ2UgaW4gcmV2ZXJzZSBkaXJlY3Rpb25cblx0ICAgIC8vIGZyb20gbGFzdCBwb2ludCBvZiBwcmV2aW91cyBwYXRoIHNlZ21lbnQgaW4gYW4gYWRqYWNlbnQgZGlhZ29uYWwuXG5cdCAgICAvLyBJbiBmaXJzdCBpdGVyYXRpb24gd2hlbiBpUiA9PT0gMCBhbmQga1IgPT09IGQgYWx3YXlzIGluc2VydC5cblx0ICAgIC8vIEluIGxhc3QgcG9zc2libGUgaXRlcmF0aW9uIHdoZW4gaVIgPT09IGQgYW5kIGtSID09PSAtZCBhbHdheXMgZGVsZXRlLlxuXHQgICAgY29uc3QgaW5zZXJ0ID0gaVIgPT09IDAgfHwgKGlSICE9PSBkICYmIGFJbmRleGVzUltpUl0gPCBhSW5kZXhQcmV2MSk7XG5cdCAgICBjb25zdCBhTGFzdFByZXYgPSBpbnNlcnQgPyBhSW5kZXhlc1JbaVJdIDogYUluZGV4UHJldjE7XG5cdCAgICBjb25zdCBhRmlyc3QgPSBpbnNlcnRcblx0ICAgICAgPyBhTGFzdFByZXYgLy8gdmVydGljYWwgdG8gaW5zZXJ0IGZyb20gYlxuXHQgICAgICA6IGFMYXN0UHJldiAtIDE7IC8vIGhvcml6b250YWwgdG8gZGVsZXRlIGZyb20gYVxuXG5cdCAgICAvLyBUbyBnZXQgbGFzdCBwb2ludCBvZiBwYXRoIHNlZ21lbnQsIG1vdmUgYWxvbmcgZGlhZ29uYWwgb2YgY29tbW9uIGl0ZW1zLlxuXHQgICAgY29uc3QgYkZpcnN0ID0gYlIgKyBhRmlyc3QgLSBrUjtcblx0ICAgIGNvbnN0IG5Db21tb25SID0gY291bnRDb21tb25JdGVtc1IoXG5cdCAgICAgIGFTdGFydCxcblx0ICAgICAgYUZpcnN0IC0gMSxcblx0ICAgICAgYlN0YXJ0LFxuXHQgICAgICBiRmlyc3QgLSAxLFxuXHQgICAgICBpc0NvbW1vblxuXHQgICAgKTtcblx0ICAgIGNvbnN0IGFMYXN0ID0gYUZpcnN0IC0gbkNvbW1vblI7XG5cdCAgICBhSW5kZXhQcmV2MSA9IGFJbmRleGVzUltpUl07XG5cdCAgICBhSW5kZXhlc1JbaVJdID0gYUxhc3Q7XG5cdCAgICBpZiAoa01pbk92ZXJsYXBSIDw9IGtSICYmIGtSIDw9IGtNYXhPdmVybGFwUikge1xuXHQgICAgICAvLyBTb2x2ZSBmb3IgaUYgb2YgZm9yd2FyZCBwYXRoIHdpdGggZCBjaGFuZ2VzIGluIGRpYWdvbmFsIGtSOlxuXHQgICAgICAvLyBrRiA9IGtSIC0gYmFEZWx0YUxlbmd0aFxuXHQgICAgICAvLyBrRiA9IDIgKiBpRiAtIGRcblx0ICAgICAgY29uc3QgaUYgPSAoZCArIChrUiAtIGJhRGVsdGFMZW5ndGgpKSAvIDI7XG5cblx0ICAgICAgLy8gSWYgdGhpcyByZXZlcnNlIHBhdGggb3ZlcmxhcHMgdGhlIGZvcndhcmQgcGF0aCBpbiB0aGlzIGRpYWdvbmFsLFxuXHQgICAgICAvLyB0aGVuIHRoaXMgaXMgYSBtaWRkbGUgY2hhbmdlIG9mIHRoZSBpbmRleCBpbnRlcnZhbHMuXG5cdCAgICAgIGlmIChpRiA8PSBpTWF4RiAmJiBhTGFzdCAtIDEgPD0gYUluZGV4ZXNGW2lGXSkge1xuXHQgICAgICAgIGNvbnN0IGJMYXN0ID0gYkZpcnN0IC0gbkNvbW1vblI7XG5cdCAgICAgICAgZGl2aXNpb24ubkNoYW5nZVByZWNlZGluZyA9IGQ7XG5cdCAgICAgICAgaWYgKGQgPT09IGFMYXN0ICsgYkxhc3QgLSBhU3RhcnQgLSBiU3RhcnQpIHtcblx0ICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogbnVtYmVyIG9mIGNoYW5nZXMgaW4gcmV2ZXJzZSBkaXJlY3Rpb25cblx0ICAgICAgICAgIC8vIGlzIGVxdWFsIHRvIG51bWJlciBvZiBpdGVtcyBpbiBwcmVjZWRpbmcgaW50ZXJ2YWwsXG5cdCAgICAgICAgICAvLyB0aGVyZWZvcmUgaXQgY2Fubm90IGNvbnRhaW4gYW55IGNvbW1vbiBpdGVtcy5cblx0ICAgICAgICAgIGRpdmlzaW9uLmFFbmRQcmVjZWRpbmcgPSBhU3RhcnQ7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iRW5kUHJlY2VkaW5nID0gYlN0YXJ0O1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICBkaXZpc2lvbi5hRW5kUHJlY2VkaW5nID0gYUxhc3Q7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iRW5kUHJlY2VkaW5nID0gYkxhc3Q7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpdmlzaW9uLm5Db21tb25QcmVjZWRpbmcgPSBuQ29tbW9uUjtcblx0ICAgICAgICBpZiAobkNvbW1vblIgIT09IDApIHtcblx0ICAgICAgICAgIC8vIFRoZSBsYXN0IHBvaW50IG9mIHJldmVyc2UgcGF0aCBzZWdtZW50IGlzIHN0YXJ0IG9mIGNvbW1vbiBzdWJzZXF1ZW5jZS5cblx0ICAgICAgICAgIGRpdmlzaW9uLmFDb21tb25QcmVjZWRpbmcgPSBhTGFzdDtcblx0ICAgICAgICAgIGRpdmlzaW9uLmJDb21tb25QcmVjZWRpbmcgPSBiTGFzdDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZGl2aXNpb24ubkNoYW5nZUZvbGxvd2luZyA9IGQgLSAxO1xuXHQgICAgICAgIGlmIChkID09PSAxKSB7XG5cdCAgICAgICAgICAvLyBUaGVyZSBpcyBubyBwcmV2aW91cyBwYXRoIHNlZ21lbnQuXG5cdCAgICAgICAgICBkaXZpc2lvbi5uQ29tbW9uRm9sbG93aW5nID0gMDtcblx0ICAgICAgICAgIGRpdmlzaW9uLmFTdGFydEZvbGxvd2luZyA9IGFFbmQ7XG5cdCAgICAgICAgICBkaXZpc2lvbi5iU3RhcnRGb2xsb3dpbmcgPSBiRW5kO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAvLyBVbmxpa2UgdGhlIE15ZXJzIGFsZ29yaXRobSB3aGljaCBmaW5kcyBvbmx5IHRoZSBtaWRkbGUg4oCcc25ha2XigJ1cblx0ICAgICAgICAgIC8vIHRoaXMgcGFja2FnZSBjYW4gZmluZCB0d28gY29tbW9uIHN1YnNlcXVlbmNlcyBwZXIgZGl2aXNpb24uXG5cdCAgICAgICAgICAvLyBMYXN0IHBvaW50IG9mIHByZXZpb3VzIHBhdGggc2VnbWVudCBpcyBvbiBhbiBhZGphY2VudCBkaWFnb25hbC5cblx0ICAgICAgICAgIGNvbnN0IGJMYXN0UHJldiA9IGJSICsgYUxhc3RQcmV2IC0gKGluc2VydCA/IGtSIC0gMSA6IGtSICsgMSk7XG5cblx0ICAgICAgICAgIC8vIEJlY2F1c2Ugb2YgaW52YXJpYW50IHRoYXQgaW50ZXJ2YWxzIGZvbGxvd2luZyB0aGUgbWlkZGxlIGNoYW5nZVxuXHQgICAgICAgICAgLy8gY2Fubm90IGhhdmUgY29tbW9uIGl0ZW1zIGF0IHRoZSBzdGFydCxcblx0ICAgICAgICAgIC8vIG1vdmUgaW4gZm9yd2FyZCBkaXJlY3Rpb24gYWxvbmcgYSBkaWFnb25hbCBvZiBjb21tb24gaXRlbXMuXG5cdCAgICAgICAgICBjb25zdCBuQ29tbW9uRiA9IGNvdW50Q29tbW9uSXRlbXNGKFxuXHQgICAgICAgICAgICBhTGFzdFByZXYsXG5cdCAgICAgICAgICAgIGFFbmQsXG5cdCAgICAgICAgICAgIGJMYXN0UHJldixcblx0ICAgICAgICAgICAgYkVuZCxcblx0ICAgICAgICAgICAgaXNDb21tb25cblx0ICAgICAgICAgICk7XG5cdCAgICAgICAgICBkaXZpc2lvbi5uQ29tbW9uRm9sbG93aW5nID0gbkNvbW1vbkY7XG5cdCAgICAgICAgICBpZiAobkNvbW1vbkYgIT09IDApIHtcblx0ICAgICAgICAgICAgLy8gVGhlIGxhc3QgcG9pbnQgb2YgcmV2ZXJzZSBwYXRoIHNlZ21lbnQgaXMgc3RhcnQgb2YgY29tbW9uIHN1YnNlcXVlbmNlLlxuXHQgICAgICAgICAgICBkaXZpc2lvbi5hQ29tbW9uRm9sbG93aW5nID0gYUxhc3RQcmV2O1xuXHQgICAgICAgICAgICBkaXZpc2lvbi5iQ29tbW9uRm9sbG93aW5nID0gYkxhc3RQcmV2O1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgICAgY29uc3QgYVN0YXJ0Rm9sbG93aW5nID0gYUxhc3RQcmV2ICsgbkNvbW1vbkY7IC8vIGFGaXJzdFByZXZcblx0ICAgICAgICAgIGNvbnN0IGJTdGFydEZvbGxvd2luZyA9IGJMYXN0UHJldiArIG5Db21tb25GOyAvLyBiRmlyc3RQcmV2XG5cblx0ICAgICAgICAgIGlmIChkIC0gMSA9PT0gYUVuZCArIGJFbmQgLSBhU3RhcnRGb2xsb3dpbmcgLSBiU3RhcnRGb2xsb3dpbmcpIHtcblx0ICAgICAgICAgICAgLy8gT3B0aW1pemF0aW9uOiBudW1iZXIgb2YgY2hhbmdlcyBpbiBmb3J3YXJkIGRpcmVjdGlvblxuXHQgICAgICAgICAgICAvLyBpcyBlcXVhbCB0byBudW1iZXIgb2YgaXRlbXMgaW4gZm9sbG93aW5nIGludGVydmFsLFxuXHQgICAgICAgICAgICAvLyB0aGVyZWZvcmUgaXQgY2Fubm90IGNvbnRhaW4gYW55IGNvbW1vbiBpdGVtcy5cblx0ICAgICAgICAgICAgZGl2aXNpb24uYVN0YXJ0Rm9sbG93aW5nID0gYUVuZDtcblx0ICAgICAgICAgICAgZGl2aXNpb24uYlN0YXJ0Rm9sbG93aW5nID0gYkVuZDtcblx0ICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIGRpdmlzaW9uLmFTdGFydEZvbGxvd2luZyA9IGFTdGFydEZvbGxvd2luZztcblx0ICAgICAgICAgICAgZGl2aXNpb24uYlN0YXJ0Rm9sbG93aW5nID0gYlN0YXJ0Rm9sbG93aW5nO1xuXHQgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdHJ1ZTtcblx0ICAgICAgfVxuXHQgICAgfVxuXHQgIH1cblx0ICByZXR1cm4gZmFsc2U7XG5cdH07XG5cblx0Ly8gR2l2ZW4gaW5kZXggaW50ZXJ2YWxzIGFuZCBpbnB1dCBmdW5jdGlvbiB0byBjb21wYXJlIGl0ZW1zIGF0IGluZGV4ZXMsXG5cdC8vIGRpdmlkZSBhdCB0aGUgbWlkZGxlIGNoYW5nZS5cblx0Ly9cblx0Ly8gRE8gTk9UIENBTEwgaWYgc3RhcnQgPT09IGVuZCwgYmVjYXVzZSBpbnRlcnZhbCBjYW5ub3QgY29udGFpbiBjb21tb24gaXRlbXNcblx0Ly8gYW5kIGJlY2F1c2UgdGhpcyBmdW5jdGlvbiB3aWxsIHRocm93IHRoZSDigJxubyBvdmVybGFw4oCdIGVycm9yLlxuXHRjb25zdCBkaXZpZGUgPSAoXG5cdCAgbkNoYW5nZSxcblx0ICBhU3RhcnQsXG5cdCAgYUVuZCxcblx0ICBiU3RhcnQsXG5cdCAgYkVuZCxcblx0ICBpc0NvbW1vbixcblx0ICBhSW5kZXhlc0YsXG5cdCAgYUluZGV4ZXNSLFxuXHQgIGRpdmlzaW9uIC8vIG91dHB1dFxuXHQpID0+IHtcblx0ICBjb25zdCBiRiA9IGJTdGFydCAtIGFTdGFydDsgLy8gYkluZGV4ID0gYkYgKyBhSW5kZXggLSBrRlxuXHQgIGNvbnN0IGJSID0gYkVuZCAtIGFFbmQ7IC8vIGJJbmRleCA9IGJSICsgYUluZGV4IC0ga1Jcblx0ICBjb25zdCBhTGVuZ3RoID0gYUVuZCAtIGFTdGFydDtcblx0ICBjb25zdCBiTGVuZ3RoID0gYkVuZCAtIGJTdGFydDtcblxuXHQgIC8vIEJlY2F1c2UgZ3JhcGggaGFzIHNxdWFyZSBvciBwb3J0cmFpdCBvcmllbnRhdGlvbixcblx0ICAvLyBsZW5ndGggZGlmZmVyZW5jZSBpcyBtaW5pbXVtIG51bWJlciBvZiBpdGVtcyB0byBpbnNlcnQgZnJvbSBiLlxuXHQgIC8vIENvcnJlc3BvbmRpbmcgZm9yd2FyZCBhbmQgcmV2ZXJzZSBkaWFnb25hbHMgaW4gZ3JhcGhcblx0ICAvLyBkZXBlbmQgb24gbGVuZ3RoIGRpZmZlcmVuY2Ugb2YgdGhlIHNlcXVlbmNlczpcblx0ICAvLyBrRiA9IGtSIC0gYmFEZWx0YUxlbmd0aFxuXHQgIC8vIGtSID0ga0YgKyBiYURlbHRhTGVuZ3RoXG5cdCAgY29uc3QgYmFEZWx0YUxlbmd0aCA9IGJMZW5ndGggLSBhTGVuZ3RoO1xuXG5cdCAgLy8gT3B0aW1pemF0aW9uOiBtYXggZGlhZ29uYWwgaW4gZ3JhcGggaW50ZXJzZWN0cyBjb3JuZXIgb2Ygc2hvcnRlciBzaWRlLlxuXHQgIGxldCBpTWF4RiA9IGFMZW5ndGg7XG5cdCAgbGV0IGlNYXhSID0gYUxlbmd0aDtcblxuXHQgIC8vIEluaXRpYWxpemUgbm8gY2hhbmdlcyB5ZXQgaW4gZm9yd2FyZCBvciByZXZlcnNlIGRpcmVjdGlvbjpcblx0ICBhSW5kZXhlc0ZbMF0gPSBhU3RhcnQgLSAxOyAvLyBhdCBvcGVuIHN0YXJ0IG9mIGludGVydmFsLCBvdXRzaWRlIGNsb3NlZCBzdGFydFxuXHQgIGFJbmRleGVzUlswXSA9IGFFbmQ7IC8vIGF0IG9wZW4gZW5kIG9mIGludGVydmFsXG5cblx0ICBpZiAoYmFEZWx0YUxlbmd0aCAlIDIgPT09IDApIHtcblx0ICAgIC8vIFRoZSBudW1iZXIgb2YgY2hhbmdlcyBpbiBwYXRocyBpcyAyICogZCBpZiBsZW5ndGggZGlmZmVyZW5jZSBpcyBldmVuLlxuXHQgICAgY29uc3QgZE1pbiA9IChuQ2hhbmdlIHx8IGJhRGVsdGFMZW5ndGgpIC8gMjtcblx0ICAgIGNvbnN0IGRNYXggPSAoYUxlbmd0aCArIGJMZW5ndGgpIC8gMjtcblx0ICAgIGZvciAobGV0IGQgPSAxOyBkIDw9IGRNYXg7IGQgKz0gMSkge1xuXHQgICAgICBpTWF4RiA9IGV4dGVuZFBhdGhzRihkLCBhRW5kLCBiRW5kLCBiRiwgaXNDb21tb24sIGFJbmRleGVzRiwgaU1heEYpO1xuXHQgICAgICBpZiAoZCA8IGRNaW4pIHtcblx0ICAgICAgICBpTWF4UiA9IGV4dGVuZFBhdGhzUihkLCBhU3RhcnQsIGJTdGFydCwgYlIsIGlzQ29tbW9uLCBhSW5kZXhlc1IsIGlNYXhSKTtcblx0ICAgICAgfSBlbHNlIGlmIChcblx0ICAgICAgICAvLyBJZiBhIHJldmVyc2UgcGF0aCBvdmVybGFwcyBhIGZvcndhcmQgcGF0aCBpbiB0aGUgc2FtZSBkaWFnb25hbCxcblx0ICAgICAgICAvLyByZXR1cm4gYSBkaXZpc2lvbiBvZiB0aGUgaW5kZXggaW50ZXJ2YWxzIGF0IHRoZSBtaWRkbGUgY2hhbmdlLlxuXHQgICAgICAgIGV4dGVuZE92ZXJsYXBwYWJsZVBhdGhzUihcblx0ICAgICAgICAgIGQsXG5cdCAgICAgICAgICBhU3RhcnQsXG5cdCAgICAgICAgICBhRW5kLFxuXHQgICAgICAgICAgYlN0YXJ0LFxuXHQgICAgICAgICAgYkVuZCxcblx0ICAgICAgICAgIGlzQ29tbW9uLFxuXHQgICAgICAgICAgYUluZGV4ZXNGLFxuXHQgICAgICAgICAgaU1heEYsXG5cdCAgICAgICAgICBhSW5kZXhlc1IsXG5cdCAgICAgICAgICBpTWF4Uixcblx0ICAgICAgICAgIGRpdmlzaW9uXG5cdCAgICAgICAgKVxuXHQgICAgICApIHtcblx0ICAgICAgICByZXR1cm47XG5cdCAgICAgIH1cblx0ICAgIH1cblx0ICB9IGVsc2Uge1xuXHQgICAgLy8gVGhlIG51bWJlciBvZiBjaGFuZ2VzIGluIHBhdGhzIGlzIDIgKiBkIC0gMSBpZiBsZW5ndGggZGlmZmVyZW5jZSBpcyBvZGQuXG5cdCAgICBjb25zdCBkTWluID0gKChuQ2hhbmdlIHx8IGJhRGVsdGFMZW5ndGgpICsgMSkgLyAyO1xuXHQgICAgY29uc3QgZE1heCA9IChhTGVuZ3RoICsgYkxlbmd0aCArIDEpIC8gMjtcblxuXHQgICAgLy8gVW5yb2xsIGZpcnN0IGhhbGYgaXRlcmF0aW9uIHNvIGxvb3AgZXh0ZW5kcyB0aGUgcmVsZXZhbnQgcGFpcnMgb2YgcGF0aHMuXG5cdCAgICAvLyBCZWNhdXNlIG9mIGludmFyaWFudCB0aGF0IGludGVydmFscyBoYXZlIG5vIGNvbW1vbiBpdGVtcyBhdCBzdGFydCBvciBlbmQsXG5cdCAgICAvLyBhbmQgbGltaXRhdGlvbiBub3QgdG8gY2FsbCBkaXZpZGUgd2l0aCBlbXB0eSBpbnRlcnZhbHMsXG5cdCAgICAvLyB0aGVyZWZvcmUgaXQgY2Fubm90IGJlIGNhbGxlZCBpZiBhIGZvcndhcmQgcGF0aCB3aXRoIG9uZSBjaGFuZ2Vcblx0ICAgIC8vIHdvdWxkIG92ZXJsYXAgYSByZXZlcnNlIHBhdGggd2l0aCBubyBjaGFuZ2VzLCBldmVuIGlmIGRNaW4gPT09IDEuXG5cdCAgICBsZXQgZCA9IDE7XG5cdCAgICBpTWF4RiA9IGV4dGVuZFBhdGhzRihkLCBhRW5kLCBiRW5kLCBiRiwgaXNDb21tb24sIGFJbmRleGVzRiwgaU1heEYpO1xuXHQgICAgZm9yIChkICs9IDE7IGQgPD0gZE1heDsgZCArPSAxKSB7XG5cdCAgICAgIGlNYXhSID0gZXh0ZW5kUGF0aHNSKFxuXHQgICAgICAgIGQgLSAxLFxuXHQgICAgICAgIGFTdGFydCxcblx0ICAgICAgICBiU3RhcnQsXG5cdCAgICAgICAgYlIsXG5cdCAgICAgICAgaXNDb21tb24sXG5cdCAgICAgICAgYUluZGV4ZXNSLFxuXHQgICAgICAgIGlNYXhSXG5cdCAgICAgICk7XG5cdCAgICAgIGlmIChkIDwgZE1pbikge1xuXHQgICAgICAgIGlNYXhGID0gZXh0ZW5kUGF0aHNGKGQsIGFFbmQsIGJFbmQsIGJGLCBpc0NvbW1vbiwgYUluZGV4ZXNGLCBpTWF4Rik7XG5cdCAgICAgIH0gZWxzZSBpZiAoXG5cdCAgICAgICAgLy8gSWYgYSBmb3J3YXJkIHBhdGggb3ZlcmxhcHMgYSByZXZlcnNlIHBhdGggaW4gdGhlIHNhbWUgZGlhZ29uYWwsXG5cdCAgICAgICAgLy8gcmV0dXJuIGEgZGl2aXNpb24gb2YgdGhlIGluZGV4IGludGVydmFscyBhdCB0aGUgbWlkZGxlIGNoYW5nZS5cblx0ICAgICAgICBleHRlbmRPdmVybGFwcGFibGVQYXRoc0YoXG5cdCAgICAgICAgICBkLFxuXHQgICAgICAgICAgYVN0YXJ0LFxuXHQgICAgICAgICAgYUVuZCxcblx0ICAgICAgICAgIGJTdGFydCxcblx0ICAgICAgICAgIGJFbmQsXG5cdCAgICAgICAgICBpc0NvbW1vbixcblx0ICAgICAgICAgIGFJbmRleGVzRixcblx0ICAgICAgICAgIGlNYXhGLFxuXHQgICAgICAgICAgYUluZGV4ZXNSLFxuXHQgICAgICAgICAgaU1heFIsXG5cdCAgICAgICAgICBkaXZpc2lvblxuXHQgICAgICAgIClcblx0ICAgICAgKSB7XG5cdCAgICAgICAgcmV0dXJuO1xuXHQgICAgICB9XG5cdCAgICB9XG5cdCAgfVxuXG5cdCAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0ICB0aHJvdyBuZXcgRXJyb3IoXG5cdCAgICBgJHtwa2d9OiBubyBvdmVybGFwIGFTdGFydD0ke2FTdGFydH0gYUVuZD0ke2FFbmR9IGJTdGFydD0ke2JTdGFydH0gYkVuZD0ke2JFbmR9YFxuXHQgICk7XG5cdH07XG5cblx0Ly8gR2l2ZW4gaW5kZXggaW50ZXJ2YWxzIGFuZCBpbnB1dCBmdW5jdGlvbiB0byBjb21wYXJlIGl0ZW1zIGF0IGluZGV4ZXMsXG5cdC8vIHJldHVybiBieSBvdXRwdXQgZnVuY3Rpb24gdGhlIG51bWJlciBvZiBhZGphY2VudCBpdGVtcyBhbmQgc3RhcnRpbmcgaW5kZXhlc1xuXHQvLyBvZiBlYWNoIGNvbW1vbiBzdWJzZXF1ZW5jZS4gRGl2aWRlIGFuZCBjb25xdWVyIHdpdGggb25seSBsaW5lYXIgc3BhY2UuXG5cdC8vXG5cdC8vIFRoZSBpbmRleCBpbnRlcnZhbHMgYXJlIGhhbGYgb3BlbiBbc3RhcnQsIGVuZCkgbGlrZSBhcnJheSBzbGljZSBtZXRob2QuXG5cdC8vIERPIE5PVCBDQUxMIGlmIHN0YXJ0ID09PSBlbmQsIGJlY2F1c2UgaW50ZXJ2YWwgY2Fubm90IGNvbnRhaW4gY29tbW9uIGl0ZW1zXG5cdC8vIGFuZCBiZWNhdXNlIGRpdmlkZSBmdW5jdGlvbiB3aWxsIHRocm93IHRoZSDigJxubyBvdmVybGFw4oCdIGVycm9yLlxuXHRjb25zdCBmaW5kU3Vic2VxdWVuY2VzID0gKFxuXHQgIG5DaGFuZ2UsXG5cdCAgYVN0YXJ0LFxuXHQgIGFFbmQsXG5cdCAgYlN0YXJ0LFxuXHQgIGJFbmQsXG5cdCAgdHJhbnNwb3NlZCxcblx0ICBjYWxsYmFja3MsXG5cdCAgYUluZGV4ZXNGLFxuXHQgIGFJbmRleGVzUixcblx0ICBkaXZpc2lvbiAvLyB0ZW1wb3JhcnkgbWVtb3J5LCBub3QgaW5wdXQgbm9yIG91dHB1dFxuXHQpID0+IHtcblx0ICBpZiAoYkVuZCAtIGJTdGFydCA8IGFFbmQgLSBhU3RhcnQpIHtcblx0ICAgIC8vIFRyYW5zcG9zZSBncmFwaCBzbyBpdCBoYXMgcG9ydHJhaXQgaW5zdGVhZCBvZiBsYW5kc2NhcGUgb3JpZW50YXRpb24uXG5cdCAgICAvLyBBbHdheXMgY29tcGFyZSBzaG9ydGVyIHRvIGxvbmdlciBzZXF1ZW5jZSBmb3IgY29uc2lzdGVuY3kgYW5kIG9wdGltaXphdGlvbi5cblx0ICAgIHRyYW5zcG9zZWQgPSAhdHJhbnNwb3NlZDtcblx0ICAgIGlmICh0cmFuc3Bvc2VkICYmIGNhbGxiYWNrcy5sZW5ndGggPT09IDEpIHtcblx0ICAgICAgLy8gTGF6aWx5IHdyYXAgY2FsbGJhY2sgZnVuY3Rpb25zIHRvIHN3YXAgYXJncyBpZiBncmFwaCBpcyB0cmFuc3Bvc2VkLlxuXHQgICAgICBjb25zdCB7Zm91bmRTdWJzZXF1ZW5jZSwgaXNDb21tb259ID0gY2FsbGJhY2tzWzBdO1xuXHQgICAgICBjYWxsYmFja3NbMV0gPSB7XG5cdCAgICAgICAgZm91bmRTdWJzZXF1ZW5jZTogKG5Db21tb24sIGJDb21tb24sIGFDb21tb24pID0+IHtcblx0ICAgICAgICAgIGZvdW5kU3Vic2VxdWVuY2UobkNvbW1vbiwgYUNvbW1vbiwgYkNvbW1vbik7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBpc0NvbW1vbjogKGJJbmRleCwgYUluZGV4KSA9PiBpc0NvbW1vbihhSW5kZXgsIGJJbmRleClcblx0ICAgICAgfTtcblx0ICAgIH1cblx0ICAgIGNvbnN0IHRTdGFydCA9IGFTdGFydDtcblx0ICAgIGNvbnN0IHRFbmQgPSBhRW5kO1xuXHQgICAgYVN0YXJ0ID0gYlN0YXJ0O1xuXHQgICAgYUVuZCA9IGJFbmQ7XG5cdCAgICBiU3RhcnQgPSB0U3RhcnQ7XG5cdCAgICBiRW5kID0gdEVuZDtcblx0ICB9XG5cdCAgY29uc3Qge2ZvdW5kU3Vic2VxdWVuY2UsIGlzQ29tbW9ufSA9IGNhbGxiYWNrc1t0cmFuc3Bvc2VkID8gMSA6IDBdO1xuXG5cdCAgLy8gRGl2aWRlIHRoZSBpbmRleCBpbnRlcnZhbHMgYXQgdGhlIG1pZGRsZSBjaGFuZ2UuXG5cdCAgZGl2aWRlKFxuXHQgICAgbkNoYW5nZSxcblx0ICAgIGFTdGFydCxcblx0ICAgIGFFbmQsXG5cdCAgICBiU3RhcnQsXG5cdCAgICBiRW5kLFxuXHQgICAgaXNDb21tb24sXG5cdCAgICBhSW5kZXhlc0YsXG5cdCAgICBhSW5kZXhlc1IsXG5cdCAgICBkaXZpc2lvblxuXHQgICk7XG5cdCAgY29uc3Qge1xuXHQgICAgbkNoYW5nZVByZWNlZGluZyxcblx0ICAgIGFFbmRQcmVjZWRpbmcsXG5cdCAgICBiRW5kUHJlY2VkaW5nLFxuXHQgICAgbkNvbW1vblByZWNlZGluZyxcblx0ICAgIGFDb21tb25QcmVjZWRpbmcsXG5cdCAgICBiQ29tbW9uUHJlY2VkaW5nLFxuXHQgICAgbkNvbW1vbkZvbGxvd2luZyxcblx0ICAgIGFDb21tb25Gb2xsb3dpbmcsXG5cdCAgICBiQ29tbW9uRm9sbG93aW5nLFxuXHQgICAgbkNoYW5nZUZvbGxvd2luZyxcblx0ICAgIGFTdGFydEZvbGxvd2luZyxcblx0ICAgIGJTdGFydEZvbGxvd2luZ1xuXHQgIH0gPSBkaXZpc2lvbjtcblxuXHQgIC8vIFVubGVzcyBlaXRoZXIgaW5kZXggaW50ZXJ2YWwgaXMgZW1wdHksIHRoZXkgbWlnaHQgY29udGFpbiBjb21tb24gaXRlbXMuXG5cdCAgaWYgKGFTdGFydCA8IGFFbmRQcmVjZWRpbmcgJiYgYlN0YXJ0IDwgYkVuZFByZWNlZGluZykge1xuXHQgICAgLy8gUmVjdXJzZWx5IGZpbmQgYW5kIHJldHVybiBjb21tb24gc3Vic2VxdWVuY2VzIHByZWNlZGluZyB0aGUgZGl2aXNpb24uXG5cdCAgICBmaW5kU3Vic2VxdWVuY2VzKFxuXHQgICAgICBuQ2hhbmdlUHJlY2VkaW5nLFxuXHQgICAgICBhU3RhcnQsXG5cdCAgICAgIGFFbmRQcmVjZWRpbmcsXG5cdCAgICAgIGJTdGFydCxcblx0ICAgICAgYkVuZFByZWNlZGluZyxcblx0ICAgICAgdHJhbnNwb3NlZCxcblx0ICAgICAgY2FsbGJhY2tzLFxuXHQgICAgICBhSW5kZXhlc0YsXG5cdCAgICAgIGFJbmRleGVzUixcblx0ICAgICAgZGl2aXNpb25cblx0ICAgICk7XG5cdCAgfVxuXG5cdCAgLy8gUmV0dXJuIGNvbW1vbiBzdWJzZXF1ZW5jZXMgdGhhdCBhcmUgYWRqYWNlbnQgdG8gdGhlIG1pZGRsZSBjaGFuZ2UuXG5cdCAgaWYgKG5Db21tb25QcmVjZWRpbmcgIT09IDApIHtcblx0ICAgIGZvdW5kU3Vic2VxdWVuY2UobkNvbW1vblByZWNlZGluZywgYUNvbW1vblByZWNlZGluZywgYkNvbW1vblByZWNlZGluZyk7XG5cdCAgfVxuXHQgIGlmIChuQ29tbW9uRm9sbG93aW5nICE9PSAwKSB7XG5cdCAgICBmb3VuZFN1YnNlcXVlbmNlKG5Db21tb25Gb2xsb3dpbmcsIGFDb21tb25Gb2xsb3dpbmcsIGJDb21tb25Gb2xsb3dpbmcpO1xuXHQgIH1cblxuXHQgIC8vIFVubGVzcyBlaXRoZXIgaW5kZXggaW50ZXJ2YWwgaXMgZW1wdHksIHRoZXkgbWlnaHQgY29udGFpbiBjb21tb24gaXRlbXMuXG5cdCAgaWYgKGFTdGFydEZvbGxvd2luZyA8IGFFbmQgJiYgYlN0YXJ0Rm9sbG93aW5nIDwgYkVuZCkge1xuXHQgICAgLy8gUmVjdXJzZWx5IGZpbmQgYW5kIHJldHVybiBjb21tb24gc3Vic2VxdWVuY2VzIGZvbGxvd2luZyB0aGUgZGl2aXNpb24uXG5cdCAgICBmaW5kU3Vic2VxdWVuY2VzKFxuXHQgICAgICBuQ2hhbmdlRm9sbG93aW5nLFxuXHQgICAgICBhU3RhcnRGb2xsb3dpbmcsXG5cdCAgICAgIGFFbmQsXG5cdCAgICAgIGJTdGFydEZvbGxvd2luZyxcblx0ICAgICAgYkVuZCxcblx0ICAgICAgdHJhbnNwb3NlZCxcblx0ICAgICAgY2FsbGJhY2tzLFxuXHQgICAgICBhSW5kZXhlc0YsXG5cdCAgICAgIGFJbmRleGVzUixcblx0ICAgICAgZGl2aXNpb25cblx0ICAgICk7XG5cdCAgfVxuXHR9O1xuXHRjb25zdCB2YWxpZGF0ZUxlbmd0aCA9IChuYW1lLCBhcmcpID0+IHtcblx0ICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicpIHtcblx0ICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7cGtnfTogJHtuYW1lfSB0eXBlb2YgJHt0eXBlb2YgYXJnfSBpcyBub3QgYSBudW1iZXJgKTtcblx0ICB9XG5cdCAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihhcmcpKSB7XG5cdCAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJHtwa2d9OiAke25hbWV9IHZhbHVlICR7YXJnfSBpcyBub3QgYSBzYWZlIGludGVnZXJgKTtcblx0ICB9XG5cdCAgaWYgKGFyZyA8IDApIHtcblx0ICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAke3BrZ306ICR7bmFtZX0gdmFsdWUgJHthcmd9IGlzIGEgbmVnYXRpdmUgaW50ZWdlcmApO1xuXHQgIH1cblx0fTtcblx0Y29uc3QgdmFsaWRhdGVDYWxsYmFjayA9IChuYW1lLCBhcmcpID0+IHtcblx0ICBjb25zdCB0eXBlID0gdHlwZW9mIGFyZztcblx0ICBpZiAodHlwZSAhPT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtwa2d9OiAke25hbWV9IHR5cGVvZiAke3R5cGV9IGlzIG5vdCBhIGZ1bmN0aW9uYCk7XG5cdCAgfVxuXHR9O1xuXG5cdC8vIENvbXBhcmUgaXRlbXMgaW4gdHdvIHNlcXVlbmNlcyB0byBmaW5kIGEgbG9uZ2VzdCBjb21tb24gc3Vic2VxdWVuY2UuXG5cdC8vIEdpdmVuIGxlbmd0aHMgb2Ygc2VxdWVuY2VzIGFuZCBpbnB1dCBmdW5jdGlvbiB0byBjb21wYXJlIGl0ZW1zIGF0IGluZGV4ZXMsXG5cdC8vIHJldHVybiBieSBvdXRwdXQgZnVuY3Rpb24gdGhlIG51bWJlciBvZiBhZGphY2VudCBpdGVtcyBhbmQgc3RhcnRpbmcgaW5kZXhlc1xuXHQvLyBvZiBlYWNoIGNvbW1vbiBzdWJzZXF1ZW5jZS5cblx0ZnVuY3Rpb24gZGlmZlNlcXVlbmNlKGFMZW5ndGgsIGJMZW5ndGgsIGlzQ29tbW9uLCBmb3VuZFN1YnNlcXVlbmNlKSB7XG5cdCAgdmFsaWRhdGVMZW5ndGgoJ2FMZW5ndGgnLCBhTGVuZ3RoKTtcblx0ICB2YWxpZGF0ZUxlbmd0aCgnYkxlbmd0aCcsIGJMZW5ndGgpO1xuXHQgIHZhbGlkYXRlQ2FsbGJhY2soJ2lzQ29tbW9uJywgaXNDb21tb24pO1xuXHQgIHZhbGlkYXRlQ2FsbGJhY2soJ2ZvdW5kU3Vic2VxdWVuY2UnLCBmb3VuZFN1YnNlcXVlbmNlKTtcblxuXHQgIC8vIENvdW50IGNvbW1vbiBpdGVtcyBmcm9tIHRoZSBzdGFydCBpbiB0aGUgZm9yd2FyZCBkaXJlY3Rpb24uXG5cdCAgY29uc3QgbkNvbW1vbkYgPSBjb3VudENvbW1vbkl0ZW1zRigwLCBhTGVuZ3RoLCAwLCBiTGVuZ3RoLCBpc0NvbW1vbik7XG5cdCAgaWYgKG5Db21tb25GICE9PSAwKSB7XG5cdCAgICBmb3VuZFN1YnNlcXVlbmNlKG5Db21tb25GLCAwLCAwKTtcblx0ICB9XG5cblx0ICAvLyBVbmxlc3MgYm90aCBzZXF1ZW5jZXMgY29uc2lzdCBvZiBjb21tb24gaXRlbXMgb25seSxcblx0ICAvLyBmaW5kIGNvbW1vbiBpdGVtcyBpbiB0aGUgaGFsZi10cmltbWVkIGluZGV4IGludGVydmFscy5cblx0ICBpZiAoYUxlbmd0aCAhPT0gbkNvbW1vbkYgfHwgYkxlbmd0aCAhPT0gbkNvbW1vbkYpIHtcblx0ICAgIC8vIEludmFyaWFudDogaW50ZXJ2YWxzIGRvIG5vdCBoYXZlIGNvbW1vbiBpdGVtcyBhdCB0aGUgc3RhcnQuXG5cdCAgICAvLyBUaGUgc3RhcnQgb2YgYW4gaW5kZXggaW50ZXJ2YWwgaXMgY2xvc2VkIGxpa2UgYXJyYXkgc2xpY2UgbWV0aG9kLlxuXHQgICAgY29uc3QgYVN0YXJ0ID0gbkNvbW1vbkY7XG5cdCAgICBjb25zdCBiU3RhcnQgPSBuQ29tbW9uRjtcblxuXHQgICAgLy8gQ291bnQgY29tbW9uIGl0ZW1zIGZyb20gdGhlIGVuZCBpbiB0aGUgcmV2ZXJzZSBkaXJlY3Rpb24uXG5cdCAgICBjb25zdCBuQ29tbW9uUiA9IGNvdW50Q29tbW9uSXRlbXNSKFxuXHQgICAgICBhU3RhcnQsXG5cdCAgICAgIGFMZW5ndGggLSAxLFxuXHQgICAgICBiU3RhcnQsXG5cdCAgICAgIGJMZW5ndGggLSAxLFxuXHQgICAgICBpc0NvbW1vblxuXHQgICAgKTtcblxuXHQgICAgLy8gSW52YXJpYW50OiBpbnRlcnZhbHMgZG8gbm90IGhhdmUgY29tbW9uIGl0ZW1zIGF0IHRoZSBlbmQuXG5cdCAgICAvLyBUaGUgZW5kIG9mIGFuIGluZGV4IGludGVydmFsIGlzIG9wZW4gbGlrZSBhcnJheSBzbGljZSBtZXRob2QuXG5cdCAgICBjb25zdCBhRW5kID0gYUxlbmd0aCAtIG5Db21tb25SO1xuXHQgICAgY29uc3QgYkVuZCA9IGJMZW5ndGggLSBuQ29tbW9uUjtcblxuXHQgICAgLy8gVW5sZXNzIG9uZSBzZXF1ZW5jZSBjb25zaXN0cyBvZiBjb21tb24gaXRlbXMgb25seSxcblx0ICAgIC8vIHRoZXJlZm9yZSB0aGUgb3RoZXIgdHJpbW1lZCBpbmRleCBpbnRlcnZhbCBjb25zaXN0cyBvZiBjaGFuZ2VzIG9ubHksXG5cdCAgICAvLyBmaW5kIGNvbW1vbiBpdGVtcyBpbiB0aGUgdHJpbW1lZCBpbmRleCBpbnRlcnZhbHMuXG5cdCAgICBjb25zdCBuQ29tbW9uRlIgPSBuQ29tbW9uRiArIG5Db21tb25SO1xuXHQgICAgaWYgKGFMZW5ndGggIT09IG5Db21tb25GUiAmJiBiTGVuZ3RoICE9PSBuQ29tbW9uRlIpIHtcblx0ICAgICAgY29uc3QgbkNoYW5nZSA9IDA7IC8vIG51bWJlciBvZiBjaGFuZ2UgaXRlbXMgaXMgbm90IHlldCBrbm93blxuXHQgICAgICBjb25zdCB0cmFuc3Bvc2VkID0gZmFsc2U7IC8vIGNhbGwgdGhlIG9yaWdpbmFsIHVud3JhcHBlZCBmdW5jdGlvbnNcblx0ICAgICAgY29uc3QgY2FsbGJhY2tzID0gW1xuXHQgICAgICAgIHtcblx0ICAgICAgICAgIGZvdW5kU3Vic2VxdWVuY2UsXG5cdCAgICAgICAgICBpc0NvbW1vblxuXHQgICAgICAgIH1cblx0ICAgICAgXTtcblxuXHQgICAgICAvLyBJbmRleGVzIGluIHNlcXVlbmNlIGEgb2YgbGFzdCBwb2ludHMgaW4gZnVydGhlc3QgcmVhY2hpbmcgcGF0aHNcblx0ICAgICAgLy8gZnJvbSBvdXRzaWRlIHRoZSBzdGFydCBhdCB0b3AgbGVmdCBpbiB0aGUgZm9yd2FyZCBkaXJlY3Rpb246XG5cdCAgICAgIGNvbnN0IGFJbmRleGVzRiA9IFtOT1RfWUVUX1NFVF07XG5cdCAgICAgIC8vIGZyb20gdGhlIGVuZCBhdCBib3R0b20gcmlnaHQgaW4gdGhlIHJldmVyc2UgZGlyZWN0aW9uOlxuXHQgICAgICBjb25zdCBhSW5kZXhlc1IgPSBbTk9UX1lFVF9TRVRdO1xuXG5cdCAgICAgIC8vIEluaXRpYWxpemUgb25lIG9iamVjdCBhcyBvdXRwdXQgb2YgYWxsIGNhbGxzIHRvIGRpdmlkZSBmdW5jdGlvbi5cblx0ICAgICAgY29uc3QgZGl2aXNpb24gPSB7XG5cdCAgICAgICAgYUNvbW1vbkZvbGxvd2luZzogTk9UX1lFVF9TRVQsXG5cdCAgICAgICAgYUNvbW1vblByZWNlZGluZzogTk9UX1lFVF9TRVQsXG5cdCAgICAgICAgYUVuZFByZWNlZGluZzogTk9UX1lFVF9TRVQsXG5cdCAgICAgICAgYVN0YXJ0Rm9sbG93aW5nOiBOT1RfWUVUX1NFVCxcblx0ICAgICAgICBiQ29tbW9uRm9sbG93aW5nOiBOT1RfWUVUX1NFVCxcblx0ICAgICAgICBiQ29tbW9uUHJlY2VkaW5nOiBOT1RfWUVUX1NFVCxcblx0ICAgICAgICBiRW5kUHJlY2VkaW5nOiBOT1RfWUVUX1NFVCxcblx0ICAgICAgICBiU3RhcnRGb2xsb3dpbmc6IE5PVF9ZRVRfU0VULFxuXHQgICAgICAgIG5DaGFuZ2VGb2xsb3dpbmc6IE5PVF9ZRVRfU0VULFxuXHQgICAgICAgIG5DaGFuZ2VQcmVjZWRpbmc6IE5PVF9ZRVRfU0VULFxuXHQgICAgICAgIG5Db21tb25Gb2xsb3dpbmc6IE5PVF9ZRVRfU0VULFxuXHQgICAgICAgIG5Db21tb25QcmVjZWRpbmc6IE5PVF9ZRVRfU0VUXG5cdCAgICAgIH07XG5cblx0ICAgICAgLy8gRmluZCBhbmQgcmV0dXJuIGNvbW1vbiBzdWJzZXF1ZW5jZXMgaW4gdGhlIHRyaW1tZWQgaW5kZXggaW50ZXJ2YWxzLlxuXHQgICAgICBmaW5kU3Vic2VxdWVuY2VzKFxuXHQgICAgICAgIG5DaGFuZ2UsXG5cdCAgICAgICAgYVN0YXJ0LFxuXHQgICAgICAgIGFFbmQsXG5cdCAgICAgICAgYlN0YXJ0LFxuXHQgICAgICAgIGJFbmQsXG5cdCAgICAgICAgdHJhbnNwb3NlZCxcblx0ICAgICAgICBjYWxsYmFja3MsXG5cdCAgICAgICAgYUluZGV4ZXNGLFxuXHQgICAgICAgIGFJbmRleGVzUixcblx0ICAgICAgICBkaXZpc2lvblxuXHQgICAgICApO1xuXHQgICAgfVxuXHQgICAgaWYgKG5Db21tb25SICE9PSAwKSB7XG5cdCAgICAgIGZvdW5kU3Vic2VxdWVuY2UobkNvbW1vblIsIGFFbmQsIGJFbmQpO1xuXHQgICAgfVxuXHQgIH1cblx0fVxuXHRyZXR1cm4gYnVpbGQ7XG59XG5cbnZhciBidWlsZEV4cG9ydHMgPSAvKkBfX1BVUkVfXyovIHJlcXVpcmVCdWlsZCgpO1xudmFyIGRpZmZTZXF1ZW5jZXMgPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMoYnVpbGRFeHBvcnRzKTtcblxuZnVuY3Rpb24gZm9ybWF0VHJhaWxpbmdTcGFjZXMobGluZSwgdHJhaWxpbmdTcGFjZUZvcm1hdHRlcikge1xuXHRyZXR1cm4gbGluZS5yZXBsYWNlKC9cXHMrJC8sIChtYXRjaCkgPT4gdHJhaWxpbmdTcGFjZUZvcm1hdHRlcihtYXRjaCkpO1xufVxuZnVuY3Rpb24gcHJpbnREaWZmTGluZShsaW5lLCBpc0ZpcnN0T3JMYXN0LCBjb2xvciwgaW5kaWNhdG9yLCB0cmFpbGluZ1NwYWNlRm9ybWF0dGVyLCBlbXB0eUZpcnN0T3JMYXN0TGluZVBsYWNlaG9sZGVyKSB7XG5cdHJldHVybiBsaW5lLmxlbmd0aCAhPT0gMCA/IGNvbG9yKGAke2luZGljYXRvcn0gJHtmb3JtYXRUcmFpbGluZ1NwYWNlcyhsaW5lLCB0cmFpbGluZ1NwYWNlRm9ybWF0dGVyKX1gKSA6IGluZGljYXRvciAhPT0gXCIgXCIgPyBjb2xvcihpbmRpY2F0b3IpIDogaXNGaXJzdE9yTGFzdCAmJiBlbXB0eUZpcnN0T3JMYXN0TGluZVBsYWNlaG9sZGVyLmxlbmd0aCAhPT0gMCA/IGNvbG9yKGAke2luZGljYXRvcn0gJHtlbXB0eUZpcnN0T3JMYXN0TGluZVBsYWNlaG9sZGVyfWApIDogXCJcIjtcbn1cbmZ1bmN0aW9uIHByaW50RGVsZXRlTGluZShsaW5lLCBpc0ZpcnN0T3JMYXN0LCB7IGFDb2xvciwgYUluZGljYXRvciwgY2hhbmdlTGluZVRyYWlsaW5nU3BhY2VDb2xvciwgZW1wdHlGaXJzdE9yTGFzdExpbmVQbGFjZWhvbGRlciB9KSB7XG5cdHJldHVybiBwcmludERpZmZMaW5lKGxpbmUsIGlzRmlyc3RPckxhc3QsIGFDb2xvciwgYUluZGljYXRvciwgY2hhbmdlTGluZVRyYWlsaW5nU3BhY2VDb2xvciwgZW1wdHlGaXJzdE9yTGFzdExpbmVQbGFjZWhvbGRlcik7XG59XG5mdW5jdGlvbiBwcmludEluc2VydExpbmUobGluZSwgaXNGaXJzdE9yTGFzdCwgeyBiQ29sb3IsIGJJbmRpY2F0b3IsIGNoYW5nZUxpbmVUcmFpbGluZ1NwYWNlQ29sb3IsIGVtcHR5Rmlyc3RPckxhc3RMaW5lUGxhY2Vob2xkZXIgfSkge1xuXHRyZXR1cm4gcHJpbnREaWZmTGluZShsaW5lLCBpc0ZpcnN0T3JMYXN0LCBiQ29sb3IsIGJJbmRpY2F0b3IsIGNoYW5nZUxpbmVUcmFpbGluZ1NwYWNlQ29sb3IsIGVtcHR5Rmlyc3RPckxhc3RMaW5lUGxhY2Vob2xkZXIpO1xufVxuZnVuY3Rpb24gcHJpbnRDb21tb25MaW5lKGxpbmUsIGlzRmlyc3RPckxhc3QsIHsgY29tbW9uQ29sb3IsIGNvbW1vbkluZGljYXRvciwgY29tbW9uTGluZVRyYWlsaW5nU3BhY2VDb2xvciwgZW1wdHlGaXJzdE9yTGFzdExpbmVQbGFjZWhvbGRlciB9KSB7XG5cdHJldHVybiBwcmludERpZmZMaW5lKGxpbmUsIGlzRmlyc3RPckxhc3QsIGNvbW1vbkNvbG9yLCBjb21tb25JbmRpY2F0b3IsIGNvbW1vbkxpbmVUcmFpbGluZ1NwYWNlQ29sb3IsIGVtcHR5Rmlyc3RPckxhc3RMaW5lUGxhY2Vob2xkZXIpO1xufVxuLy8gSW4gR05VIGRpZmYgZm9ybWF0LCBpbmRleGVzIGFyZSBvbmUtYmFzZWQgaW5zdGVhZCBvZiB6ZXJvLWJhc2VkLlxuZnVuY3Rpb24gY3JlYXRlUGF0Y2hNYXJrKGFTdGFydCwgYUVuZCwgYlN0YXJ0LCBiRW5kLCB7IHBhdGNoQ29sb3IgfSkge1xuXHRyZXR1cm4gcGF0Y2hDb2xvcihgQEAgLSR7YVN0YXJ0ICsgMX0sJHthRW5kIC0gYVN0YXJ0fSArJHtiU3RhcnQgKyAxfSwke2JFbmQgLSBiU3RhcnR9IEBAYCk7XG59XG4vLyBqZXN0IC0tbm8tZXhwYW5kXG4vL1xuLy8gR2l2ZW4gYXJyYXkgb2YgYWxpZ25lZCBzdHJpbmdzIHdpdGggaW52ZXJzZSBoaWdobGlnaHQgZm9ybWF0dGluZyxcbi8vIHJldHVybiBqb2luZWQgbGluZXMgd2l0aCBkaWZmIGZvcm1hdHRpbmcgKGFuZCBwYXRjaCBtYXJrcywgaWYgbmVlZGVkKS5cbmZ1bmN0aW9uIGpvaW5BbGlnbmVkRGlmZnNOb0V4cGFuZChkaWZmcywgb3B0aW9ucykge1xuXHRjb25zdCBpTGVuZ3RoID0gZGlmZnMubGVuZ3RoO1xuXHRjb25zdCBuQ29udGV4dExpbmVzID0gb3B0aW9ucy5jb250ZXh0TGluZXM7XG5cdGNvbnN0IG5Db250ZXh0TGluZXMyID0gbkNvbnRleHRMaW5lcyArIG5Db250ZXh0TGluZXM7XG5cdC8vIEZpcnN0IHBhc3M6IGNvdW50IG91dHB1dCBsaW5lcyBhbmQgc2VlIGlmIGl0IGhhcyBwYXRjaGVzLlxuXHRsZXQgakxlbmd0aCA9IGlMZW5ndGg7XG5cdGxldCBoYXNFeGNlc3NBdFN0YXJ0T3JFbmQgPSBmYWxzZTtcblx0bGV0IG5FeGNlc3Nlc0JldHdlZW5DaGFuZ2VzID0gMDtcblx0bGV0IGkgPSAwO1xuXHR3aGlsZSAoaSAhPT0gaUxlbmd0aCkge1xuXHRcdGNvbnN0IGlTdGFydCA9IGk7XG5cdFx0d2hpbGUgKGkgIT09IGlMZW5ndGggJiYgZGlmZnNbaV1bMF0gPT09IERJRkZfRVFVQUwpIHtcblx0XHRcdGkgKz0gMTtcblx0XHR9XG5cdFx0aWYgKGlTdGFydCAhPT0gaSkge1xuXHRcdFx0aWYgKGlTdGFydCA9PT0gMCkge1xuXHRcdFx0XHQvLyBhdCBzdGFydFxuXHRcdFx0XHRpZiAoaSA+IG5Db250ZXh0TGluZXMpIHtcblx0XHRcdFx0XHRqTGVuZ3RoIC09IGkgLSBuQ29udGV4dExpbmVzO1xuXHRcdFx0XHRcdGhhc0V4Y2Vzc0F0U3RhcnRPckVuZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoaSA9PT0gaUxlbmd0aCkge1xuXHRcdFx0XHQvLyBhdCBlbmRcblx0XHRcdFx0Y29uc3QgbiA9IGkgLSBpU3RhcnQ7XG5cdFx0XHRcdGlmIChuID4gbkNvbnRleHRMaW5lcykge1xuXHRcdFx0XHRcdGpMZW5ndGggLT0gbiAtIG5Db250ZXh0TGluZXM7XG5cdFx0XHRcdFx0aGFzRXhjZXNzQXRTdGFydE9yRW5kID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gYmV0d2VlbiBjaGFuZ2VzXG5cdFx0XHRcdGNvbnN0IG4gPSBpIC0gaVN0YXJ0O1xuXHRcdFx0XHRpZiAobiA+IG5Db250ZXh0TGluZXMyKSB7XG5cdFx0XHRcdFx0akxlbmd0aCAtPSBuIC0gbkNvbnRleHRMaW5lczI7XG5cdFx0XHRcdFx0bkV4Y2Vzc2VzQmV0d2VlbkNoYW5nZXMgKz0gMTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHR3aGlsZSAoaSAhPT0gaUxlbmd0aCAmJiBkaWZmc1tpXVswXSAhPT0gRElGRl9FUVVBTCkge1xuXHRcdFx0aSArPSAxO1xuXHRcdH1cblx0fVxuXHRjb25zdCBoYXNQYXRjaCA9IG5FeGNlc3Nlc0JldHdlZW5DaGFuZ2VzICE9PSAwIHx8IGhhc0V4Y2Vzc0F0U3RhcnRPckVuZDtcblx0aWYgKG5FeGNlc3Nlc0JldHdlZW5DaGFuZ2VzICE9PSAwKSB7XG5cdFx0akxlbmd0aCArPSBuRXhjZXNzZXNCZXR3ZWVuQ2hhbmdlcyArIDE7XG5cdH0gZWxzZSBpZiAoaGFzRXhjZXNzQXRTdGFydE9yRW5kKSB7XG5cdFx0akxlbmd0aCArPSAxO1xuXHR9XG5cdGNvbnN0IGpMYXN0ID0gakxlbmd0aCAtIDE7XG5cdGNvbnN0IGxpbmVzID0gW107XG5cdGxldCBqUGF0Y2hNYXJrID0gMDtcblx0aWYgKGhhc1BhdGNoKSB7XG5cdFx0bGluZXMucHVzaChcIlwiKTtcblx0fVxuXHQvLyBJbmRleGVzIG9mIGV4cGVjdGVkIG9yIHJlY2VpdmVkIGxpbmVzIGluIGN1cnJlbnQgcGF0Y2g6XG5cdGxldCBhU3RhcnQgPSAwO1xuXHRsZXQgYlN0YXJ0ID0gMDtcblx0bGV0IGFFbmQgPSAwO1xuXHRsZXQgYkVuZCA9IDA7XG5cdGNvbnN0IHB1c2hDb21tb25MaW5lID0gKGxpbmUpID0+IHtcblx0XHRjb25zdCBqID0gbGluZXMubGVuZ3RoO1xuXHRcdGxpbmVzLnB1c2gocHJpbnRDb21tb25MaW5lKGxpbmUsIGogPT09IDAgfHwgaiA9PT0gakxhc3QsIG9wdGlvbnMpKTtcblx0XHRhRW5kICs9IDE7XG5cdFx0YkVuZCArPSAxO1xuXHR9O1xuXHRjb25zdCBwdXNoRGVsZXRlTGluZSA9IChsaW5lKSA9PiB7XG5cdFx0Y29uc3QgaiA9IGxpbmVzLmxlbmd0aDtcblx0XHRsaW5lcy5wdXNoKHByaW50RGVsZXRlTGluZShsaW5lLCBqID09PSAwIHx8IGogPT09IGpMYXN0LCBvcHRpb25zKSk7XG5cdFx0YUVuZCArPSAxO1xuXHR9O1xuXHRjb25zdCBwdXNoSW5zZXJ0TGluZSA9IChsaW5lKSA9PiB7XG5cdFx0Y29uc3QgaiA9IGxpbmVzLmxlbmd0aDtcblx0XHRsaW5lcy5wdXNoKHByaW50SW5zZXJ0TGluZShsaW5lLCBqID09PSAwIHx8IGogPT09IGpMYXN0LCBvcHRpb25zKSk7XG5cdFx0YkVuZCArPSAxO1xuXHR9O1xuXHQvLyBTZWNvbmQgcGFzczogcHVzaCBsaW5lcyB3aXRoIGRpZmYgZm9ybWF0dGluZyAoYW5kIHBhdGNoIG1hcmtzLCBpZiBuZWVkZWQpLlxuXHRpID0gMDtcblx0d2hpbGUgKGkgIT09IGlMZW5ndGgpIHtcblx0XHRsZXQgaVN0YXJ0ID0gaTtcblx0XHR3aGlsZSAoaSAhPT0gaUxlbmd0aCAmJiBkaWZmc1tpXVswXSA9PT0gRElGRl9FUVVBTCkge1xuXHRcdFx0aSArPSAxO1xuXHRcdH1cblx0XHRpZiAoaVN0YXJ0ICE9PSBpKSB7XG5cdFx0XHRpZiAoaVN0YXJ0ID09PSAwKSB7XG5cdFx0XHRcdC8vIGF0IGJlZ2lubmluZ1xuXHRcdFx0XHRpZiAoaSA+IG5Db250ZXh0TGluZXMpIHtcblx0XHRcdFx0XHRpU3RhcnQgPSBpIC0gbkNvbnRleHRMaW5lcztcblx0XHRcdFx0XHRhU3RhcnQgPSBpU3RhcnQ7XG5cdFx0XHRcdFx0YlN0YXJ0ID0gaVN0YXJ0O1xuXHRcdFx0XHRcdGFFbmQgPSBhU3RhcnQ7XG5cdFx0XHRcdFx0YkVuZCA9IGJTdGFydDtcblx0XHRcdFx0fVxuXHRcdFx0XHRmb3IgKGxldCBpQ29tbW9uID0gaVN0YXJ0OyBpQ29tbW9uICE9PSBpOyBpQ29tbW9uICs9IDEpIHtcblx0XHRcdFx0XHRwdXNoQ29tbW9uTGluZShkaWZmc1tpQ29tbW9uXVsxXSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoaSA9PT0gaUxlbmd0aCkge1xuXHRcdFx0XHQvLyBhdCBlbmRcblx0XHRcdFx0Y29uc3QgaUVuZCA9IGkgLSBpU3RhcnQgPiBuQ29udGV4dExpbmVzID8gaVN0YXJ0ICsgbkNvbnRleHRMaW5lcyA6IGk7XG5cdFx0XHRcdGZvciAobGV0IGlDb21tb24gPSBpU3RhcnQ7IGlDb21tb24gIT09IGlFbmQ7IGlDb21tb24gKz0gMSkge1xuXHRcdFx0XHRcdHB1c2hDb21tb25MaW5lKGRpZmZzW2lDb21tb25dWzFdKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gYmV0d2VlbiBjaGFuZ2VzXG5cdFx0XHRcdGNvbnN0IG5Db21tb24gPSBpIC0gaVN0YXJ0O1xuXHRcdFx0XHRpZiAobkNvbW1vbiA+IG5Db250ZXh0TGluZXMyKSB7XG5cdFx0XHRcdFx0Y29uc3QgaUVuZCA9IGlTdGFydCArIG5Db250ZXh0TGluZXM7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaUNvbW1vbiA9IGlTdGFydDsgaUNvbW1vbiAhPT0gaUVuZDsgaUNvbW1vbiArPSAxKSB7XG5cdFx0XHRcdFx0XHRwdXNoQ29tbW9uTGluZShkaWZmc1tpQ29tbW9uXVsxXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGxpbmVzW2pQYXRjaE1hcmtdID0gY3JlYXRlUGF0Y2hNYXJrKGFTdGFydCwgYUVuZCwgYlN0YXJ0LCBiRW5kLCBvcHRpb25zKTtcblx0XHRcdFx0XHRqUGF0Y2hNYXJrID0gbGluZXMubGVuZ3RoO1xuXHRcdFx0XHRcdGxpbmVzLnB1c2goXCJcIik7XG5cdFx0XHRcdFx0Y29uc3Qgbk9taXQgPSBuQ29tbW9uIC0gbkNvbnRleHRMaW5lczI7XG5cdFx0XHRcdFx0YVN0YXJ0ID0gYUVuZCArIG5PbWl0O1xuXHRcdFx0XHRcdGJTdGFydCA9IGJFbmQgKyBuT21pdDtcblx0XHRcdFx0XHRhRW5kID0gYVN0YXJ0O1xuXHRcdFx0XHRcdGJFbmQgPSBiU3RhcnQ7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaUNvbW1vbiA9IGkgLSBuQ29udGV4dExpbmVzOyBpQ29tbW9uICE9PSBpOyBpQ29tbW9uICs9IDEpIHtcblx0XHRcdFx0XHRcdHB1c2hDb21tb25MaW5lKGRpZmZzW2lDb21tb25dWzFdKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaUNvbW1vbiA9IGlTdGFydDsgaUNvbW1vbiAhPT0gaTsgaUNvbW1vbiArPSAxKSB7XG5cdFx0XHRcdFx0XHRwdXNoQ29tbW9uTGluZShkaWZmc1tpQ29tbW9uXVsxXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHdoaWxlIChpICE9PSBpTGVuZ3RoICYmIGRpZmZzW2ldWzBdID09PSBESUZGX0RFTEVURSkge1xuXHRcdFx0cHVzaERlbGV0ZUxpbmUoZGlmZnNbaV1bMV0pO1xuXHRcdFx0aSArPSAxO1xuXHRcdH1cblx0XHR3aGlsZSAoaSAhPT0gaUxlbmd0aCAmJiBkaWZmc1tpXVswXSA9PT0gRElGRl9JTlNFUlQpIHtcblx0XHRcdHB1c2hJbnNlcnRMaW5lKGRpZmZzW2ldWzFdKTtcblx0XHRcdGkgKz0gMTtcblx0XHR9XG5cdH1cblx0aWYgKGhhc1BhdGNoKSB7XG5cdFx0bGluZXNbalBhdGNoTWFya10gPSBjcmVhdGVQYXRjaE1hcmsoYVN0YXJ0LCBhRW5kLCBiU3RhcnQsIGJFbmQsIG9wdGlvbnMpO1xuXHR9XG5cdHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xufVxuLy8gamVzdCAtLWV4cGFuZFxuLy9cbi8vIEdpdmVuIGFycmF5IG9mIGFsaWduZWQgc3RyaW5ncyB3aXRoIGludmVyc2UgaGlnaGxpZ2h0IGZvcm1hdHRpbmcsXG4vLyByZXR1cm4gam9pbmVkIGxpbmVzIHdpdGggZGlmZiBmb3JtYXR0aW5nLlxuZnVuY3Rpb24gam9pbkFsaWduZWREaWZmc0V4cGFuZChkaWZmcywgb3B0aW9ucykge1xuXHRyZXR1cm4gZGlmZnMubWFwKChkaWZmLCBpLCBkaWZmcykgPT4ge1xuXHRcdGNvbnN0IGxpbmUgPSBkaWZmWzFdO1xuXHRcdGNvbnN0IGlzRmlyc3RPckxhc3QgPSBpID09PSAwIHx8IGkgPT09IGRpZmZzLmxlbmd0aCAtIDE7XG5cdFx0c3dpdGNoIChkaWZmWzBdKSB7XG5cdFx0XHRjYXNlIERJRkZfREVMRVRFOiByZXR1cm4gcHJpbnREZWxldGVMaW5lKGxpbmUsIGlzRmlyc3RPckxhc3QsIG9wdGlvbnMpO1xuXHRcdFx0Y2FzZSBESUZGX0lOU0VSVDogcmV0dXJuIHByaW50SW5zZXJ0TGluZShsaW5lLCBpc0ZpcnN0T3JMYXN0LCBvcHRpb25zKTtcblx0XHRcdGRlZmF1bHQ6IHJldHVybiBwcmludENvbW1vbkxpbmUobGluZSwgaXNGaXJzdE9yTGFzdCwgb3B0aW9ucyk7XG5cdFx0fVxuXHR9KS5qb2luKFwiXFxuXCIpO1xufVxuXG5jb25zdCBub0NvbG9yID0gKHN0cmluZykgPT4gc3RyaW5nO1xuY29uc3QgRElGRl9DT05URVhUX0RFRkFVTFQgPSA1O1xuY29uc3QgRElGRl9UUlVOQ0FURV9USFJFU0hPTERfREVGQVVMVCA9IDA7XG5mdW5jdGlvbiBnZXREZWZhdWx0T3B0aW9ucygpIHtcblx0cmV0dXJuIHtcblx0XHRhQW5ub3RhdGlvbjogXCJFeHBlY3RlZFwiLFxuXHRcdGFDb2xvcjogYy5ncmVlbixcblx0XHRhSW5kaWNhdG9yOiBcIi1cIixcblx0XHRiQW5ub3RhdGlvbjogXCJSZWNlaXZlZFwiLFxuXHRcdGJDb2xvcjogYy5yZWQsXG5cdFx0YkluZGljYXRvcjogXCIrXCIsXG5cdFx0Y2hhbmdlQ29sb3I6IGMuaW52ZXJzZSxcblx0XHRjaGFuZ2VMaW5lVHJhaWxpbmdTcGFjZUNvbG9yOiBub0NvbG9yLFxuXHRcdGNvbW1vbkNvbG9yOiBjLmRpbSxcblx0XHRjb21tb25JbmRpY2F0b3I6IFwiIFwiLFxuXHRcdGNvbW1vbkxpbmVUcmFpbGluZ1NwYWNlQ29sb3I6IG5vQ29sb3IsXG5cdFx0Y29tcGFyZUtleXM6IHVuZGVmaW5lZCxcblx0XHRjb250ZXh0TGluZXM6IERJRkZfQ09OVEVYVF9ERUZBVUxULFxuXHRcdGVtcHR5Rmlyc3RPckxhc3RMaW5lUGxhY2Vob2xkZXI6IFwiXCIsXG5cdFx0ZXhwYW5kOiBmYWxzZSxcblx0XHRpbmNsdWRlQ2hhbmdlQ291bnRzOiBmYWxzZSxcblx0XHRvbWl0QW5ub3RhdGlvbkxpbmVzOiBmYWxzZSxcblx0XHRwYXRjaENvbG9yOiBjLnllbGxvdyxcblx0XHRwcmludEJhc2ljUHJvdG90eXBlOiBmYWxzZSxcblx0XHR0cnVuY2F0ZVRocmVzaG9sZDogRElGRl9UUlVOQ0FURV9USFJFU0hPTERfREVGQVVMVCxcblx0XHR0cnVuY2F0ZUFubm90YXRpb246IFwiLi4uIERpZmYgcmVzdWx0IGlzIHRydW5jYXRlZFwiLFxuXHRcdHRydW5jYXRlQW5ub3RhdGlvbkNvbG9yOiBub0NvbG9yXG5cdH07XG59XG5mdW5jdGlvbiBnZXRDb21wYXJlS2V5cyhjb21wYXJlS2V5cykge1xuXHRyZXR1cm4gY29tcGFyZUtleXMgJiYgdHlwZW9mIGNvbXBhcmVLZXlzID09PSBcImZ1bmN0aW9uXCIgPyBjb21wYXJlS2V5cyA6IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGdldENvbnRleHRMaW5lcyhjb250ZXh0TGluZXMpIHtcblx0cmV0dXJuIHR5cGVvZiBjb250ZXh0TGluZXMgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzU2FmZUludGVnZXIoY29udGV4dExpbmVzKSAmJiBjb250ZXh0TGluZXMgPj0gMCA/IGNvbnRleHRMaW5lcyA6IERJRkZfQ09OVEVYVF9ERUZBVUxUO1xufVxuLy8gUHVyZSBmdW5jdGlvbiByZXR1cm5zIG9wdGlvbnMgd2l0aCBhbGwgcHJvcGVydGllcy5cbmZ1bmN0aW9uIG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMgPSB7fSkge1xuXHRyZXR1cm4ge1xuXHRcdC4uLmdldERlZmF1bHRPcHRpb25zKCksXG5cdFx0Li4ub3B0aW9ucyxcblx0XHRjb21wYXJlS2V5czogZ2V0Q29tcGFyZUtleXMob3B0aW9ucy5jb21wYXJlS2V5cyksXG5cdFx0Y29udGV4dExpbmVzOiBnZXRDb250ZXh0TGluZXMob3B0aW9ucy5jb250ZXh0TGluZXMpXG5cdH07XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHlTdHJpbmcobGluZXMpIHtcblx0cmV0dXJuIGxpbmVzLmxlbmd0aCA9PT0gMSAmJiBsaW5lc1swXS5sZW5ndGggPT09IDA7XG59XG5mdW5jdGlvbiBjb3VudENoYW5nZXMoZGlmZnMpIHtcblx0bGV0IGEgPSAwO1xuXHRsZXQgYiA9IDA7XG5cdGRpZmZzLmZvckVhY2goKGRpZmYpID0+IHtcblx0XHRzd2l0Y2ggKGRpZmZbMF0pIHtcblx0XHRcdGNhc2UgRElGRl9ERUxFVEU6XG5cdFx0XHRcdGEgKz0gMTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIERJRkZfSU5TRVJUOlxuXHRcdFx0XHRiICs9IDE7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fSk7XG5cdHJldHVybiB7XG5cdFx0YSxcblx0XHRiXG5cdH07XG59XG5mdW5jdGlvbiBwcmludEFubm90YXRpb24oeyBhQW5ub3RhdGlvbiwgYUNvbG9yLCBhSW5kaWNhdG9yLCBiQW5ub3RhdGlvbiwgYkNvbG9yLCBiSW5kaWNhdG9yLCBpbmNsdWRlQ2hhbmdlQ291bnRzLCBvbWl0QW5ub3RhdGlvbkxpbmVzIH0sIGNoYW5nZUNvdW50cykge1xuXHRpZiAob21pdEFubm90YXRpb25MaW5lcykge1xuXHRcdHJldHVybiBcIlwiO1xuXHR9XG5cdGxldCBhUmVzdCA9IFwiXCI7XG5cdGxldCBiUmVzdCA9IFwiXCI7XG5cdGlmIChpbmNsdWRlQ2hhbmdlQ291bnRzKSB7XG5cdFx0Y29uc3QgYUNvdW50ID0gU3RyaW5nKGNoYW5nZUNvdW50cy5hKTtcblx0XHRjb25zdCBiQ291bnQgPSBTdHJpbmcoY2hhbmdlQ291bnRzLmIpO1xuXHRcdC8vIFBhZGRpbmcgcmlnaHQgYWxpZ25zIHRoZSBlbmRzIG9mIHRoZSBhbm5vdGF0aW9ucy5cblx0XHRjb25zdCBiYUFubm90YXRpb25MZW5ndGhEaWZmID0gYkFubm90YXRpb24ubGVuZ3RoIC0gYUFubm90YXRpb24ubGVuZ3RoO1xuXHRcdGNvbnN0IGFBbm5vdGF0aW9uUGFkZGluZyA9IFwiIFwiLnJlcGVhdChNYXRoLm1heCgwLCBiYUFubm90YXRpb25MZW5ndGhEaWZmKSk7XG5cdFx0Y29uc3QgYkFubm90YXRpb25QYWRkaW5nID0gXCIgXCIucmVwZWF0KE1hdGgubWF4KDAsIC1iYUFubm90YXRpb25MZW5ndGhEaWZmKSk7XG5cdFx0Ly8gUGFkZGluZyBsZWZ0IGFsaWducyB0aGUgZW5kcyBvZiB0aGUgY291bnRzLlxuXHRcdGNvbnN0IGJhQ291bnRMZW5ndGhEaWZmID0gYkNvdW50Lmxlbmd0aCAtIGFDb3VudC5sZW5ndGg7XG5cdFx0Y29uc3QgYUNvdW50UGFkZGluZyA9IFwiIFwiLnJlcGVhdChNYXRoLm1heCgwLCBiYUNvdW50TGVuZ3RoRGlmZikpO1xuXHRcdGNvbnN0IGJDb3VudFBhZGRpbmcgPSBcIiBcIi5yZXBlYXQoTWF0aC5tYXgoMCwgLWJhQ291bnRMZW5ndGhEaWZmKSk7XG5cdFx0YVJlc3QgPSBgJHthQW5ub3RhdGlvblBhZGRpbmd9ICAke2FJbmRpY2F0b3J9ICR7YUNvdW50UGFkZGluZ30ke2FDb3VudH1gO1xuXHRcdGJSZXN0ID0gYCR7YkFubm90YXRpb25QYWRkaW5nfSAgJHtiSW5kaWNhdG9yfSAke2JDb3VudFBhZGRpbmd9JHtiQ291bnR9YDtcblx0fVxuXHRjb25zdCBhID0gYCR7YUluZGljYXRvcn0gJHthQW5ub3RhdGlvbn0ke2FSZXN0fWA7XG5cdGNvbnN0IGIgPSBgJHtiSW5kaWNhdG9yfSAke2JBbm5vdGF0aW9ufSR7YlJlc3R9YDtcblx0cmV0dXJuIGAke2FDb2xvcihhKX1cXG4ke2JDb2xvcihiKX1cXG5cXG5gO1xufVxuZnVuY3Rpb24gcHJpbnREaWZmTGluZXMoZGlmZnMsIHRydW5jYXRlZCwgb3B0aW9ucykge1xuXHRyZXR1cm4gcHJpbnRBbm5vdGF0aW9uKG9wdGlvbnMsIGNvdW50Q2hhbmdlcyhkaWZmcykpICsgKG9wdGlvbnMuZXhwYW5kID8gam9pbkFsaWduZWREaWZmc0V4cGFuZChkaWZmcywgb3B0aW9ucykgOiBqb2luQWxpZ25lZERpZmZzTm9FeHBhbmQoZGlmZnMsIG9wdGlvbnMpKSArICh0cnVuY2F0ZWQgPyBvcHRpb25zLnRydW5jYXRlQW5ub3RhdGlvbkNvbG9yKGBcXG4ke29wdGlvbnMudHJ1bmNhdGVBbm5vdGF0aW9ufWApIDogXCJcIik7XG59XG4vLyBDb21wYXJlIHR3byBhcnJheXMgb2Ygc3RyaW5ncyBsaW5lLWJ5LWxpbmUuIEZvcm1hdCBhcyBjb21wYXJpc29uIGxpbmVzLlxuZnVuY3Rpb24gZGlmZkxpbmVzVW5pZmllZChhTGluZXMsIGJMaW5lcywgb3B0aW9ucykge1xuXHRjb25zdCBub3JtYWxpemVkT3B0aW9ucyA9IG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMpO1xuXHRjb25zdCBbZGlmZnMsIHRydW5jYXRlZF0gPSBkaWZmTGluZXNSYXcoaXNFbXB0eVN0cmluZyhhTGluZXMpID8gW10gOiBhTGluZXMsIGlzRW1wdHlTdHJpbmcoYkxpbmVzKSA/IFtdIDogYkxpbmVzLCBub3JtYWxpemVkT3B0aW9ucyk7XG5cdHJldHVybiBwcmludERpZmZMaW5lcyhkaWZmcywgdHJ1bmNhdGVkLCBub3JtYWxpemVkT3B0aW9ucyk7XG59XG4vLyBHaXZlbiB0d28gcGFpcnMgb2YgYXJyYXlzIG9mIHN0cmluZ3M6XG4vLyBDb21wYXJlIHRoZSBwYWlyIG9mIGNvbXBhcmlzb24gYXJyYXlzIGxpbmUtYnktbGluZS5cbi8vIEZvcm1hdCB0aGUgY29ycmVzcG9uZGluZyBsaW5lcyBpbiB0aGUgcGFpciBvZiBkaXNwbGF5YWJsZSBhcnJheXMuXG5mdW5jdGlvbiBkaWZmTGluZXNVbmlmaWVkMihhTGluZXNEaXNwbGF5LCBiTGluZXNEaXNwbGF5LCBhTGluZXNDb21wYXJlLCBiTGluZXNDb21wYXJlLCBvcHRpb25zKSB7XG5cdGlmIChpc0VtcHR5U3RyaW5nKGFMaW5lc0Rpc3BsYXkpICYmIGlzRW1wdHlTdHJpbmcoYUxpbmVzQ29tcGFyZSkpIHtcblx0XHRhTGluZXNEaXNwbGF5ID0gW107XG5cdFx0YUxpbmVzQ29tcGFyZSA9IFtdO1xuXHR9XG5cdGlmIChpc0VtcHR5U3RyaW5nKGJMaW5lc0Rpc3BsYXkpICYmIGlzRW1wdHlTdHJpbmcoYkxpbmVzQ29tcGFyZSkpIHtcblx0XHRiTGluZXNEaXNwbGF5ID0gW107XG5cdFx0YkxpbmVzQ29tcGFyZSA9IFtdO1xuXHR9XG5cdGlmIChhTGluZXNEaXNwbGF5Lmxlbmd0aCAhPT0gYUxpbmVzQ29tcGFyZS5sZW5ndGggfHwgYkxpbmVzRGlzcGxheS5sZW5ndGggIT09IGJMaW5lc0NvbXBhcmUubGVuZ3RoKSB7XG5cdFx0Ly8gRmFsbCBiYWNrIHRvIGRpZmYgb2YgZGlzcGxheSBsaW5lcy5cblx0XHRyZXR1cm4gZGlmZkxpbmVzVW5pZmllZChhTGluZXNEaXNwbGF5LCBiTGluZXNEaXNwbGF5LCBvcHRpb25zKTtcblx0fVxuXHRjb25zdCBbZGlmZnMsIHRydW5jYXRlZF0gPSBkaWZmTGluZXNSYXcoYUxpbmVzQ29tcGFyZSwgYkxpbmVzQ29tcGFyZSwgb3B0aW9ucyk7XG5cdC8vIFJlcGxhY2UgY29tcGFyaXNvbiBsaW5lcyB3aXRoIGRpc3BsYXlhYmxlIGxpbmVzLlxuXHRsZXQgYUluZGV4ID0gMDtcblx0bGV0IGJJbmRleCA9IDA7XG5cdGRpZmZzLmZvckVhY2goKGRpZmYpID0+IHtcblx0XHRzd2l0Y2ggKGRpZmZbMF0pIHtcblx0XHRcdGNhc2UgRElGRl9ERUxFVEU6XG5cdFx0XHRcdGRpZmZbMV0gPSBhTGluZXNEaXNwbGF5W2FJbmRleF07XG5cdFx0XHRcdGFJbmRleCArPSAxO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRElGRl9JTlNFUlQ6XG5cdFx0XHRcdGRpZmZbMV0gPSBiTGluZXNEaXNwbGF5W2JJbmRleF07XG5cdFx0XHRcdGJJbmRleCArPSAxO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdGRpZmZbMV0gPSBiTGluZXNEaXNwbGF5W2JJbmRleF07XG5cdFx0XHRcdGFJbmRleCArPSAxO1xuXHRcdFx0XHRiSW5kZXggKz0gMTtcblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4gcHJpbnREaWZmTGluZXMoZGlmZnMsIHRydW5jYXRlZCwgbm9ybWFsaXplRGlmZk9wdGlvbnMob3B0aW9ucykpO1xufVxuLy8gQ29tcGFyZSB0d28gYXJyYXlzIG9mIHN0cmluZ3MgbGluZS1ieS1saW5lLlxuZnVuY3Rpb24gZGlmZkxpbmVzUmF3KGFMaW5lcywgYkxpbmVzLCBvcHRpb25zKSB7XG5cdGNvbnN0IHRydW5jYXRlID0gb3B0aW9ucz8udHJ1bmNhdGVUaHJlc2hvbGQgPz8gZmFsc2U7XG5cdGNvbnN0IHRydW5jYXRlVGhyZXNob2xkID0gTWF0aC5tYXgoTWF0aC5mbG9vcihvcHRpb25zPy50cnVuY2F0ZVRocmVzaG9sZCA/PyAwKSwgMCk7XG5cdGNvbnN0IGFMZW5ndGggPSB0cnVuY2F0ZSA/IE1hdGgubWluKGFMaW5lcy5sZW5ndGgsIHRydW5jYXRlVGhyZXNob2xkKSA6IGFMaW5lcy5sZW5ndGg7XG5cdGNvbnN0IGJMZW5ndGggPSB0cnVuY2F0ZSA/IE1hdGgubWluKGJMaW5lcy5sZW5ndGgsIHRydW5jYXRlVGhyZXNob2xkKSA6IGJMaW5lcy5sZW5ndGg7XG5cdGNvbnN0IHRydW5jYXRlZCA9IGFMZW5ndGggIT09IGFMaW5lcy5sZW5ndGggfHwgYkxlbmd0aCAhPT0gYkxpbmVzLmxlbmd0aDtcblx0Y29uc3QgaXNDb21tb24gPSAoYUluZGV4LCBiSW5kZXgpID0+IGFMaW5lc1thSW5kZXhdID09PSBiTGluZXNbYkluZGV4XTtcblx0Y29uc3QgZGlmZnMgPSBbXTtcblx0bGV0IGFJbmRleCA9IDA7XG5cdGxldCBiSW5kZXggPSAwO1xuXHRjb25zdCBmb3VuZFN1YnNlcXVlbmNlID0gKG5Db21tb24sIGFDb21tb24sIGJDb21tb24pID0+IHtcblx0XHRmb3IgKDsgYUluZGV4ICE9PSBhQ29tbW9uOyBhSW5kZXggKz0gMSkge1xuXHRcdFx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0RFTEVURSwgYUxpbmVzW2FJbmRleF0pKTtcblx0XHR9XG5cdFx0Zm9yICg7IGJJbmRleCAhPT0gYkNvbW1vbjsgYkluZGV4ICs9IDEpIHtcblx0XHRcdGRpZmZzLnB1c2gobmV3IERpZmYoRElGRl9JTlNFUlQsIGJMaW5lc1tiSW5kZXhdKSk7XG5cdFx0fVxuXHRcdGZvciAoOyBuQ29tbW9uICE9PSAwOyBuQ29tbW9uIC09IDEsIGFJbmRleCArPSAxLCBiSW5kZXggKz0gMSkge1xuXHRcdFx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0VRVUFMLCBiTGluZXNbYkluZGV4XSkpO1xuXHRcdH1cblx0fTtcblx0ZGlmZlNlcXVlbmNlcyhhTGVuZ3RoLCBiTGVuZ3RoLCBpc0NvbW1vbiwgZm91bmRTdWJzZXF1ZW5jZSk7XG5cdC8vIEFmdGVyIHRoZSBsYXN0IGNvbW1vbiBzdWJzZXF1ZW5jZSwgcHVzaCByZW1haW5pbmcgY2hhbmdlIGl0ZW1zLlxuXHRmb3IgKDsgYUluZGV4ICE9PSBhTGVuZ3RoOyBhSW5kZXggKz0gMSkge1xuXHRcdGRpZmZzLnB1c2gobmV3IERpZmYoRElGRl9ERUxFVEUsIGFMaW5lc1thSW5kZXhdKSk7XG5cdH1cblx0Zm9yICg7IGJJbmRleCAhPT0gYkxlbmd0aDsgYkluZGV4ICs9IDEpIHtcblx0XHRkaWZmcy5wdXNoKG5ldyBEaWZmKERJRkZfSU5TRVJULCBiTGluZXNbYkluZGV4XSkpO1xuXHR9XG5cdHJldHVybiBbZGlmZnMsIHRydW5jYXRlZF07XG59XG5cbi8vIGdldCB0aGUgdHlwZSBvZiBhIHZhbHVlIHdpdGggaGFuZGxpbmcgdGhlIGVkZ2UgY2FzZXMgbGlrZSBgdHlwZW9mIFtdYFxuLy8gYW5kIGB0eXBlb2YgbnVsbGBcbmZ1bmN0aW9uIGdldFR5cGUodmFsdWUpIHtcblx0aWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gXCJ1bmRlZmluZWRcIjtcblx0fSBlbHNlIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBcIm51bGxcIjtcblx0fSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuXHRcdHJldHVybiBcImFycmF5XCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcImJvb2xlYW5cIikge1xuXHRcdHJldHVybiBcImJvb2xlYW5cIjtcblx0fSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuXHRcdHJldHVybiBcImZ1bmN0aW9uXCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSB7XG5cdFx0cmV0dXJuIFwibnVtYmVyXCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG5cdFx0cmV0dXJuIFwic3RyaW5nXCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcImJpZ2ludFwiKSB7XG5cdFx0cmV0dXJuIFwiYmlnaW50XCI7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG5cdFx0aWYgKHZhbHVlICE9IG51bGwpIHtcblx0XHRcdGlmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gUmVnRXhwKSB7XG5cdFx0XHRcdHJldHVybiBcInJlZ2V4cFwiO1xuXHRcdFx0fSBlbHNlIGlmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gTWFwKSB7XG5cdFx0XHRcdHJldHVybiBcIm1hcFwiO1xuXHRcdFx0fSBlbHNlIGlmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gU2V0KSB7XG5cdFx0XHRcdHJldHVybiBcInNldFwiO1xuXHRcdFx0fSBlbHNlIGlmICh2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gRGF0ZSkge1xuXHRcdFx0XHRyZXR1cm4gXCJkYXRlXCI7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBcIm9iamVjdFwiO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzeW1ib2xcIikge1xuXHRcdHJldHVybiBcInN5bWJvbFwiO1xuXHR9XG5cdHRocm93IG5ldyBFcnJvcihgdmFsdWUgb2YgdW5rbm93biB0eXBlOiAke3ZhbHVlfWApO1xufVxuXG4vLyBwbGF0Zm9ybXMgY29tcGF0aWJsZVxuZnVuY3Rpb24gZ2V0TmV3TGluZVN5bWJvbChzdHJpbmcpIHtcblx0cmV0dXJuIHN0cmluZy5pbmNsdWRlcyhcIlxcclxcblwiKSA/IFwiXFxyXFxuXCIgOiBcIlxcblwiO1xufVxuZnVuY3Rpb24gZGlmZlN0cmluZ3MoYSwgYiwgb3B0aW9ucykge1xuXHRjb25zdCB0cnVuY2F0ZSA9IG9wdGlvbnM/LnRydW5jYXRlVGhyZXNob2xkID8/IGZhbHNlO1xuXHRjb25zdCB0cnVuY2F0ZVRocmVzaG9sZCA9IE1hdGgubWF4KE1hdGguZmxvb3Iob3B0aW9ucz8udHJ1bmNhdGVUaHJlc2hvbGQgPz8gMCksIDApO1xuXHRsZXQgYUxlbmd0aCA9IGEubGVuZ3RoO1xuXHRsZXQgYkxlbmd0aCA9IGIubGVuZ3RoO1xuXHRpZiAodHJ1bmNhdGUpIHtcblx0XHRjb25zdCBhTXVsdGlwbGVMaW5lcyA9IGEuaW5jbHVkZXMoXCJcXG5cIik7XG5cdFx0Y29uc3QgYk11bHRpcGxlTGluZXMgPSBiLmluY2x1ZGVzKFwiXFxuXCIpO1xuXHRcdGNvbnN0IGFOZXdMaW5lU3ltYm9sID0gZ2V0TmV3TGluZVN5bWJvbChhKTtcblx0XHRjb25zdCBiTmV3TGluZVN5bWJvbCA9IGdldE5ld0xpbmVTeW1ib2woYik7XG5cdFx0Ly8gbXVsdGlwbGUtbGluZXMgc3RyaW5nIGV4cGVjdHMgYSBuZXdsaW5lIHRvIGJlIGFwcGVuZGVkIGF0IHRoZSBlbmRcblx0XHRjb25zdCBfYSA9IGFNdWx0aXBsZUxpbmVzID8gYCR7YS5zcGxpdChhTmV3TGluZVN5bWJvbCwgdHJ1bmNhdGVUaHJlc2hvbGQpLmpvaW4oYU5ld0xpbmVTeW1ib2wpfVxcbmAgOiBhO1xuXHRcdGNvbnN0IF9iID0gYk11bHRpcGxlTGluZXMgPyBgJHtiLnNwbGl0KGJOZXdMaW5lU3ltYm9sLCB0cnVuY2F0ZVRocmVzaG9sZCkuam9pbihiTmV3TGluZVN5bWJvbCl9XFxuYCA6IGI7XG5cdFx0YUxlbmd0aCA9IF9hLmxlbmd0aDtcblx0XHRiTGVuZ3RoID0gX2IubGVuZ3RoO1xuXHR9XG5cdGNvbnN0IHRydW5jYXRlZCA9IGFMZW5ndGggIT09IGEubGVuZ3RoIHx8IGJMZW5ndGggIT09IGIubGVuZ3RoO1xuXHRjb25zdCBpc0NvbW1vbiA9IChhSW5kZXgsIGJJbmRleCkgPT4gYVthSW5kZXhdID09PSBiW2JJbmRleF07XG5cdGxldCBhSW5kZXggPSAwO1xuXHRsZXQgYkluZGV4ID0gMDtcblx0Y29uc3QgZGlmZnMgPSBbXTtcblx0Y29uc3QgZm91bmRTdWJzZXF1ZW5jZSA9IChuQ29tbW9uLCBhQ29tbW9uLCBiQ29tbW9uKSA9PiB7XG5cdFx0aWYgKGFJbmRleCAhPT0gYUNvbW1vbikge1xuXHRcdFx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0RFTEVURSwgYS5zbGljZShhSW5kZXgsIGFDb21tb24pKSk7XG5cdFx0fVxuXHRcdGlmIChiSW5kZXggIT09IGJDb21tb24pIHtcblx0XHRcdGRpZmZzLnB1c2gobmV3IERpZmYoRElGRl9JTlNFUlQsIGIuc2xpY2UoYkluZGV4LCBiQ29tbW9uKSkpO1xuXHRcdH1cblx0XHRhSW5kZXggPSBhQ29tbW9uICsgbkNvbW1vbjtcblx0XHRiSW5kZXggPSBiQ29tbW9uICsgbkNvbW1vbjtcblx0XHRkaWZmcy5wdXNoKG5ldyBEaWZmKERJRkZfRVFVQUwsIGIuc2xpY2UoYkNvbW1vbiwgYkluZGV4KSkpO1xuXHR9O1xuXHRkaWZmU2VxdWVuY2VzKGFMZW5ndGgsIGJMZW5ndGgsIGlzQ29tbW9uLCBmb3VuZFN1YnNlcXVlbmNlKTtcblx0Ly8gQWZ0ZXIgdGhlIGxhc3QgY29tbW9uIHN1YnNlcXVlbmNlLCBwdXNoIHJlbWFpbmluZyBjaGFuZ2UgaXRlbXMuXG5cdGlmIChhSW5kZXggIT09IGFMZW5ndGgpIHtcblx0XHRkaWZmcy5wdXNoKG5ldyBEaWZmKERJRkZfREVMRVRFLCBhLnNsaWNlKGFJbmRleCkpKTtcblx0fVxuXHRpZiAoYkluZGV4ICE9PSBiTGVuZ3RoKSB7XG5cdFx0ZGlmZnMucHVzaChuZXcgRGlmZihESUZGX0lOU0VSVCwgYi5zbGljZShiSW5kZXgpKSk7XG5cdH1cblx0cmV0dXJuIFtkaWZmcywgdHJ1bmNhdGVkXTtcbn1cblxuLy8gR2l2ZW4gY2hhbmdlIG9wIGFuZCBhcnJheSBvZiBkaWZmcywgcmV0dXJuIGNvbmNhdGVuYXRlZCBzdHJpbmc6XG4vLyAqIGluY2x1ZGUgY29tbW9uIHN0cmluZ3Ncbi8vICogaW5jbHVkZSBjaGFuZ2Ugc3RyaW5ncyB3aGljaCBoYXZlIGFyZ3VtZW50IG9wIHdpdGggY2hhbmdlQ29sb3Jcbi8vICogZXhjbHVkZSBjaGFuZ2Ugc3RyaW5ncyB3aGljaCBoYXZlIG9wcG9zaXRlIG9wXG5mdW5jdGlvbiBjb25jYXRlbmF0ZVJlbGV2YW50RGlmZnMob3AsIGRpZmZzLCBjaGFuZ2VDb2xvcikge1xuXHRyZXR1cm4gZGlmZnMucmVkdWNlKChyZWR1Y2VkLCBkaWZmKSA9PiByZWR1Y2VkICsgKGRpZmZbMF0gPT09IERJRkZfRVFVQUwgPyBkaWZmWzFdIDogZGlmZlswXSA9PT0gb3AgJiYgZGlmZlsxXS5sZW5ndGggIT09IDAgPyBjaGFuZ2VDb2xvcihkaWZmWzFdKSA6IFwiXCIpLCBcIlwiKTtcbn1cbi8vIEVuY2Fwc3VsYXRlIGNoYW5nZSBsaW5lcyB1bnRpbCBlaXRoZXIgYSBjb21tb24gbmV3bGluZSBvciB0aGUgZW5kLlxuY2xhc3MgQ2hhbmdlQnVmZmVyIHtcblx0b3A7XG5cdGxpbmU7XG5cdGxpbmVzO1xuXHRjaGFuZ2VDb2xvcjtcblx0Y29uc3RydWN0b3Iob3AsIGNoYW5nZUNvbG9yKSB7XG5cdFx0dGhpcy5vcCA9IG9wO1xuXHRcdHRoaXMubGluZSA9IFtdO1xuXHRcdHRoaXMubGluZXMgPSBbXTtcblx0XHR0aGlzLmNoYW5nZUNvbG9yID0gY2hhbmdlQ29sb3I7XG5cdH1cblx0cHVzaFN1YnN0cmluZyhzdWJzdHJpbmcpIHtcblx0XHR0aGlzLnB1c2hEaWZmKG5ldyBEaWZmKHRoaXMub3AsIHN1YnN0cmluZykpO1xuXHR9XG5cdHB1c2hMaW5lKCkge1xuXHRcdC8vIEFzc3VtZSBjYWxsIG9ubHkgaWYgbGluZSBoYXMgYXQgbGVhc3Qgb25lIGRpZmYsXG5cdFx0Ly8gdGhlcmVmb3JlIGFuIGVtcHR5IGxpbmUgbXVzdCBoYXZlIGEgZGlmZiB3aGljaCBoYXMgYW4gZW1wdHkgc3RyaW5nLlxuXHRcdC8vIElmIGxpbmUgaGFzIG11bHRpcGxlIGRpZmZzLCB0aGVuIGFzc3VtZSBpdCBoYXMgYSBjb21tb24gZGlmZixcblx0XHQvLyB0aGVyZWZvcmUgY2hhbmdlIGRpZmZzIGhhdmUgY2hhbmdlIGNvbG9yO1xuXHRcdC8vIG90aGVyd2lzZSB0aGVuIGl0IGhhcyBsaW5lIGNvbG9yIG9ubHkuXG5cdFx0dGhpcy5saW5lcy5wdXNoKHRoaXMubGluZS5sZW5ndGggIT09IDEgPyBuZXcgRGlmZih0aGlzLm9wLCBjb25jYXRlbmF0ZVJlbGV2YW50RGlmZnModGhpcy5vcCwgdGhpcy5saW5lLCB0aGlzLmNoYW5nZUNvbG9yKSkgOiB0aGlzLmxpbmVbMF1bMF0gPT09IHRoaXMub3AgPyB0aGlzLmxpbmVbMF0gOiBuZXcgRGlmZih0aGlzLm9wLCB0aGlzLmxpbmVbMF1bMV0pKTtcblx0XHR0aGlzLmxpbmUubGVuZ3RoID0gMDtcblx0fVxuXHRpc0xpbmVFbXB0eSgpIHtcblx0XHRyZXR1cm4gdGhpcy5saW5lLmxlbmd0aCA9PT0gMDtcblx0fVxuXHQvLyBNaW5vciBpbnB1dCB0byBidWZmZXIuXG5cdHB1c2hEaWZmKGRpZmYpIHtcblx0XHR0aGlzLmxpbmUucHVzaChkaWZmKTtcblx0fVxuXHQvLyBNYWluIGlucHV0IHRvIGJ1ZmZlci5cblx0YWxpZ24oZGlmZikge1xuXHRcdGNvbnN0IHN0cmluZyA9IGRpZmZbMV07XG5cdFx0aWYgKHN0cmluZy5pbmNsdWRlcyhcIlxcblwiKSkge1xuXHRcdFx0Y29uc3Qgc3Vic3RyaW5ncyA9IHN0cmluZy5zcGxpdChcIlxcblwiKTtcblx0XHRcdGNvbnN0IGlMYXN0ID0gc3Vic3RyaW5ncy5sZW5ndGggLSAxO1xuXHRcdFx0c3Vic3RyaW5ncy5mb3JFYWNoKChzdWJzdHJpbmcsIGkpID0+IHtcblx0XHRcdFx0aWYgKGkgPCBpTGFzdCkge1xuXHRcdFx0XHRcdC8vIFRoZSBmaXJzdCBzdWJzdHJpbmcgY29tcGxldGVzIHRoZSBjdXJyZW50IGNoYW5nZSBsaW5lLlxuXHRcdFx0XHRcdC8vIEEgbWlkZGxlIHN1YnN0cmluZyBpcyBhIGNoYW5nZSBsaW5lLlxuXHRcdFx0XHRcdHRoaXMucHVzaFN1YnN0cmluZyhzdWJzdHJpbmcpO1xuXHRcdFx0XHRcdHRoaXMucHVzaExpbmUoKTtcblx0XHRcdFx0fSBlbHNlIGlmIChzdWJzdHJpbmcubGVuZ3RoICE9PSAwKSB7XG5cdFx0XHRcdFx0Ly8gVGhlIGxhc3Qgc3Vic3RyaW5nIHN0YXJ0cyBhIGNoYW5nZSBsaW5lLCBpZiBpdCBpcyBub3QgZW1wdHkuXG5cdFx0XHRcdFx0Ly8gSW1wb3J0YW50OiBUaGlzIG5vbi1lbXB0eSBjb25kaXRpb24gYWxzbyBhdXRvbWF0aWNhbGx5IG9taXRzXG5cdFx0XHRcdFx0Ly8gdGhlIG5ld2xpbmUgYXBwZW5kZWQgdG8gdGhlIGVuZCBvZiBleHBlY3RlZCBhbmQgcmVjZWl2ZWQgc3RyaW5ncy5cblx0XHRcdFx0XHR0aGlzLnB1c2hTdWJzdHJpbmcoc3Vic3RyaW5nKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEFwcGVuZCBub24tbXVsdGlsaW5lIHN0cmluZyB0byBjdXJyZW50IGNoYW5nZSBsaW5lLlxuXHRcdFx0dGhpcy5wdXNoRGlmZihkaWZmKTtcblx0XHR9XG5cdH1cblx0Ly8gT3V0cHV0IGZyb20gYnVmZmVyLlxuXHRtb3ZlTGluZXNUbyhsaW5lcykge1xuXHRcdGlmICghdGhpcy5pc0xpbmVFbXB0eSgpKSB7XG5cdFx0XHR0aGlzLnB1c2hMaW5lKCk7XG5cdFx0fVxuXHRcdGxpbmVzLnB1c2goLi4udGhpcy5saW5lcyk7XG5cdFx0dGhpcy5saW5lcy5sZW5ndGggPSAwO1xuXHR9XG59XG4vLyBFbmNhcHN1bGF0ZSBjb21tb24gYW5kIGNoYW5nZSBsaW5lcy5cbmNsYXNzIENvbW1vbkJ1ZmZlciB7XG5cdGRlbGV0ZUJ1ZmZlcjtcblx0aW5zZXJ0QnVmZmVyO1xuXHRsaW5lcztcblx0Y29uc3RydWN0b3IoZGVsZXRlQnVmZmVyLCBpbnNlcnRCdWZmZXIpIHtcblx0XHR0aGlzLmRlbGV0ZUJ1ZmZlciA9IGRlbGV0ZUJ1ZmZlcjtcblx0XHR0aGlzLmluc2VydEJ1ZmZlciA9IGluc2VydEJ1ZmZlcjtcblx0XHR0aGlzLmxpbmVzID0gW107XG5cdH1cblx0cHVzaERpZmZDb21tb25MaW5lKGRpZmYpIHtcblx0XHR0aGlzLmxpbmVzLnB1c2goZGlmZik7XG5cdH1cblx0cHVzaERpZmZDaGFuZ2VMaW5lcyhkaWZmKSB7XG5cdFx0Y29uc3QgaXNEaWZmRW1wdHkgPSBkaWZmWzFdLmxlbmd0aCA9PT0gMDtcblx0XHQvLyBBbiBlbXB0eSBkaWZmIHN0cmluZyBpcyByZWR1bmRhbnQsIHVubGVzcyBhIGNoYW5nZSBsaW5lIGlzIGVtcHR5LlxuXHRcdGlmICghaXNEaWZmRW1wdHkgfHwgdGhpcy5kZWxldGVCdWZmZXIuaXNMaW5lRW1wdHkoKSkge1xuXHRcdFx0dGhpcy5kZWxldGVCdWZmZXIucHVzaERpZmYoZGlmZik7XG5cdFx0fVxuXHRcdGlmICghaXNEaWZmRW1wdHkgfHwgdGhpcy5pbnNlcnRCdWZmZXIuaXNMaW5lRW1wdHkoKSkge1xuXHRcdFx0dGhpcy5pbnNlcnRCdWZmZXIucHVzaERpZmYoZGlmZik7XG5cdFx0fVxuXHR9XG5cdGZsdXNoQ2hhbmdlTGluZXMoKSB7XG5cdFx0dGhpcy5kZWxldGVCdWZmZXIubW92ZUxpbmVzVG8odGhpcy5saW5lcyk7XG5cdFx0dGhpcy5pbnNlcnRCdWZmZXIubW92ZUxpbmVzVG8odGhpcy5saW5lcyk7XG5cdH1cblx0Ly8gSW5wdXQgdG8gYnVmZmVyLlxuXHRhbGlnbihkaWZmKSB7XG5cdFx0Y29uc3Qgb3AgPSBkaWZmWzBdO1xuXHRcdGNvbnN0IHN0cmluZyA9IGRpZmZbMV07XG5cdFx0aWYgKHN0cmluZy5pbmNsdWRlcyhcIlxcblwiKSkge1xuXHRcdFx0Y29uc3Qgc3Vic3RyaW5ncyA9IHN0cmluZy5zcGxpdChcIlxcblwiKTtcblx0XHRcdGNvbnN0IGlMYXN0ID0gc3Vic3RyaW5ncy5sZW5ndGggLSAxO1xuXHRcdFx0c3Vic3RyaW5ncy5mb3JFYWNoKChzdWJzdHJpbmcsIGkpID0+IHtcblx0XHRcdFx0aWYgKGkgPT09IDApIHtcblx0XHRcdFx0XHRjb25zdCBzdWJkaWZmID0gbmV3IERpZmYob3AsIHN1YnN0cmluZyk7XG5cdFx0XHRcdFx0aWYgKHRoaXMuZGVsZXRlQnVmZmVyLmlzTGluZUVtcHR5KCkgJiYgdGhpcy5pbnNlcnRCdWZmZXIuaXNMaW5lRW1wdHkoKSkge1xuXHRcdFx0XHRcdFx0Ly8gSWYgYm90aCBjdXJyZW50IGNoYW5nZSBsaW5lcyBhcmUgZW1wdHksXG5cdFx0XHRcdFx0XHQvLyB0aGVuIHRoZSBmaXJzdCBzdWJzdHJpbmcgaXMgYSBjb21tb24gbGluZS5cblx0XHRcdFx0XHRcdHRoaXMuZmx1c2hDaGFuZ2VMaW5lcygpO1xuXHRcdFx0XHRcdFx0dGhpcy5wdXNoRGlmZkNvbW1vbkxpbmUoc3ViZGlmZik7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIElmIGVpdGhlciBjdXJyZW50IGNoYW5nZSBsaW5lIGlzIG5vbi1lbXB0eSxcblx0XHRcdFx0XHRcdC8vIHRoZW4gdGhlIGZpcnN0IHN1YnN0cmluZyBjb21wbGV0ZXMgdGhlIGNoYW5nZSBsaW5lcy5cblx0XHRcdFx0XHRcdHRoaXMucHVzaERpZmZDaGFuZ2VMaW5lcyhzdWJkaWZmKTtcblx0XHRcdFx0XHRcdHRoaXMuZmx1c2hDaGFuZ2VMaW5lcygpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmIChpIDwgaUxhc3QpIHtcblx0XHRcdFx0XHQvLyBBIG1pZGRsZSBzdWJzdHJpbmcgaXMgYSBjb21tb24gbGluZS5cblx0XHRcdFx0XHR0aGlzLnB1c2hEaWZmQ29tbW9uTGluZShuZXcgRGlmZihvcCwgc3Vic3RyaW5nKSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoc3Vic3RyaW5nLmxlbmd0aCAhPT0gMCkge1xuXHRcdFx0XHRcdC8vIFRoZSBsYXN0IHN1YnN0cmluZyBzdGFydHMgYSBjaGFuZ2UgbGluZSwgaWYgaXQgaXMgbm90IGVtcHR5LlxuXHRcdFx0XHRcdC8vIEltcG9ydGFudDogVGhpcyBub24tZW1wdHkgY29uZGl0aW9uIGFsc28gYXV0b21hdGljYWxseSBvbWl0c1xuXHRcdFx0XHRcdC8vIHRoZSBuZXdsaW5lIGFwcGVuZGVkIHRvIHRoZSBlbmQgb2YgZXhwZWN0ZWQgYW5kIHJlY2VpdmVkIHN0cmluZ3MuXG5cdFx0XHRcdFx0dGhpcy5wdXNoRGlmZkNoYW5nZUxpbmVzKG5ldyBEaWZmKG9wLCBzdWJzdHJpbmcpKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEFwcGVuZCBub24tbXVsdGlsaW5lIHN0cmluZyB0byBjdXJyZW50IGNoYW5nZSBsaW5lcy5cblx0XHRcdC8vIEltcG9ydGFudDogSXQgY2Fubm90IGJlIGF0IHRoZSBlbmQgZm9sbG93aW5nIGVtcHR5IGNoYW5nZSBsaW5lcyxcblx0XHRcdC8vIGJlY2F1c2UgbmV3bGluZSBhcHBlbmRlZCB0byB0aGUgZW5kIG9mIGV4cGVjdGVkIGFuZCByZWNlaXZlZCBzdHJpbmdzLlxuXHRcdFx0dGhpcy5wdXNoRGlmZkNoYW5nZUxpbmVzKGRpZmYpO1xuXHRcdH1cblx0fVxuXHQvLyBPdXRwdXQgZnJvbSBidWZmZXIuXG5cdGdldExpbmVzKCkge1xuXHRcdHRoaXMuZmx1c2hDaGFuZ2VMaW5lcygpO1xuXHRcdHJldHVybiB0aGlzLmxpbmVzO1xuXHR9XG59XG4vLyBHaXZlbiBkaWZmcyBmcm9tIGV4cGVjdGVkIGFuZCByZWNlaXZlZCBzdHJpbmdzLFxuLy8gcmV0dXJuIG5ldyBhcnJheSBvZiBkaWZmcyBzcGxpdCBvciBqb2luZWQgaW50byBsaW5lcy5cbi8vXG4vLyBUbyBjb3JyZWN0bHkgYWxpZ24gYSBjaGFuZ2UgbGluZSBhdCB0aGUgZW5kLCB0aGUgYWxnb3JpdGhtOlxuLy8gKiBhc3N1bWVzIHRoYXQgYSBuZXdsaW5lIHdhcyBhcHBlbmRlZCB0byB0aGUgc3RyaW5nc1xuLy8gKiBvbWl0cyB0aGUgbGFzdCBuZXdsaW5lIGZyb20gdGhlIG91dHB1dCBhcnJheVxuLy9cbi8vIEFzc3VtZSB0aGUgZnVuY3Rpb24gaXMgbm90IGNhbGxlZDpcbi8vICogaWYgZWl0aGVyIGV4cGVjdGVkIG9yIHJlY2VpdmVkIGlzIGVtcHR5IHN0cmluZ1xuLy8gKiBpZiBuZWl0aGVyIGV4cGVjdGVkIG5vciByZWNlaXZlZCBpcyBtdWx0aWxpbmUgc3RyaW5nXG5mdW5jdGlvbiBnZXRBbGlnbmVkRGlmZnMoZGlmZnMsIGNoYW5nZUNvbG9yKSB7XG5cdGNvbnN0IGRlbGV0ZUJ1ZmZlciA9IG5ldyBDaGFuZ2VCdWZmZXIoRElGRl9ERUxFVEUsIGNoYW5nZUNvbG9yKTtcblx0Y29uc3QgaW5zZXJ0QnVmZmVyID0gbmV3IENoYW5nZUJ1ZmZlcihESUZGX0lOU0VSVCwgY2hhbmdlQ29sb3IpO1xuXHRjb25zdCBjb21tb25CdWZmZXIgPSBuZXcgQ29tbW9uQnVmZmVyKGRlbGV0ZUJ1ZmZlciwgaW5zZXJ0QnVmZmVyKTtcblx0ZGlmZnMuZm9yRWFjaCgoZGlmZikgPT4ge1xuXHRcdHN3aXRjaCAoZGlmZlswXSkge1xuXHRcdFx0Y2FzZSBESUZGX0RFTEVURTpcblx0XHRcdFx0ZGVsZXRlQnVmZmVyLmFsaWduKGRpZmYpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgRElGRl9JTlNFUlQ6XG5cdFx0XHRcdGluc2VydEJ1ZmZlci5hbGlnbihkaWZmKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OiBjb21tb25CdWZmZXIuYWxpZ24oZGlmZik7XG5cdFx0fVxuXHR9KTtcblx0cmV0dXJuIGNvbW1vbkJ1ZmZlci5nZXRMaW5lcygpO1xufVxuXG5mdW5jdGlvbiBoYXNDb21tb25EaWZmKGRpZmZzLCBpc011bHRpbGluZSkge1xuXHRpZiAoaXNNdWx0aWxpbmUpIHtcblx0XHQvLyBJbXBvcnRhbnQ6IElnbm9yZSBjb21tb24gbmV3bGluZSB0aGF0IHdhcyBhcHBlbmRlZCB0byBtdWx0aWxpbmUgc3RyaW5ncyFcblx0XHRjb25zdCBpTGFzdCA9IGRpZmZzLmxlbmd0aCAtIDE7XG5cdFx0cmV0dXJuIGRpZmZzLnNvbWUoKGRpZmYsIGkpID0+IGRpZmZbMF0gPT09IERJRkZfRVFVQUwgJiYgKGkgIT09IGlMYXN0IHx8IGRpZmZbMV0gIT09IFwiXFxuXCIpKTtcblx0fVxuXHRyZXR1cm4gZGlmZnMuc29tZSgoZGlmZikgPT4gZGlmZlswXSA9PT0gRElGRl9FUVVBTCk7XG59XG4vLyBDb21wYXJlIHR3byBzdHJpbmdzIGNoYXJhY3Rlci1ieS1jaGFyYWN0ZXIuXG4vLyBGb3JtYXQgYXMgY29tcGFyaXNvbiBsaW5lcyBpbiB3aGljaCBjaGFuZ2VkIHN1YnN0cmluZ3MgaGF2ZSBpbnZlcnNlIGNvbG9ycy5cbmZ1bmN0aW9uIGRpZmZTdHJpbmdzVW5pZmllZChhLCBiLCBvcHRpb25zKSB7XG5cdGlmIChhICE9PSBiICYmIGEubGVuZ3RoICE9PSAwICYmIGIubGVuZ3RoICE9PSAwKSB7XG5cdFx0Y29uc3QgaXNNdWx0aWxpbmUgPSBhLmluY2x1ZGVzKFwiXFxuXCIpIHx8IGIuaW5jbHVkZXMoXCJcXG5cIik7XG5cdFx0Ly8gZ2V0QWxpZ25lZERpZmZzIGFzc3VtZXMgdGhhdCBhIG5ld2xpbmUgd2FzIGFwcGVuZGVkIHRvIHRoZSBzdHJpbmdzLlxuXHRcdGNvbnN0IFtkaWZmcywgdHJ1bmNhdGVkXSA9IGRpZmZTdHJpbmdzUmF3KGlzTXVsdGlsaW5lID8gYCR7YX1cXG5gIDogYSwgaXNNdWx0aWxpbmUgPyBgJHtifVxcbmAgOiBiLCB0cnVlLCBvcHRpb25zKTtcblx0XHRpZiAoaGFzQ29tbW9uRGlmZihkaWZmcywgaXNNdWx0aWxpbmUpKSB7XG5cdFx0XHRjb25zdCBvcHRpb25zTm9ybWFsaXplZCA9IG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMpO1xuXHRcdFx0Y29uc3QgbGluZXMgPSBnZXRBbGlnbmVkRGlmZnMoZGlmZnMsIG9wdGlvbnNOb3JtYWxpemVkLmNoYW5nZUNvbG9yKTtcblx0XHRcdHJldHVybiBwcmludERpZmZMaW5lcyhsaW5lcywgdHJ1bmNhdGVkLCBvcHRpb25zTm9ybWFsaXplZCk7XG5cdFx0fVxuXHR9XG5cdC8vIEZhbGwgYmFjayB0byBsaW5lLWJ5LWxpbmUgZGlmZi5cblx0cmV0dXJuIGRpZmZMaW5lc1VuaWZpZWQoYS5zcGxpdChcIlxcblwiKSwgYi5zcGxpdChcIlxcblwiKSwgb3B0aW9ucyk7XG59XG4vLyBDb21wYXJlIHR3byBzdHJpbmdzIGNoYXJhY3Rlci1ieS1jaGFyYWN0ZXIuXG4vLyBPcHRpb25hbGx5IGNsZWFuIHVwIHNtYWxsIGNvbW1vbiBzdWJzdHJpbmdzLCBhbHNvIGtub3duIGFzIGNoYWZmLlxuZnVuY3Rpb24gZGlmZlN0cmluZ3NSYXcoYSwgYiwgY2xlYW51cCwgb3B0aW9ucykge1xuXHRjb25zdCBbZGlmZnMsIHRydW5jYXRlZF0gPSBkaWZmU3RyaW5ncyhhLCBiLCBvcHRpb25zKTtcblx0aWYgKGNsZWFudXApIHtcblx0XHRkaWZmX2NsZWFudXBTZW1hbnRpYyhkaWZmcyk7XG5cdH1cblx0cmV0dXJuIFtkaWZmcywgdHJ1bmNhdGVkXTtcbn1cblxuZnVuY3Rpb24gZ2V0Q29tbW9uTWVzc2FnZShtZXNzYWdlLCBvcHRpb25zKSB7XG5cdGNvbnN0IHsgY29tbW9uQ29sb3IgfSA9IG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMpO1xuXHRyZXR1cm4gY29tbW9uQ29sb3IobWVzc2FnZSk7XG59XG5jb25zdCB7IEFzeW1tZXRyaWNNYXRjaGVyLCBET01Db2xsZWN0aW9uLCBET01FbGVtZW50LCBJbW11dGFibGUsIFJlYWN0RWxlbWVudCwgUmVhY3RUZXN0Q29tcG9uZW50IH0gPSBwbHVnaW5zO1xuY29uc3QgUExVR0lOUyA9IFtcblx0UmVhY3RUZXN0Q29tcG9uZW50LFxuXHRSZWFjdEVsZW1lbnQsXG5cdERPTUVsZW1lbnQsXG5cdERPTUNvbGxlY3Rpb24sXG5cdEltbXV0YWJsZSxcblx0QXN5bW1ldHJpY01hdGNoZXIsXG5cdHBsdWdpbnMuRXJyb3Jcbl07XG5jb25zdCBGT1JNQVRfT1BUSU9OUyA9IHtcblx0bWF4RGVwdGg6IDIwLFxuXHRwbHVnaW5zOiBQTFVHSU5TXG59O1xuY29uc3QgRkFMTEJBQ0tfRk9STUFUX09QVElPTlMgPSB7XG5cdGNhbGxUb0pTT046IGZhbHNlLFxuXHRtYXhEZXB0aDogOCxcblx0cGx1Z2luczogUExVR0lOU1xufTtcbi8vIEdlbmVyYXRlIGEgc3RyaW5nIHRoYXQgd2lsbCBoaWdobGlnaHQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gdmFsdWVzXG4vLyB3aXRoIGdyZWVuIGFuZCByZWQuIChzaW1pbGFyIHRvIGhvdyBnaXRodWIgZG9lcyBjb2RlIGRpZmZpbmcpXG4vKipcbiogQHBhcmFtIGEgRXhwZWN0ZWQgdmFsdWVcbiogQHBhcmFtIGIgUmVjZWl2ZWQgdmFsdWVcbiogQHBhcmFtIG9wdGlvbnMgRGlmZiBvcHRpb25zXG4qIEByZXR1cm5zIHtzdHJpbmcgfCBudWxsfSBhIHN0cmluZyBkaWZmXG4qL1xuZnVuY3Rpb24gZGlmZihhLCBiLCBvcHRpb25zKSB7XG5cdGlmIChPYmplY3QuaXMoYSwgYikpIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXHRjb25zdCBhVHlwZSA9IGdldFR5cGUoYSk7XG5cdGxldCBleHBlY3RlZFR5cGUgPSBhVHlwZTtcblx0bGV0IG9taXREaWZmZXJlbmNlID0gZmFsc2U7XG5cdGlmIChhVHlwZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgYS5hc3ltbWV0cmljTWF0Y2ggPT09IFwiZnVuY3Rpb25cIikge1xuXHRcdGlmIChhLiQkdHlwZW9mICE9PSBTeW1ib2wuZm9yKFwiamVzdC5hc3ltbWV0cmljTWF0Y2hlclwiKSkge1xuXHRcdFx0Ly8gRG8gbm90IGtub3cgZXhwZWN0ZWQgdHlwZSBvZiB1c2VyLWRlZmluZWQgYXN5bW1ldHJpYyBtYXRjaGVyLlxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBhLmdldEV4cGVjdGVkVHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHQvLyBGb3IgZXhhbXBsZSwgZXhwZWN0LmFueXRoaW5nKCkgbWF0Y2hlcyBlaXRoZXIgbnVsbCBvciB1bmRlZmluZWRcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGV4cGVjdGVkVHlwZSA9IGEuZ2V0RXhwZWN0ZWRUeXBlKCk7XG5cdFx0Ly8gUHJpbWl0aXZlIHR5cGVzIGJvb2xlYW4gYW5kIG51bWJlciBvbWl0IGRpZmZlcmVuY2UgYmVsb3cuXG5cdFx0Ly8gRm9yIGV4YW1wbGUsIG9taXQgZGlmZmVyZW5jZSBmb3IgZXhwZWN0LnN0cmluZ01hdGNoaW5nKHJlZ2V4cClcblx0XHRvbWl0RGlmZmVyZW5jZSA9IGV4cGVjdGVkVHlwZSA9PT0gXCJzdHJpbmdcIjtcblx0fVxuXHRpZiAoZXhwZWN0ZWRUeXBlICE9PSBnZXRUeXBlKGIpKSB7XG5cdFx0Y29uc3QgeyBhQW5ub3RhdGlvbiwgYUNvbG9yLCBhSW5kaWNhdG9yLCBiQW5ub3RhdGlvbiwgYkNvbG9yLCBiSW5kaWNhdG9yIH0gPSBub3JtYWxpemVEaWZmT3B0aW9ucyhvcHRpb25zKTtcblx0XHRjb25zdCBmb3JtYXRPcHRpb25zID0gZ2V0Rm9ybWF0T3B0aW9ucyhGQUxMQkFDS19GT1JNQVRfT1BUSU9OUywgb3B0aW9ucyk7XG5cdFx0bGV0IGFEaXNwbGF5ID0gZm9ybWF0KGEsIGZvcm1hdE9wdGlvbnMpO1xuXHRcdGxldCBiRGlzcGxheSA9IGZvcm1hdChiLCBmb3JtYXRPcHRpb25zKTtcblx0XHQvLyBldmVuIGlmIHByZXR0eUZvcm1hdCBwcmludHMgc3VjY2Vzc2Z1bGx5IGJpZyBvYmplY3RzLFxuXHRcdC8vIGxhcmdlIHN0cmluZyBjYW4gY2hva2UgbGF0ZXIgb24gKGNvbmNhdGVuYXRpb24/IFJQQz8pLFxuXHRcdC8vIHNvIHRydW5jYXRlIGl0IHRvIGEgcmVhc29uYWJsZSBsZW5ndGggaGVyZS5cblx0XHQvLyAoRm9yIGV4YW1wbGUsIHBsYXl3cmlnaHQncyBFbGVtZW50SGFuZGxlIGNhbiBiZWNvbWUgYWJvdXQgMjAwXzAwMF8wMDAgbGVuZ3RoIHN0cmluZylcblx0XHRjb25zdCBNQVhfTEVOR1RIID0gMWU1O1xuXHRcdGZ1bmN0aW9uIHRydW5jYXRlKHMpIHtcblx0XHRcdHJldHVybiBzLmxlbmd0aCA8PSBNQVhfTEVOR1RIID8gcyA6IGAke3Muc2xpY2UoMCwgTUFYX0xFTkdUSCl9Li4uYDtcblx0XHR9XG5cdFx0YURpc3BsYXkgPSB0cnVuY2F0ZShhRGlzcGxheSk7XG5cdFx0YkRpc3BsYXkgPSB0cnVuY2F0ZShiRGlzcGxheSk7XG5cdFx0Y29uc3QgYURpZmYgPSBgJHthQ29sb3IoYCR7YUluZGljYXRvcn0gJHthQW5ub3RhdGlvbn06YCl9XFxuJHthRGlzcGxheX1gO1xuXHRcdGNvbnN0IGJEaWZmID0gYCR7YkNvbG9yKGAke2JJbmRpY2F0b3J9ICR7YkFubm90YXRpb259OmApfVxcbiR7YkRpc3BsYXl9YDtcblx0XHRyZXR1cm4gYCR7YURpZmZ9XFxuXFxuJHtiRGlmZn1gO1xuXHR9XG5cdGlmIChvbWl0RGlmZmVyZW5jZSkge1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0c3dpdGNoIChhVHlwZSkge1xuXHRcdGNhc2UgXCJzdHJpbmdcIjogcmV0dXJuIGRpZmZMaW5lc1VuaWZpZWQoYS5zcGxpdChcIlxcblwiKSwgYi5zcGxpdChcIlxcblwiKSwgb3B0aW9ucyk7XG5cdFx0Y2FzZSBcImJvb2xlYW5cIjpcblx0XHRjYXNlIFwibnVtYmVyXCI6IHJldHVybiBjb21wYXJlUHJpbWl0aXZlKGEsIGIsIG9wdGlvbnMpO1xuXHRcdGNhc2UgXCJtYXBcIjogcmV0dXJuIGNvbXBhcmVPYmplY3RzKHNvcnRNYXAoYSksIHNvcnRNYXAoYiksIG9wdGlvbnMpO1xuXHRcdGNhc2UgXCJzZXRcIjogcmV0dXJuIGNvbXBhcmVPYmplY3RzKHNvcnRTZXQoYSksIHNvcnRTZXQoYiksIG9wdGlvbnMpO1xuXHRcdGRlZmF1bHQ6IHJldHVybiBjb21wYXJlT2JqZWN0cyhhLCBiLCBvcHRpb25zKTtcblx0fVxufVxuZnVuY3Rpb24gY29tcGFyZVByaW1pdGl2ZShhLCBiLCBvcHRpb25zKSB7XG5cdGNvbnN0IGFGb3JtYXQgPSBmb3JtYXQoYSwgRk9STUFUX09QVElPTlMpO1xuXHRjb25zdCBiRm9ybWF0ID0gZm9ybWF0KGIsIEZPUk1BVF9PUFRJT05TKTtcblx0cmV0dXJuIGFGb3JtYXQgPT09IGJGb3JtYXQgPyBcIlwiIDogZGlmZkxpbmVzVW5pZmllZChhRm9ybWF0LnNwbGl0KFwiXFxuXCIpLCBiRm9ybWF0LnNwbGl0KFwiXFxuXCIpLCBvcHRpb25zKTtcbn1cbmZ1bmN0aW9uIHNvcnRNYXAobWFwKSB7XG5cdHJldHVybiBuZXcgTWFwKEFycmF5LmZyb20obWFwLmVudHJpZXMoKSkuc29ydCgpKTtcbn1cbmZ1bmN0aW9uIHNvcnRTZXQoc2V0KSB7XG5cdHJldHVybiBuZXcgU2V0KEFycmF5LmZyb20oc2V0LnZhbHVlcygpKS5zb3J0KCkpO1xufVxuZnVuY3Rpb24gY29tcGFyZU9iamVjdHMoYSwgYiwgb3B0aW9ucykge1xuXHRsZXQgZGlmZmVyZW5jZTtcblx0bGV0IGhhc1Rocm93biA9IGZhbHNlO1xuXHR0cnkge1xuXHRcdGNvbnN0IGZvcm1hdE9wdGlvbnMgPSBnZXRGb3JtYXRPcHRpb25zKEZPUk1BVF9PUFRJT05TLCBvcHRpb25zKTtcblx0XHRkaWZmZXJlbmNlID0gZ2V0T2JqZWN0c0RpZmZlcmVuY2UoYSwgYiwgZm9ybWF0T3B0aW9ucywgb3B0aW9ucyk7XG5cdH0gY2F0Y2gge1xuXHRcdGhhc1Rocm93biA9IHRydWU7XG5cdH1cblx0Y29uc3Qgbm9EaWZmTWVzc2FnZSA9IGdldENvbW1vbk1lc3NhZ2UoTk9fRElGRl9NRVNTQUdFLCBvcHRpb25zKTtcblx0Ly8gSWYgdGhlIGNvbXBhcmlzb24geWllbGRzIG5vIHJlc3VsdHMsIGNvbXBhcmUgYWdhaW4gYnV0IHRoaXMgdGltZVxuXHQvLyB3aXRob3V0IGNhbGxpbmcgYHRvSlNPTmAuIEl0J3MgYWxzbyBwb3NzaWJsZSB0aGF0IHRvSlNPTiBtaWdodCB0aHJvdy5cblx0aWYgKGRpZmZlcmVuY2UgPT09IHVuZGVmaW5lZCB8fCBkaWZmZXJlbmNlID09PSBub0RpZmZNZXNzYWdlKSB7XG5cdFx0Y29uc3QgZm9ybWF0T3B0aW9ucyA9IGdldEZvcm1hdE9wdGlvbnMoRkFMTEJBQ0tfRk9STUFUX09QVElPTlMsIG9wdGlvbnMpO1xuXHRcdGRpZmZlcmVuY2UgPSBnZXRPYmplY3RzRGlmZmVyZW5jZShhLCBiLCBmb3JtYXRPcHRpb25zLCBvcHRpb25zKTtcblx0XHRpZiAoZGlmZmVyZW5jZSAhPT0gbm9EaWZmTWVzc2FnZSAmJiAhaGFzVGhyb3duKSB7XG5cdFx0XHRkaWZmZXJlbmNlID0gYCR7Z2V0Q29tbW9uTWVzc2FnZShTSU1JTEFSX01FU1NBR0UsIG9wdGlvbnMpfVxcblxcbiR7ZGlmZmVyZW5jZX1gO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZGlmZmVyZW5jZTtcbn1cbmZ1bmN0aW9uIGdldEZvcm1hdE9wdGlvbnMoZm9ybWF0T3B0aW9ucywgb3B0aW9ucykge1xuXHRjb25zdCB7IGNvbXBhcmVLZXlzLCBwcmludEJhc2ljUHJvdG90eXBlLCBtYXhEZXB0aCB9ID0gbm9ybWFsaXplRGlmZk9wdGlvbnMob3B0aW9ucyk7XG5cdHJldHVybiB7XG5cdFx0Li4uZm9ybWF0T3B0aW9ucyxcblx0XHRjb21wYXJlS2V5cyxcblx0XHRwcmludEJhc2ljUHJvdG90eXBlLFxuXHRcdG1heERlcHRoOiBtYXhEZXB0aCA/PyBmb3JtYXRPcHRpb25zLm1heERlcHRoXG5cdH07XG59XG5mdW5jdGlvbiBnZXRPYmplY3RzRGlmZmVyZW5jZShhLCBiLCBmb3JtYXRPcHRpb25zLCBvcHRpb25zKSB7XG5cdGNvbnN0IGZvcm1hdE9wdGlvbnNaZXJvSW5kZW50ID0ge1xuXHRcdC4uLmZvcm1hdE9wdGlvbnMsXG5cdFx0aW5kZW50OiAwXG5cdH07XG5cdGNvbnN0IGFDb21wYXJlID0gZm9ybWF0KGEsIGZvcm1hdE9wdGlvbnNaZXJvSW5kZW50KTtcblx0Y29uc3QgYkNvbXBhcmUgPSBmb3JtYXQoYiwgZm9ybWF0T3B0aW9uc1plcm9JbmRlbnQpO1xuXHRpZiAoYUNvbXBhcmUgPT09IGJDb21wYXJlKSB7XG5cdFx0cmV0dXJuIGdldENvbW1vbk1lc3NhZ2UoTk9fRElGRl9NRVNTQUdFLCBvcHRpb25zKTtcblx0fSBlbHNlIHtcblx0XHRjb25zdCBhRGlzcGxheSA9IGZvcm1hdChhLCBmb3JtYXRPcHRpb25zKTtcblx0XHRjb25zdCBiRGlzcGxheSA9IGZvcm1hdChiLCBmb3JtYXRPcHRpb25zKTtcblx0XHRyZXR1cm4gZGlmZkxpbmVzVW5pZmllZDIoYURpc3BsYXkuc3BsaXQoXCJcXG5cIiksIGJEaXNwbGF5LnNwbGl0KFwiXFxuXCIpLCBhQ29tcGFyZS5zcGxpdChcIlxcblwiKSwgYkNvbXBhcmUuc3BsaXQoXCJcXG5cIiksIG9wdGlvbnMpO1xuXHR9XG59XG5jb25zdCBNQVhfRElGRl9TVFJJTkdfTEVOR1RIID0gMmU0O1xuZnVuY3Rpb24gaXNBc3ltbWV0cmljTWF0Y2hlcihkYXRhKSB7XG5cdGNvbnN0IHR5cGUgPSBnZXRUeXBlJDEoZGF0YSk7XG5cdHJldHVybiB0eXBlID09PSBcIk9iamVjdFwiICYmIHR5cGVvZiBkYXRhLmFzeW1tZXRyaWNNYXRjaCA9PT0gXCJmdW5jdGlvblwiO1xufVxuZnVuY3Rpb24gaXNSZXBsYWNlYWJsZShvYmoxLCBvYmoyKSB7XG5cdGNvbnN0IG9iajFUeXBlID0gZ2V0VHlwZSQxKG9iajEpO1xuXHRjb25zdCBvYmoyVHlwZSA9IGdldFR5cGUkMShvYmoyKTtcblx0cmV0dXJuIG9iajFUeXBlID09PSBvYmoyVHlwZSAmJiAob2JqMVR5cGUgPT09IFwiT2JqZWN0XCIgfHwgb2JqMVR5cGUgPT09IFwiQXJyYXlcIik7XG59XG5mdW5jdGlvbiBwcmludERpZmZPclN0cmluZ2lmeShyZWNlaXZlZCwgZXhwZWN0ZWQsIG9wdGlvbnMpIHtcblx0Y29uc3QgeyBhQW5ub3RhdGlvbiwgYkFubm90YXRpb24gfSA9IG5vcm1hbGl6ZURpZmZPcHRpb25zKG9wdGlvbnMpO1xuXHRpZiAodHlwZW9mIGV4cGVjdGVkID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiByZWNlaXZlZCA9PT0gXCJzdHJpbmdcIiAmJiBleHBlY3RlZC5sZW5ndGggPiAwICYmIHJlY2VpdmVkLmxlbmd0aCA+IDAgJiYgZXhwZWN0ZWQubGVuZ3RoIDw9IE1BWF9ESUZGX1NUUklOR19MRU5HVEggJiYgcmVjZWl2ZWQubGVuZ3RoIDw9IE1BWF9ESUZGX1NUUklOR19MRU5HVEggJiYgZXhwZWN0ZWQgIT09IHJlY2VpdmVkKSB7XG5cdFx0aWYgKGV4cGVjdGVkLmluY2x1ZGVzKFwiXFxuXCIpIHx8IHJlY2VpdmVkLmluY2x1ZGVzKFwiXFxuXCIpKSB7XG5cdFx0XHRyZXR1cm4gZGlmZlN0cmluZ3NVbmlmaWVkKGV4cGVjdGVkLCByZWNlaXZlZCwgb3B0aW9ucyk7XG5cdFx0fVxuXHRcdGNvbnN0IFtkaWZmc10gPSBkaWZmU3RyaW5nc1JhdyhleHBlY3RlZCwgcmVjZWl2ZWQsIHRydWUpO1xuXHRcdGNvbnN0IGhhc0NvbW1vbkRpZmYgPSBkaWZmcy5zb21lKChkaWZmKSA9PiBkaWZmWzBdID09PSBESUZGX0VRVUFMKTtcblx0XHRjb25zdCBwcmludExhYmVsID0gZ2V0TGFiZWxQcmludGVyKGFBbm5vdGF0aW9uLCBiQW5ub3RhdGlvbik7XG5cdFx0Y29uc3QgZXhwZWN0ZWRMaW5lID0gcHJpbnRMYWJlbChhQW5ub3RhdGlvbikgKyBwcmludEV4cGVjdGVkKGdldENvbW1vbkFuZENoYW5nZWRTdWJzdHJpbmdzKGRpZmZzLCBESUZGX0RFTEVURSwgaGFzQ29tbW9uRGlmZikpO1xuXHRcdGNvbnN0IHJlY2VpdmVkTGluZSA9IHByaW50TGFiZWwoYkFubm90YXRpb24pICsgcHJpbnRSZWNlaXZlZChnZXRDb21tb25BbmRDaGFuZ2VkU3Vic3RyaW5ncyhkaWZmcywgRElGRl9JTlNFUlQsIGhhc0NvbW1vbkRpZmYpKTtcblx0XHRyZXR1cm4gYCR7ZXhwZWN0ZWRMaW5lfVxcbiR7cmVjZWl2ZWRMaW5lfWA7XG5cdH1cblx0Ly8gaWYgKGlzTGluZURpZmZhYmxlKGV4cGVjdGVkLCByZWNlaXZlZCkpIHtcblx0Y29uc3QgY2xvbmVkRXhwZWN0ZWQgPSBkZWVwQ2xvbmUoZXhwZWN0ZWQsIHsgZm9yY2VXcml0YWJsZTogdHJ1ZSB9KTtcblx0Y29uc3QgY2xvbmVkUmVjZWl2ZWQgPSBkZWVwQ2xvbmUocmVjZWl2ZWQsIHsgZm9yY2VXcml0YWJsZTogdHJ1ZSB9KTtcblx0Y29uc3QgeyByZXBsYWNlZEV4cGVjdGVkLCByZXBsYWNlZEFjdHVhbCB9ID0gcmVwbGFjZUFzeW1tZXRyaWNNYXRjaGVyKGNsb25lZFJlY2VpdmVkLCBjbG9uZWRFeHBlY3RlZCk7XG5cdGNvbnN0IGRpZmZlcmVuY2UgPSBkaWZmKHJlcGxhY2VkRXhwZWN0ZWQsIHJlcGxhY2VkQWN0dWFsLCBvcHRpb25zKTtcblx0cmV0dXJuIGRpZmZlcmVuY2U7XG5cdC8vIH1cblx0Ly8gY29uc3QgcHJpbnRMYWJlbCA9IGdldExhYmVsUHJpbnRlcihhQW5ub3RhdGlvbiwgYkFubm90YXRpb24pXG5cdC8vIGNvbnN0IGV4cGVjdGVkTGluZSA9IHByaW50TGFiZWwoYUFubm90YXRpb24pICsgcHJpbnRFeHBlY3RlZChleHBlY3RlZClcblx0Ly8gY29uc3QgcmVjZWl2ZWRMaW5lXG5cdC8vICAgPSBwcmludExhYmVsKGJBbm5vdGF0aW9uKVxuXHQvLyAgICsgKHN0cmluZ2lmeShleHBlY3RlZCkgPT09IHN0cmluZ2lmeShyZWNlaXZlZClcblx0Ly8gICAgID8gJ3NlcmlhbGl6ZXMgdG8gdGhlIHNhbWUgc3RyaW5nJ1xuXHQvLyAgICAgOiBwcmludFJlY2VpdmVkKHJlY2VpdmVkKSlcblx0Ly8gcmV0dXJuIGAke2V4cGVjdGVkTGluZX1cXG4ke3JlY2VpdmVkTGluZX1gXG59XG5mdW5jdGlvbiByZXBsYWNlQXN5bW1ldHJpY01hdGNoZXIoYWN0dWFsLCBleHBlY3RlZCwgYWN0dWFsUmVwbGFjZWQgPSBuZXcgV2Vha1NldCgpLCBleHBlY3RlZFJlcGxhY2VkID0gbmV3IFdlYWtTZXQoKSkge1xuXHQvLyBoYW5kbGUgYXN5bW1ldHJpYyBFcnJvci5jYXVzZSBkaWZmXG5cdGlmIChhY3R1YWwgaW5zdGFuY2VvZiBFcnJvciAmJiBleHBlY3RlZCBpbnN0YW5jZW9mIEVycm9yICYmIHR5cGVvZiBhY3R1YWwuY2F1c2UgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIGV4cGVjdGVkLmNhdXNlID09PSBcInVuZGVmaW5lZFwiKSB7XG5cdFx0ZGVsZXRlIGFjdHVhbC5jYXVzZTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cmVwbGFjZWRBY3R1YWw6IGFjdHVhbCxcblx0XHRcdHJlcGxhY2VkRXhwZWN0ZWQ6IGV4cGVjdGVkXG5cdFx0fTtcblx0fVxuXHRpZiAoIWlzUmVwbGFjZWFibGUoYWN0dWFsLCBleHBlY3RlZCkpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cmVwbGFjZWRBY3R1YWw6IGFjdHVhbCxcblx0XHRcdHJlcGxhY2VkRXhwZWN0ZWQ6IGV4cGVjdGVkXG5cdFx0fTtcblx0fVxuXHRpZiAoYWN0dWFsUmVwbGFjZWQuaGFzKGFjdHVhbCkgfHwgZXhwZWN0ZWRSZXBsYWNlZC5oYXMoZXhwZWN0ZWQpKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHJlcGxhY2VkQWN0dWFsOiBhY3R1YWwsXG5cdFx0XHRyZXBsYWNlZEV4cGVjdGVkOiBleHBlY3RlZFxuXHRcdH07XG5cdH1cblx0YWN0dWFsUmVwbGFjZWQuYWRkKGFjdHVhbCk7XG5cdGV4cGVjdGVkUmVwbGFjZWQuYWRkKGV4cGVjdGVkKTtcblx0Z2V0T3duUHJvcGVydGllcyhleHBlY3RlZCkuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdFx0Y29uc3QgZXhwZWN0ZWRWYWx1ZSA9IGV4cGVjdGVkW2tleV07XG5cdFx0Y29uc3QgYWN0dWFsVmFsdWUgPSBhY3R1YWxba2V5XTtcblx0XHRpZiAoaXNBc3ltbWV0cmljTWF0Y2hlcihleHBlY3RlZFZhbHVlKSkge1xuXHRcdFx0aWYgKGV4cGVjdGVkVmFsdWUuYXN5bW1ldHJpY01hdGNoKGFjdHVhbFZhbHVlKSkge1xuXHRcdFx0XHQvLyBXaGVuIG1hdGNoZXIgbWF0Y2hlcywgcmVwbGFjZSBleHBlY3RlZCB3aXRoIGFjdHVhbCB2YWx1ZVxuXHRcdFx0XHQvLyBzbyB0aGV5IGFwcGVhciB0aGUgc2FtZSBpbiB0aGUgZGlmZlxuXHRcdFx0XHRleHBlY3RlZFtrZXldID0gYWN0dWFsVmFsdWU7XG5cdFx0XHR9IGVsc2UgaWYgKFwic2FtcGxlXCIgaW4gZXhwZWN0ZWRWYWx1ZSAmJiBleHBlY3RlZFZhbHVlLnNhbXBsZSAhPT0gdW5kZWZpbmVkICYmIGlzUmVwbGFjZWFibGUoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUuc2FtcGxlKSkge1xuXHRcdFx0XHQvLyBGb3IgY29udGFpbmVyIG1hdGNoZXJzIChBcnJheUNvbnRhaW5pbmcsIE9iamVjdENvbnRhaW5pbmcpLCB1bndyYXAgYW5kIHJlY3Vyc2l2ZWx5IHByb2Nlc3Ncblx0XHRcdFx0Ly8gTWF0Y2hlciBkb2Vzbid0IG1hdGNoOiB1bndyYXAgYnV0IGtlZXAgc3RydWN0dXJlIHRvIHNob3cgbWlzbWF0Y2hcblx0XHRcdFx0Y29uc3QgcmVwbGFjZWQgPSByZXBsYWNlQXN5bW1ldHJpY01hdGNoZXIoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUuc2FtcGxlLCBhY3R1YWxSZXBsYWNlZCwgZXhwZWN0ZWRSZXBsYWNlZCk7XG5cdFx0XHRcdGFjdHVhbFtrZXldID0gcmVwbGFjZWQucmVwbGFjZWRBY3R1YWw7XG5cdFx0XHRcdGV4cGVjdGVkW2tleV0gPSByZXBsYWNlZC5yZXBsYWNlZEV4cGVjdGVkO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoaXNBc3ltbWV0cmljTWF0Y2hlcihhY3R1YWxWYWx1ZSkpIHtcblx0XHRcdGlmIChhY3R1YWxWYWx1ZS5hc3ltbWV0cmljTWF0Y2goZXhwZWN0ZWRWYWx1ZSkpIHtcblx0XHRcdFx0YWN0dWFsW2tleV0gPSBleHBlY3RlZFZhbHVlO1xuXHRcdFx0fSBlbHNlIGlmIChcInNhbXBsZVwiIGluIGFjdHVhbFZhbHVlICYmIGFjdHVhbFZhbHVlLnNhbXBsZSAhPT0gdW5kZWZpbmVkICYmIGlzUmVwbGFjZWFibGUoYWN0dWFsVmFsdWUuc2FtcGxlLCBleHBlY3RlZFZhbHVlKSkge1xuXHRcdFx0XHRjb25zdCByZXBsYWNlZCA9IHJlcGxhY2VBc3ltbWV0cmljTWF0Y2hlcihhY3R1YWxWYWx1ZS5zYW1wbGUsIGV4cGVjdGVkVmFsdWUsIGFjdHVhbFJlcGxhY2VkLCBleHBlY3RlZFJlcGxhY2VkKTtcblx0XHRcdFx0YWN0dWFsW2tleV0gPSByZXBsYWNlZC5yZXBsYWNlZEFjdHVhbDtcblx0XHRcdFx0ZXhwZWN0ZWRba2V5XSA9IHJlcGxhY2VkLnJlcGxhY2VkRXhwZWN0ZWQ7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChpc1JlcGxhY2VhYmxlKGFjdHVhbFZhbHVlLCBleHBlY3RlZFZhbHVlKSkge1xuXHRcdFx0Y29uc3QgcmVwbGFjZWQgPSByZXBsYWNlQXN5bW1ldHJpY01hdGNoZXIoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUsIGFjdHVhbFJlcGxhY2VkLCBleHBlY3RlZFJlcGxhY2VkKTtcblx0XHRcdGFjdHVhbFtrZXldID0gcmVwbGFjZWQucmVwbGFjZWRBY3R1YWw7XG5cdFx0XHRleHBlY3RlZFtrZXldID0gcmVwbGFjZWQucmVwbGFjZWRFeHBlY3RlZDtcblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4ge1xuXHRcdHJlcGxhY2VkQWN0dWFsOiBhY3R1YWwsXG5cdFx0cmVwbGFjZWRFeHBlY3RlZDogZXhwZWN0ZWRcblx0fTtcbn1cbmZ1bmN0aW9uIGdldExhYmVsUHJpbnRlciguLi5zdHJpbmdzKSB7XG5cdGNvbnN0IG1heExlbmd0aCA9IHN0cmluZ3MucmVkdWNlKChtYXgsIHN0cmluZykgPT4gc3RyaW5nLmxlbmd0aCA+IG1heCA/IHN0cmluZy5sZW5ndGggOiBtYXgsIDApO1xuXHRyZXR1cm4gKHN0cmluZykgPT4gYCR7c3RyaW5nfTogJHtcIiBcIi5yZXBlYXQobWF4TGVuZ3RoIC0gc3RyaW5nLmxlbmd0aCl9YDtcbn1cbmNvbnN0IFNQQUNFX1NZTUJPTCA9IFwiwrdcIjtcbmZ1bmN0aW9uIHJlcGxhY2VUcmFpbGluZ1NwYWNlcyh0ZXh0KSB7XG5cdHJldHVybiB0ZXh0LnJlcGxhY2UoL1xccyskL2dtLCAoc3BhY2VzKSA9PiBTUEFDRV9TWU1CT0wucmVwZWF0KHNwYWNlcy5sZW5ndGgpKTtcbn1cbmZ1bmN0aW9uIHByaW50UmVjZWl2ZWQob2JqZWN0KSB7XG5cdHJldHVybiBjLnJlZChyZXBsYWNlVHJhaWxpbmdTcGFjZXMoc3RyaW5naWZ5KG9iamVjdCkpKTtcbn1cbmZ1bmN0aW9uIHByaW50RXhwZWN0ZWQodmFsdWUpIHtcblx0cmV0dXJuIGMuZ3JlZW4ocmVwbGFjZVRyYWlsaW5nU3BhY2VzKHN0cmluZ2lmeSh2YWx1ZSkpKTtcbn1cbmZ1bmN0aW9uIGdldENvbW1vbkFuZENoYW5nZWRTdWJzdHJpbmdzKGRpZmZzLCBvcCwgaGFzQ29tbW9uRGlmZikge1xuXHRyZXR1cm4gZGlmZnMucmVkdWNlKChyZWR1Y2VkLCBkaWZmKSA9PiByZWR1Y2VkICsgKGRpZmZbMF0gPT09IERJRkZfRVFVQUwgPyBkaWZmWzFdIDogZGlmZlswXSA9PT0gb3AgPyBoYXNDb21tb25EaWZmID8gYy5pbnZlcnNlKGRpZmZbMV0pIDogZGlmZlsxXSA6IFwiXCIpLCBcIlwiKTtcbn1cblxuZXhwb3J0IHsgRElGRl9ERUxFVEUsIERJRkZfRVFVQUwsIERJRkZfSU5TRVJULCBEaWZmLCBkaWZmLCBkaWZmTGluZXNSYXcsIGRpZmZMaW5lc1VuaWZpZWQsIGRpZmZMaW5lc1VuaWZpZWQyLCBkaWZmU3RyaW5nc1JhdywgZGlmZlN0cmluZ3NVbmlmaWVkLCBnZXRMYWJlbFByaW50ZXIsIHByaW50RGlmZk9yU3RyaW5naWZ5LCBy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