@cartanova/qgrid-cli 1.0.4 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/bundle/dist/application/qgrid/pool.js +15 -6
  2. package/bundle/dist/application/qgrid/qgrid.frame.js +17 -22
  3. package/bundle/dist/application/qgrid/qgrid.types.js +5 -2
  4. package/bundle/dist/application/request-log/request-log.model.js +2 -2
  5. package/bundle/dist/sonamu.config.js +5 -2
  6. package/bundle/src/application/qgrid/pool.ts +17 -7
  7. package/bundle/src/application/qgrid/qgrid.frame.ts +18 -25
  8. package/bundle/src/application/qgrid/qgrid.types.ts +1 -1
  9. package/bundle/src/application/request-log/request-log.model.ts +2 -2
  10. package/bundle/src/sonamu.config.ts +1 -1
  11. package/bundle/web-dist/{web-dist/client/assets/index-DlPchHBY.js → client/assets/index-C0m8rRjO.js} +2 -2
  12. package/bundle/web-dist/client/assets/{routes-CagDz23B.js → routes-B1eOXnpo.js} +1 -1
  13. package/bundle/web-dist/client/assets/{show-aXUGa0gm.js → show-BztN6MXO.js} +1 -1
  14. package/bundle/web-dist/client/assets/tokens-rR2_-Pte.js +1 -0
  15. package/bundle/web-dist/client/index.html +1 -1
  16. package/bundle/web-dist/server/assets/{tokens-JH6FsnWZ.js → tokens-ARL5AOAh.js} +4 -1
  17. package/bundle/web-dist/server/entry-server.generated.js +1 -1
  18. package/dist/cli.js +38 -24
  19. package/package.json +10 -10
  20. package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +0 -9
  21. package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +0 -6
  22. package/bundle/dist/dist/_virtual/_rolldown/runtime.js +0 -15
  23. package/bundle/dist/dist/application/qgrid/oauth.js +0 -140
  24. package/bundle/dist/dist/application/qgrid/pool.js +0 -100
  25. package/bundle/dist/dist/application/qgrid/qgrid.frame.js +0 -280
  26. package/bundle/dist/dist/application/qgrid/qgrid.types.js +0 -79
  27. package/bundle/dist/dist/application/qgrid/worker.js +0 -183
  28. package/bundle/dist/dist/application/queries.generated.js +0 -31
  29. package/bundle/dist/dist/application/request-log/request-log.model.js +0 -113
  30. package/bundle/dist/dist/application/request-log/request-log.types.js +0 -13
  31. package/bundle/dist/dist/application/sonamu.generated.js +0 -99
  32. package/bundle/dist/dist/application/sonamu.generated.sso.js +0 -34
  33. package/bundle/dist/dist/application/token/token.model.js +0 -157
  34. package/bundle/dist/dist/application/token/token.types.js +0 -22
  35. package/bundle/dist/dist/i18n/en.js +0 -63
  36. package/bundle/dist/dist/i18n/ko.js +0 -62
  37. package/bundle/dist/dist/i18n/sd.generated.js +0 -272
  38. package/bundle/dist/dist/index.js +0 -11
  39. package/bundle/dist/dist/migrations/20260410171405_create__request_logs.js +0 -26
  40. package/bundle/dist/dist/migrations/20260410171406_create__tokens.js +0 -24
  41. package/bundle/dist/dist/migrations/20260411120624_alter_tokens_alter2.js +0 -16
  42. package/bundle/dist/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -155
  43. package/bundle/dist/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +0 -1484
  44. package/bundle/dist/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  45. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2746
  46. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +0 -8
  47. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +0 -8
  48. package/bundle/dist/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +0 -662
  49. package/bundle/dist/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +0 -386
  50. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -82
  51. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +0 -48
  52. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +0 -1307
  53. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +0 -558
  54. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +0 -33
  55. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +0 -226
  56. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +0 -27
  57. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +0 -77
  58. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +0 -374
  59. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +0 -37
  60. package/bundle/dist/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2886
  61. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  62. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  63. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  64. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  65. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  66. package/bundle/dist/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1127
  67. package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  68. package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  69. package/bundle/dist/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -506
  70. package/bundle/dist/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -86
  71. 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 +0 -426
  72. 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 +0 -6
  73. 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 +0 -41
  74. 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 +0 -19
  75. 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 +0 -202
  76. 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 +0 -16
  77. 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 +0 -59
  78. 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 +0 -2910
  79. 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 +0 -44
  80. 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 +0 -28
  81. package/bundle/dist/dist/sonamu.config.js +0 -196
  82. package/bundle/dist/dist/testing/fixture.js +0 -8
  83. package/bundle/dist/dist/testing/global.js +0 -9
  84. package/bundle/dist/dist/testing/setup-mocks.js +0 -17
  85. package/bundle/dist/dist/utils/subset-loaders.js +0 -12
  86. package/bundle/src/src/application/qgrid/oauth.ts +0 -181
  87. package/bundle/src/src/application/qgrid/pool.ts +0 -132
  88. package/bundle/src/src/application/qgrid/qgrid.frame.ts +0 -275
  89. package/bundle/src/src/application/qgrid/qgrid.types.ts +0 -117
  90. package/bundle/src/src/application/qgrid/worker.ts +0 -234
  91. package/bundle/src/src/application/queries.generated.ts +0 -59
  92. package/bundle/src/src/application/request-log/request-log.entity.json +0 -75
  93. package/bundle/src/src/application/request-log/request-log.model.ts +0 -155
  94. package/bundle/src/src/application/request-log/request-log.types.ts +0 -15
  95. package/bundle/src/src/application/sonamu.generated.http +0 -187
  96. package/bundle/src/src/application/sonamu.generated.sso.ts +0 -66
  97. package/bundle/src/src/application/sonamu.generated.ts +0 -135
  98. package/bundle/src/src/application/token/token.entity.json +0 -37
  99. package/bundle/src/src/application/token/token.model.ts +0 -160
  100. package/bundle/src/src/application/token/token.types.ts +0 -26
  101. package/bundle/src/src/i18n/en.ts +0 -59
  102. package/bundle/src/src/i18n/ko.ts +0 -59
  103. package/bundle/src/src/i18n/sd.generated.ts +0 -384
  104. package/bundle/src/src/index.ts +0 -6
  105. package/bundle/src/src/migrations/20260410171405_create__request_logs.ts +0 -23
  106. package/bundle/src/src/migrations/20260410171406_create__tokens.ts +0 -21
  107. package/bundle/src/src/migrations/20260411120624_alter_tokens_alter2.ts +0 -15
  108. package/bundle/src/src/sonamu.config.ts +0 -248
  109. package/bundle/src/src/testing/fixture.ts +0 -6
  110. package/bundle/src/src/testing/global.ts +0 -6
  111. package/bundle/src/src/testing/setup-mocks.ts +0 -44
  112. package/bundle/src/src/typings/fastify.d.ts +0 -8
  113. package/bundle/src/src/typings/sonamu.d.ts +0 -17
  114. package/bundle/src/src/utils/subset-loaders.ts +0 -11
  115. package/bundle/web-dist/client/assets/index-DlPchHBY.js +0 -116
  116. package/bundle/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
  117. package/bundle/web-dist/web-dist/client/assets/index-vZsvyuFn.css +0 -1
  118. package/bundle/web-dist/web-dist/client/assets/rolldown-runtime-Dw2cE7zH.js +0 -1
  119. package/bundle/web-dist/web-dist/client/assets/routes-CagDz23B.js +0 -1
  120. package/bundle/web-dist/web-dist/client/assets/sd.generated-BrQoQXvv.js +0 -47
  121. package/bundle/web-dist/web-dist/client/assets/services.generated-BspO2L0j.js +0 -1
  122. package/bundle/web-dist/web-dist/client/assets/show-aXUGa0gm.js +0 -29
  123. package/bundle/web-dist/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
  124. package/bundle/web-dist/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
  125. package/bundle/web-dist/web-dist/client/assets/vendor-tanstack-CUxlo6YN.js +0 -1
  126. package/bundle/web-dist/web-dist/client/index.html +0 -18
  127. package/bundle/web-dist/web-dist/server/assets/react-dom-CGIzOSuj.js +0 -335
  128. package/bundle/web-dist/web-dist/server/assets/routes-ClzReRep.js +0 -490
  129. package/bundle/web-dist/web-dist/server/assets/sd.generated-BnonqqKr.js +0 -21694
  130. package/bundle/web-dist/web-dist/server/assets/services.generated-D5ABD5fr.js +0 -836
  131. package/bundle/web-dist/web-dist/server/assets/show-C9pcdSxc.js +0 -23364
  132. package/bundle/web-dist/web-dist/server/assets/tokens-JH6FsnWZ.js +0 -860
  133. package/bundle/web-dist/web-dist/server/entry-server.generated.js +0 -44646
@@ -1,1307 +0,0 @@
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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