appium 2.0.0-beta.24 → 2.0.0-beta.27

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 (124) hide show
  1. package/build/lib/appium-config.schema.json +278 -0
  2. package/build/lib/appium.js +45 -66
  3. package/build/lib/cli/args.js +19 -39
  4. package/build/lib/cli/driver-command.js +5 -9
  5. package/build/lib/cli/extension-command.js +73 -64
  6. package/build/lib/cli/extension.js +10 -23
  7. package/build/lib/cli/parser.js +9 -19
  8. package/build/lib/cli/plugin-command.js +5 -9
  9. package/build/lib/cli/utils.js +2 -4
  10. package/build/lib/config-file.js +5 -10
  11. package/build/lib/config.js +50 -20
  12. package/build/lib/constants.js +60 -0
  13. package/build/lib/extension/driver-config.js +190 -0
  14. package/build/lib/extension/extension-config.js +297 -0
  15. package/build/lib/extension/index.js +77 -0
  16. package/build/lib/extension/manifest.js +246 -0
  17. package/build/lib/extension/package-changed.js +68 -0
  18. package/build/lib/extension/plugin-config.js +87 -0
  19. package/build/lib/grid-register.js +2 -4
  20. package/build/lib/logger.js +2 -4
  21. package/build/lib/logsink.js +2 -4
  22. package/build/lib/main.js +42 -71
  23. package/build/lib/schema/appium-config-schema.js +2 -4
  24. package/build/lib/schema/arg-spec.js +11 -14
  25. package/build/lib/schema/cli-args.js +2 -4
  26. package/build/lib/schema/cli-transformers.js +2 -4
  27. package/build/lib/schema/index.js +2 -4
  28. package/build/lib/schema/keywords.js +2 -4
  29. package/build/lib/schema/schema.js +61 -37
  30. package/build/lib/utils.js +1 -32
  31. package/lib/appium.js +50 -68
  32. package/lib/cli/args.js +19 -23
  33. package/lib/cli/driver-command.js +10 -2
  34. package/lib/cli/extension-command.js +216 -135
  35. package/lib/cli/extension.js +7 -15
  36. package/lib/cli/parser.js +6 -14
  37. package/lib/cli/plugin-command.js +1 -2
  38. package/lib/config-file.js +12 -15
  39. package/lib/config.js +55 -24
  40. package/lib/constants.js +79 -0
  41. package/lib/extension/driver-config.js +230 -0
  42. package/lib/extension/extension-config.js +459 -0
  43. package/lib/extension/index.js +103 -0
  44. package/lib/extension/manifest.js +590 -0
  45. package/lib/extension/package-changed.js +64 -0
  46. package/lib/extension/plugin-config.js +111 -0
  47. package/lib/grid-register.js +4 -4
  48. package/lib/main.js +57 -93
  49. package/lib/schema/arg-spec.js +3 -3
  50. package/lib/schema/cli-args.js +1 -0
  51. package/lib/schema/keywords.js +1 -1
  52. package/lib/schema/schema.js +67 -29
  53. package/lib/utils.js +2 -32
  54. package/package.json +29 -21
  55. package/{postinstall.js → scripts/postinstall.js} +1 -1
  56. package/types/types.d.ts +70 -31
  57. package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
  58. package/build/check-npm-pack-files.js +0 -23
  59. package/build/commands-yml/parse.js +0 -319
  60. package/build/commands-yml/validator.js +0 -130
  61. package/build/index.js +0 -19
  62. package/build/lib/cli/npm.js +0 -220
  63. package/build/lib/driver-config.js +0 -100
  64. package/build/lib/drivers.js +0 -100
  65. package/build/lib/ext-config-io.js +0 -165
  66. package/build/lib/extension-config.js +0 -320
  67. package/build/lib/plugin-config.js +0 -69
  68. package/build/lib/plugins.js +0 -18
  69. package/build/postinstall.js +0 -90
  70. package/build/test/cli/cli-e2e-specs.js +0 -221
  71. package/build/test/cli/cli-helpers.js +0 -86
  72. package/build/test/cli/cli-specs.js +0 -71
  73. package/build/test/cli/fixtures/test-driver/package.json +0 -27
  74. package/build/test/cli/schema-args-specs.js +0 -48
  75. package/build/test/cli/schema-e2e-specs.js +0 -47
  76. package/build/test/config-e2e-specs.js +0 -112
  77. package/build/test/config-file-e2e-specs.js +0 -209
  78. package/build/test/config-file-specs.js +0 -281
  79. package/build/test/config-specs.js +0 -246
  80. package/build/test/driver-e2e-specs.js +0 -435
  81. package/build/test/driver-specs.js +0 -386
  82. package/build/test/ext-config-io-specs.js +0 -181
  83. package/build/test/extension-config-specs.js +0 -365
  84. package/build/test/fixtures/allow-feat.txt +0 -5
  85. package/build/test/fixtures/caps.json +0 -3
  86. package/build/test/fixtures/config/allow-insecure.txt +0 -3
  87. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +0 -5
  88. package/build/test/fixtures/config/appium.config.bad.json +0 -32
  89. package/build/test/fixtures/config/appium.config.ext-good.json +0 -9
  90. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +0 -10
  91. package/build/test/fixtures/config/appium.config.good.js +0 -40
  92. package/build/test/fixtures/config/appium.config.good.json +0 -33
  93. package/build/test/fixtures/config/appium.config.good.yaml +0 -30
  94. package/build/test/fixtures/config/appium.config.invalid.json +0 -31
  95. package/build/test/fixtures/config/appium.config.security-array.json +0 -5
  96. package/build/test/fixtures/config/appium.config.security-delimited.json +0 -5
  97. package/build/test/fixtures/config/appium.config.security-path.json +0 -5
  98. package/build/test/fixtures/config/driver-fake.config.json +0 -8
  99. package/build/test/fixtures/config/nodeconfig.json +0 -3
  100. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  101. package/build/test/fixtures/default-args.js +0 -35
  102. package/build/test/fixtures/deny-feat.txt +0 -5
  103. package/build/test/fixtures/driver.schema.js +0 -20
  104. package/build/test/fixtures/extensions.yaml +0 -27
  105. package/build/test/fixtures/flattened-schema.js +0 -532
  106. package/build/test/fixtures/plugin.schema.js +0 -20
  107. package/build/test/fixtures/schema-with-extensions.js +0 -28
  108. package/build/test/grid-register-specs.js +0 -74
  109. package/build/test/helpers.js +0 -75
  110. package/build/test/logger-specs.js +0 -76
  111. package/build/test/npm-specs.js +0 -20
  112. package/build/test/parser-specs.js +0 -319
  113. package/build/test/plugin-e2e-specs.js +0 -316
  114. package/build/test/schema/arg-spec-specs.js +0 -70
  115. package/build/test/schema/cli-args-specs.js +0 -408
  116. package/build/test/schema/schema-specs.js +0 -407
  117. package/build/test/utils-specs.js +0 -288
  118. package/lib/cli/npm.js +0 -251
  119. package/lib/driver-config.js +0 -101
  120. package/lib/drivers.js +0 -84
  121. package/lib/ext-config-io.js +0 -287
  122. package/lib/extension-config.js +0 -366
  123. package/lib/plugin-config.js +0 -63
  124. package/lib/plugins.js +0 -13
@@ -1,181 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- require("source-map-support/register");
6
-
7
- var _fs = require("fs");
8
-
9
- var _path = _interopRequireDefault(require("path"));
10
-
11
- var _sinon = _interopRequireDefault(require("sinon"));
12
-
13
- var _yaml = _interopRequireDefault(require("yaml"));
14
-
15
- var _helpers = require("./helpers");
16
-
17
- const expect = chai.expect;
18
- describe('ExtensionConfigIO', function () {
19
- let sandbox;
20
- let yamlFixture;
21
- before(async function () {
22
- yamlFixture = await _fs.promises.readFile(_path.default.join(__dirname, 'fixtures', 'extensions.yaml'), 'utf8');
23
- });
24
- let getExtConfigIOInstance;
25
- let mocks;
26
- beforeEach(function () {
27
- sandbox = _sinon.default.createSandbox();
28
- mocks = {
29
- '@appium/support': {
30
- fs: {
31
- readFile: sandbox.stub().resolves(yamlFixture),
32
- writeFile: sandbox.stub().resolves(true)
33
- },
34
- mkdirp: sandbox.stub().resolves()
35
- }
36
- };
37
- getExtConfigIOInstance = _helpers.rewiremock.proxy('../lib/ext-config-io', mocks).getExtConfigIOInstance;
38
- });
39
- afterEach(function () {
40
- sandbox.restore();
41
- getExtConfigIOInstance.cache = new Map();
42
- });
43
- describe('instantiation', function () {
44
- describe('when called twice with the same `appiumHome` value', function () {
45
- it('should return the same object both times', function () {
46
- const firstInstance = getExtConfigIOInstance('/some/path');
47
- const secondInstance = getExtConfigIOInstance('/some/path');
48
- expect(firstInstance).to.equal(secondInstance);
49
- });
50
- });
51
- describe('when called twice with different `appiumHome` values', function () {
52
- it('should return different objects', function () {
53
- const firstInstance = getExtConfigIOInstance('/some/path');
54
- const secondInstance = getExtConfigIOInstance('/some/other/path');
55
- expect(firstInstance).to.not.equal(secondInstance);
56
- });
57
- });
58
- });
59
- describe('property', function () {
60
- describe('filepath', function () {
61
- it('should not be writable', function () {
62
- const instance = getExtConfigIOInstance('/some/path');
63
- expect(() => {
64
- instance.filepath = '/some/other/path';
65
- }).to.throw(TypeError);
66
- });
67
- });
68
- });
69
- describe('read()', function () {
70
- let io;
71
- beforeEach(function () {
72
- io = getExtConfigIOInstance('/some/path');
73
- });
74
- describe('when called with a valid extension type', function () {
75
- describe('when the file does not yet exist', function () {
76
- beforeEach(async function () {
77
- const err = new Error();
78
- err.code = 'ENOENT';
79
- mocks['@appium/support'].fs.readFile.rejects(err);
80
- await io.read('driver');
81
- });
82
- it('should create a new file', function () {
83
- expect(mocks['@appium/support'].fs.writeFile).to.be.calledOnceWith(io.filepath, _yaml.default.stringify({
84
- drivers: {},
85
- plugins: {},
86
- schemaRev: 2
87
- }), 'utf8');
88
- });
89
- });
90
- describe('when the file already exists', function () {
91
- beforeEach(async function () {
92
- await io.read('driver');
93
- });
94
- it('should attempt to create the `appiumHome` directory', function () {
95
- expect(mocks['@appium/support'].mkdirp).to.have.been.calledOnceWith('/some/path');
96
- });
97
- it('should attempt to read the file at `filepath`', function () {
98
- expect(mocks['@appium/support'].fs.readFile).to.have.been.calledOnceWith(io.filepath, 'utf8');
99
- });
100
- });
101
- });
102
- describe('when called with an unknown extension type`', function () {
103
- it('should reject', async function () {
104
- const promise = io.read('unknown');
105
- return await expect(promise).to.be.rejectedWith(TypeError, /invalid extension type/i);
106
- });
107
- });
108
- describe('when called twice with the same `extensionType`', function () {
109
- it('should return the same object both times', async function () {
110
- const firstInstance = await io.read('driver');
111
- const secondInstance = await io.read('driver');
112
- expect(firstInstance).to.equal(secondInstance);
113
- });
114
- });
115
- });
116
- describe('write()', function () {
117
- let io;
118
- let driverData;
119
- beforeEach(function () {
120
- io = getExtConfigIOInstance('/some/path');
121
- });
122
- describe('when called after `read()`', function () {
123
- beforeEach(async function () {
124
- driverData = await io.read('driver');
125
- });
126
- describe('when called without modifying the data', function () {
127
- it('should not write the file', async function () {
128
- expect(await io.write()).to.be.false;
129
- });
130
- });
131
- describe('when called after adding a property', function () {
132
- beforeEach(function () {
133
- driverData.foo = {
134
- name: 'foo',
135
- version: '1.0.0',
136
- path: '/foo/path'
137
- };
138
- });
139
- it('should write the file', async function () {
140
- expect(await io.write()).to.be.true;
141
- });
142
- });
143
- describe('when called after deleting a property', function () {
144
- beforeEach(function () {
145
- driverData.foo = {
146
- name: 'foo',
147
- version: '1.0.0',
148
- path: '/foo/path'
149
- };
150
- io._dirty = false;
151
- delete driverData.foo;
152
- });
153
- it('should write the file', async function () {
154
- expect(await io.write()).to.be.true;
155
- });
156
- });
157
- describe('when the config file could not be written', function () {
158
- beforeEach(function () {
159
- mocks['@appium/support'].fs.writeFile = sandbox.stub().rejects(new Error());
160
- io._dirty = true;
161
- });
162
- it('should reject', async function () {
163
- await expect(io.write()).to.be.rejectedWith(Error, /Appium could not parse or write/i);
164
- });
165
- });
166
- });
167
- describe('when called before `read()`', function () {
168
- it('should return `false`', async function () {
169
- expect(await io.write()).to.be.false;
170
- });
171
- describe('when called with `force: true`', function () {
172
- it('should reject', async function () {
173
- await expect(io.write(true)).to.be.rejectedWith(ReferenceError, 'No data to write. Call `read()` first');
174
- });
175
- });
176
- });
177
- });
178
- });require('source-map-support').install();
179
-
180
-
181
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZXh0LWNvbmZpZy1pby1zcGVjcy5qcyJdLCJuYW1lcyI6WyJleHBlY3QiLCJjaGFpIiwiZGVzY3JpYmUiLCJzYW5kYm94IiwieWFtbEZpeHR1cmUiLCJiZWZvcmUiLCJmcyIsInJlYWRGaWxlIiwicGF0aCIsImpvaW4iLCJfX2Rpcm5hbWUiLCJnZXRFeHRDb25maWdJT0luc3RhbmNlIiwibW9ja3MiLCJiZWZvcmVFYWNoIiwic2lub24iLCJjcmVhdGVTYW5kYm94Iiwic3R1YiIsInJlc29sdmVzIiwid3JpdGVGaWxlIiwibWtkaXJwIiwicmV3aXJlbW9jayIsInByb3h5IiwiYWZ0ZXJFYWNoIiwicmVzdG9yZSIsImNhY2hlIiwiTWFwIiwiaXQiLCJmaXJzdEluc3RhbmNlIiwic2Vjb25kSW5zdGFuY2UiLCJ0byIsImVxdWFsIiwibm90IiwiaW5zdGFuY2UiLCJmaWxlcGF0aCIsInRocm93IiwiVHlwZUVycm9yIiwiaW8iLCJlcnIiLCJFcnJvciIsImNvZGUiLCJyZWplY3RzIiwicmVhZCIsImJlIiwiY2FsbGVkT25jZVdpdGgiLCJZQU1MIiwic3RyaW5naWZ5IiwiZHJpdmVycyIsInBsdWdpbnMiLCJzY2hlbWFSZXYiLCJoYXZlIiwiYmVlbiIsInByb21pc2UiLCJyZWplY3RlZFdpdGgiLCJkcml2ZXJEYXRhIiwid3JpdGUiLCJmYWxzZSIsImZvbyIsIm5hbWUiLCJ2ZXJzaW9uIiwidHJ1ZSIsIl9kaXJ0eSIsIlJlZmVyZW5jZUVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQSxNQUFNQSxNQUFNLEdBQUdDLElBQUksQ0FBQ0QsTUFBcEI7QUFFQUUsUUFBUSxDQUFDLG1CQUFELEVBQXNCLFlBQVk7QUFJeEMsTUFBSUMsT0FBSjtBQUdBLE1BQUlDLFdBQUo7QUFFQUMsRUFBQUEsTUFBTSxDQUFDLGtCQUFrQjtBQUN2QkQsSUFBQUEsV0FBVyxHQUFHLE1BQU1FLGFBQUdDLFFBQUgsQ0FDbEJD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QUFzREFwQyxJQUFBQSxRQUFRLENBQUMsNkJBQUQsRUFBZ0MsWUFBWTtBQUNsRHdCLE1BQUFBLEVBQUUsQ0FBQyx1QkFBRCxFQUEwQixrQkFBa0I7QUFDNUMxQixRQUFBQSxNQUFNLENBQUMsTUFBTW9DLEVBQUUsQ0FBQ2tCLEtBQUgsRUFBUCxDQUFOLENBQXlCekIsRUFBekIsQ0FBNEJhLEVBQTVCLENBQStCYSxLQUEvQjtBQUNELE9BRkMsQ0FBRjtBQUlBckQsTUFBQUEsUUFBUSxDQUFDLGdDQUFELEVBQW1DLFlBQVk7QUFDckR3QixRQUFBQSxFQUFFLENBQUMsZUFBRCxFQUFrQixrQkFBa0I7QUFDcEMsZ0JBQU0xQixNQUFNLENBQUNvQyxFQUFFLENBQUNrQixLQUFILENBQVMsSUFBVCxDQUFELENBQU4sQ0FBdUJ6QixFQUF2QixDQUEwQmEsRUFBMUIsQ0FBNkJVLFlBQTdCLENBQTBDUyxjQUExQyxFQUEwRCx1Q0FBMUQsQ0FBTjtBQUNELFNBRkMsQ0FBRjtBQUdELE9BSk8sQ0FBUjtBQUtELEtBVk8sQ0FBUjtBQVdELEdBekVPLENBQVI7QUEwRUQsQ0F2Tk8sQ0FBUiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmcyB9IGZyb20gJ2ZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCBZQU1MIGZyb20gJ3lhbWwnO1xuaW1wb3J0IHsgcmV3aXJlbW9jayB9IGZyb20gJy4vaGVscGVycyc7XG5jb25zdCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcblxuZGVzY3JpYmUoJ0V4dGVuc2lvbkNvbmZpZ0lPJywgZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHR5cGUge2ltcG9ydCgnc2lub24nKS5TaW5vblNhbmRib3h9XG4gICAqL1xuICBsZXQgc2FuZGJveDtcblxuICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgbGV0IHlhbWxGaXh0dXJlO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgeWFtbEZpeHR1cmUgPSBhd2FpdCBmcy5yZWFkRmlsZShcbiAgICAgIHBhdGguam9pbihfX2Rpcm5hbWUsICdmaXh0dXJlcycsICdleHRlbnNpb25zLnlhbWwnKSxcbiAgICAgICd1dGY4JyxcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4uL2xpYi9leHQtY29uZmlnLWlvJykuZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZX1cbiAgICovXG4gIGxldCBnZXRFeHRDb25maWdJT0luc3RhbmNlO1xuXG4gIGxldCBtb2NrcztcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIG1vY2tzID0ge1xuICAgICAgJ0BhcHBpdW0vc3VwcG9ydCc6IHtcbiAgICAgICAgZnM6IHtcbiAgICAgICAgICByZWFkRmlsZTogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoeWFtbEZpeHR1cmUpLFxuICAgICAgICAgIHdyaXRlRmlsZTogc2FuZGJveC5zdHViKCkucmVzb2x2ZXModHJ1ZSksXG4gICAgICAgIH0sXG4gICAgICAgIG1rZGlycDogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBnZXRFeHRDb25maWdJT0luc3RhbmNlID0gcmV3aXJlbW9jay5wcm94eShcbiAgICAgICcuLi9saWIvZXh0LWNvbmZpZy1pbycsXG4gICAgICBtb2NrcyxcbiAgICApLmdldEV4dENvbmZpZ0lPSW5zdGFuY2U7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZS5jYWNoZSA9IG5ldyBNYXAoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2luc3RhbnRpYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIHR3aWNlIHdpdGggdGhlIHNhbWUgYGFwcGl1bUhvbWVgIHZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHNhbWUgb2JqZWN0IGJvdGggdGltZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0SW5zdGFuY2UgPSBnZXRFeHRDb25maWdJT0luc3RhbmNlKCcvc29tZS9wYXRoJyk7XG4gICAgICAgIGNvbnN0IHNlY29uZEluc3RhbmNlID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgICAgICBleHBlY3QoZmlyc3RJbnN0YW5jZSkudG8uZXF1YWwoc2Vjb25kSW5zdGFuY2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgdHdpY2Ugd2l0aCBkaWZmZXJlbnQgYGFwcGl1bUhvbWVgIHZhbHVlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGRpZmZlcmVudCBvYmplY3RzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBmaXJzdEluc3RhbmNlID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgICAgICBjb25zdCBzZWNvbmRJbnN0YW5jZSA9IGdldEV4dENvbmZpZ0lPSW5zdGFuY2UoJy9zb21lL290aGVyL3BhdGgnKTtcbiAgICAgICAgZXhwZWN0KGZpcnN0SW5zdGFuY2UpLnRvLm5vdC5lcXVhbChzZWNvbmRJbnN0YW5jZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Byb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgIGRlc2NyaWJlKCdmaWxlcGF0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgbm90IGJlIHdyaXRhYmxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGdldEV4dENvbmZpZ0lPSW5zdGFuY2UoJy9zb21lL3BhdGgnKTtcbiAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgaW5zdGFuY2UuZmlsZXBhdGggPSAnL3NvbWUvb3RoZXIvcGF0aCc7XG4gICAgICAgIH0pLnRvLnRocm93KFR5cGVFcnJvcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlYWQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydCgnLi4vbGliL2V4dC1jb25maWctaW8nKS5FeHRlbnNpb25Db25maWdJT30gKi9cbiAgICBsZXQgaW87XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlvID0gZ2V0RXh0Q29uZmlnSU9JbnN0YW5jZSgnL3NvbWUvcGF0aCcpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIHdpdGggYSB2YWxpZCBleHRlbnNpb24gdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBmaWxlIGRvZXMgbm90IHlldCBleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLyoqIEB0eXBlIHtOb2RlSlMuRXJybm9FeGNlcHRpb259ICovXG4gICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgICAgICAgZXJyLmNvZGUgPSAnRU5PRU5UJztcbiAgICAgICAgICBtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMucmVhZEZpbGUucmVqZWN0cyhlcnIpO1xuICAgICAgICAgIGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBmaWxlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMud3JpdGVGaWxlKS50by5iZS5jYWxsZWRPbmNlV2l0aChcbiAgICAgICAgICAgIGlvLmZpbGVwYXRoLFxuICAgICAgICAgICAgWUFNTC5zdHJpbmdpZnkoe2RyaXZlcnM6IHt9LCBwbHVnaW5zOiB7fSwgc2NoZW1hUmV2OiAyfSksXG4gICAgICAgICAgICAndXRmOCcsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGZpbGUgYWxyZWFkeSBleGlzdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGF0dGVtcHQgdG8gY3JlYXRlIHRoZSBgYXBwaXVtSG9tZWAgZGlyZWN0b3J5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGV4cGVjdChtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10ubWtkaXJwKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoXG4gICAgICAgICAgICAnL3NvbWUvcGF0aCcsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBhdHRlbXB0IHRvIHJlYWQgdGhlIGZpbGUgYXQgYGZpbGVwYXRoYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBleHBlY3QoXG4gICAgICAgICAgICBtb2Nrc1snQGFwcGl1bS9zdXBwb3J0J10uZnMucmVhZEZpbGUsXG4gICAgICAgICAgKS50by5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoaW8uZmlsZXBhdGgsICd1dGY4Jyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgd2l0aCBhbiB1bmtub3duIGV4dGVuc2lvbiB0eXBlYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBpby5yZWFkKCd1bmtub3duJyk7XG4gICAgICAgIHJldHVybiBhd2FpdCBleHBlY3QocHJvbWlzZSkudG8uYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIFR5cGVFcnJvcixcbiAgICAgICAgICAvaW52YWxpZCBleHRlbnNpb24gdHlwZS9pLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgdHdpY2Ugd2l0aCB0aGUgc2FtZSBgZXh0ZW5zaW9uVHlwZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgc2FtZSBvYmplY3QgYm90aCB0aW1lcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZmlyc3RJbnN0YW5jZSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICBjb25zdCBzZWNvbmRJbnN0YW5jZSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgICBleHBlY3QoZmlyc3RJbnN0YW5jZSkudG8uZXF1YWwoc2Vjb25kSW5zdGFuY2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3cml0ZSgpJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBpbztcbiAgICBsZXQgZHJpdmVyRGF0YTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgaW8gPSBnZXRFeHRDb25maWdJT0luc3RhbmNlKCcvc29tZS9wYXRoJyk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYWZ0ZXIgYHJlYWQoKWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZHJpdmVyRGF0YSA9IGF3YWl0IGlvLnJlYWQoJ2RyaXZlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIGNhbGxlZCB3aXRob3V0IG1vZGlmeWluZyB0aGUgZGF0YScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBub3Qgd3JpdGUgdGhlIGZpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYWZ0ZXIgYWRkaW5nIGEgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRyaXZlckRhdGEuZm9vID0ge1xuICAgICAgICAgICAgbmFtZTogJ2ZvbycsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS4wLjAnLFxuICAgICAgICAgICAgcGF0aDogJy9mb28vcGF0aCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB3cml0ZSB0aGUgZmlsZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBleHBlY3QoYXdhaXQgaW8ud3JpdGUoKSkudG8uYmUudHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gY2FsbGVkIGFmdGVyIGRlbGV0aW5nIGEgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRyaXZlckRhdGEuZm9vID0ge1xuICAgICAgICAgICAgbmFtZTogJ2ZvbycsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS4wLjAnLFxuICAgICAgICAgICAgcGF0aDogJy9mb28vcGF0aCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpby5fZGlydHkgPSBmYWxzZTtcbiAgICAgICAgICBkZWxldGUgZHJpdmVyRGF0YS5mb287XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgd3JpdGUgdGhlIGZpbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLnRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBjb25maWcgZmlsZSBjb3VsZCBub3QgYmUgd3JpdHRlbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbW9ja3NbJ0BhcHBpdW0vc3VwcG9ydCddLmZzLndyaXRlRmlsZSA9IHNhbmRib3guc3R1YigpLnJlamVjdHMobmV3IEVycm9yKCkpO1xuICAgICAgICAgIGlvLl9kaXJ0eSA9IHRydWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChpby53cml0ZSgpKS50by5iZS5yZWplY3RlZFdpdGgoRXJyb3IsIC9BcHBpdW0gY291bGQgbm90IHBhcnNlIG9yIHdyaXRlL2kpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd2hlbiBjYWxsZWQgYmVmb3JlIGByZWFkKClgJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYGZhbHNlYCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXhwZWN0KGF3YWl0IGlvLndyaXRlKCkpLnRvLmJlLmZhbHNlO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIGNhbGxlZCB3aXRoIGBmb3JjZTogdHJ1ZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdChpby53cml0ZSh0cnVlKSkudG8uYmUucmVqZWN0ZWRXaXRoKFJlZmVyZW5jZUVycm9yLCAnTm8gZGF0YSB0byB3cml0ZS4gQ2FsbCBgcmVhZCgpYCBmaXJzdCcpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sImZpbGUiOiJ0ZXN0L2V4dC1jb25maWctaW8tc3BlY3MuanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==