oxygen-cli 1.22.0 → 1.99.0-alpha.0

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 (232) hide show
  1. package/CHANGELOG.md +0 -50
  2. package/build/core/OxygenCore.js +56 -145
  3. package/build/errors/OxygenError.js +5 -15
  4. package/build/errors/helper.js +45 -49
  5. package/build/index.js +14 -6
  6. package/build/lib/cli-util.js +19 -19
  7. package/build/lib/cli.js +4 -2
  8. package/build/lib/parallel-launcher.js +333 -0
  9. package/build/lib/param-manager.js +66 -47
  10. package/build/lib/util.js +38 -9
  11. package/build/ox_modules/index.js +1 -97
  12. package/build/ox_modules/module-assert.js +19 -9
  13. package/build/ox_modules/module-dns.js +220 -0
  14. package/build/ox_modules/module-http.js +39 -51
  15. package/build/ox_modules/module-shell.js +19 -75
  16. package/build/ox_modules/module-utils.js +1 -108
  17. package/build/ox_modules/utils.js +1 -357
  18. package/build/reporter/FileReporterBase.js +5 -5
  19. package/build/reporter/ReportAggregator.js +127 -4
  20. package/build/runners/WorkerProcess.js +15 -28
  21. package/build/runners/index.js +2 -6
  22. package/build/runners/oxygen/OxygenWorker.js +8 -8
  23. package/build/runners/oxygen/index.js +17 -18
  24. package/build/runners/oxygen/worker.js +10 -8
  25. package/package.json +12 -46
  26. package/build/lib/img-merge.js +0 -163
  27. package/build/ox_modules/module-db.js +0 -146
  28. package/build/ox_modules/module-email.js +0 -212
  29. package/build/ox_modules/module-eyes.js +0 -189
  30. package/build/ox_modules/module-mailinator.js +0 -207
  31. package/build/ox_modules/module-mob/commands/alertAccept.js +0 -35
  32. package/build/ox_modules/module-mob/commands/alertDismiss.js +0 -35
  33. package/build/ox_modules/module-mob/commands/assertAlert.js +0 -56
  34. package/build/ox_modules/module-mob/commands/assertText.js +0 -45
  35. package/build/ox_modules/module-mob/commands/assertTitle.js +0 -43
  36. package/build/ox_modules/module-mob/commands/assertValue.js +0 -66
  37. package/build/ox_modules/module-mob/commands/back.js +0 -27
  38. package/build/ox_modules/module-mob/commands/clear.js +0 -40
  39. package/build/ox_modules/module-mob/commands/click.js +0 -35
  40. package/build/ox_modules/module-mob/commands/clickHidden.js +0 -52
  41. package/build/ox_modules/module-mob/commands/clickLong.js +0 -34
  42. package/build/ox_modules/module-mob/commands/clickMultipleTimes.js +0 -37
  43. package/build/ox_modules/module-mob/commands/closeApp.js +0 -27
  44. package/build/ox_modules/module-mob/commands/debug.js +0 -26
  45. package/build/ox_modules/module-mob/commands/dragAndDrop.js +0 -38
  46. package/build/ox_modules/module-mob/commands/enableNetwork.js +0 -75
  47. package/build/ox_modules/module-mob/commands/execute.js +0 -32
  48. package/build/ox_modules/module-mob/commands/findElement.js +0 -36
  49. package/build/ox_modules/module-mob/commands/findElements.js +0 -39
  50. package/build/ox_modules/module-mob/commands/getAlertText.js +0 -31
  51. package/build/ox_modules/module-mob/commands/getAppiumLogs.js +0 -26
  52. package/build/ox_modules/module-mob/commands/getBrowserLogs.js +0 -66
  53. package/build/ox_modules/module-mob/commands/getCurrentActivity.js +0 -26
  54. package/build/ox_modules/module-mob/commands/getCurrentPackage.js +0 -26
  55. package/build/ox_modules/module-mob/commands/getDeviceLogs.js +0 -57
  56. package/build/ox_modules/module-mob/commands/getDeviceTime.js +0 -27
  57. package/build/ox_modules/module-mob/commands/getLocation.js +0 -32
  58. package/build/ox_modules/module-mob/commands/getSource.js +0 -26
  59. package/build/ox_modules/module-mob/commands/getText.js +0 -36
  60. package/build/ox_modules/module-mob/commands/getTitle.js +0 -24
  61. package/build/ox_modules/module-mob/commands/getUrl.js +0 -28
  62. package/build/ox_modules/module-mob/commands/getValue.js +0 -50
  63. package/build/ox_modules/module-mob/commands/getWindowHandles.js +0 -27
  64. package/build/ox_modules/module-mob/commands/hideKeyboard.js +0 -33
  65. package/build/ox_modules/module-mob/commands/index.js +0 -594
  66. package/build/ox_modules/module-mob/commands/installApp.js +0 -28
  67. package/build/ox_modules/module-mob/commands/isAppInstalled.js +0 -28
  68. package/build/ox_modules/module-mob/commands/isCheckable.js +0 -31
  69. package/build/ox_modules/module-mob/commands/isChecked.js +0 -31
  70. package/build/ox_modules/module-mob/commands/isClickable.js +0 -31
  71. package/build/ox_modules/module-mob/commands/isExist.js +0 -36
  72. package/build/ox_modules/module-mob/commands/isSelected.js +0 -36
  73. package/build/ox_modules/module-mob/commands/isVisible.js +0 -36
  74. package/build/ox_modules/module-mob/commands/isWebViewContext.js +0 -27
  75. package/build/ox_modules/module-mob/commands/launchApp.js +0 -26
  76. package/build/ox_modules/module-mob/commands/longPressKeyCode.js +0 -30
  77. package/build/ox_modules/module-mob/commands/open.js +0 -43
  78. package/build/ox_modules/module-mob/commands/pause.js +0 -27
  79. package/build/ox_modules/module-mob/commands/removeApp.js +0 -28
  80. package/build/ox_modules/module-mob/commands/resetApp.js +0 -26
  81. package/build/ox_modules/module-mob/commands/scrollIntoElement.js +0 -86
  82. package/build/ox_modules/module-mob/commands/scrollIntoView.js +0 -40
  83. package/build/ox_modules/module-mob/commands/select.js +0 -54
  84. package/build/ox_modules/module-mob/commands/selectFrame.js +0 -53
  85. package/build/ox_modules/module-mob/commands/selectWindow.js +0 -149
  86. package/build/ox_modules/module-mob/commands/sendKeys.js +0 -84
  87. package/build/ox_modules/module-mob/commands/setContext.js +0 -28
  88. package/build/ox_modules/module-mob/commands/setNativeContext.js +0 -26
  89. package/build/ox_modules/module-mob/commands/setTimeout.js +0 -33
  90. package/build/ox_modules/module-mob/commands/setWebViewContext.js +0 -39
  91. package/build/ox_modules/module-mob/commands/shake.js +0 -27
  92. package/build/ox_modules/module-mob/commands/smsClickLink.js +0 -32
  93. package/build/ox_modules/module-mob/commands/smsGetText.js +0 -45
  94. package/build/ox_modules/module-mob/commands/swipe.js +0 -58
  95. package/build/ox_modules/module-mob/commands/swipeElement.js +0 -58
  96. package/build/ox_modules/module-mob/commands/swipeScreen.js +0 -56
  97. package/build/ox_modules/module-mob/commands/takeScreenshot.js +0 -27
  98. package/build/ox_modules/module-mob/commands/tap.js +0 -34
  99. package/build/ox_modules/module-mob/commands/type.js +0 -67
  100. package/build/ox_modules/module-mob/commands/unlockPattern.js +0 -92
  101. package/build/ox_modules/module-mob/commands/waitForExist.js +0 -29
  102. package/build/ox_modules/module-mob/commands/waitForInteractable.js +0 -42
  103. package/build/ox_modules/module-mob/commands/waitForVisible.js +0 -28
  104. package/build/ox_modules/module-mob.js +0 -699
  105. package/build/ox_modules/module-pdf.js +0 -328
  106. package/build/ox_modules/module-proxy.js +0 -324
  107. package/build/ox_modules/module-serial.js +0 -187
  108. package/build/ox_modules/module-soap.js +0 -260
  109. package/build/ox_modules/module-twilio.js +0 -192
  110. package/build/ox_modules/module-web/commands/alertAccept.js +0 -35
  111. package/build/ox_modules/module-web/commands/alertDismiss.js +0 -35
  112. package/build/ox_modules/module-web/commands/assertAlert.js +0 -55
  113. package/build/ox_modules/module-web/commands/assertExist.js +0 -28
  114. package/build/ox_modules/module-web/commands/assertSelectedLabel.js +0 -51
  115. package/build/ox_modules/module-web/commands/assertSelectedValue.js +0 -45
  116. package/build/ox_modules/module-web/commands/assertText.js +0 -45
  117. package/build/ox_modules/module-web/commands/assertTextNotPresent.js +0 -56
  118. package/build/ox_modules/module-web/commands/assertTextPresent.js +0 -52
  119. package/build/ox_modules/module-web/commands/assertTitle.js +0 -42
  120. package/build/ox_modules/module-web/commands/assertValue.js +0 -44
  121. package/build/ox_modules/module-web/commands/back.js +0 -27
  122. package/build/ox_modules/module-web/commands/clear.js +0 -41
  123. package/build/ox_modules/module-web/commands/click.js +0 -112
  124. package/build/ox_modules/module-web/commands/clickHidden.js +0 -79
  125. package/build/ox_modules/module-web/commands/closeWindow.js +0 -25
  126. package/build/ox_modules/module-web/commands/debug.js +0 -25
  127. package/build/ox_modules/module-web/commands/deleteCookies.js +0 -22
  128. package/build/ox_modules/module-web/commands/deselect.js +0 -34
  129. package/build/ox_modules/module-web/commands/doubleClick.js +0 -65
  130. package/build/ox_modules/module-web/commands/dragAndDrop.js +0 -36
  131. package/build/ox_modules/module-web/commands/execute.js +0 -36
  132. package/build/ox_modules/module-web/commands/fileBrowse.js +0 -72
  133. package/build/ox_modules/module-web/commands/findElement.js +0 -35
  134. package/build/ox_modules/module-web/commands/findElements.js +0 -38
  135. package/build/ox_modules/module-web/commands/fullscreenWindow.js +0 -24
  136. package/build/ox_modules/module-web/commands/getAlertText.js +0 -30
  137. package/build/ox_modules/module-web/commands/getAttribute.js +0 -38
  138. package/build/ox_modules/module-web/commands/getBrowserLogs.js +0 -34
  139. package/build/ox_modules/module-web/commands/getCookies.js +0 -23
  140. package/build/ox_modules/module-web/commands/getCssValue.js +0 -38
  141. package/build/ox_modules/module-web/commands/getElementCount.js +0 -29
  142. package/build/ox_modules/module-web/commands/getHTML.js +0 -30
  143. package/build/ox_modules/module-web/commands/getSource.js +0 -26
  144. package/build/ox_modules/module-web/commands/getText.js +0 -36
  145. package/build/ox_modules/module-web/commands/getTitle.js +0 -22
  146. package/build/ox_modules/module-web/commands/getUrl.js +0 -26
  147. package/build/ox_modules/module-web/commands/getValue.js +0 -43
  148. package/build/ox_modules/module-web/commands/getWindowHandles.js +0 -26
  149. package/build/ox_modules/module-web/commands/getWindowSize.js +0 -26
  150. package/build/ox_modules/module-web/commands/getXMLPageSource.js +0 -51
  151. package/build/ox_modules/module-web/commands/index.js +0 -634
  152. package/build/ox_modules/module-web/commands/isAlertPresent.js +0 -31
  153. package/build/ox_modules/module-web/commands/isChecked.js +0 -30
  154. package/build/ox_modules/module-web/commands/isExist.js +0 -36
  155. package/build/ox_modules/module-web/commands/isSelected.js +0 -35
  156. package/build/ox_modules/module-web/commands/isVisible.js +0 -36
  157. package/build/ox_modules/module-web/commands/makeVisible.js +0 -74
  158. package/build/ox_modules/module-web/commands/maximizeWindow.js +0 -24
  159. package/build/ox_modules/module-web/commands/minimizeWindow.js +0 -24
  160. package/build/ox_modules/module-web/commands/newWindow.js +0 -27
  161. package/build/ox_modules/module-web/commands/open.js +0 -42
  162. package/build/ox_modules/module-web/commands/pause.js +0 -26
  163. package/build/ox_modules/module-web/commands/point.js +0 -37
  164. package/build/ox_modules/module-web/commands/pointJS.js +0 -56
  165. package/build/ox_modules/module-web/commands/refresh.js +0 -26
  166. package/build/ox_modules/module-web/commands/rightClick.js +0 -61
  167. package/build/ox_modules/module-web/commands/rightClickActions.js +0 -57
  168. package/build/ox_modules/module-web/commands/scrollToElement.js +0 -33
  169. package/build/ox_modules/module-web/commands/select.js +0 -55
  170. package/build/ox_modules/module-web/commands/selectFrame.js +0 -52
  171. package/build/ox_modules/module-web/commands/selectWindow.js +0 -148
  172. package/build/ox_modules/module-web/commands/sendKeys.js +0 -56
  173. package/build/ox_modules/module-web/commands/setAutoWaitForAngular.js +0 -33
  174. package/build/ox_modules/module-web/commands/setTimeout.js +0 -33
  175. package/build/ox_modules/module-web/commands/setWindowSize.js +0 -29
  176. package/build/ox_modules/module-web/commands/takeScreenshot.js +0 -37
  177. package/build/ox_modules/module-web/commands/type.js +0 -52
  178. package/build/ox_modules/module-web/commands/waitForAngular.js +0 -83
  179. package/build/ox_modules/module-web/commands/waitForExist.js +0 -28
  180. package/build/ox_modules/module-web/commands/waitForInteractable.js +0 -31
  181. package/build/ox_modules/module-web/commands/waitForNotExist.js +0 -57
  182. package/build/ox_modules/module-web/commands/waitForNotText.js +0 -45
  183. package/build/ox_modules/module-web/commands/waitForNotValue.js +0 -45
  184. package/build/ox_modules/module-web/commands/waitForText.js +0 -45
  185. package/build/ox_modules/module-web/commands/waitForValue.js +0 -45
  186. package/build/ox_modules/module-web/commands/waitForVisible.js +0 -28
  187. package/build/ox_modules/module-web/commands/waitForWindow.js +0 -118
  188. package/build/ox_modules/module-web.js +0 -909
  189. package/build/ox_modules/module-win/commands/assertText.js +0 -41
  190. package/build/ox_modules/module-win/commands/assertTitle.js +0 -38
  191. package/build/ox_modules/module-win/commands/assertValue.js +0 -62
  192. package/build/ox_modules/module-win/commands/back.js +0 -21
  193. package/build/ox_modules/module-win/commands/clear.js +0 -34
  194. package/build/ox_modules/module-win/commands/click.js +0 -25
  195. package/build/ox_modules/module-win/commands/clickLong.js +0 -30
  196. package/build/ox_modules/module-win/commands/clickMultipleTimes.js +0 -33
  197. package/build/ox_modules/module-win/commands/findElement.js +0 -31
  198. package/build/ox_modules/module-win/commands/findElements.js +0 -31
  199. package/build/ox_modules/module-win/commands/getAppiumLogs.js +0 -22
  200. package/build/ox_modules/module-win/commands/getCurrentWindowHandle.js +0 -25
  201. package/build/ox_modules/module-win/commands/getLocation.js +0 -26
  202. package/build/ox_modules/module-win/commands/getSource.js +0 -22
  203. package/build/ox_modules/module-win/commands/getText.js +0 -32
  204. package/build/ox_modules/module-win/commands/getValue.js +0 -46
  205. package/build/ox_modules/module-win/commands/getWindowHandles.js +0 -25
  206. package/build/ox_modules/module-win/commands/index.js +0 -298
  207. package/build/ox_modules/module-win/commands/isCheckable.js +0 -26
  208. package/build/ox_modules/module-win/commands/isChecked.js +0 -26
  209. package/build/ox_modules/module-win/commands/isClickable.js +0 -26
  210. package/build/ox_modules/module-win/commands/isExist.js +0 -32
  211. package/build/ox_modules/module-win/commands/isSelected.js +0 -26
  212. package/build/ox_modules/module-win/commands/isVisible.js +0 -32
  213. package/build/ox_modules/module-win/commands/open.js +0 -24
  214. package/build/ox_modules/module-win/commands/pause.js +0 -23
  215. package/build/ox_modules/module-win/commands/rightClick.js +0 -30
  216. package/build/ox_modules/module-win/commands/selectWindow.js +0 -97
  217. package/build/ox_modules/module-win/commands/sendKeys.js +0 -50
  218. package/build/ox_modules/module-win/commands/setTimeout.js +0 -29
  219. package/build/ox_modules/module-win/commands/takeScreenshot.js +0 -26
  220. package/build/ox_modules/module-win/commands/tap.js +0 -29
  221. package/build/ox_modules/module-win/commands/type.js +0 -38
  222. package/build/ox_modules/module-win/commands/waitForExist.js +0 -25
  223. package/build/ox_modules/module-win/commands/waitForInteractable.js +0 -43
  224. package/build/ox_modules/module-win/commands/waitForVisible.js +0 -24
  225. package/build/ox_modules/module-win.js +0 -367
  226. package/build/ox_services/service-devtools/submodule-network.js +0 -338
  227. package/build/ox_services/service-devtools.js +0 -83
  228. package/build/runners/cucumber/CucumberEventListener.js +0 -181
  229. package/build/runners/cucumber/CucumberReporter.js +0 -277
  230. package/build/runners/cucumber/CucumberWorker.js +0 -337
  231. package/build/runners/cucumber/index.js +0 -159
  232. package/build/runners/cucumber/worker.js +0 -184
@@ -1,328 +0,0 @@
1
- "use strict";
2
-
3
- require("source-map-support/register");
4
-
5
- var _OxygenError = _interopRequireDefault(require("../errors/OxygenError"));
6
-
7
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
-
9
- /*
10
- * Copyright (C) 2019-present CloudBeat Limited
11
- *
12
- * This program is free software: you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation, either version 3 of the License, or
15
- * (at your option) any later version.
16
- */
17
-
18
- /**
19
- * @name pdf
20
- * @description Provides generic methods for working with PDF files.
21
- */
22
- const errHelper = require('../errors/helper');
23
-
24
- const path = require('path');
25
-
26
- var PDFParser = require('pdf2json/pdfparser');
27
-
28
- function countRows(searchStr, rows, reverse) {
29
- let result = 0;
30
- var strRegex = new RegExp(searchStr, 'g');
31
- var reverseStrRegex = reverse ? new RegExp(searchStr.split('').reverse().join(''), 'g') : null;
32
- Object.keys(rows) // => array of y-positions (type: float)
33
- .sort((y1, y2) => parseFloat(y1) - parseFloat(y2)) // sort float positions
34
- .some(y => {
35
- var line = (rows[y] || []).join('').replace(/\s/g, '');
36
- var count = (line.match(strRegex) || []).length;
37
-
38
- if (count === 0 && reverseStrRegex) {
39
- count = (line.match(reverseStrRegex) || []).length;
40
- }
41
-
42
- result += count;
43
- });
44
- return result;
45
- }
46
-
47
- function checkRows(searchStr, rows, reverse) {
48
- let result = false;
49
- Object.keys(rows) // => array of y-positions (type: float)
50
- .sort((y1, y2) => parseFloat(y1) - parseFloat(y2)) // sort float positions
51
- .some(y => {
52
- var line = (rows[y] || []).join('').replace(/\s/g, '');
53
- let inludes;
54
-
55
- if (reverse) {
56
- const reverseSearchStr = searchStr.split('').reverse().join('');
57
- inludes = line.includes(searchStr) || line.includes(reverseSearchStr);
58
- } else {
59
- inludes = line.includes(searchStr);
60
- }
61
-
62
- if (inludes) {
63
- result = true;
64
- return true;
65
- }
66
- });
67
- return result;
68
- }
69
-
70
- function assertion(pdfFilePath, text, pageNum = 0, reverse = false) {
71
- let rows = {}; // indexed by y-position
72
-
73
- return new Promise(function (resolve, reject) {
74
- const searchStr = text.replace(/\s/g, '');
75
- let pdfParser = new PDFParser();
76
- pdfParser.on('pdfParser_dataError', function (err) {
77
- let errorMessage = err.parserError ? err.parserError : 'Error parsing the PDF.';
78
- throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, errorMessage);
79
- });
80
- pdfParser.on('pdfParser_dataReady', function (pdfData) {
81
- var totalPages = pdfData.formImage.Pages.length;
82
-
83
- if (pageNum && totalPages < pageNum - 1) {
84
- throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, `Invalid argument - 'pageNum' is ${pageNum}, but PDF contains only ${totalPages} pages`);
85
- } // locate on a specific page
86
-
87
-
88
- if (pageNum) {
89
- processText(rows, pdfData.formImage.Pages[pageNum - 1].Texts);
90
- let isFound = checkRows(searchStr, rows, reverse);
91
- resolve(!!isFound);
92
- return;
93
- } // locate on any page
94
-
95
-
96
- for (let p in pdfData.formImage.Pages) {
97
- processText(rows, pdfData.formImage.Pages[p].Texts);
98
- let isFound = checkRows(searchStr, rows, reverse);
99
-
100
- if (isFound) {
101
- resolve(true);
102
- break;
103
- }
104
-
105
- rows = {}; // clear rows for next page
106
- }
107
-
108
- resolve(false);
109
- });
110
- pdfParser.loadPDF(pdfFilePath, 0);
111
- });
112
- }
113
-
114
- function processText(rows, texts) {
115
- for (var t in texts) {
116
- var item = texts[t];
117
- var text = decodeURIComponent(item.R[0].T); // accumulate text items into rows object, per line
118
-
119
- (rows[item.y] = rows[item.y] || []).push(text);
120
- }
121
- }
122
-
123
- function count(pdfFilePath, text, pageNum = 0, reverse = false) {
124
- let rows = {}; // indexed by y-position
125
-
126
- let totalCount = 0;
127
- return new Promise(function (resolve, reject) {
128
- const searchStr = text.replace(/\s/g, '');
129
- let pdfParser = new PDFParser();
130
- pdfParser.on('pdfParser_dataError', function (err) {
131
- let errorMessage = err.parserError ? err.parserError : 'Error parsing the PDF.';
132
- throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, errorMessage);
133
- });
134
- pdfParser.on('pdfParser_dataReady', function (pdfData) {
135
- let totalPages = pdfData.formImage.Pages.length;
136
-
137
- if (pageNum && totalPages < pageNum - 1) {
138
- throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, `Invalid argument - 'pageNum' is ${pageNum}, but PDF contains only ${totalPages} pages`);
139
- } // count on a specific page
140
-
141
-
142
- if (pageNum) {
143
- processText(rows, pdfData.formImage.Pages[pageNum - 1].Texts);
144
- let count = countRows(searchStr, rows, reverse);
145
- resolve(count);
146
- return;
147
- } // count on all pages
148
-
149
-
150
- for (var p in pdfData.formImage.Pages) {
151
- processText(rows, pdfData.formImage.Pages[p].Texts);
152
- let count = countRows(searchStr, rows, reverse);
153
-
154
- if (count > 0) {
155
- totalCount += count;
156
- }
157
-
158
- rows = {}; // clear rows for next page
159
- }
160
-
161
- resolve(totalCount);
162
- });
163
- pdfParser.loadPDF(pdfFilePath, 0);
164
- });
165
- }
166
-
167
- function validateString(arg, name) {
168
- if (arg && typeof arg === 'string' && arg.trim().length > 0) {// text is correct
169
- } else {
170
- throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, "Invalid argument - '" + name + "' should be a non-empty string.");
171
- }
172
- }
173
-
174
- function validatePageNum(arg, name) {
175
- if (arg === null || arg && typeof arg === 'number' && arg > 0) {// pageNum is correct
176
- } else {
177
- throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, "Invalid argument - '" + name + "' should be a non-negative number.");
178
- }
179
- }
180
-
181
- function validateMessage(arg, name) {
182
- if (arg === null || arg && typeof arg === 'string' && arg.trim().length > 0) {// pageNum is correct
183
- } else {
184
- throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, "Invalid argument - '" + name + "' should be a non-empty string.");
185
- }
186
- }
187
-
188
- function validateReverse(arg, name) {
189
- if (arg === null || typeof arg !== 'undefined' && typeof arg === 'boolean') {// pageNum is correct
190
- } else {
191
- throw new _OxygenError.default(errHelper.errorCode.SCRIPT_ERROR, "Invalid argument - '" + name + "' should be a boolean");
192
- }
193
- }
194
-
195
- function resolvePath(pdfFilePath, options) {
196
- pdfFilePath = pdfFilePath.trim().split('').map((item, idx) => {
197
- return ![8206, 8296].includes(pdfFilePath.charCodeAt(idx)) ? item : null;
198
- }).join('');
199
-
200
- if (pdfFilePath[0] === '~') {
201
- // resolve path relative to home directory
202
- return path.join(process.env.HOME, pdfFilePath.slice(1));
203
- } else {
204
- let cwd = process.cwd();
205
-
206
- if (options && options.cwd) {
207
- cwd = options.cwd;
208
- }
209
-
210
- if (options && options.rootPath) {
211
- cwd = options.rootPath;
212
- }
213
-
214
- cwd = cwd.trim();
215
- return path.resolve(cwd, pdfFilePath);
216
- }
217
- }
218
-
219
- module.exports = function (options, context, rs, logger, modules, services) {
220
- module.isInitialized = function () {
221
- return true;
222
- };
223
- /**
224
- * @summary Asserts that text is present in a PDF file
225
- * @function assert
226
- * @param {String} pdfFilePath - Relative or absolute path to the PDF file.
227
- * @param {String} text - Text to assert.
228
- * @param {Number=} pageNum - Page number.
229
- * @param {String=} message - Message to throw if assertion fails.
230
- * @param {Boolean=} reverse - Check also reverse variant of string.
231
- */
232
-
233
-
234
- module.assert = async function (pdfFilePath, text, pageNum = null, message = null, reverse = false) {
235
- validateString(pdfFilePath, 'pdfFilePath');
236
- validateString(text, 'text');
237
- validatePageNum(pageNum, 'pageNum');
238
- validateMessage(message, 'message');
239
- validateReverse(reverse, 'reverse');
240
- pdfFilePath = resolvePath(pdfFilePath, options);
241
- let error;
242
-
243
- try {
244
- const ret = await assertion(pdfFilePath, text, pageNum, reverse);
245
-
246
- if (!ret) {
247
- if (message) {
248
- throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, message);
249
- }
250
-
251
- let msg = `"${text}" is not found in the PDF ${pageNum ? 'on page ' + pageNum : ''}`;
252
- throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, msg);
253
- }
254
- } catch (e) {
255
- error = new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, e.message);
256
- }
257
-
258
- if (error) {
259
- throw error;
260
- }
261
- };
262
- /**
263
- * @summary Asserts that text is not present in a PDF file
264
- * @function assertNot
265
- * @param {String} pdfFilePath - Relative or absolute path to the pdf file.
266
- * @param {String} text - Text to assert.
267
- * @param {Number=} pageNum - Page number.
268
- * @param {String=} message - Message to throw if assertion fails.
269
- * @param {Boolean=} reverse - Check also reverse variant of string.
270
- */
271
-
272
-
273
- module.assertNot = async function (pdfFilePath, text, pageNum = null, message = null, reverse = false) {
274
- validateString(pdfFilePath, 'pdfFilePath');
275
- validateString(text, 'text');
276
- validatePageNum(pageNum, 'pageNum');
277
- validateMessage(message, 'message');
278
- validateReverse(reverse, 'reverse');
279
- pdfFilePath = resolvePath(pdfFilePath, options);
280
- let error;
281
-
282
- try {
283
- const ret = await assertion(pdfFilePath, text, pageNum, reverse);
284
-
285
- if (ret) {
286
- if (message) {
287
- throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, message);
288
- }
289
-
290
- let msg = `"${text}" is found in the PDF ${pageNum ? 'on page ' + pageNum : ''}`;
291
- throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, msg);
292
- }
293
- } catch (e) {
294
- throw new _OxygenError.default(errHelper.errorCode.ASSERT_ERROR, e.message);
295
- }
296
-
297
- if (error) {
298
- throw error;
299
- }
300
- };
301
- /**
302
- * @summary Count the number of times specified text is present in a PDF file.
303
- * @function count
304
- * @param {String} pdfFilePath - Relative or absolute path to the pdf file.
305
- * @param {String} text - Text to count.
306
- * @param {Number=} pageNum - Page number.
307
- * @param {Boolean=} reverse - Check also reverse variant of string.
308
- * @return {Number} Number of times the specified text was found.
309
- */
310
-
311
-
312
- module.count = async function (pdfFilePath, text, pageNum = null, reverse = false) {
313
- validateString(pdfFilePath, 'pdfFilePath');
314
- validateString(text, 'text');
315
- validatePageNum(pageNum, 'pageNum');
316
- validateReverse(reverse, 'reverse');
317
- pdfFilePath = resolvePath(pdfFilePath, options);
318
-
319
- try {
320
- return await count(pdfFilePath, text, pageNum, reverse);
321
- } catch (e) {
322
- throw new _OxygenError.default(errHelper.errorCode.PDF_ERROR, e.message || e);
323
- }
324
- };
325
-
326
- return module;
327
- };
328
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9veF9tb2R1bGVzL21vZHVsZS1wZGYuanMiXSwibmFtZXMiOlsiZXJySGVscGVyIiwicmVxdWlyZSIsInBhdGgiLCJQREZQYXJzZXIiLCJjb3VudFJvd3MiLCJzZWFyY2hTdHIiLCJyb3dzIiwicmV2ZXJzZSIsInJlc3VsdCIsInN0clJlZ2V4IiwiUmVnRXhwIiwicmV2ZXJzZVN0clJlZ2V4Iiwic3BsaXQiLCJqb2luIiwiT2JqZWN0Iiwia2V5cyIsInNvcnQiLCJ5MSIsInkyIiwicGFyc2VGbG9hdCIsInNvbWUiLCJ5IiwibGluZSIsInJlcGxhY2UiLCJjb3VudCIsIm1hdGNoIiwibGVuZ3RoIiwiY2hlY2tSb3dzIiwiaW5sdWRlcyIsInJldmVyc2VTZWFyY2hTdHIiLCJpbmNsdWRlcyIsImFzc2VydGlvbiIsInBkZkZpbGVQYXRoIiwidGV4dCIsInBhZ2VOdW0iLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInBkZlBhcnNlciIsIm9uIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwicGFyc2VyRXJyb3IiLCJPeEVycm9yIiwiZXJyb3JDb2RlIiwiQVNTRVJUX0VSUk9SIiwicGRmRGF0YSIsInRvdGFsUGFnZXMiLCJmb3JtSW1hZ2UiLCJQYWdlcyIsIlNDUklQVF9FUlJPUiIsInByb2Nlc3NUZXh0IiwiVGV4dHMiLCJpc0ZvdW5kIiwicCIsImxvYWRQREYiLCJ0ZXh0cyIsInQiLCJpdGVtIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwiUiIsIlQiLCJwdXNoIiwidG90YWxDb3VudCIsInZhbGlkYXRlU3RyaW5nIiwiYXJnIiwibmFtZSIsInRyaW0iLCJ2YWxpZGF0ZVBhZ2VOdW0iLCJ2YWxpZGF0ZU1lc3NhZ2UiLCJ2YWxpZGF0ZVJldmVyc2UiLCJyZXNvbHZlUGF0aCIsIm9wdGlvbnMiLCJtYXAiLCJpZHgiLCJjaGFyQ29kZUF0IiwicHJvY2VzcyIsImVudiIsIkhPTUUiLCJzbGljZSIsImN3ZCIsInJvb3RQYXRoIiwibW9kdWxlIiwiZXhwb3J0cyIsImNvbnRleHQiLCJycyIsImxvZ2dlciIsIm1vZHVsZXMiLCJzZXJ2aWNlcyIsImlzSW5pdGlhbGl6ZWQiLCJhc3NlcnQiLCJtZXNzYWdlIiwiZXJyb3IiLCJyZXQiLCJtc2ciLCJlIiwiYXNzZXJ0Tm90IiwiUERGX0VSUk9SIl0sIm1hcHBpbmdzIjoiOzs7O0FBY0E7Ozs7QUFkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBR0EsTUFBTUEsU0FBUyxHQUFHQyxPQUFPLENBQUMsa0JBQUQsQ0FBekI7O0FBQ0EsTUFBTUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFwQjs7QUFDQSxJQUFJRSxTQUFTLEdBQUdGLE9BQU8sQ0FBQyxvQkFBRCxDQUF2Qjs7QUFFQSxTQUFTRyxTQUFULENBQW1CQyxTQUFuQixFQUE4QkMsSUFBOUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQ3pDLE1BQUlDLE1BQU0sR0FBRyxDQUFiO0FBQ0EsTUFBSUMsUUFBUSxHQUFHLElBQUlDLE1BQUosQ0FBV0wsU0FBWCxFQUFzQixHQUF0QixDQUFmO0FBQ0EsTUFBSU0sZUFBZSxHQUFHSixPQUFPLEdBQUcsSUFBSUcsTUFBSixDQUFXTCxTQUFTLENBQUNPLEtBQVYsQ0FBZ0IsRUFBaEIsRUFBb0JMLE9BQXBCLEdBQThCTSxJQUE5QixDQUFtQyxFQUFuQyxDQUFYLEVBQW1ELEdBQW5ELENBQUgsR0FBNkQsSUFBMUY7QUFFQUMsRUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVlULElBQVosRUFBa0I7QUFBbEIsR0FDS1UsSUFETCxDQUNVLENBQUNDLEVBQUQsRUFBS0MsRUFBTCxLQUFZQyxVQUFVLENBQUNGLEVBQUQsQ0FBVixHQUFpQkUsVUFBVSxDQUFDRCxFQUFELENBRGpELEVBQ3VEO0FBRHZELEdBRUtFLElBRkwsQ0FFVUMsQ0FBQyxJQUFJO0FBQ1AsUUFBSUMsSUFBSSxHQUFHLENBQUNoQixJQUFJLENBQUNlLENBQUQsQ0FBSixJQUFXLEVBQVosRUFBZ0JS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QUEsTUFBTSxDQUFDMUQsS0FBUCxHQUFlLGdCQUFlUSxXQUFmLEVBQTRCQyxJQUE1QixFQUFrQ0MsT0FBTyxHQUFHLElBQTVDLEVBQWtEM0IsT0FBTyxHQUFHLEtBQTVELEVBQW1FO0FBQzlFeUQsSUFBQUEsY0FBYyxDQUFDaEMsV0FBRCxFQUFjLGFBQWQsQ0FBZDtBQUNBZ0MsSUFBQUEsY0FBYyxDQUFDL0IsSUFBRCxFQUFPLE1BQVAsQ0FBZDtBQUNBbUMsSUFBQUEsZUFBZSxDQUFDbEMsT0FBRCxFQUFVLFNBQVYsQ0FBZjtBQUNBb0MsSUFBQUEsZUFBZSxDQUFDL0QsT0FBRCxFQUFVLFNBQVYsQ0FBZjtBQUVBeUIsSUFBQUEsV0FBVyxHQUFHdUMsV0FBVyxDQUFDdkMsV0FBRCxFQUFjd0MsT0FBZCxDQUF6Qjs7QUFFQSxRQUFJO0FBQ0EsYUFBTyxNQUFNaEQsS0FBSyxDQUFDUSxXQUFELEVBQWNDLElBQWQsRUFBb0JDLE9BQXBCLEVBQTZCM0IsT0FBN0IsQ0FBbEI7QUFDSCxLQUZELENBR0EsT0FBT3dGLENBQVAsRUFBVTtBQUNOLFlBQU0sSUFBSXBELG9CQUFKLENBQVkzQyxTQUFTLENBQUM0QyxTQUFWLENBQW9CcUQsU0FBaEMsRUFBMkNGLENBQUMsQ0FBQ0osT0FBRixJQUFhSSxDQUF4RCxDQUFOO0FBQ0g7QUFDSixHQWREOztBQWdCQSxTQUFPYixNQUFQO0FBQ0gsQ0FqSEQiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTktcHJlc2VudCBDbG91ZEJlYXQgTGltaXRlZFxyXG4gKlxyXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxyXG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxyXG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxyXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBAbmFtZSBwZGZcclxuICogQGRlc2NyaXB0aW9uIFByb3ZpZGVzIGdlbmVyaWMgbWV0aG9kcyBmb3Igd29ya2luZyB3aXRoIFBERiBmaWxlcy5cclxuICovXHJcblxyXG5pbXBvcnQgT3hFcnJvciBmcm9tICcuLi9lcnJvcnMvT3h5Z2VuRXJyb3InO1xyXG5jb25zdCBlcnJIZWxwZXIgPSByZXF1aXJlKCcuLi9lcnJvcnMvaGVscGVyJyk7XHJcbmNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XHJcbnZhciBQREZQYXJzZXIgPSByZXF1aXJlKCdwZGYyanNvbi9wZGZwYXJzZXInKTtcclxuXHJcbmZ1bmN0aW9uIGNvdW50Um93cyhzZWFyY2hTdHIsIHJvd3MsIHJldmVyc2UpIHtcclxuICAgIGxldCByZXN1bHQgPSAwO1xyXG4gICAgdmFyIHN0clJlZ2V4ID0gbmV3IFJlZ0V4cChzZWFyY2hTdHIsICdnJyk7XHJcbiAgICB2YXIgcmV2ZXJzZVN0clJlZ2V4ID0gcmV2ZXJzZSA/IG5ldyBSZWdFeHAoc2VhcmNoU3RyLnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJyksICdnJykgOiBudWxsO1xyXG5cclxuICAgIE9iamVjdC5rZXlzKHJvd3MpIC8vID0+IGFycmF5IG9mIHktcG9zaXRpb25zICh0eXBlOiBmbG9hdClcclxuICAgICAgICAuc29ydCgoeTEsIHkyKSA9PiBwYXJzZUZsb2F0KHkxKSAtIHBhcnNlRmxvYXQoeTIpKSAvLyBzb3J0IGZsb2F0IHBvc2l0aW9uc1xyXG4gICAgICAgIC5zb21lKHkgPT4ge1xyXG4gICAgICAgICAgICB2YXIgbGluZSA9IChyb3dzW3ldIHx8IFtdKS5qb2luKCcnKS5yZXBsYWNlKC9cXHMvZywgJycpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGNvdW50ID0gKGxpbmUubWF0Y2goc3RyUmVnZXgpIHx8IFtdKS5sZW5ndGg7XHJcbiAgICAgICAgICAgIGlmIChjb3VudCA9PT0gMCAmJiByZXZlcnNlU3RyUmVnZXgpIHtcclxuICAgICAgICAgICAgICAgIGNvdW50ID0gKGxpbmUubWF0Y2gocmV2ZXJzZVN0clJlZ2V4KSB8fCBbXSkubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJlc3VsdCArPSBjb3VudDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjaGVja1Jvd3Moc2VhcmNoU3RyLCByb3dzLCByZXZlcnNlKSB7XHJcbiAgICBsZXQgcmVzdWx0ID0gZmFsc2U7XHJcblxyXG4gICAgT2JqZWN0LmtleXMocm93cykgLy8gPT4gYXJyYXkgb2YgeS1wb3NpdGlvbnMgKHR5cGU6IGZsb2F0KVxyXG4gICAgICAgIC5zb3J0KCh5MSwgeTIpID0+IHBhcnNlRmxvYXQoeTEpIC0gcGFyc2VGbG9hdCh5MikpIC8vIHNvcnQgZmxvYXQgcG9zaXRpb25zXHJcbiAgICAgICAgLnNvbWUoeSA9PiB7XHJcblxyXG4gICAgICAgICAgICB2YXIgbGluZSA9IChyb3dzW3ldIHx8IFtdKS5qb2luKCcnKS5yZXBsYWNlKC9cXHMvZywgJycpO1xyXG5cclxuICAgICAgICAgICAgbGV0IGlubHVkZXM7XHJcblxyXG4gICAgICAgICAgICBpZiAocmV2ZXJzZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmV2ZXJzZVNlYXJjaFN0ciA9IHNlYXJjaFN0ci5zcGxpdCgnJykucmV2ZXJzZSgpLmpvaW4oJycpO1xyXG4gICAgICAgICAgICAgICAgaW5sdWRlcyA9IGxpbmUuaW5jbHVkZXMoc2VhcmNoU3RyKSB8fCBsaW5lLmluY2x1ZGVzKHJldmVyc2VTZWFyY2hTdHIpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaW5sdWRlcyA9IGxpbmUuaW5jbHVkZXMoc2VhcmNoU3RyKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGlubHVkZXMpIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFzc2VydGlvbihwZGZGaWxlUGF0aCwgdGV4dCwgcGFnZU51bSA9IDAsIHJldmVyc2UgPSBmYWxzZSkge1xyXG4gICAgbGV0IHJvd3MgPSB7fTsgLy8gaW5kZXhlZCBieSB5LXBvc2l0aW9uXHJcblxyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGNvbnN0IHNlYXJjaFN0ciA9IHRleHQucmVwbGFjZSgvXFxzL2csICcnKTtcclxuXHJcbiAgICAgICAgbGV0IHBkZlBhcnNlciA9IG5ldyBQREZQYXJzZXIoKTtcclxuICAgICAgICBwZGZQYXJzZXIub24oJ3BkZlBhcnNlcl9kYXRhRXJyb3InLCBmdW5jdGlvbihlcnIpIHtcclxuICAgICAgICAgICAgbGV0IGVycm9yTWVzc2FnZSA9IGVyci5wYXJzZXJFcnJvciA/IGVyci5wYXJzZXJFcnJvciA6ICdFcnJvciBwYXJzaW5nIHRoZSBQREYuJztcclxuICAgICAgICAgICAgdGhyb3cgbmV3IE94RXJyb3IoZXJySGVscGVyLmVycm9yQ29kZS5BU1NFUlRfRVJST1IsIGVycm9yTWVzc2FnZSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHBkZlBhcnNlci5vbigncGRmUGFyc2VyX2RhdGFSZWFkeScsIGZ1bmN0aW9uIChwZGZEYXRhKSB7XHJcbiAgICAgICAgICAgIHZhciB0b3RhbFBhZ2VzID0gcGRmRGF0YS5mb3JtSW1hZ2UuUGFnZXMubGVuZ3RoO1xyXG4gICAgICAgICAgICBpZiAocGFnZU51bSAmJiB0b3RhbFBhZ2VzIDwgcGFnZU51bSAtIDEpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuU0NSSVBUX0VSUk9SLCBgSW52YWxpZCBhcmd1bWVudCAtICdwYWdlTnVtJyBpcyAke3BhZ2VOdW19LCBidXQgUERGIGNvbnRhaW5zIG9ubHkgJHt0b3RhbFBhZ2VzfSBwYWdlc2ApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBsb2NhdGUgb24gYSBzcGVjaWZpYyBwYWdlXHJcbiAgICAgICAgICAgIGlmIChwYWdlTnVtKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChyb3dzLCBwZGZEYXRhLmZvcm1JbWFnZS5QYWdlc1twYWdlTnVtLTFdLlRleHRzKTtcclxuICAgICAgICAgICAgICAgIGxldCBpc0ZvdW5kID0gY2hlY2tSb3dzKHNlYXJjaFN0ciwgcm93cywgcmV2ZXJzZSk7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKCEhaXNGb3VuZCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGxvY2F0ZSBvbiBhbnkgcGFnZVxyXG4gICAgICAgICAgICBmb3IgKGxldCBwIGluIHBkZkRhdGEuZm9ybUltYWdlLlBhZ2VzKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChyb3dzLCBwZGZEYXRhLmZvcm1JbWFnZS5QYWdlc1twXS5UZXh0cyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgaXNGb3VuZCA9IGNoZWNrUm93cyhzZWFyY2hTdHIsIHJvd3MsIHJldmVyc2UpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzRm91bmQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcm93cyA9IHt9OyAvLyBjbGVhciByb3dzIGZvciBuZXh0IHBhZ2VcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGRmUGFyc2VyLmxvYWRQREYocGRmRmlsZVBhdGgsIDApO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHByb2Nlc3NUZXh0KHJvd3MsIHRleHRzKSB7XHJcbiAgICBmb3IgKHZhciB0IGluIHRleHRzKSB7XHJcbiAgICAgICAgdmFyIGl0ZW0gPSB0ZXh0c1t0XTtcclxuICAgICAgICB2YXIgdGV4dCA9IGRlY29kZVVSSUNvbXBvbmVudChpdGVtLlJbMF0uVCk7XHJcbiAgICAgICAgLy8gYWNjdW11bGF0ZSB0ZXh0IGl0ZW1zIGludG8gcm93cyBvYmplY3QsIHBlciBsaW5lXHJcbiAgICAgICAgKHJvd3NbaXRlbS55XSA9IHJvd3NbaXRlbS55XSB8fCBbXSkucHVzaCh0ZXh0KTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gY291bnQocGRmRmlsZVBhdGgsIHRleHQsIHBhZ2VOdW0gPSAwLCByZXZlcnNlID0gZmFsc2UpIHtcclxuICAgIGxldCByb3dzID0ge307IC8vIGluZGV4ZWQgYnkgeS1wb3NpdGlvblxyXG4gICAgbGV0IHRvdGFsQ291bnQgPSAwO1xyXG5cclxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBjb25zdCBzZWFyY2hTdHIgPSB0ZXh0LnJlcGxhY2UoL1xccy9nLCAnJyk7XHJcblxyXG4gICAgICAgIGxldCBwZGZQYXJzZXIgPSBuZXcgUERGUGFyc2VyKCk7XHJcbiAgICAgICAgcGRmUGFyc2VyLm9uKCdwZGZQYXJzZXJfZGF0YUVycm9yJywgZnVuY3Rpb24oZXJyKSB7XHJcbiAgICAgICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSBlcnIucGFyc2VyRXJyb3IgPyBlcnIucGFyc2VyRXJyb3IgOiAnRXJyb3IgcGFyc2luZyB0aGUgUERGLic7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuQVNTRVJUX0VSUk9SLCBlcnJvck1lc3NhZ2UpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBwZGZQYXJzZXIub24oJ3BkZlBhcnNlcl9kYXRhUmVhZHknLCBmdW5jdGlvbiAocGRmRGF0YSkge1xyXG4gICAgICAgICAgICBsZXQgdG90YWxQYWdlcyA9IHBkZkRhdGEuZm9ybUltYWdlLlBhZ2VzLmxlbmd0aDtcclxuICAgICAgICAgICAgaWYgKHBhZ2VOdW0gJiYgdG90YWxQYWdlcyA8IHBhZ2VOdW0gLSAxKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgYEludmFsaWQgYXJndW1lbnQgLSAncGFnZU51bScgaXMgJHtwYWdlTnVtfSwgYnV0IFBERiBjb250YWlucyBvbmx5ICR7dG90YWxQYWdlc30gcGFnZXNgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gY291bnQgb24gYSBzcGVjaWZpYyBwYWdlXHJcbiAgICAgICAgICAgIGlmIChwYWdlTnVtKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChyb3dzLCBwZGZEYXRhLmZvcm1JbWFnZS5QYWdlc1twYWdlTnVtLTFdLlRleHRzKTtcclxuICAgICAgICAgICAgICAgIGxldCBjb3VudCA9IGNvdW50Um93cyhzZWFyY2hTdHIsIHJvd3MsIHJldmVyc2UpO1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb3VudCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGNvdW50IG9uIGFsbCBwYWdlc1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHBkZkRhdGEuZm9ybUltYWdlLlBhZ2VzKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChyb3dzLCBwZGZEYXRhLmZvcm1JbWFnZS5QYWdlc1twXS5UZXh0cyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgY291bnQgPSBjb3VudFJvd3Moc2VhcmNoU3RyLCByb3dzLCByZXZlcnNlKTtcclxuICAgICAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0b3RhbENvdW50ICs9IGNvdW50O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcm93cyA9IHt9OyAvLyBjbGVhciByb3dzIGZvciBuZXh0IHBhZ2VcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVzb2x2ZSh0b3RhbENvdW50KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwZGZQYXJzZXIubG9hZFBERihwZGZGaWxlUGF0aCwgMCk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gdmFsaWRhdGVTdHJpbmcoYXJnLCBuYW1lKSB7XHJcbiAgICBpZiAoYXJnICYmIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnICYmIGFyZy50cmltKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIC8vIHRleHQgaXMgY29ycmVjdFxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgXCJJbnZhbGlkIGFyZ3VtZW50IC0gJ1wiICsgbmFtZSArIFwiJyBzaG91bGQgYmUgYSBub24tZW1wdHkgc3RyaW5nLlwiKTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdmFsaWRhdGVQYWdlTnVtKGFyZywgbmFtZSkge1xyXG4gICAgaWYgKGFyZyA9PT0gbnVsbCB8fCAoYXJnICYmIHR5cGVvZiBhcmcgPT09ICdudW1iZXInICYmIGFyZyA+IDApKSB7XHJcbiAgICAgICAgLy8gcGFnZU51bSBpcyBjb3JyZWN0XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuU0NSSVBUX0VSUk9SLCBcIkludmFsaWQgYXJndW1lbnQgLSAnXCIgKyBuYW1lICsgXCInIHNob3VsZCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuXCIpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiB2YWxpZGF0ZU1lc3NhZ2UoYXJnLCBuYW1lKSB7XHJcbiAgICBpZiAoYXJnID09PSBudWxsIHx8IChhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgJiYgYXJnLnRyaW0oKS5sZW5ndGggPiAwKSkge1xyXG4gICAgICAgIC8vIHBhZ2VOdW0gaXMgY29ycmVjdFxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgXCJJbnZhbGlkIGFyZ3VtZW50IC0gJ1wiICsgbmFtZSArIFwiJyBzaG91bGQgYmUgYSBub24tZW1wdHkgc3RyaW5nLlwiKTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdmFsaWRhdGVSZXZlcnNlKGFyZywgbmFtZSkge1xyXG4gICAgaWYgKGFyZyA9PT0gbnVsbCB8fCAodHlwZW9mIGFyZyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nKSkge1xyXG4gICAgICAgIC8vIHBhZ2VOdW0gaXMgY29ycmVjdFxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLlNDUklQVF9FUlJPUiwgXCJJbnZhbGlkIGFyZ3VtZW50IC0gJ1wiICsgbmFtZSArIFwiJyBzaG91bGQgYmUgYSBib29sZWFuXCIpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZXNvbHZlUGF0aChwZGZGaWxlUGF0aCwgb3B0aW9ucykge1xyXG5cclxuICAgIHBkZkZpbGVQYXRoID0gcGRmRmlsZVBhdGgudHJpbSgpLnNwbGl0KCcnKS5tYXAoKGl0ZW0sIGlkeCkgPT4ge1xyXG4gICAgICAgIHJldHVybiAhWzgyMDYsIDgyOTZdLmluY2x1ZGVzKHBkZkZpbGVQYXRoLmNoYXJDb2RlQXQoaWR4KSkgPyBpdGVtIDogbnVsbDtcclxuICAgIH0pLmpvaW4oJycpO1xyXG5cclxuICAgIGlmIChwZGZGaWxlUGF0aFswXSA9PT0gJ34nKSB7XHJcbiAgICAgICAgLy8gcmVzb2x2ZSBwYXRoIHJlbGF0aXZlIHRvIGhvbWUgZGlyZWN0b3J5XHJcbiAgICAgICAgcmV0dXJuIHBhdGguam9pbihwcm9jZXNzLmVudi5IT01FLCBwZGZGaWxlUGF0aC5zbGljZSgxKSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxldCBjd2QgPSBwcm9jZXNzLmN3ZCgpO1xyXG5cclxuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmN3ZCkge1xyXG4gICAgICAgICAgICBjd2QgPSBvcHRpb25zLmN3ZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMucm9vdFBhdGgpIHtcclxuICAgICAgICAgICAgY3dkID0gb3B0aW9ucy5yb290UGF0aDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGN3ZCA9IGN3ZC50cmltKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBwYXRoLnJlc29sdmUoY3dkLCBwZGZGaWxlUGF0aCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob3B0aW9ucywgY29udGV4dCwgcnMsIGxvZ2dlciwgbW9kdWxlcywgc2VydmljZXMpIHtcclxuXHJcbiAgICBtb2R1bGUuaXNJbml0aWFsaXplZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBzdW1tYXJ5IEFzc2VydHMgdGhhdCB0ZXh0IGlzIHByZXNlbnQgaW4gYSBQREYgZmlsZVxyXG4gICAgICogQGZ1bmN0aW9uIGFzc2VydFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHBkZkZpbGVQYXRoIC0gUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgUERGIGZpbGUuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIFRleHQgdG8gYXNzZXJ0LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXI9fSBwYWdlTnVtIC0gUGFnZSBudW1iZXIuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZz19IG1lc3NhZ2UgLSBNZXNzYWdlIHRvIHRocm93IGlmIGFzc2VydGlvbiBmYWlscy5cclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbj19IHJldmVyc2UgLSBDaGVjayBhbHNvIHJldmVyc2UgdmFyaWFudCBvZiBzdHJpbmcuXHJcbiAgICAgKi9cclxuICAgIG1vZHVsZS5hc3NlcnQgPSBhc3luYyBmdW5jdGlvbihwZGZGaWxlUGF0aCwgdGV4dCwgcGFnZU51bSA9IG51bGwsIG1lc3NhZ2UgPSBudWxsLCByZXZlcnNlID0gZmFsc2UpIHtcclxuICAgICAgICB2YWxpZGF0ZVN0cmluZyhwZGZGaWxlUGF0aCwgJ3BkZkZpbGVQYXRoJyk7XHJcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcodGV4dCwgJ3RleHQnKTtcclxuICAgICAgICB2YWxpZGF0ZVBhZ2VOdW0ocGFnZU51bSwgJ3BhZ2VOdW0nKTtcclxuICAgICAgICB2YWxpZGF0ZU1lc3NhZ2UobWVzc2FnZSwgJ21lc3NhZ2UnKTtcclxuICAgICAgICB2YWxpZGF0ZVJldmVyc2UocmV2ZXJzZSwgJ3JldmVyc2UnKTtcclxuXHJcbiAgICAgICAgcGRmRmlsZVBhdGggPSByZXNvbHZlUGF0aChwZGZGaWxlUGF0aCwgb3B0aW9ucyk7XHJcblxyXG4gICAgICAgIGxldCBlcnJvcjtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCByZXQgPSBhd2FpdCBhc3NlcnRpb24ocGRmRmlsZVBhdGgsIHRleHQsIHBhZ2VOdW0sIHJldmVyc2UpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFyZXQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE94RXJyb3IoZXJySGVscGVyLmVycm9yQ29kZS5BU1NFUlRfRVJST1IsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGxldCBtc2cgPSBgXCIke3RleHR9XCIgaXMgbm90IGZvdW5kIGluIHRoZSBQREYgJHtwYWdlTnVtID8gJ29uIHBhZ2UgJyArIHBhZ2VOdW0gOiAnJ31gO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IE94RXJyb3IoZXJySGVscGVyLmVycm9yQ29kZS5BU1NFUlRfRVJST1IsIG1zZyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBlcnJvciA9IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuQVNTRVJUX0VSUk9SLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHN1bW1hcnkgQXNzZXJ0cyB0aGF0IHRleHQgaXMgbm90IHByZXNlbnQgaW4gYSBQREYgZmlsZVxyXG4gICAgICogQGZ1bmN0aW9uIGFzc2VydE5vdFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHBkZkZpbGVQYXRoIC0gUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgcGRmIGZpbGUuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIFRleHQgdG8gYXNzZXJ0LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXI9fSBwYWdlTnVtIC0gUGFnZSBudW1iZXIuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZz19IG1lc3NhZ2UgLSBNZXNzYWdlIHRvIHRocm93IGlmIGFzc2VydGlvbiBmYWlscy5cclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbj19IHJldmVyc2UgLSBDaGVjayBhbHNvIHJldmVyc2UgdmFyaWFudCBvZiBzdHJpbmcuXHJcbiAgICAgKi9cclxuICAgIG1vZHVsZS5hc3NlcnROb3QgPSBhc3luYyBmdW5jdGlvbihwZGZGaWxlUGF0aCwgdGV4dCwgcGFnZU51bSA9IG51bGwsIG1lc3NhZ2UgPSBudWxsLCByZXZlcnNlID0gZmFsc2UpIHtcclxuICAgICAgICB2YWxpZGF0ZVN0cmluZyhwZGZGaWxlUGF0aCwgJ3BkZkZpbGVQYXRoJyk7XHJcbiAgICAgICAgdmFsaWRhdGVTdHJpbmcodGV4dCwgJ3RleHQnKTtcclxuICAgICAgICB2YWxpZGF0ZVBhZ2VOdW0ocGFnZU51bSwgJ3BhZ2VOdW0nKTtcclxuICAgICAgICB2YWxpZGF0ZU1lc3NhZ2UobWVzc2FnZSwgJ21lc3NhZ2UnKTtcclxuICAgICAgICB2YWxpZGF0ZVJldmVyc2UocmV2ZXJzZSwgJ3JldmVyc2UnKTtcclxuXHJcbiAgICAgICAgcGRmRmlsZVBhdGggPSByZXNvbHZlUGF0aChwZGZGaWxlUGF0aCwgb3B0aW9ucyk7XHJcblxyXG4gICAgICAgIGxldCBlcnJvcjtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCByZXQgPSBhd2FpdCBhc3NlcnRpb24ocGRmRmlsZVBhdGgsIHRleHQsIHBhZ2VOdW0sIHJldmVyc2UpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHJldCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgT3hFcnJvcihlcnJIZWxwZXIuZXJyb3JDb2RlLkFTU0VSVF9FUlJPUiwgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IG1zZyA9IGBcIiR7dGV4dH1cIiBpcyBmb3VuZCBpbiB0aGUgUERGICR7cGFnZU51bSA/ICdvbiBwYWdlICcgKyBwYWdlTnVtIDogJyd9YDtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuQVNTRVJUX0VSUk9SLCBtc2cpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBPeEVycm9yKGVyckhlbHBlci5lcnJvckNvZGUuQVNTRVJUX0VSUk9SLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAc3VtbWFyeSBDb3VudCB0aGUgbnVtYmVyIG9mIHRpbWVzIHNwZWNpZmllZCB0ZXh0IGlzIHByZXNlbnQgaW4gYSBQREYgZmlsZS5cclxuICAgICAqIEBmdW5jdGlvbiBjb3VudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHBkZkZpbGVQYXRoIC0gUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgcGRmIGZpbGUuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCAtIFRleHQgdG8gY291bnQuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcj19IHBhZ2VOdW0gLSBQYWdlIG51bWJlci5cclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbj19IHJldmVyc2UgLSBDaGVjayBhbHNvIHJldmVyc2UgdmFyaWFudCBvZiBzdHJpbmcuXHJcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IE51bWJlciBvZiB0aW1lcyB0aGUgc3BlY2lmaWVkIHRleHQgd2FzIGZvdW5kLlxyXG4gICAgICovXHJcbiAgICBtb2R1bGUuY291bnQgPSBhc3luYyBmdW5jdGlvbihwZGZGaWxlUGF0aCwgdGV4dCwgcGFnZU51bSA9IG51bGwsIHJldmVyc2UgPSBmYWxzZSkge1xyXG4gICAgICAgIHZhbGlkYXRlU3RyaW5nKHBkZkZpbGVQYXRoLCAncGRmRmlsZVBhdGgnKTtcclxuICAgICAgICB2YWxpZGF0ZVN0cmluZyh0ZXh0LCAndGV4dCcpO1xyXG4gICAgICAgIHZhbGlkYXRlUGFnZU51bShwYWdlTnVtLCAncGFnZU51bScpO1xyXG4gICAgICAgIHZhbGlkYXRlUmV2ZXJzZShyZXZlcnNlLCAncmV2ZXJzZScpO1xyXG5cclxuICAgICAgICBwZGZGaWxlUGF0aCA9IHJlc29sdmVQYXRoKHBkZkZpbGVQYXRoLCBvcHRpb25zKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGNvdW50KHBkZkZpbGVQYXRoLCB0ZXh0LCBwYWdlTnVtLCByZXZlcnNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IE94RXJyb3IoZXJySGVscGVyLmVycm9yQ29kZS5QREZfRVJST1IsIGUubWVzc2FnZSB8fCBlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiBtb2R1bGU7XHJcbn07XHJcbiJdfQ==