@nlabs/lex 1.53.2 → 1.53.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -61,7 +61,7 @@ export default {
61
61
  preset: 'web', // 'web' | 'node' | 'lambda'
62
62
  sourcePath: './src',
63
63
  outputPath: './lib'
64
- }
64
+ };
65
65
  ```
66
66
 
67
67
  ### Command Implementation Pattern
package/README.md CHANGED
@@ -412,25 +412,6 @@ You can also specify ESLint rules in your `lex.config.js` file, but this is less
412
412
  | `webpack.plugins` | `unknown[]` | `undefined` | Webpack plugins | `webpack: { plugins: [new MyPlugin()] }` |
413
413
  | `webpack.staticPath` | `string` | `'./src/static'` | Path to static assets directory. Files in this directory will be copied to the output and optimized (images/videos compressed, audio optimized) | `webpack: { staticPath: './assets' }` |
414
414
 
415
- ### **Tailwind CSS Configuration**
416
-
417
- | Option | Type | Default | Description | Example |
418
- |--------|------|---------|-------------|---------|
419
- | `tailwindContent` | `string[]` | `undefined` | Content paths for Tailwind CSS to scan for class names. Passed to the PostCSS Tailwind plugin during webpack builds. | `tailwindContent: ['./src/**/*.{js,ts,jsx,tsx}', './node_modules/@nlabs/gothamjs/lib/**/*.{js,ts,jsx,tsx}']` |
420
-
421
- **Example usage in `lex.config.js`:**
422
-
423
- ```javascript
424
- export default {
425
- // ... other config
426
- tailwindContent: [
427
- './src/**/*.{js,ts,jsx,tsx}',
428
- // Include external packages that use Tailwind classes
429
- './node_modules/@nlabs/gothamjs/lib/**/*.{js,ts,jsx,tsx}'
430
- ]
431
- };
432
- ```
433
-
434
415
  ### **Library Configuration**
435
416
 
436
417
  | Option | Type | Default | Description | Example |
@@ -497,7 +478,7 @@ export default {
497
478
 
498
479
  ```javascript
499
480
  export default {
500
- useTypescript: true,
481
+ useTypescript: true
501
482
  // SWC provides optimal defaults for all compilation tasks
502
483
  // No additional configuration needed for most use cases
503
484
  // SWC automatically handles:
@@ -16,7 +16,7 @@ const LexConfig = {
16
16
  checkLintTypescriptConfig: jest.fn(),
17
17
  checkTestTypescriptConfig: jest.fn(),
18
18
  getLexDir: jest.fn(() => '/mock/lex/dir'),
19
- updateConfig: jest.fn((config) => ({ ...defaultConfigValues, ...config })),
19
+ updateConfig: jest.fn((config) => ({...defaultConfigValues, ...config})),
20
20
  addConfigParams: jest.fn(),
21
21
  get useTypescript() {
22
22
  return this.config.useTypescript;
@@ -1,7 +1,5 @@
1
1
  // Mock implementation of boxen
2
- const mockBoxen = jest.fn().mockImplementation((text, options) => {
3
- return `[BOXED] ${text}`;
4
- });
2
+ const mockBoxen = jest.fn().mockImplementation((text, options) => `[BOXED] ${text}`);
5
3
 
6
4
  module.exports = mockBoxen;
7
5
  module.exports.default = mockBoxen;
package/__mocks__/file.js CHANGED
@@ -1,5 +1,5 @@
1
- const path = require('path');
2
1
  const fs = require('fs');
2
+ const path = require('path');
3
3
 
4
4
  // Mock implementations that don't use import.meta.url
5
5
  function getDirName() {
@@ -33,7 +33,7 @@ function getNodePath(moduleName) {
33
33
 
34
34
  function resolveBinaryPath(binaryName, packageName) {
35
35
  // Mock implementation
36
- if (packageName) {
36
+ if(packageName) {
37
37
  return path.resolve(process.cwd(), `node_modules/${packageName}/bin/${binaryName}`);
38
38
  }
39
39
  return path.resolve(process.cwd(), `node_modules/.bin/${binaryName}`);
@@ -1,12 +1,10 @@
1
1
  const React = require('react');
2
2
 
3
3
  // Mock implementation of react-markdown
4
- const ReactMarkdown = ({children}) => {
5
- return React.createElement('div', {
6
- 'data-testid': 'react-markdown',
7
- dangerouslySetInnerHTML: {__html: children}
8
- });
9
- };
4
+ const ReactMarkdown = ({children}) => React.createElement('div', {
5
+ 'data-testid': 'react-markdown',
6
+ dangerouslySetInnerHTML: {__html: children}
7
+ });
10
8
 
11
9
  module.exports = ReactMarkdown;
12
10
  module.exports.default = ReactMarkdown;
package/eslint.config.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import {typescriptConfig} from 'eslint-config-styleguidejs';
1
+ import styleguideConfig from 'eslint-config-styleguidejs';
2
2
 
3
3
  export default [
4
- ...typescriptConfig,
4
+ ...styleguideConfig,
5
5
  {
6
6
  ignores: ['*.md'],
7
7
  rules: {
@@ -94,7 +94,7 @@ export default {
94
94
  minify: false, // Enable minification
95
95
  sourceMaps: 'inline', // 'inline', true, false
96
96
  inlineSourcesContent: true, // Inline source content
97
- isModule: true, // Treat as module
97
+ isModule: true // Treat as module
98
98
 
99
99
  // Environment configuration (optional)
100
100
  // env: {
@@ -156,13 +156,5 @@ export default {
156
156
  // },
157
157
  // minify: true,
158
158
  // sourceMaps: true
159
- // },
160
-
161
- // Tailwind CSS content paths
162
- // Specify which files Tailwind should scan for class names
163
- // tailwindContent: [
164
- // './src/**/*.{js,ts,jsx,tsx}',
165
- // // Include external packages that use Tailwind classes
166
- // './node_modules/@nlabs/gothamjs/lib/**/*.{js,ts,jsx,tsx}'
167
- // ]
159
+ // }
168
160
  // };
@@ -3,10 +3,10 @@ require('@testing-library/jest-dom');
3
3
  global.ResizeObserver = jest.fn().mockImplementation(() => ({
4
4
  observe: jest.fn(),
5
5
  unobserve: jest.fn(),
6
- disconnect: jest.fn(),
6
+ disconnect: jest.fn()
7
7
  }));
8
8
 
9
- global.matchMedia = jest.fn().mockImplementation(query => ({
9
+ global.matchMedia = jest.fn().mockImplementation((query) => ({
10
10
  matches: false,
11
11
  media: query,
12
12
  onchange: null,
@@ -14,5 +14,5 @@ global.matchMedia = jest.fn().mockImplementation(query => ({
14
14
  removeListener: jest.fn(),
15
15
  addEventListener: jest.fn(),
16
16
  removeEventListener: jest.fn(),
17
- dispatchEvent: jest.fn(),
17
+ dispatchEvent: jest.fn()
18
18
  }));
package/lex.config.js CHANGED
@@ -73,14 +73,5 @@ export default {
73
73
  jest: {
74
74
  roots: ['<rootDir>/src'],
75
75
  testEnvironment: 'node'
76
- },
77
-
78
- // Tailwind CSS content paths
79
- // Specify which files Tailwind should scan for class names
80
- // This is used by the PostCSS Tailwind plugin during build
81
- tailwindContent: [
82
- './src/**/*.{js,ts,jsx,tsx}',
83
- // Include external packages that use Tailwind classes
84
- // './node_modules/@nlabs/gothamjs/lib/**/*.{js,ts,jsx,tsx}'
85
- ]
76
+ }
86
77
  };
@@ -51,7 +51,6 @@ export interface LexConfigType {
51
51
  sourceFullPath?: string;
52
52
  sourcePath?: string;
53
53
  swc?: SWCOptions;
54
- tailwindContent?: string[];
55
54
  targetEnvironment?: 'node' | 'web';
56
55
  useGraphQl?: boolean;
57
56
  useTypescript?: boolean;
package/lib/LexConfig.js CHANGED
@@ -414,4 +414,4 @@ _define_property(LexConfig, "config", {
414
414
  ...defaultConfigValues
415
415
  });
416
416
 
417
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9MZXhDb25maWcudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCBmaW5kRmlsZVVwIGZyb20gJ2ZpbmQtZmlsZS11cCc7XG5pbXBvcnQge2V4aXN0c1N5bmMsIHJlYWRGaWxlU3luYywgd3JpdGVGaWxlU3luY30gZnJvbSAnZnMnO1xuaW1wb3J0IHtcbiAgZGlybmFtZSxcbiAgZXh0bmFtZSBhcyBwYXRoRXh0bmFtZSxcbiAgcmVsYXRpdmUgYXMgcGF0aFJlbGF0aXZlLFxuICByZXNvbHZlIGFzIHBhdGhSZXNvbHZlXG59IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtVUkx9IGZyb20gJ3VybCc7XG5cbmltcG9ydCB7Z2V0TGV4UGFja2FnZUpzb25QYXRoLCByZWxhdGl2ZUZpbGVQYXRofSBmcm9tICcuL3V0aWxzL2ZpbGUuanMnO1xuaW1wb3J0IHtsb2d9IGZyb20gJy4vdXRpbHMvbG9nLmpzJztcblxuaW1wb3J0IHR5cGUge09wdGlvbnN9IGZyb20gJ0Bzd2MvY29yZSc7XG5pbXBvcnQgdHlwZSB7TGludGVyfSBmcm9tICdlc2xpbnQnO1xuXG5jb25zdCBjd2Q6IHN0cmluZyA9IHByb2Nlc3MuY3dkKCk7XG5cblxuZXhwb3J0IGludGVyZmFjZSBKZXN0Q29uZmlnIHtcbiAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbiAgcm9vdHM/OiBzdHJpbmdbXTtcbiAgdGVzdEVudmlyb25tZW50Pzogc3RyaW5nO1xuICB0cmFuc2Zvcm0/OiBSZWNvcmQ8c3RyaW5nLCBbc3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPl0+O1xuICB0cmFuc2Zvcm1JZ25vcmVQYXR0ZXJucz86IHN0cmluZ1tdO1xuICBtb2R1bGVOYW1lTWFwcGVyPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgZXh0ZW5zaW9uc1RvVHJlYXRBc0VzbT86IHN0cmluZ1tdO1xuICBwcmVzZXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2VicGFja0NvbmZpZyB7XG4gIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gIGVudHJ5Pzogc3RyaW5nIHwgc3RyaW5nW107XG4gIG91dHB1dD86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBtb2R1bGU/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgcGx1Z2lucz86IHVua25vd25bXTtcbiAgc3RhdGljUGF0aD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBSUNvbmZpZyB7XG4gIHByb3ZpZGVyPzogJ2N1cnNvcicgfCAnY29waWxvdCcgfCAnb3BlbmFpJyB8ICdhbnRocm9waWMnIHwgJ25vbmUnO1xuICBhcGlLZXk/OiBzdHJpbmc7XG4gIG1vZGVsPzogc3RyaW5nO1xuICBtYXhUb2tlbnM/OiBudW1iZXI7XG4gIHRlbXBlcmF0dXJlPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVTTGludENvbmZpZyB7XG4gIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gIGV4dGVuZHM/OiBzdHJpbmdbXTtcbiAgcnVsZXM/OiBMaW50ZXIuUnVsZXNSZWNvcmQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGV4Q29uZmlnVHlwZSB7XG4gIGFpPzogQUlDb25maWc7XG4gIGNvbmZpZ0ZpbGVzPzogc3RyaW5nW107XG4gIGNvcHlGaWxlcz86IHN0cmluZ1tdO1xuICBlbnRyeUhUTUw/OiBzdHJpbmc7XG4gIGVudHJ5SnM/OiBzdHJpbmc7XG4gIGVudj86IG9iamVjdDtcbiAgZXNsaW50PzogRVNMaW50Q29uZmlnO1xuICBnaXRVcmw/OiBzdHJpbmc7XG4gIGplc3Q/OiBKZXN0Q29uZmlnO1xuICBsaWJyYXJ5TmFtZT86IHN0cmluZztcbiAgbGlicmFyeVRhcmdldD86IHN0cmluZztcbiAgb3V0cHV0RmlsZT86IHN0cmluZztcbiAgb3V0cHV0RnVsbFBhdGg/OiBzdHJpbmc7XG4gIG91dHB1dEhhc2g/OiBib29sZWFuO1xuICBvdXRwdXRQYXRoPzogc3RyaW5nO1xuICBwYWNrYWdlTWFuYWdlcj86ICducG0nIHwgJ3lhcm4nO1xuICBwcmVzZXQ/OiAnd2ViJyB8ICdub2RlJyB8ICdsYW1iZGEnIHwgJ21vYmlsZSc7XG4gIHNvdXJjZUZ1bGxQYXRoPzogc3RyaW5nO1xuICBzb3VyY2VQYXRoPzogc3RyaW5nO1xuICBzd2M/OiBTV0NPcHRpb25zO1xuICB0YWlsd2luZENvbnRlbnQ/OiBzdHJpbmdbXTtcbiAgdGFyZ2V0RW52aXJvbm1lbnQ/OiAnbm9kZScgfCAnd2ViJztcbiAgdXNlR3JhcGhRbD86IGJvb2xlYW47XG4gIHVzZVR5cGVzY3JpcHQ/OiBib29sZWFuO1xuICB3ZWJwYWNrPzogV2VicGFja0NvbmZpZztcbn1cblxuZXhwb3J0IHR5cGUgQ29uZmlnID0gTGV4Q29uZmlnVHlwZTtcblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRDb25maWdWYWx1ZXM6IExleENvbmZpZ1R5cGUgPSB7XG4gIGFpOiB7XG4gICAgbWF4VG9rZW5zOiA0MDAwLFxuICAgIG1vZGVsOiAnZ3B0LTRvJyxcbiAgICBwcm92aWRlcjogJ25vbmUnLFxuICAgIHRlbXBlcmF0dXJlOiAwLjFcbiAgfSxcbiAgY29uZmlnRmlsZXM6IFtdLFxuICBjb3B5RmlsZXM6IFtdLFxuICBlbnRyeUhUTUw6ICdpbmRleC5odG1sJyxcbiAgZW50cnlKczogJ2luZGV4LmpzJyxcbiAgZW52OiBudWxsLFxuICBlc2xpbnQ6IHt9LFxuICBqZXN0OiB7fSxcbiAgb3V0cHV0RnVsbFBhdGg6IHBhdGhSZXNvbHZlKGN3ZCwgJy4vbGliJyksXG4gIG91dHB1dEhhc2g6IGZhbHNlLFxuICBvdXRwdXRQYXRoOiAnLi9saWInLFxuICBwYWNrYWdlTWFuYWdlcjogJ25wbScsXG4gIHByZXNldDogJ3dlYicsXG4gIHNvdXJjZUZ1bGxQYXRoOiBwYXRoUmVzb2x2ZShjd2QsICcuL3NyYycpLFxuICBzb3VyY2VQYXRoOiAnLi9zcmMnLFxuICBzd2M6IHtcbiAgICBpbmxpbmVTb3VyY2VzQ29udGVudDogdHJ1ZSxcbiAgICBpc01vZHVsZTogdHJ1ZSxcbiAgICBqc2M6IHtcbiAgICAgIGV4dGVybmFsSGVscGVyczogZmFsc2UsXG4gICAgICBrZWVwQ2xhc3NOYW1lczogZmFsc2UsXG4gICAgICBsb29zZTogZmFsc2UsXG4gICAgICBwYXJzZXI6IHtcbiAgICAgICAgZGVjb3JhdG9yczogdHJ1ZSxcbiAgICAgICAgZHluYW1pY0ltcG9ydDogdHJ1ZSxcbiAgICAgICAgc3ludGF4OiAndHlwZXNjcmlwdCcsXG4gICAgICAgIHRzeDogdHJ1ZVxuICAgICAgfSxcbiAgICAgIHRhcmdldDogJ2VzMjAyMycsXG4gICAgICB0cmFuc2Zvcm06IHtcbiAgICAgICAgcmVhY3Q6IHtcbiAgICAgICAgICBydW50aW1lOiAnYXV0b21hdGljJ1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBtaW5pZnk6IGZhbHNlLFxuICAgIG1vZHVsZToge1xuICAgICAgbGF6eTogZmFsc2UsXG4gICAgICBub0ludGVyb3A6IGZhbHNlLFxuICAgICAgc3RyaWN0OiBmYWxzZSxcbiAgICAgIHN0cmljdE1vZGU6IHRydWUsXG4gICAgICB0eXBlOiAnZXM2J1xuICAgIH0sXG4gICAgc291cmNlTWFwczogJ2lubGluZSdcbiAgfSxcbiAgdGFyZ2V0RW52aXJvbm1lbnQ6ICd3ZWInLFxuICB1c2VHcmFwaFFsOiBmYWxzZSxcbiAgdXNlVHlwZXNjcmlwdDogZmFsc2UsXG4gIHdlYnBhY2s6IHtcbiAgICBzdGF0aWNQYXRoOiAnLi9zcmMvc3RhdGljJ1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0UGFja2FnZURpciA9ICgpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjd2QgPSBwcm9jZXNzLmN3ZCgpO1xuICBjb25zdCBjdXJyZW50UGtnUGF0aCA9IHBhdGhSZXNvbHZlKGN3ZCwgJ3BhY2thZ2UuanNvbicpO1xuXG4gIGlmKGV4aXN0c1N5bmMoY3VycmVudFBrZ1BhdGgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBrZyA9IEpTT04ucGFyc2UocmVhZEZpbGVTeW5jKGN1cnJlbnRQa2dQYXRoLCAndXRmOCcpKTtcbiAgICAgIGlmKCFwa2cud29ya3NwYWNlcykge1xuICAgICAgICByZXR1cm4gY3dkO1xuICAgICAgfVxuICAgIH0gY2F0Y2h7XG4gICAgICByZXR1cm4gY3dkO1xuICAgIH1cbiAgfVxuXG4gIGxldCBzZWFyY2hEaXIgPSBjd2Q7XG5cbiAgZm9yKGxldCBpID0gMDsgaSA8IDEwOyBpKyspIHtcbiAgICBjb25zdCBwa2dQYXRoID0gcGF0aFJlc29sdmUoc2VhcmNoRGlyLCAncGFja2FnZS5qc29uJyk7XG4gICAgaWYoZXhpc3RzU3luYyhwa2dQYXRoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGtnID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMocGtnUGF0aCwgJ3V0ZjgnKSk7XG5cbiAgICAgICAgaWYoIXBrZy53b3Jrc3BhY2VzKSB7XG4gICAgICAgICAgcmV0dXJuIHNlYXJjaERpcjtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaHtcbiAgICAgICAgLy8gQ29udGludWUgc2VhcmNoaW5nXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcGFyZW50ID0gZGlybmFtZShzZWFyY2hEaXIpO1xuXG4gICAgaWYocGFyZW50ID09PSBzZWFyY2hEaXIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBzZWFyY2hEaXIgPSBwYXJlbnQ7XG4gIH1cblxuICBjb25zdCBjb25maWdGb3JtYXRzID0gWydqcycsICdtanMnLCAnY2pzJywgJ3RzJywgJ2pzb24nXTtcblxuICBmb3IoY29uc3QgZm9ybWF0IG9mIGNvbmZpZ0Zvcm1hdHMpIHtcbiAgICBjb25zdCBjb25maWdQYXRoID0gZmluZEZpbGVVcC5zeW5jKGBsZXguY29uZmlnLiR7Zm9ybWF0fWAsIGN3ZCwgNSk7XG5cbiAgICBpZihjb25maWdQYXRoKSB7XG4gICAgICByZXR1cm4gZGlybmFtZShjb25maWdQYXRoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY3dkO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFR5cGVTY3JpcHRDb25maWdQYXRoID0gKGNvbmZpZ05hbWU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHBhY2thZ2VEaXIgPSBnZXRQYWNrYWdlRGlyKCk7XG4gIGNvbnN0IGN3ZCA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgaWYoY29uZmlnTmFtZSA9PT0gJ3RzY29uZmlnLmJ1aWxkLmpzb24nKSB7XG4gICAgY29uc3QgcHJvamVjdEJ1aWxkQ29uZmlnID0gcGF0aFJlc29sdmUocGFja2FnZURpciwgJ3RzY29uZmlnLmJ1aWxkLmpzb24nKTtcblxuICAgIGlmKGV4aXN0c1N5bmMocHJvamVjdEJ1aWxkQ29uZmlnKSkge1xuICAgICAgcmV0dXJuIHByb2plY3RCdWlsZENvbmZpZztcbiAgICB9XG5cbiAgICBjb25zdCByb290QnVpbGRDb25maWcgPSBwYXRoUmVzb2x2ZShjd2QsICd0c2NvbmZpZy5idWlsZC5qc29uJyk7XG4gICAgaWYoZXhpc3RzU3luYyhyb290QnVpbGRDb25maWcpKSB7XG4gICAgICByZXR1cm4gcm9vdEJ1aWxkQ29uZmlnO1xuICAgIH1cbiAgfVxuXG4gIGlmKGNvbmZpZ05hbWUgPT09ICd0c2NvbmZpZy5saW50Lmpzb24nKSB7XG4gICAgY29uc3QgcHJvamVjdExpbnRDb25maWcgPSBwYXRoUmVzb2x2ZShwYWNrYWdlRGlyLCAndHNjb25maWcuZXNsaW50Lmpzb24nKTtcbiAgICBpZihleGlzdHNTeW5jKHByb2plY3RMaW50Q29uZmlnKSkge1xuICAgICAgcmV0dXJuIHByb2plY3RMaW50Q29uZmlnO1xuICAgIH1cblxuICAgIGNvbnN0IHJvb3RMaW50Q29uZmlnID0gcGF0aFJlc29sdmUoY3dkLCAndHNjb25maWcuZXNsaW50Lmpzb24nKTtcblxuICAgIGlmKGV4aXN0c1N5bmMocm9vdExpbnRDb25maWcpKSB7XG4gICAgICByZXR1cm4gcm9vdExpbnRDb25maWc7XG4gICAgfVxuICB9XG5cbiAgaWYoY29uZmlnTmFtZSA9PT0gJ3RzY29uZmlnLnRlc3QuanNvbicpIHtcbiAgICBjb25zdCBwcm9qZWN0VGVzdENvbmZpZyA9IHBhdGhSZXNvbHZlKHBhY2thZ2VEaXIsICd0c2NvbmZpZy50ZXN0Lmpzb24nKTtcbiAgICBpZihleGlzdHNTeW5jKHByb2plY3RUZXN0Q29uZmlnKSkge1xuICAgICAgcmV0dXJuIHByb2plY3RUZXN0Q29uZmlnO1xuICAgIH1cblxuICAgIGNvbnN0IHJvb3RUZXN0Q29uZmlnID0gcGF0aFJlc29sdmUoY3dkLCAndHNjb25maWcudGVzdC5qc29uJyk7XG5cbiAgICBpZihleGlzdHNTeW5jKHJvb3RUZXN0Q29uZmlnKSkge1xuICAgICAgcmV0dXJuIHJvb3RUZXN0Q29uZmlnO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHByb2plY3RDb25maWdQYXRoID0gcGF0aFJlc29sdmUocGFja2FnZURpciwgY29uZmlnTmFtZSk7XG5cbiAgaWYoZXhpc3RzU3luYyhwcm9qZWN0Q29uZmlnUGF0aCkpIHtcbiAgICByZXR1cm4gcHJvamVjdENvbmZpZ1BhdGg7XG4gIH1cblxuICBjb25zdCByb290Q29uZmlnUGF0aCA9IHBhdGhSZXNvbHZlKGN3ZCwgY29uZmlnTmFtZSk7XG5cbiAgaWYoZXhpc3RzU3luYyhyb290Q29uZmlnUGF0aCkpIHtcbiAgICByZXR1cm4gcm9vdENvbmZpZ1BhdGg7XG4gIH1cblxuICBjb25zdCBsZXhEaXIgPSBMZXhDb25maWcuZ2V0TGV4RGlyKCk7XG5cbiAgcmV0dXJuIHBhdGhSZXNvbHZlKGxleERpciwgY29uZmlnTmFtZSk7XG59O1xuXG5leHBvcnQgY2xhc3MgTGV4Q29uZmlnIHtcbiAgc3RhdGljIGNvbmZpZzogTGV4Q29uZmlnVHlwZSA9IHtcbiAgICAuLi5kZWZhdWx0Q29uZmlnVmFsdWVzXG4gIH07XG5cbiAgc3RhdGljIHNldCB1c2VUeXBlc2NyaXB0KHZhbHVlOiBib29sZWFuKSB7XG4gICAgTGV4Q29uZmlnLmNvbmZpZy51c2VUeXBlc2NyaXB0ID0gdmFsdWU7XG4gICAgY29uc3Qge2VudHJ5SnMsIHNvdXJjZUZ1bGxQYXRoLCB0YXJnZXRFbnZpcm9ubWVudH0gPSBMZXhDb25maWcuY29uZmlnO1xuXG4gICAgaWYoZW50cnlKcyA9PT0gJ2luZGV4LmpzJyAmJiB2YWx1ZSkge1xuICAgICAgY29uc3QgaW5kZXhQYXRoOiBzdHJpbmcgPSBwYXRoUmVzb2x2ZShjd2QsIHNvdXJjZUZ1bGxQYXRoLCAnaW5kZXgudHN4Jyk7XG4gICAgICBjb25zdCBoYXNJbmRleFRzeDogYm9vbGVhbiA9IGV4aXN0c1N5bmMoaW5kZXhQYXRoKTtcblxuICAgICAgaWYoaGFzSW5kZXhUc3gpIHtcbiAgICAgICAgTGV4Q29uZmlnLmNvbmZpZy5lbnRyeUpzID0gJ2luZGV4LnRzeCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBMZXhDb25maWcuY29uZmlnLmVudHJ5SnMgPSAnaW5kZXgudHMnO1xuICAgICAgfVxuICAgIH1cblxuICAgIExleENvbmZpZy5jb25maWcuc3djLmpzYy5wYXJzZXIgPSB7XG4gICAgICBzeW50YXg6ICd0eXBlc2NyaXB0JyxcbiAgICAgIHRzeDogdHJ1ZVxuICAgIH07XG5cbiAgICBpZih0YXJnZXRFbnZpcm9ubWVudCA9PT0gJ3dlYicpIHtcbiAgICAgIExleENvbmZpZy5jb25maWcuc3djLmpzYy50cmFuc2Zvcm0gPSB7XG4gICAgICAgIHJlYWN0OiB7XG4gICAgICAgICAgcnVudGltZTogJ2F1dG9tYXRpYydcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0TGV4RGlyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGRpcm5hbWUoZ2V0TGV4UGFja2FnZUpzb25QYXRoKCkpO1xuICB9XG5cbiAgc3RhdGljIHVwZGF0ZUNvbmZpZyh1cGRhdGVkQ29uZmlnOiBMZXhDb25maWdUeXBlKTogTGV4Q29uZmlnVHlwZSB7XG4gICAgY29uc3Qge291dHB1dEZ1bGxQYXRoLCBvdXRwdXRQYXRoLCBzb3VyY2VQYXRoLCBzb3VyY2VGdWxsUGF0aCwgdXNlVHlwZXNjcmlwdCwgYWl9ID0gdXBkYXRlZENvbmZpZztcbiAgICBjb25zdCBwYWNrYWdlRGlyID0gZ2V0UGFja2FnZURpcigpO1xuXG4gICAgaWYodXNlVHlwZXNjcmlwdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBMZXhDb25maWcudXNlVHlwZXNjcmlwdCA9IHVzZVR5cGVzY3JpcHQ7XG4gICAgfVxuXG4gICAgaWYob3V0cHV0UGF0aCAhPT0gdW5kZWZpbmVkICYmIG91dHB1dEZ1bGxQYXRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHVwZGF0ZWRDb25maWcub3V0cHV0RnVsbFBhdGggPSBwYXRoUmVzb2x2ZShwYWNrYWdlRGlyLCBvdXRwdXRQYXRoKTtcbiAgICB9XG5cbiAgICBpZihzb3VyY2VQYXRoICE9PSB1bmRlZmluZWQgJiYgc291cmNlRnVsbFBhdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgdXBkYXRlZENvbmZpZy5zb3VyY2VGdWxsUGF0aCA9IHBhdGhSZXNvbHZlKHBhY2thZ2VEaXIsIHNvdXJjZVBhdGgpO1xuICAgIH1cblxuICAgIGlmKGFpKSB7XG4gICAgICBMZXhDb25maWcuY29uZmlnLmFpID0gey4uLkxleENvbmZpZy5jb25maWcuYWksIC4uLmFpfTtcblxuICAgICAgaWYocHJvY2Vzcy5lbnYuQ1VSU09SX0lERSA9PT0gJ3RydWUnICYmIExleENvbmZpZy5jb25maWcuYWkucHJvdmlkZXIgPT09ICdub25lJykge1xuICAgICAgICBMZXhDb25maWcuY29uZmlnLmFpLnByb3ZpZGVyID0gJ2N1cnNvcic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgTGV4Q29uZmlnLmNvbmZpZyA9IHsuLi5MZXhDb25maWcuY29uZmlnLCAuLi51cGRhdGVkQ29uZmlnfTtcblxuICAgIHJldHVybiBMZXhDb25maWcuY29uZmlnO1xuICB9XG5cbiAgc3RhdGljIGFkZENvbmZpZ1BhcmFtcyhjbWQsIHBhcmFtczogTGV4Q29uZmlnVHlwZSkge1xuICAgIGNvbnN0IG5hbWVQcm9wZXJ0eTogc3RyaW5nID0gJ19uYW1lJztcbiAgICBjb25zdCB7ZW52aXJvbm1lbnQsIG91dHB1dFBhdGgsIHNvdXJjZVBhdGgsIHR5cGVzY3JpcHR9ID0gY21kO1xuICAgIGNvbnN0IHBhY2thZ2VEaXIgPSBnZXRQYWNrYWdlRGlyKCk7XG5cbiAgICBpZihvdXRwdXRQYXRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhcmFtcy5vdXRwdXRQYXRoID0gb3V0cHV0UGF0aDtcbiAgICAgIHBhcmFtcy5vdXRwdXRGdWxsUGF0aCA9IHBhdGhSZXNvbHZlKHBhY2thZ2VEaXIsIG91dHB1dFBhdGgpO1xuICAgIH0gZWxzZSBpZihwYXJhbXMub3V0cHV0UGF0aCAmJiAhcGFyYW1zLm91dHB1dEZ1bGxQYXRoKSB7XG4gICAgICBwYXJhbXMub3V0cHV0RnVsbFBhdGggPSBwYXRoUmVzb2x2ZShwYWNrYWdlRGlyLCBwYXJhbXMub3V0cHV0UGF0aCk7XG4gICAgfVxuXG4gICAgaWYoc291cmNlUGF0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXJhbXMuc291cmNlUGF0aCA9IHNvdXJjZVBhdGg7XG4gICAgICBwYXJhbXMuc291cmNlRnVsbFBhdGggPSBwYXRoUmVzb2x2ZShwYWNrYWdlRGlyLCBzb3VyY2VQYXRoKTtcbiAgICB9IGVsc2UgaWYocGFyYW1zLnNvdXJjZVBhdGggJiYgIXBhcmFtcy5zb3VyY2VGdWxsUGF0aCkge1xuICAgICAgcGFyYW1zLnNvdXJjZUZ1bGxQYXRoID0gcGF0aFJlc29sdmUocGFja2FnZURpciwgcGFyYW1zLnNvdXJjZVBhdGgpO1xuICAgIH1cblxuICAgIGlmKHR5cGVzY3JpcHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFyYW1zLnVzZVR5cGVzY3JpcHQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmKGVudmlyb25tZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhcmFtcy50YXJnZXRFbnZpcm9ubWVudCA9IGVudmlyb25tZW50ID09PSAnd2ViJyA/ICd3ZWInIDogJ25vZGUnO1xuICAgIH1cblxuICAgIHByb2Nlc3MuZW52LkxFWF9DT05GSUcgPSBKU09OLnN0cmluZ2lmeShcbiAgICAgIHtcbiAgICAgICAgLi4uTGV4Q29uZmlnLnVwZGF0ZUNvbmZpZyhwYXJhbXMpLFxuICAgICAgICBjb21tYW5kTmFtZTogY21kW25hbWVQcm9wZXJ0eV0sXG4gICAgICAgIGlzU3RhdGljOiBjbWQuc3RhdGljXG4gICAgICB9LCBudWxsLCAwXG4gICAgKTtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBwYXJzZUNvbmZpZyhjbWQsIGlzUm9vdDogYm9vbGVhbiA9IHRydWUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7Y2xpTmFtZSA9ICdMZXgnLCBsZXhDb25maWcsIGxleENvbmZpZ05hbWUsIHF1aWV0LCB0eXBlc2NyaXB0LCBkZWJ1ZyA9IGZhbHNlfSA9IGNtZDtcbiAgICBjb25zdCBjb25maWdGb3JtYXRzID0gWydqcycsICdtanMnLCAnY2pzJywgJ3RzJywgJ2pzb24nXTtcbiAgICBjb25zdCBjb25maWdCYXNlTmFtZTogc3RyaW5nID0gbGV4Q29uZmlnTmFtZSB8fCAnbGV4LmNvbmZpZyc7XG4gICAgbGV0IGNvbmZpZ1BhdGg6IHN0cmluZyA9IGxleENvbmZpZyB8fCAnJztcbiAgICBsZXQgY29uZmlnRXhpc3RzOiBib29sZWFuID0gbGV4Q29uZmlnID8gZXhpc3RzU3luYyhjb25maWdQYXRoKSA6IGZhbHNlO1xuXG4gICAgaWYoIWNvbmZpZ1BhdGggfHwgIWNvbmZpZ0V4aXN0cykge1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBTZWFyY2hpbmcgZm9yIGNvbmZpZyBmaWxlcyB3aXRoIGJhc2UgbmFtZTogJHtjb25maWdCYXNlTmFtZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cblxuICAgICAgZm9yKGNvbnN0IGZvcm1hdCBvZiBjb25maWdGb3JtYXRzKSB7XG4gICAgICAgIGNvbnN0IHBvdGVudGlhbFBhdGggPSBpc1Jvb3RcbiAgICAgICAgICA/IHBhdGhSZXNvbHZlKGN3ZCwgYC4vJHtjb25maWdCYXNlTmFtZX0uJHtmb3JtYXR9YClcbiAgICAgICAgICA6IHJlbGF0aXZlRmlsZVBhdGgoYCR7Y29uZmlnQmFzZU5hbWV9LiR7Zm9ybWF0fWAsIGN3ZCk7XG5cbiAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICBsb2coYENoZWNraW5nIGZvciBjb25maWcgZmlsZTogJHtwb3RlbnRpYWxQYXRofWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoZXhpc3RzU3luYyhwb3RlbnRpYWxQYXRoKSkge1xuICAgICAgICAgIGNvbmZpZ1BhdGggPSBwb3RlbnRpYWxQYXRoO1xuICAgICAgICAgIGNvbmZpZ0V4aXN0cyA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZihjb25maWdFeGlzdHMpIHtcbiAgICAgIGxvZyhgVXNpbmcgJHtjbGlOYW1lfSBjb25maWd1cmF0aW9uIGZpbGU6ICR7Y29uZmlnUGF0aH1gLCAnbm90ZScsIHF1aWV0KTtcbiAgICAgIGNvbnN0IGV4dDogc3RyaW5nID0gcGF0aEV4dG5hbWUoY29uZmlnUGF0aCk7XG5cbiAgICAgIGlmKGV4dCA9PT0gJy5qc29uJykge1xuICAgICAgICBjb25zdCBjb25maWdDb250ZW50OiBzdHJpbmcgPSByZWFkRmlsZVN5bmMoY29uZmlnUGF0aCwgJ3V0ZjgnKTtcblxuICAgICAgICBpZihjb25maWdDb250ZW50KSB7XG4gICAgICAgICAgbGV0IGNvbmZpZ0pzb246IExleENvbmZpZ1R5cGU7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uZmlnSnNvbiA9IEpTT04ucGFyc2UoY29uZmlnQ29udGVudCk/LmRlZmF1bHQgfHwge307XG4gICAgICAgICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBGYWlsZWQgdG8gcGFyc2UgSlNPTiBjb25maWc6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICAgICAgICBjb25maWdKc29uID0ge307XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgTGV4Q29uZmlnLmFkZENvbmZpZ1BhcmFtcyhjbWQsIGNvbmZpZ0pzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogQ29uZmlnIGZpbGUgbWFsZm9ybWVkLCAke2NvbmZpZ1BhdGh9YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYoWycuanMnLCAnLm1qcycsICcuY2pzJywgJy50cyddLmluY2x1ZGVzKGV4dCkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsZXQgbGV4Q3VzdG9tQ29uZmlnO1xuXG4gICAgICAgICAgaWYoZXh0ID09PSAnLmNqcycpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVVcmwgPSBuZXcgVVJMKGBmaWxlOi8vLyR7cGF0aFJlc29sdmUoY29uZmlnUGF0aCl9YCkuaHJlZjtcblxuICAgICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgICAgbG9nKGBMb2FkaW5nIENvbW1vbkpTIGNvbmZpZyBmcm9tOiAke2ZpbGVVcmx9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXhDdXN0b21Db25maWcgPSBhd2FpdCBpbXBvcnQoZmlsZVVybCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgICAgIGxvZyhgTG9hZGluZyBFU00vVFMgY29uZmlnIGZyb206ICR7Y29uZmlnUGF0aH1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV4Q3VzdG9tQ29uZmlnID0gYXdhaXQgaW1wb3J0KGNvbmZpZ1BhdGgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IGxleEN1c3RvbUNvbmZpZy5kZWZhdWx0IHx8IGxleEN1c3RvbUNvbmZpZztcblxuICAgICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgICBsb2coYExvYWRlZCBjb25maWc6ICR7SlNPTi5zdHJpbmdpZnkoY29uZmlnLCBudWxsLCAyKX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZighY29uZmlnKSB7XG4gICAgICAgICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gV2FybmluZzogQ29uZmlnIGZpbGUgbG9hZGVkIGJ1dCBubyBjb25maWd1cmF0aW9uIGZvdW5kYCwgJ3dhcm4nLCBxdWlldCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgTGV4Q29uZmlnLmFkZENvbmZpZ1BhcmFtcyhjbWQsIGNvbmZpZyB8fCB7fSk7XG4gICAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IEZhaWxlZCB0byBsb2FkIGNvbmZpZyBmaWxlOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IENvbmZpZyBmaWxlIG11c3QgYmUgYSBKUywgQ0pTLCBNSlMsIFRTLCBvciBKU09OIGZpbGUuYCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coJ05vIGNvbmZpZyBmaWxlIGZvdW5kLiBVc2luZyBkZWZhdWx0IGNvbmZpZ3VyYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIExleENvbmZpZy51c2VUeXBlc2NyaXB0ID0gISF0eXBlc2NyaXB0O1xuICAgICAgTGV4Q29uZmlnLmFkZENvbmZpZ1BhcmFtcyhjbWQsIExleENvbmZpZy5jb25maWcpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBjaGVja1R5cGVzY3JpcHRDb25maWcoKSB7XG4gICAgY29uc3QgcGFja2FnZURpciA9IGdldFBhY2thZ2VEaXIoKTtcbiAgICBjb25zdCB0c2NvbmZpZ1BhdGg6IHN0cmluZyA9IHBhdGhSZXNvbHZlKHBhY2thZ2VEaXIsICcuL3RzY29uZmlnLmpzb24nKTtcblxuICAgIGlmKCFleGlzdHNTeW5jKHRzY29uZmlnUGF0aCkpIHtcbiAgICAgIGNvbnN0IGxleERpciA9IExleENvbmZpZy5nZXRMZXhEaXIoKTtcbiAgICAgIGNvbnN0IGJhc2VDb25maWdQYXRoID0gcGF0aFJlc29sdmUobGV4RGlyLCAndHNjb25maWcuYmFzZS5qc29uJyk7XG4gICAgICBjb25zdCB0ZW1wbGF0ZUNvbmZpZ1BhdGggPSBwYXRoUmVzb2x2ZShsZXhEaXIsICd0c2NvbmZpZy50ZW1wbGF0ZS5qc29uJyk7XG4gICAgICBjb25zdCBzb3VyY2VQYXRoID0gZXhpc3RzU3luYyhiYXNlQ29uZmlnUGF0aCkgPyBiYXNlQ29uZmlnUGF0aCA6IHRlbXBsYXRlQ29uZmlnUGF0aDtcblxuICAgICAgaWYoZXhpc3RzU3luYyhzb3VyY2VQYXRoKSkge1xuICAgICAgICB3cml0ZUZpbGVTeW5jKHRzY29uZmlnUGF0aCwgcmVhZEZpbGVTeW5jKHNvdXJjZVBhdGgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0VHlwZVNjcmlwdERlY2xhcmF0aW9uRmxhZ3MoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGN3ZCA9IHByb2Nlc3MuY3dkKCk7XG4gICAgY29uc3Qgb3V0cHV0UGF0aCA9IExleENvbmZpZy5jb25maWcub3V0cHV0UGF0aCB8fCAnLi9saWInO1xuICAgIGNvbnN0IG91dHB1dEZ1bGxQYXRoID0gTGV4Q29uZmlnLmNvbmZpZy5vdXRwdXRGdWxsUGF0aCB8fCBwYXRoUmVzb2x2ZShjd2QsIG91dHB1dFBhdGgpO1xuICAgIGNvbnN0IHNvdXJjZVBhdGggPSBMZXhDb25maWcuY29uZmlnLnNvdXJjZVBhdGggfHwgJy4vc3JjJztcbiAgICBjb25zdCBzb3VyY2VGdWxsUGF0aCA9IExleENvbmZpZy5jb25maWcuc291cmNlRnVsbFBhdGggfHwgcGF0aFJlc29sdmUoY3dkLCBzb3VyY2VQYXRoKTtcbiAgICBjb25zdCByZWxhdGl2ZU91dERpciA9IHBhdGhSZWxhdGl2ZShjd2QsIG91dHB1dEZ1bGxQYXRoKSB8fCAnLi9saWInO1xuICAgIGNvbnN0IHJlbGF0aXZlUm9vdERpciA9IHBhdGhSZWxhdGl2ZShjd2QsIHNvdXJjZUZ1bGxQYXRoKSB8fCAnLi9zcmMnO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgICctLWVtaXREZWNsYXJhdGlvbk9ubHknLCAvLyBDUklUSUNBTDogT25seSBlbWl0IC5kLnRzIGZpbGVzLCBubyBKUyBmaWxlc1xuICAgICAgJy0tZGVjbGFyYXRpb24nLCAvLyBHZW5lcmF0ZSBkZWNsYXJhdGlvbiBmaWxlc1xuICAgICAgJy0tZGVjbGFyYXRpb25NYXAnLCAvLyBHZW5lcmF0ZSBzb3VyY2UgbWFwcyBmb3IgZGVjbGFyYXRpb25zXG4gICAgICAnLS1vdXREaXInLCByZWxhdGl2ZU91dERpcixcbiAgICAgICctLXJvb3REaXInLCByZWxhdGl2ZVJvb3REaXIsXG4gICAgICAnLS1za2lwTGliQ2hlY2snLCAvLyBTa2lwIHR5cGUgY2hlY2tpbmcgb2YgZGVjbGFyYXRpb24gZmlsZXMgKGZhc3RlciwgbW9yZSBsZW5pZW50KVxuICAgICAgJy0tZXNNb2R1bGVJbnRlcm9wJyxcbiAgICAgICctLWFsbG93U3ludGhldGljRGVmYXVsdEltcG9ydHMnLFxuICAgICAgJy0tbW9kdWxlJywgJ05vZGVOZXh0JyxcbiAgICAgICctLW1vZHVsZVJlc29sdXRpb24nLCAnTm9kZU5leHQnLFxuICAgICAgJy0tdGFyZ2V0JywgJ0VTTmV4dCcsXG4gICAgICAnLS1qc3gnLCAncmVhY3QtanN4JyxcbiAgICAgICctLWlzb2xhdGVkTW9kdWxlcycsXG4gICAgICAnLS1yZXNvbHZlSnNvbk1vZHVsZScsXG4gICAgICAnLS1hbGxvd0pzJ1xuICAgICAgLy8gTm90ZTogLS1ub1VudXNlZExvY2FscyBhbmQgLS1ub1VudXNlZFBhcmFtZXRlcnMgYXJlIG5vdCBuZWVkZWQgZm9yIGRlY2xhcmF0aW9uIGdlbmVyYXRpb25cbiAgICAgIC8vIGFuZCB3b3VsZCBhY3R1YWxseSBlbmFibGUgc3RyaWN0IGNoZWNraW5nLCB3aGljaCB3ZSB3YW50IHRvIGF2b2lkIGZvciBmYXN0ZXIgZGVjbGFyYXRpb24gZ2VuZXJhdGlvblxuICAgIF07XG4gIH1cblxuICBzdGF0aWMgY2hlY2tMaW50VHlwZXNjcmlwdENvbmZpZygpIHtcbiAgICBjb25zdCBsZXhEaXIgPSBMZXhDb25maWcuZ2V0TGV4RGlyKCk7XG4gICAgY29uc3QgdHNjb25maWdMaW50UGF0aDogc3RyaW5nID0gcGF0aFJlc29sdmUobGV4RGlyLCAnLi90c2NvbmZpZy5saW50Lmpzb24nKTtcblxuICAgIGlmKCFleGlzdHNTeW5jKHRzY29uZmlnTGludFBhdGgpKSB7XG4gICAgICBjb25zdCB0ZW1wbGF0ZVBhdGggPSBwYXRoUmVzb2x2ZShsZXhEaXIsICd0c2NvbmZpZy5saW50Lmpzb24nKTtcbiAgICAgIGlmKGV4aXN0c1N5bmModGVtcGxhdGVQYXRoKSkge1xuICAgICAgICB3cml0ZUZpbGVTeW5jKHRzY29uZmlnTGludFBhdGgsIHJlYWRGaWxlU3luYyh0ZW1wbGF0ZVBhdGgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgY2hlY2tUZXN0VHlwZXNjcmlwdENvbmZpZygpIHtcbiAgICBjb25zdCBsZXhEaXIgPSBMZXhDb25maWcuZ2V0TGV4RGlyKCk7XG4gICAgY29uc3QgdHNjb25maWdUZXN0UGF0aDogc3RyaW5nID0gcGF0aFJlc29sdmUobGV4RGlyLCAnLi90c2NvbmZpZy50ZXN0Lmpzb24nKTtcblxuICAgIGlmKCFleGlzdHNTeW5jKHRzY29uZmlnVGVzdFBhdGgpKSB7XG4gICAgICBjb25zdCB0ZW1wbGF0ZVBhdGggPSBwYXRoUmVzb2x2ZShsZXhEaXIsICd0c2NvbmZpZy50ZXN0Lmpzb24nKTtcbiAgICAgIGlmKGV4aXN0c1N5bmModGVtcGxhdGVQYXRoKSkge1xuICAgICAgICB3cml0ZUZpbGVTeW5jKHRzY29uZmlnVGVzdFBhdGgsIHJlYWRGaWxlU3luYyh0ZW1wbGF0ZVBhdGgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgU1dDT3B0aW9ucyA9IE9wdGlvbnM7Il0sIm5hbWVzIjpbImZpbmRGaWxlVXAiLCJleGlzdHNTeW5jIiwicmVhZEZpbGVTeW5jIiwid3JpdGVGaWxlU3luYyIsImRpcm5hbWUiLCJleHRuYW1lIiwicGF0aEV4dG5hbWUiLCJyZWxhdGl2ZSIsInBhdGhSZWxhdGl2ZSIsInJlc29sdmUiLCJwYXRoUmVzb2x2ZSIsIlVSTCIsImdldExleFBhY2thZ2VKc29uUGF0aCIsInJlbGF0aXZlRmlsZVBhdGgiLCJsb2ciLCJjd2QiLCJwcm9jZXNzIiwiZGVmYXVsdENvbmZpZ1ZhbHVlcyIsImFpIiwibWF4VG9rZW5zIiwibW9kZWwiLCJwcm92aWRlciIsInRlbXBlcmF0dXJlIiwiY29uZmlnRmlsZXMiLCJjb3B5RmlsZXMiLCJlbnRyeUhUTUwiLCJlbnRyeUpzIiwiZW52IiwiZXNsaW50IiwiamVzdCIsIm91dHB1dEZ1bGxQYXRoIiwib3V0cHV0SGFzaCIsIm91dHB1dFBhdGgiLCJwYWNrYWdlTWFuYWdlciIsInByZXNldCIsInNvdXJjZUZ1bGxQYXRoIiwic291cmNlUGF0aCIsInN3YyIsImlubGluZVNvdXJjZXNDb250ZW50IiwiaXNNb2R1bGUiLCJqc2MiLCJleHRlcm5hbEhlbHBlcnMiLCJrZWVwQ2xhc3NOYW1lcyIsImxvb3NlIiwicGFyc2VyIiwiZGVjb3JhdG9ycyIsImR5bmFtaWNJbXBvcnQiLCJzeW50YXgiLCJ0c3giLCJ0YXJnZXQiLCJ0cmFuc2Zvcm0iLCJyZWFjdCIsInJ1bnRpbWUiLCJtaW5pZnkiLCJtb2R1bGUiLCJsYXp5Iiwibm9JbnRlcm9wIiwic3RyaWN0Iiwic3RyaWN0TW9kZSIsInR5cGUiLCJzb3VyY2VNYXBzIiwidGFyZ2V0RW52aXJvbm1lbnQiLCJ1c2VHcmFwaFFsIiwidXNlVHlwZXNjcmlwdCIsIndlYnBhY2siLCJzdGF0aWNQYXRoIiwiZ2V0UGFja2FnZURpciIsImN1cnJlbnRQa2dQYXRoIiwicGtnIiwiSlNPTiIsInBhcnNlIiwid29ya3NwYWNlcyIsInNlYXJjaERpciIsImkiLCJwa2dQYXRoIiwicGFyZW50IiwiY29uZmlnRm9ybWF0cyIsImZvcm1hdCIsImNvbmZpZ1BhdGgiLCJzeW5jIiwiZ2V0VHlwZVNjcmlwdENvbmZpZ1BhdGgiLCJjb25maWdOYW1lIiwicGFja2FnZURpciIsInByb2plY3RCdWlsZENvbmZpZyIsInJvb3RCdWlsZENvbmZpZyIsInByb2plY3RMaW50Q29uZmlnIiwicm9vdExpbnRDb25maWciLCJwcm9qZWN0VGVzdENvbmZpZyIsInJvb3RUZXN0Q29uZmlnIiwicHJvamVjdENvbmZpZ1BhdGgiLCJyb290Q29uZmlnUGF0aCIsImxleERpciIsIkxleENvbmZpZyIsImdldExleERpciIsInZhbHVlIiwiY29uZmlnIiwiaW5kZXhQYXRoIiwiaGFzSW5kZXhUc3giLCJ1cGRhdGVDb25maWciLCJ1cGRhdGVkQ29uZmlnIiwidW5kZWZpbmVkIiwiQ1VSU09SX0lERSIsImFkZENvbmZpZ1BhcmFtcyIsImNtZCIsInBhcmFtcyIsIm5hbWVQcm9wZXJ0eSIsImVudmlyb25tZW50IiwidHlwZXNjcmlwdCIsIkxFWF9DT05GSUciLCJzdHJpbmdpZnkiLCJjb21tYW5kTmFtZSIsImlzU3RhdGljIiwic3RhdGljIiwicGFyc2VDb25maWciLCJpc1Jvb3QiLCJjbGlOYW1lIiwibGV4Q29uZmlnIiwibGV4Q29uZmlnTmFtZSIsInF1aWV0IiwiZGVidWciLCJjb25maWdCYXNlTmFtZSIsImNvbmZpZ0V4aXN0cyIsInBvdGVudGlhbFBhdGgiLCJleHQiLCJjb25maWdDb250ZW50IiwiY29uZmlnSnNvbiIsImRlZmF1bHQiLCJlcnJvciIsIm1lc3NhZ2UiLCJpbmNsdWRlcyIsImxleEN1c3RvbUNvbmZpZyIsImZpbGVVcmwiLCJocmVmIiwiY29uc29sZSIsImNoZWNrVHlwZXNjcmlwdENvbmZpZyIsInRzY29uZmlnUGF0aCIsImJhc2VDb25maWdQYXRoIiwidGVtcGxhdGVDb25maWdQYXRoIiwiZ2V0VHlwZVNjcmlwdERlY2xhcmF0aW9uRmxhZ3MiLCJyZWxhdGl2ZU91dERpciIsInJlbGF0aXZlUm9vdERpciIsImNoZWNrTGludFR5cGVzY3JpcHRDb25maWciLCJ0c2NvbmZpZ0xpbnRQYXRoIiwidGVtcGxhdGVQYXRoIiwiY2hlY2tUZXN0VHlwZXNjcmlwdENvbmZpZyIsInRzY29uZmlnVGVzdFBhdGgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFBQTs7O0NBR0MsR0FDRCxPQUFPQSxnQkFBZ0IsZUFBZTtBQUN0QyxTQUFRQyxVQUFVLEVBQUVDLFlBQVksRUFBRUMsYUFBYSxRQUFPLEtBQUs7QUFDM0QsU0FDRUMsT0FBTyxFQUNQQyxXQUFXQyxXQUFXLEVBQ3RCQyxZQUFZQyxZQUFZLEVBQ3hCQyxXQUFXQyxXQUFXLFFBQ2pCLE9BQU87QUFDZCxTQUFRQyxHQUFHLFFBQU8sTUFBTTtBQUV4QixTQUFRQyxxQkFBcUIsRUFBRUMsZ0JBQWdCLFFBQU8sa0JBQWtCO0FBQ3hFLFNBQVFDLEdBQUcsUUFBTyxpQkFBaUI7QUFLbkMsTUFBTUMsTUFBY0MsUUFBUUQsR0FBRztBQW1FL0IsT0FBTyxNQUFNRSxzQkFB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
417
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9MZXhDb25maWcudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCBmaW5kRmlsZVVwIGZyb20gJ2ZpbmQtZmlsZS11cCc7XG5pbXBvcnQge2V4aXN0c1N5bmMsIHJlYWRGaWxlU3luYywgd3JpdGVGaWxlU3luY30gZnJvbSAnZnMnO1xuaW1wb3J0IHtcbiAgZGlybmFtZSxcbiAgZXh0bmFtZSBhcyBwYXRoRXh0bmFtZSxcbiAgcmVsYXRpdmUgYXMgcGF0aFJlbGF0aXZlLFxuICByZXNvbHZlIGFzIHBhdGhSZXNvbHZlXG59IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtVUkx9IGZyb20gJ3VybCc7XG5cbmltcG9ydCB7Z2V0TGV4UGFja2FnZUpzb25QYXRoLCByZWxhdGl2ZUZpbGVQYXRofSBmcm9tICcuL3V0aWxzL2ZpbGUuanMnO1xuaW1wb3J0IHtsb2d9IGZyb20gJy4vdXRpbHMvbG9nLmpzJztcblxuaW1wb3J0IHR5cGUge09wdGlvbnN9IGZyb20gJ0Bzd2MvY29yZSc7XG5pbXBvcnQgdHlwZSB7TGludGVyfSBmcm9tICdlc2xpbnQnO1xuXG5jb25zdCBjd2Q6IHN0cmluZyA9IHByb2Nlc3MuY3dkKCk7XG5cblxuZXhwb3J0IGludGVyZmFjZSBKZXN0Q29uZmlnIHtcbiAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbiAgcm9vdHM/OiBzdHJpbmdbXTtcbiAgdGVzdEVudmlyb25tZW50Pzogc3RyaW5nO1xuICB0cmFuc2Zvcm0/OiBSZWNvcmQ8c3RyaW5nLCBbc3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPl0+O1xuICB0cmFuc2Zvcm1JZ25vcmVQYXR0ZXJucz86IHN0cmluZ1tdO1xuICBtb2R1bGVOYW1lTWFwcGVyPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgZXh0ZW5zaW9uc1RvVHJlYXRBc0VzbT86IHN0cmluZ1tdO1xuICBwcmVzZXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2VicGFja0NvbmZpZyB7XG4gIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gIGVudHJ5Pzogc3RyaW5nIHwgc3RyaW5nW107XG4gIG91dHB1dD86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBtb2R1bGU/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgcGx1Z2lucz86IHVua25vd25bXTtcbiAgc3RhdGljUGF0aD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBSUNvbmZpZyB7XG4gIHByb3ZpZGVyPzogJ2N1cnNvcicgfCAnY29waWxvdCcgfCAnb3BlbmFpJyB8ICdhbnRocm9waWMnIHwgJ25vbmUnO1xuICBhcGlLZXk/OiBzdHJpbmc7XG4gIG1vZGVsPzogc3RyaW5nO1xuICBtYXhUb2tlbnM/OiBudW1iZXI7XG4gIHRlbXBlcmF0dXJlPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVTTGludENvbmZpZyB7XG4gIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gIGV4dGVuZHM/OiBzdHJpbmdbXTtcbiAgcnVsZXM/OiBMaW50ZXIuUnVsZXNSZWNvcmQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGV4Q29uZmlnVHlwZSB7XG4gIGFpPzogQUlDb25maWc7XG4gIGNvbmZpZ0ZpbGVzPzogc3RyaW5nW107XG4gIGNvcHlGaWxlcz86IHN0cmluZ1tdO1xuICBlbnRyeUhUTUw/OiBzdHJpbmc7XG4gIGVudHJ5SnM/OiBzdHJpbmc7XG4gIGVudj86IG9iamVjdDtcbiAgZXNsaW50PzogRVNMaW50Q29uZmlnO1xuICBnaXRVcmw/OiBzdHJpbmc7XG4gIGplc3Q/OiBKZXN0Q29uZmlnO1xuICBsaWJyYXJ5TmFtZT86IHN0cmluZztcbiAgbGlicmFyeVRhcmdldD86IHN0cmluZztcbiAgb3V0cHV0RmlsZT86IHN0cmluZztcbiAgb3V0cHV0RnVsbFBhdGg/OiBzdHJpbmc7XG4gIG91dHB1dEhhc2g/OiBib29sZWFuO1xuICBvdXRwdXRQYXRoPzogc3RyaW5nO1xuICBwYWNrYWdlTWFuYWdlcj86ICducG0nIHwgJ3lhcm4nO1xuICBwcmVzZXQ/OiAnd2ViJyB8ICdub2RlJyB8ICdsYW1iZGEnIHwgJ21vYmlsZSc7XG4gIHNvdXJjZUZ1bGxQYXRoPzogc3RyaW5nO1xuICBzb3VyY2VQYXRoPzogc3RyaW5nO1xuICBzd2M/OiBTV0NPcHRpb25zO1xuICB0YXJnZXRFbnZpcm9ubWVudD86ICdub2RlJyB8ICd3ZWInO1xuICB1c2VHcmFwaFFsPzogYm9vbGVhbjtcbiAgdXNlVHlwZXNjcmlwdD86IGJvb2xlYW47XG4gIHdlYnBhY2s/OiBXZWJwYWNrQ29uZmlnO1xufVxuXG5leHBvcnQgdHlwZSBDb25maWcgPSBMZXhDb25maWdUeXBlO1xuXG5leHBvcnQgY29uc3QgZGVmYXVsdENvbmZpZ1ZhbHVlczogTGV4Q29uZmlnVHlwZSA9IHtcbiAgYWk6IHtcbiAgICBtYXhUb2tlbnM6IDQwMDAsXG4gICAgbW9kZWw6ICdncHQtNG8nLFxuICAgIHByb3ZpZGVyOiAnbm9uZScsXG4gICAgdGVtcGVyYXR1cmU6IDAuMVxuICB9LFxuICBjb25maWdGaWxlczogW10sXG4gIGNvcHlGaWxlczogW10sXG4gIGVudHJ5SFRNTDogJ2luZGV4Lmh0bWwnLFxuICBlbnRyeUpzOiAnaW5kZXguanMnLFxuICBlbnY6IG51bGwsXG4gIGVzbGludDoge30sXG4gIGplc3Q6IHt9LFxuICBvdXRwdXRGdWxsUGF0aDogcGF0aFJlc29sdmUoY3dkLCAnLi9saWInKSxcbiAgb3V0cHV0SGFzaDogZmFsc2UsXG4gIG91dHB1dFBhdGg6ICcuL2xpYicsXG4gIHBhY2thZ2VNYW5hZ2VyOiAnbnBtJyxcbiAgcHJlc2V0OiAnd2ViJyxcbiAgc291cmNlRnVsbFBhdGg6IHBhdGhSZXNvbHZlKGN3ZCwgJy4vc3JjJyksXG4gIHNvdXJjZVBhdGg6ICcuL3NyYycsXG4gIHN3Yzoge1xuICAgIGlubGluZVNvdXJjZXNDb250ZW50OiB0cnVlLFxuICAgIGlzTW9kdWxlOiB0cnVlLFxuICAgIGpzYzoge1xuICAgICAgZXh0ZXJuYWxIZWxwZXJzOiBmYWxzZSxcbiAgICAgIGtlZXBDbGFzc05hbWVzOiBmYWxzZSxcbiAgICAgIGxvb3NlOiBmYWxzZSxcbiAgICAgIHBhcnNlcjoge1xuICAgICAgICBkZWNvcmF0b3JzOiB0cnVlLFxuICAgICAgICBkeW5hbWljSW1wb3J0OiB0cnVlLFxuICAgICAgICBzeW50YXg6ICd0eXBlc2NyaXB0JyxcbiAgICAgICAgdHN4OiB0cnVlXG4gICAgICB9LFxuICAgICAgdGFyZ2V0OiAnZXMyMDIzJyxcbiAgICAgIHRyYW5zZm9ybToge1xuICAgICAgICByZWFjdDoge1xuICAgICAgICAgIHJ1bnRpbWU6ICdhdXRvbWF0aWMnXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIG1pbmlmeTogZmFsc2UsXG4gICAgbW9kdWxlOiB7XG4gICAgICBsYXp5OiBmYWxzZSxcbiAgICAgIG5vSW50ZXJvcDogZmFsc2UsXG4gICAgICBzdHJpY3Q6IGZhbHNlLFxuICAgICAgc3RyaWN0TW9kZTogdHJ1ZSxcbiAgICAgIHR5cGU6ICdlczYnXG4gICAgfSxcbiAgICBzb3VyY2VNYXBzOiAnaW5saW5lJ1xuICB9LFxuICB0YXJnZXRFbnZpcm9ubWVudDogJ3dlYicsXG4gIHVzZUdyYXBoUWw6IGZhbHNlLFxuICB1c2VUeXBlc2NyaXB0OiBmYWxzZSxcbiAgd2VicGFjazoge1xuICAgIHN0YXRpY1BhdGg6ICcuL3NyYy9zdGF0aWMnXG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQYWNrYWdlRGlyID0gKCk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGN3ZCA9IHByb2Nlc3MuY3dkKCk7XG4gIGNvbnN0IGN1cnJlbnRQa2dQYXRoID0gcGF0aFJlc29sdmUoY3dkLCAncGFja2FnZS5qc29uJyk7XG5cbiAgaWYoZXhpc3RzU3luYyhjdXJyZW50UGtnUGF0aCkpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGtnID0gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMoY3VycmVudFBrZ1BhdGgsICd1dGY4JykpO1xuICAgICAgaWYoIXBrZy53b3Jrc3BhY2VzKSB7XG4gICAgICAgIHJldHVybiBjd2Q7XG4gICAgICB9XG4gICAgfSBjYXRjaHtcbiAgICAgIHJldHVybiBjd2Q7XG4gICAgfVxuICB9XG5cbiAgbGV0IHNlYXJjaERpciA9IGN3ZDtcblxuICBmb3IobGV0IGkgPSAwOyBpIDwgMTA7IGkrKykge1xuICAgIGNvbnN0IHBrZ1BhdGggPSBwYXRoUmVzb2x2ZShzZWFyY2hEaXIsICdwYWNrYWdlLmpzb24nKTtcbiAgICBpZihleGlzdHNTeW5jKHBrZ1BhdGgpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBwa2cgPSBKU09OLnBhcnNlKHJlYWRGaWxlU3luYyhwa2dQYXRoLCAndXRmOCcpKTtcblxuICAgICAgICBpZighcGtnLndvcmtzcGFjZXMpIHtcbiAgICAgICAgICByZXR1cm4gc2VhcmNoRGlyO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoe1xuICAgICAgICAvLyBDb250aW51ZSBzZWFyY2hpbmdcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBwYXJlbnQgPSBkaXJuYW1lKHNlYXJjaERpcik7XG5cbiAgICBpZihwYXJlbnQgPT09IHNlYXJjaERpcikge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHNlYXJjaERpciA9IHBhcmVudDtcbiAgfVxuXG4gIGNvbnN0IGNvbmZpZ0Zvcm1hdHMgPSBbJ2pzJywgJ21qcycsICdjanMnLCAndHMnLCAnanNvbiddO1xuXG4gIGZvcihjb25zdCBmb3JtYXQgb2YgY29uZmlnRm9ybWF0cykge1xuICAgIGNvbnN0IGNvbmZpZ1BhdGggPSBmaW5kRmlsZVVwLnN5bmMoYGxleC5jb25maWcuJHtmb3JtYXR9YCwgY3dkLCA1KTtcblxuICAgIGlmKGNvbmZpZ1BhdGgpIHtcbiAgICAgIHJldHVybiBkaXJuYW1lKGNvbmZpZ1BhdGgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjd2Q7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VHlwZVNjcmlwdENvbmZpZ1BhdGggPSAoY29uZmlnTmFtZTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcGFja2FnZURpciA9IGdldFBhY2thZ2VEaXIoKTtcbiAgY29uc3QgY3dkID0gcHJvY2Vzcy5jd2QoKTtcblxuICBpZihjb25maWdOYW1lID09PSAndHNjb25maWcuYnVpbGQuanNvbicpIHtcbiAgICBjb25zdCBwcm9qZWN0QnVpbGRDb25maWcgPSBwYXRoUmVzb2x2ZShwYWNrYWdlRGlyLCAndHNjb25maWcuYnVpbGQuanNvbicpO1xuXG4gICAgaWYoZXhpc3RzU3luYyhwcm9qZWN0QnVpbGRDb25maWcpKSB7XG4gICAgICByZXR1cm4gcHJvamVjdEJ1aWxkQ29uZmlnO1xuICAgIH1cblxuICAgIGNvbnN0IHJvb3RCdWlsZENvbmZpZyA9IHBhdGhSZXNvbHZlKGN3ZCwgJ3RzY29uZmlnLmJ1aWxkLmpzb24nKTtcbiAgICBpZihleGlzdHNTeW5jKHJvb3RCdWlsZENvbmZpZykpIHtcbiAgICAgIHJldHVybiByb290QnVpbGRDb25maWc7XG4gICAgfVxuICB9XG5cbiAgaWYoY29uZmlnTmFtZSA9PT0gJ3RzY29uZmlnLmxpbnQuanNvbicpIHtcbiAgICBjb25zdCBwcm9qZWN0TGludENvbmZpZyA9IHBhdGhSZXNvbHZlKHBhY2thZ2VEaXIsICd0c2NvbmZpZy5lc2xpbnQuanNvbicpO1xuICAgIGlmKGV4aXN0c1N5bmMocHJvamVjdExpbnRDb25maWcpKSB7XG4gICAgICByZXR1cm4gcHJvamVjdExpbnRDb25maWc7XG4gICAgfVxuXG4gICAgY29uc3Qgcm9vdExpbnRDb25maWcgPSBwYXRoUmVzb2x2ZShjd2QsICd0c2NvbmZpZy5lc2xpbnQuanNvbicpO1xuXG4gICAgaWYoZXhpc3RzU3luYyhyb290TGludENvbmZpZykpIHtcbiAgICAgIHJldHVybiByb290TGludENvbmZpZztcbiAgICB9XG4gIH1cblxuICBpZihjb25maWdOYW1lID09PSAndHNjb25maWcudGVzdC5qc29uJykge1xuICAgIGNvbnN0IHByb2plY3RUZXN0Q29uZmlnID0gcGF0aFJlc29sdmUocGFja2FnZURpciwgJ3RzY29uZmlnLnRlc3QuanNvbicpO1xuICAgIGlmKGV4aXN0c1N5bmMocHJvamVjdFRlc3RDb25maWcpKSB7XG4gICAgICByZXR1cm4gcHJvamVjdFRlc3RDb25maWc7XG4gICAgfVxuXG4gICAgY29uc3Qgcm9vdFRlc3RDb25maWcgPSBwYXRoUmVzb2x2ZShjd2QsICd0c2NvbmZpZy50ZXN0Lmpzb24nKTtcblxuICAgIGlmKGV4aXN0c1N5bmMocm9vdFRlc3RDb25maWcpKSB7XG4gICAgICByZXR1cm4gcm9vdFRlc3RDb25maWc7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcHJvamVjdENvbmZpZ1BhdGggPSBwYXRoUmVzb2x2ZShwYWNrYWdlRGlyLCBjb25maWdOYW1lKTtcblxuICBpZihleGlzdHNTeW5jKHByb2plY3RDb25maWdQYXRoKSkge1xuICAgIHJldHVybiBwcm9qZWN0Q29uZmlnUGF0aDtcbiAgfVxuXG4gIGNvbnN0IHJvb3RDb25maWdQYXRoID0gcGF0aFJlc29sdmUoY3dkLCBjb25maWdOYW1lKTtcblxuICBpZihleGlzdHNTeW5jKHJvb3RDb25maWdQYXRoKSkge1xuICAgIHJldHVybiByb290Q29uZmlnUGF0aDtcbiAgfVxuXG4gIGNvbnN0IGxleERpciA9IExleENvbmZpZy5nZXRMZXhEaXIoKTtcblxuICByZXR1cm4gcGF0aFJlc29sdmUobGV4RGlyLCBjb25maWdOYW1lKTtcbn07XG5cbmV4cG9ydCBjbGFzcyBMZXhDb25maWcge1xuICBzdGF0aWMgY29uZmlnOiBMZXhDb25maWdUeXBlID0ge1xuICAgIC4uLmRlZmF1bHRDb25maWdWYWx1ZXNcbiAgfTtcblxuICBzdGF0aWMgc2V0IHVzZVR5cGVzY3JpcHQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBMZXhDb25maWcuY29uZmlnLnVzZVR5cGVzY3JpcHQgPSB2YWx1ZTtcbiAgICBjb25zdCB7ZW50cnlKcywgc291cmNlRnVsbFBhdGgsIHRhcmdldEVudmlyb25tZW50fSA9IExleENvbmZpZy5jb25maWc7XG5cbiAgICBpZihlbnRyeUpzID09PSAnaW5kZXguanMnICYmIHZhbHVlKSB7XG4gICAgICBjb25zdCBpbmRleFBhdGg6IHN0cmluZyA9IHBhdGhSZXNvbHZlKGN3ZCwgc291cmNlRnVsbFBhdGgsICdpbmRleC50c3gnKTtcbiAgICAgIGNvbnN0IGhhc0luZGV4VHN4OiBib29sZWFuID0gZXhpc3RzU3luYyhpbmRleFBhdGgpO1xuXG4gICAgICBpZihoYXNJbmRleFRzeCkge1xuICAgICAgICBMZXhDb25maWcuY29uZmlnLmVudHJ5SnMgPSAnaW5kZXgudHN4JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIExleENvbmZpZy5jb25maWcuZW50cnlKcyA9ICdpbmRleC50cyc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgTGV4Q29uZmlnLmNvbmZpZy5zd2MuanNjLnBhcnNlciA9IHtcbiAgICAgIHN5bnRheDogJ3R5cGVzY3JpcHQnLFxuICAgICAgdHN4OiB0cnVlXG4gICAgfTtcblxuICAgIGlmKHRhcmdldEVudmlyb25tZW50ID09PSAnd2ViJykge1xuICAgICAgTGV4Q29uZmlnLmNvbmZpZy5zd2MuanNjLnRyYW5zZm9ybSA9IHtcbiAgICAgICAgcmVhY3Q6IHtcbiAgICAgICAgICBydW50aW1lOiAnYXV0b21hdGljJ1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXRMZXhEaXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGlybmFtZShnZXRMZXhQYWNrYWdlSnNvblBhdGgoKSk7XG4gIH1cblxuICBzdGF0aWMgdXBkYXRlQ29uZmlnKHVwZGF0ZWRDb25maWc6IExleENvbmZpZ1R5cGUpOiBMZXhDb25maWdUeXBlIHtcbiAgICBjb25zdCB7b3V0cHV0RnVsbFBhdGgsIG91dHB1dFBhdGgsIHNvdXJjZVBhdGgsIHNvdXJjZUZ1bGxQYXRoLCB1c2VUeXBlc2NyaXB0LCBhaX0gPSB1cGRhdGVkQ29uZmlnO1xuICAgIGNvbnN0IHBhY2thZ2VEaXIgPSBnZXRQYWNrYWdlRGlyKCk7XG5cbiAgICBpZih1c2VUeXBlc2NyaXB0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIExleENvbmZpZy51c2VUeXBlc2NyaXB0ID0gdXNlVHlwZXNjcmlwdDtcbiAgICB9XG5cbiAgICBpZihvdXRwdXRQYXRoICE9PSB1bmRlZmluZWQgJiYgb3V0cHV0RnVsbFBhdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgdXBkYXRlZENvbmZpZy5vdXRwdXRGdWxsUGF0aCA9IHBhdGhSZXNvbHZlKHBhY2thZ2VEaXIsIG91dHB1dFBhdGgpO1xuICAgIH1cblxuICAgIGlmKHNvdXJjZVBhdGggIT09IHVuZGVmaW5lZCAmJiBzb3VyY2VGdWxsUGF0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB1cGRhdGVkQ29uZmlnLnNvdXJjZUZ1bGxQYXRoID0gcGF0aFJlc29sdmUocGFja2FnZURpciwgc291cmNlUGF0aCk7XG4gICAgfVxuXG4gICAgaWYoYWkpIHtcbiAgICAgIExleENvbmZpZy5jb25maWcuYWkgPSB7Li4uTGV4Q29uZmlnLmNvbmZpZy5haSwgLi4uYWl9O1xuXG4gICAgICBpZihwcm9jZXNzLmVudi5DVVJTT1JfSURFID09PSAndHJ1ZScgJiYgTGV4Q29uZmlnLmNvbmZpZy5haS5wcm92aWRlciA9PT0gJ25vbmUnKSB7XG4gICAgICAgIExleENvbmZpZy5jb25maWcuYWkucHJvdmlkZXIgPSAnY3Vyc29yJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBMZXhDb25maWcuY29uZmlnID0gey4uLkxleENvbmZpZy5jb25maWcsIC4uLnVwZGF0ZWRDb25maWd9O1xuXG4gICAgcmV0dXJuIExleENvbmZpZy5jb25maWc7XG4gIH1cblxuICBzdGF0aWMgYWRkQ29uZmlnUGFyYW1zKGNtZCwgcGFyYW1zOiBMZXhDb25maWdUeXBlKSB7XG4gICAgY29uc3QgbmFtZVByb3BlcnR5OiBzdHJpbmcgPSAnX25hbWUnO1xuICAgIGNvbnN0IHtlbnZpcm9ubWVudCwgb3V0cHV0UGF0aCwgc291cmNlUGF0aCwgdHlwZXNjcmlwdH0gPSBjbWQ7XG4gICAgY29uc3QgcGFja2FnZURpciA9IGdldFBhY2thZ2VEaXIoKTtcblxuICAgIGlmKG91dHB1dFBhdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFyYW1zLm91dHB1dFBhdGggPSBvdXRwdXRQYXRoO1xuICAgICAgcGFyYW1zLm91dHB1dEZ1bGxQYXRoID0gcGF0aFJlc29sdmUocGFja2FnZURpciwgb3V0cHV0UGF0aCk7XG4gICAgfSBlbHNlIGlmKHBhcmFtcy5vdXRwdXRQYXRoICYmICFwYXJhbXMub3V0cHV0RnVsbFBhdGgpIHtcbiAgICAgIHBhcmFtcy5vdXRwdXRGdWxsUGF0aCA9IHBhdGhSZXNvbHZlKHBhY2thZ2VEaXIsIHBhcmFtcy5vdXRwdXRQYXRoKTtcbiAgICB9XG5cbiAgICBpZihzb3VyY2VQYXRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhcmFtcy5zb3VyY2VQYXRoID0gc291cmNlUGF0aDtcbiAgICAgIHBhcmFtcy5zb3VyY2VGdWxsUGF0aCA9IHBhdGhSZXNvbHZlKHBhY2thZ2VEaXIsIHNvdXJjZVBhdGgpO1xuICAgIH0gZWxzZSBpZihwYXJhbXMuc291cmNlUGF0aCAmJiAhcGFyYW1zLnNvdXJjZUZ1bGxQYXRoKSB7XG4gICAgICBwYXJhbXMuc291cmNlRnVsbFBhdGggPSBwYXRoUmVzb2x2ZShwYWNrYWdlRGlyLCBwYXJhbXMuc291cmNlUGF0aCk7XG4gICAgfVxuXG4gICAgaWYodHlwZXNjcmlwdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXJhbXMudXNlVHlwZXNjcmlwdCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYoZW52aXJvbm1lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFyYW1zLnRhcmdldEVudmlyb25tZW50ID0gZW52aXJvbm1lbnQgPT09ICd3ZWInID8gJ3dlYicgOiAnbm9kZSc7XG4gICAgfVxuXG4gICAgcHJvY2Vzcy5lbnYuTEVYX0NPTkZJRyA9IEpTT04uc3RyaW5naWZ5KFxuICAgICAge1xuICAgICAgICAuLi5MZXhDb25maWcudXBkYXRlQ29uZmlnKHBhcmFtcyksXG4gICAgICAgIGNvbW1hbmROYW1lOiBjbWRbbmFtZVByb3BlcnR5XSxcbiAgICAgICAgaXNTdGF0aWM6IGNtZC5zdGF0aWNcbiAgICAgIH0sIG51bGwsIDBcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGFzeW5jIHBhcnNlQ29uZmlnKGNtZCwgaXNSb290OiBib29sZWFuID0gdHJ1ZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHtjbGlOYW1lID0gJ0xleCcsIGxleENvbmZpZywgbGV4Q29uZmlnTmFtZSwgcXVpZXQsIHR5cGVzY3JpcHQsIGRlYnVnID0gZmFsc2V9ID0gY21kO1xuICAgIGNvbnN0IGNvbmZpZ0Zvcm1hdHMgPSBbJ2pzJywgJ21qcycsICdjanMnLCAndHMnLCAnanNvbiddO1xuICAgIGNvbnN0IGNvbmZpZ0Jhc2VOYW1lOiBzdHJpbmcgPSBsZXhDb25maWdOYW1lIHx8ICdsZXguY29uZmlnJztcbiAgICBsZXQgY29uZmlnUGF0aDogc3RyaW5nID0gbGV4Q29uZmlnIHx8ICcnO1xuICAgIGxldCBjb25maWdFeGlzdHM6IGJvb2xlYW4gPSBsZXhDb25maWcgPyBleGlzdHNTeW5jKGNvbmZpZ1BhdGgpIDogZmFsc2U7XG5cbiAgICBpZighY29uZmlnUGF0aCB8fCAhY29uZmlnRXhpc3RzKSB7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYFNlYXJjaGluZyBmb3IgY29uZmlnIGZpbGVzIHdpdGggYmFzZSBuYW1lOiAke2NvbmZpZ0Jhc2VOYW1lfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuXG4gICAgICBmb3IoY29uc3QgZm9ybWF0IG9mIGNvbmZpZ0Zvcm1hdHMpIHtcbiAgICAgICAgY29uc3QgcG90ZW50aWFsUGF0aCA9IGlzUm9vdFxuICAgICAgICAgID8gcGF0aFJlc29sdmUoY3dkLCBgLi8ke2NvbmZpZ0Jhc2VOYW1lfS4ke2Zvcm1hdH1gKVxuICAgICAgICAgIDogcmVsYXRpdmVGaWxlUGF0aChgJHtjb25maWdCYXNlTmFtZX0uJHtmb3JtYXR9YCwgY3dkKTtcblxuICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgIGxvZyhgQ2hlY2tpbmcgZm9yIGNvbmZpZyBmaWxlOiAke3BvdGVudGlhbFBhdGh9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZihleGlzdHNTeW5jKHBvdGVudGlhbFBhdGgpKSB7XG4gICAgICAgICAgY29uZmlnUGF0aCA9IHBvdGVudGlhbFBhdGg7XG4gICAgICAgICAgY29uZmlnRXhpc3RzID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmKGNvbmZpZ0V4aXN0cykge1xuICAgICAgbG9nKGBVc2luZyAke2NsaU5hbWV9IGNvbmZpZ3VyYXRpb24gZmlsZTogJHtjb25maWdQYXRofWAsICdub3RlJywgcXVpZXQpO1xuICAgICAgY29uc3QgZXh0OiBzdHJpbmcgPSBwYXRoRXh0bmFtZShjb25maWdQYXRoKTtcblxuICAgICAgaWYoZXh0ID09PSAnLmpzb24nKSB7XG4gICAgICAgIGNvbnN0IGNvbmZpZ0NvbnRlbnQ6IHN0cmluZyA9IHJlYWRGaWxlU3luYyhjb25maWdQYXRoLCAndXRmOCcpO1xuXG4gICAgICAgIGlmKGNvbmZpZ0NvbnRlbnQpIHtcbiAgICAgICAgICBsZXQgY29uZmlnSnNvbjogTGV4Q29uZmlnVHlwZTtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25maWdKc29uID0gSlNPTi5wYXJzZShjb25maWdDb250ZW50KT8uZGVmYXVsdCB8fCB7fTtcbiAgICAgICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IEZhaWxlZCB0byBwYXJzZSBKU09OIGNvbmZpZzogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgICAgICAgIGNvbmZpZ0pzb24gPSB7fTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBMZXhDb25maWcuYWRkQ29uZmlnUGFyYW1zKGNtZCwgY29uZmlnSnNvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiBDb25maWcgZmlsZSBtYWxmb3JtZWQsICR7Y29uZmlnUGF0aH1gLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZihbJy5qcycsICcubWpzJywgJy5janMnLCAnLnRzJ10uaW5jbHVkZXMoZXh0KSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxldCBsZXhDdXN0b21Db25maWc7XG5cbiAgICAgICAgICBpZihleHQgPT09ICcuY2pzJykge1xuICAgICAgICAgICAgY29uc3QgZmlsZVVybCA9IG5ldyBVUkwoYGZpbGU6Ly8vJHtwYXRoUmVzb2x2ZShjb25maWdQYXRoKX1gKS5ocmVmO1xuXG4gICAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgICBsb2coYExvYWRpbmcgQ29tbW9uSlMgY29uZmlnIGZyb206ICR7ZmlsZVVybH1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxleEN1c3RvbUNvbmZpZyA9IGF3YWl0IGltcG9ydChmaWxlVXJsKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgICAgbG9nKGBMb2FkaW5nIEVTTS9UUyBjb25maWcgZnJvbTogJHtjb25maWdQYXRofWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXhDdXN0b21Db25maWcgPSBhd2FpdCBpbXBvcnQoY29uZmlnUGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY29uZmlnID0gbGV4Q3VzdG9tQ29uZmlnLmRlZmF1bHQgfHwgbGV4Q3VzdG9tQ29uZmlnO1xuXG4gICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgIGxvZyhgTG9hZGVkIGNvbmZpZzogJHtKU09OLnN0cmluZ2lmeShjb25maWcsIG51bGwsIDIpfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmKCFjb25maWcpIHtcbiAgICAgICAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBXYXJuaW5nOiBDb25maWcgZmlsZSBsb2FkZWQgYnV0IG5vIGNvbmZpZ3VyYXRpb24gZm91bmRgLCAnd2FybicsIHF1aWV0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBMZXhDb25maWcuYWRkQ29uZmlnUGFyYW1zKGNtZCwgY29uZmlnIHx8IHt9KTtcbiAgICAgICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogRmFpbGVkIHRvIGxvYWQgY29uZmlnIGZpbGU6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogQ29uZmlnIGZpbGUgbXVzdCBiZSBhIEpTLCBDSlMsIE1KUywgVFMsIG9yIEpTT04gZmlsZS5gLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZygnTm8gY29uZmlnIGZpbGUgZm91bmQuIFVzaW5nIGRlZmF1bHQgY29uZmlndXJhdGlvbi4nLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cblxuICAgICAgTGV4Q29uZmlnLnVzZVR5cGVzY3JpcHQgPSAhIXR5cGVzY3JpcHQ7XG4gICAgICBMZXhDb25maWcuYWRkQ29uZmlnUGFyYW1zKGNtZCwgTGV4Q29uZmlnLmNvbmZpZyk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGNoZWNrVHlwZXNjcmlwdENvbmZpZygpIHtcbiAgICBjb25zdCBwYWNrYWdlRGlyID0gZ2V0UGFja2FnZURpcigpO1xuICAgIGNvbnN0IHRzY29uZmlnUGF0aDogc3RyaW5nID0gcGF0aFJlc29sdmUocGFja2FnZURpciwgJy4vdHNjb25maWcuanNvbicpO1xuXG4gICAgaWYoIWV4aXN0c1N5bmModHNjb25maWdQYXRoKSkge1xuICAgICAgY29uc3QgbGV4RGlyID0gTGV4Q29uZmlnLmdldExleERpcigpO1xuICAgICAgY29uc3QgYmFzZUNvbmZpZ1BhdGggPSBwYXRoUmVzb2x2ZShsZXhEaXIsICd0c2NvbmZpZy5iYXNlLmpzb24nKTtcbiAgICAgIGNvbnN0IHRlbXBsYXRlQ29uZmlnUGF0aCA9IHBhdGhSZXNvbHZlKGxleERpciwgJ3RzY29uZmlnLnRlbXBsYXRlLmpzb24nKTtcbiAgICAgIGNvbnN0IHNvdXJjZVBhdGggPSBleGlzdHNTeW5jKGJhc2VDb25maWdQYXRoKSA/IGJhc2VDb25maWdQYXRoIDogdGVtcGxhdGVDb25maWdQYXRoO1xuXG4gICAgICBpZihleGlzdHNTeW5jKHNvdXJjZVBhdGgpKSB7XG4gICAgICAgIHdyaXRlRmlsZVN5bmModHNjb25maWdQYXRoLCByZWFkRmlsZVN5bmMoc291cmNlUGF0aCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXRUeXBlU2NyaXB0RGVjbGFyYXRpb25GbGFncygpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgY3dkID0gcHJvY2Vzcy5jd2QoKTtcbiAgICBjb25zdCBvdXRwdXRQYXRoID0gTGV4Q29uZmlnLmNvbmZpZy5vdXRwdXRQYXRoIHx8ICcuL2xpYic7XG4gICAgY29uc3Qgb3V0cHV0RnVsbFBhdGggPSBMZXhDb25maWcuY29uZmlnLm91dHB1dEZ1bGxQYXRoIHx8IHBhdGhSZXNvbHZlKGN3ZCwgb3V0cHV0UGF0aCk7XG4gICAgY29uc3Qgc291cmNlUGF0aCA9IExleENvbmZpZy5jb25maWcuc291cmNlUGF0aCB8fCAnLi9zcmMnO1xuICAgIGNvbnN0IHNvdXJjZUZ1bGxQYXRoID0gTGV4Q29uZmlnLmNvbmZpZy5zb3VyY2VGdWxsUGF0aCB8fCBwYXRoUmVzb2x2ZShjd2QsIHNvdXJjZVBhdGgpO1xuICAgIGNvbnN0IHJlbGF0aXZlT3V0RGlyID0gcGF0aFJlbGF0aXZlKGN3ZCwgb3V0cHV0RnVsbFBhdGgpIHx8ICcuL2xpYic7XG4gICAgY29uc3QgcmVsYXRpdmVSb290RGlyID0gcGF0aFJlbGF0aXZlKGN3ZCwgc291cmNlRnVsbFBhdGgpIHx8ICcuL3NyYyc7XG5cbiAgICByZXR1cm4gW1xuICAgICAgJy0tZW1pdERlY2xhcmF0aW9uT25seScsIC8vIENSSVRJQ0FMOiBPbmx5IGVtaXQgLmQudHMgZmlsZXMsIG5vIEpTIGZpbGVzXG4gICAgICAnLS1kZWNsYXJhdGlvbicsIC8vIEdlbmVyYXRlIGRlY2xhcmF0aW9uIGZpbGVzXG4gICAgICAnLS1kZWNsYXJhdGlvbk1hcCcsIC8vIEdlbmVyYXRlIHNvdXJjZSBtYXBzIGZvciBkZWNsYXJhdGlvbnNcbiAgICAgICctLW91dERpcicsIHJlbGF0aXZlT3V0RGlyLFxuICAgICAgJy0tcm9vdERpcicsIHJlbGF0aXZlUm9vdERpcixcbiAgICAgICctLXNraXBMaWJDaGVjaycsIC8vIFNraXAgdHlwZSBjaGVja2luZyBvZiBkZWNsYXJhdGlvbiBmaWxlcyAoZmFzdGVyLCBtb3JlIGxlbmllbnQpXG4gICAgICAnLS1lc01vZHVsZUludGVyb3AnLFxuICAgICAgJy0tYWxsb3dTeW50aGV0aWNEZWZhdWx0SW1wb3J0cycsXG4gICAgICAnLS1tb2R1bGUnLCAnTm9kZU5leHQnLFxuICAgICAgJy0tbW9kdWxlUmVzb2x1dGlvbicsICdOb2RlTmV4dCcsXG4gICAgICAnLS10YXJnZXQnLCAnRVNOZXh0JyxcbiAgICAgICctLWpzeCcsICdyZWFjdC1qc3gnLFxuICAgICAgJy0taXNvbGF0ZWRNb2R1bGVzJyxcbiAgICAgICctLXJlc29sdmVKc29uTW9kdWxlJyxcbiAgICAgICctLWFsbG93SnMnXG4gICAgICAvLyBOb3RlOiAtLW5vVW51c2VkTG9jYWxzIGFuZCAtLW5vVW51c2VkUGFyYW1ldGVycyBhcmUgbm90IG5lZWRlZCBmb3IgZGVjbGFyYXRpb24gZ2VuZXJhdGlvblxuICAgICAgLy8gYW5kIHdvdWxkIGFjdHVhbGx5IGVuYWJsZSBzdHJpY3QgY2hlY2tpbmcsIHdoaWNoIHdlIHdhbnQgdG8gYXZvaWQgZm9yIGZhc3RlciBkZWNsYXJhdGlvbiBnZW5lcmF0aW9uXG4gICAgXTtcbiAgfVxuXG4gIHN0YXRpYyBjaGVja0xpbnRUeXBlc2NyaXB0Q29uZmlnKCkge1xuICAgIGNvbnN0IGxleERpciA9IExleENvbmZpZy5nZXRMZXhEaXIoKTtcbiAgICBjb25zdCB0c2NvbmZpZ0xpbnRQYXRoOiBzdHJpbmcgPSBwYXRoUmVzb2x2ZShsZXhEaXIsICcuL3RzY29uZmlnLmxpbnQuanNvbicpO1xuXG4gICAgaWYoIWV4aXN0c1N5bmModHNjb25maWdMaW50UGF0aCkpIHtcbiAgICAgIGNvbnN0IHRlbXBsYXRlUGF0aCA9IHBhdGhSZXNvbHZlKGxleERpciwgJ3RzY29uZmlnLmxpbnQuanNvbicpO1xuICAgICAgaWYoZXhpc3RzU3luYyh0ZW1wbGF0ZVBhdGgpKSB7XG4gICAgICAgIHdyaXRlRmlsZVN5bmModHNjb25maWdMaW50UGF0aCwgcmVhZEZpbGVTeW5jKHRlbXBsYXRlUGF0aCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBjaGVja1Rlc3RUeXBlc2NyaXB0Q29uZmlnKCkge1xuICAgIGNvbnN0IGxleERpciA9IExleENvbmZpZy5nZXRMZXhEaXIoKTtcbiAgICBjb25zdCB0c2NvbmZpZ1Rlc3RQYXRoOiBzdHJpbmcgPSBwYXRoUmVzb2x2ZShsZXhEaXIsICcuL3RzY29uZmlnLnRlc3QuanNvbicpO1xuXG4gICAgaWYoIWV4aXN0c1N5bmModHNjb25maWdUZXN0UGF0aCkpIHtcbiAgICAgIGNvbnN0IHRlbXBsYXRlUGF0aCA9IHBhdGhSZXNvbHZlKGxleERpciwgJ3RzY29uZmlnLnRlc3QuanNvbicpO1xuICAgICAgaWYoZXhpc3RzU3luYyh0ZW1wbGF0ZVBhdGgpKSB7XG4gICAgICAgIHdyaXRlRmlsZVN5bmModHNjb25maWdUZXN0UGF0aCwgcmVhZEZpbGVTeW5jKHRlbXBsYXRlUGF0aCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgdHlwZSBTV0NPcHRpb25zID0gT3B0aW9uczsiXSwibmFtZXMiOlsiZmluZEZpbGVVcCIsImV4aXN0c1N5bmMiLCJyZWFkRmlsZVN5bmMiLCJ3cml0ZUZpbGVTeW5jIiwiZGlybmFtZSIsImV4dG5hbWUiLCJwYXRoRXh0bmFtZSIsInJlbGF0aXZlIiwicGF0aFJlbGF0aXZlIiwicmVzb2x2ZSIsInBhdGhSZXNvbHZlIiwiVVJMIiwiZ2V0TGV4UGFja2FnZUpzb25QYXRoIiwicmVsYXRpdmVGaWxlUGF0aCIsImxvZyIsImN3ZCIsInByb2Nlc3MiLCJkZWZhdWx0Q29uZmlnVmFsdWVzIiwiYWkiLCJtYXhUb2tlbnMiLCJtb2RlbCIsInByb3ZpZGVyIiwidGVtcGVyYXR1cmUiLCJjb25maWdGaWxlcyIsImNvcHlGaWxlcyIsImVudHJ5SFRNTCIsImVudHJ5SnMiLCJlbnYiLCJlc2xpbnQiLCJqZXN0Iiwib3V0cHV0RnVsbFBhdGgiLCJvdXRwdXRIYXNoIiwib3V0cHV0UGF0aCIsInBhY2thZ2VNYW5hZ2VyIiwicHJlc2V0Iiwic291cmNlRnVsbFBhdGgiLCJzb3VyY2VQYXRoIiwic3djIiwiaW5saW5lU291cmNlc0NvbnRlbnQiLCJpc01vZHVsZSIsImpzYyIsImV4dGVybmFsSGVscGVycyIsImtlZXBDbGFzc05hbWVzIiwibG9vc2UiLCJwYXJzZXIiLCJkZWNvcmF0b3JzIiwiZHluYW1pY0ltcG9ydCIsInN5bnRheCIsInRzeCIsInRhcmdldCIsInRyYW5zZm9ybSIsInJlYWN0IiwicnVudGltZSIsIm1pbmlmeSIsIm1vZHVsZSIsImxhenkiLCJub0ludGVyb3AiLCJzdHJpY3QiLCJzdHJpY3RNb2RlIiwidHlwZSIsInNvdXJjZU1hcHMiLCJ0YXJnZXRFbnZpcm9ubWVudCIsInVzZUdyYXBoUWwiLCJ1c2VUeXBlc2NyaXB0Iiwid2VicGFjayIsInN0YXRpY1BhdGgiLCJnZXRQYWNrYWdlRGlyIiwiY3VycmVudFBrZ1BhdGgiLCJwa2ciLCJKU09OIiwicGFyc2UiLCJ3b3Jrc3BhY2VzIiwic2VhcmNoRGlyIiwiaSIsInBrZ1BhdGgiLCJwYXJlbnQiLCJjb25maWdGb3JtYXRzIiwiZm9ybWF0IiwiY29uZmlnUGF0aCIsInN5bmMiLCJnZXRUeXBlU2NyaXB0Q29uZmlnUGF0aCIsImNvbmZpZ05hbWUiLCJwYWNrYWdlRGlyIiwicHJvamVjdEJ1aWxkQ29uZmlnIiwicm9vdEJ1aWxkQ29uZmlnIiwicHJvamVjdExpbnRDb25maWciLCJyb290TGludENvbmZpZyIsInByb2plY3RUZXN0Q29uZmlnIiwicm9vdFRlc3RDb25maWciLCJwcm9qZWN0Q29uZmlnUGF0aCIsInJvb3RDb25maWdQYXRoIiwibGV4RGlyIiwiTGV4Q29uZmlnIiwiZ2V0TGV4RGlyIiwidmFsdWUiLCJjb25maWciLCJpbmRleFBhdGgiLCJoYXNJbmRleFRzeCIsInVwZGF0ZUNvbmZpZyIsInVwZGF0ZWRDb25maWciLCJ1bmRlZmluZWQiLCJDVVJTT1JfSURFIiwiYWRkQ29uZmlnUGFyYW1zIiwiY21kIiwicGFyYW1zIiwibmFtZVByb3BlcnR5IiwiZW52aXJvbm1lbnQiLCJ0eXBlc2NyaXB0IiwiTEVYX0NPTkZJRyIsInN0cmluZ2lmeSIsImNvbW1hbmROYW1lIiwiaXNTdGF0aWMiLCJzdGF0aWMiLCJwYXJzZUNvbmZpZyIsImlzUm9vdCIsImNsaU5hbWUiLCJsZXhDb25maWciLCJsZXhDb25maWdOYW1lIiwicXVpZXQiLCJkZWJ1ZyIsImNvbmZpZ0Jhc2VOYW1lIiwiY29uZmlnRXhpc3RzIiwicG90ZW50aWFsUGF0aCIsImV4dCIsImNvbmZpZ0NvbnRlbnQiLCJjb25maWdKc29uIiwiZGVmYXVsdCIsImVycm9yIiwibWVzc2FnZSIsImluY2x1ZGVzIiwibGV4Q3VzdG9tQ29uZmlnIiwiZmlsZVVybCIsImhyZWYiLCJjb25zb2xlIiwiY2hlY2tUeXBlc2NyaXB0Q29uZmlnIiwidHNjb25maWdQYXRoIiwiYmFzZUNvbmZpZ1BhdGgiLCJ0ZW1wbGF0ZUNvbmZpZ1BhdGgiLCJnZXRUeXBlU2NyaXB0RGVjbGFyYXRpb25GbGFncyIsInJlbGF0aXZlT3V0RGlyIiwicmVsYXRpdmVSb290RGlyIiwiY2hlY2tMaW50VHlwZXNjcmlwdENvbmZpZyIsInRzY29uZmlnTGludFBhdGgiLCJ0ZW1wbGF0ZVBhdGgiLCJjaGVja1Rlc3RUeXBlc2NyaXB0Q29uZmlnIiwidHNjb25maWdUZXN0UGF0aCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFBOzs7Q0FHQyxHQUNELE9BQU9BLGdCQUFnQixlQUFlO0FBQ3RDLFNBQVFDLFVBQVUsRUFBRUMsWUFBWSxFQUFFQyxhQUFhLFFBQU8sS0FBSztBQUMzRCxTQUNFQyxPQUFPLEVBQ1BDLFdBQVdDLFdBQVcsRUFDdEJDLFlBQVlDLFlBQVksRUFDeEJDLFdBQVdDLFdBQVcsUUFDakIsT0FBTztBQUNkLFNBQVFDLEdBQUcsUUFBTyxNQUFNO0FBRXhCLFNBQVFDLHFCQUFxQixFQUFFQyxnQkFBZ0IsUUFBTyxrQkFBa0I7QUFDeEUsU0FBUUMsR0FBRyxRQUFPLGlCQUFpQjtBQUtuQyxNQUFNQyxNQUFjQyxRQUFRRCxHQUFHO0FBa0UvQixPQUFPLE1BQU1FLHNCQUFxQztJQUNoREMsSUFBSTtRQUNGQyxXQUFXO1FBQ1hD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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nlabs/lex",
3
- "version": "1.53.2",
3
+ "version": "1.53.3",
4
4
  "description": "Lex",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/postcss.config.js CHANGED
@@ -2,6 +2,8 @@
2
2
  * Copyright (c) 2018-Present, Nitrogen Labs, Inc.
3
3
  * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
4
  */
5
+ import tailwindNesting from '@tailwindcss/nesting';
6
+ import tailwindcss from '@tailwindcss/postcss';
5
7
  import autoprefixer from 'autoprefixer';
6
8
  import cssnano from 'cssnano';
7
9
  import postcssBrowserReporter from 'postcss-browser-reporter';
@@ -10,8 +12,6 @@ import postcssFlexbugsFixes from 'postcss-flexbugs-fixes';
10
12
  import postcssHash from 'postcss-hash';
11
13
  import postcssImport from 'postcss-import';
12
14
  import postcssNesting from 'postcss-nesting';
13
- import tailwindcss from '@tailwindcss/postcss';
14
- import tailwindNesting from '@tailwindcss/nesting';
15
15
  import postcssPresetEnv from 'postcss-preset-env';
16
16
  import postcssSimpleVars from 'postcss-simple-vars';
17
17
  import postcssSvgo from 'postcss-svgo';
@@ -6,9 +6,8 @@
6
6
 
7
7
  import {spawn} from 'child_process';
8
8
  import {createConnection} from 'net';
9
- import {join} from 'path';
9
+ import {join,dirname} from 'path';
10
10
  import {fileURLToPath} from 'url';
11
- import {dirname} from 'path';
12
11
 
13
12
  const __filename = fileURLToPath(import.meta.url);
14
13
  const __dirname = dirname(__filename);
@@ -31,33 +30,31 @@ const devServerProcess = spawn('node', [lexPath, 'dev', '--port', testPort.toStr
31
30
  }
32
31
  });
33
32
 
34
- const checkPort = (port) => {
35
- return new Promise((resolve) => {
36
- const socket = createConnection(port, 'localhost');
37
- socket.on('connect', () => {
38
- socket.destroy();
39
- resolve(true);
40
- });
41
- socket.on('error', () => {
42
- resolve(false);
43
- });
44
- socket.setTimeout(2000, () => {
45
- socket.destroy();
46
- resolve(false);
47
- });
33
+ const checkPort = (port) => new Promise((resolve) => {
34
+ const socket = createConnection(port, 'localhost');
35
+ socket.on('connect', () => {
36
+ socket.destroy();
37
+ resolve(true);
48
38
  });
49
- };
39
+ socket.on('error', () => {
40
+ resolve(false);
41
+ });
42
+ socket.setTimeout(2000, () => {
43
+ socket.destroy();
44
+ resolve(false);
45
+ });
46
+ });
50
47
 
51
48
  const waitForServer = async () => {
52
49
  console.log('⏳ Waiting for server to start...');
53
- for (let i = 0; i < 60; i++) {
54
- await new Promise(resolve => setTimeout(resolve, 1000));
50
+ for(let i = 0; i < 60; i++) {
51
+ await new Promise((resolve) => setTimeout(resolve, 1000));
55
52
  const portOpen = await checkPort(testPort);
56
- if (portOpen) {
53
+ if(portOpen) {
57
54
  console.log(`✅ Server is running on port ${testPort}\n`);
58
55
  return true;
59
56
  }
60
- if (i % 5 === 4) {
57
+ if(i % 5 === 4) {
61
58
  process.stdout.write('.');
62
59
  }
63
60
  }
@@ -69,41 +66,40 @@ const testStaticFile = async () => {
69
66
  console.log('🌐 Testing static file access...');
70
67
  const response = await fetch(`http://localhost:${testPort}/test.txt`);
71
68
  console.log(` Status: ${response.status}`);
72
- console.log(` Headers:`, Object.fromEntries(response.headers.entries()));
69
+ console.log(' Headers:', Object.fromEntries(response.headers.entries()));
73
70
 
74
- if (response.ok) {
71
+ if(response.ok) {
75
72
  const content = await response.text();
76
73
  console.log(` Content: "${content}"`);
77
74
  console.log('\n✅ Static file is accessible!');
78
75
  return true;
79
- } else {
80
- console.log(`\n❌ Static file returned status ${response.status}`);
81
- const text = await response.text();
82
- console.log(` Response: ${text.substring(0, 200)}`);
83
- return false;
84
76
  }
85
- } catch (error) {
77
+ console.log(`\n❌ Static file returned status ${response.status}`);
78
+ const text = await response.text();
79
+ console.log(` Response: ${text.substring(0, 200)}`);
80
+ return false;
81
+ } catch(error) {
86
82
  console.log(`\n❌ Error accessing static file: ${error.message}`);
87
83
  return false;
88
84
  }
89
85
  };
90
86
 
91
87
  waitForServer().then(async (serverReady) => {
92
- if (!serverReady) {
88
+ if(!serverReady) {
93
89
  console.log('\n❌ Server did not start within 60 seconds');
94
90
  devServerProcess.kill('SIGTERM');
95
91
  process.exit(1);
96
92
  }
97
93
 
98
94
  // Give it a moment to fully initialize
99
- await new Promise(resolve => setTimeout(resolve, 2000));
95
+ await new Promise((resolve) => setTimeout(resolve, 2000));
100
96
 
101
97
  const success = await testStaticFile();
102
98
 
103
99
  console.log('\n🛑 Stopping dev server...');
104
100
  devServerProcess.kill('SIGTERM');
105
101
  setTimeout(() => {
106
- if (!devServerProcess.killed) {
102
+ if(!devServerProcess.killed) {
107
103
  devServerProcess.kill('SIGKILL');
108
104
  }
109
105
  process.exit(success ? 0 : 1);
@@ -15,8 +15,8 @@
15
15
  import {execSync, spawn} from 'child_process';
16
16
  import {existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync} from 'fs';
17
17
  import {createConnection} from 'net';
18
- import {join} from 'path';
19
18
  import {tmpdir} from 'os';
19
+ import {join} from 'path';
20
20
 
21
21
  const testDir = join(tmpdir(), `lex-webpack-test-${Date.now()}`);
22
22
 
@@ -105,7 +105,7 @@ try {
105
105
  }
106
106
  });
107
107
  console.log(result.toString());
108
- } catch (error) {
108
+ } catch(error) {
109
109
  console.error('Build error output:', error.stdout || error.stderr || error.message);
110
110
  throw error;
111
111
  }
@@ -117,9 +117,9 @@ try {
117
117
  console.log('🔍 Verifying build output...');
118
118
 
119
119
  const indexHtml = join(buildDir, 'index.html');
120
- if (existsSync(indexHtml)) {
120
+ if(existsSync(indexHtml)) {
121
121
  const htmlContent = readFileSync(indexHtml, 'utf8');
122
- if (htmlContent.includes('Test App')) {
122
+ if(htmlContent.includes('Test App')) {
123
123
  console.log('✅ HTML file generated correctly');
124
124
  } else {
125
125
  console.log('❌ HTML content incorrect');
@@ -133,24 +133,24 @@ try {
133
133
  let cssFound = false;
134
134
  let cssProcessed = false;
135
135
 
136
- for (const cssFile of cssFiles) {
136
+ for(const cssFile of cssFiles) {
137
137
  const cssPath = join(buildDir, cssFile);
138
- if (existsSync(cssPath)) {
138
+ if(existsSync(cssPath)) {
139
139
  cssFound = true;
140
140
  const cssContent = readFileSync(cssPath, 'utf8');
141
141
  console.log('✅ CSS file generated');
142
142
 
143
- if (cssContent.includes('test-for-loop')) {
143
+ if(cssContent.includes('test-for-loop')) {
144
144
  const hasForLoop = /width:\s*calc\([^)]*25px\)/.test(cssContent);
145
- if (hasForLoop) {
145
+ if(hasForLoop) {
146
146
  console.log('✅ PostCSS @for loop processed correctly');
147
147
  cssProcessed = true;
148
148
  }
149
149
  }
150
150
 
151
- if (cssContent.includes('test-percentage')) {
151
+ if(cssContent.includes('test-percentage')) {
152
152
  const hasPercentage = /width:\s*[\d.]+%/.test(cssContent);
153
- if (hasPercentage) {
153
+ if(hasPercentage) {
154
154
  console.log('✅ PostCSS percentage() function processed correctly');
155
155
  cssProcessed = true;
156
156
  }
@@ -159,29 +159,29 @@ try {
159
159
  }
160
160
  }
161
161
 
162
- if (!cssFound) {
162
+ if(!cssFound) {
163
163
  const files = readdirSync(buildDir);
164
- const jsFile = files.find(f => f.startsWith('index.') && f.endsWith('.js') && !f.includes('runtime') && !f.includes('vendors'));
165
- if (jsFile) {
164
+ const jsFile = files.find((f) => f.startsWith('index.') && f.endsWith('.js') && !f.includes('runtime') && !f.includes('vendors'));
165
+ if(jsFile) {
166
166
  const jsContent = readFileSync(join(buildDir, jsFile), 'utf8');
167
- if (jsContent.includes('calc') && jsContent.includes('25px')) {
167
+ if(jsContent.includes('calc') && jsContent.includes('25px')) {
168
168
  console.log('✅ CSS processed and inlined in JS (PostCSS @for loop detected)');
169
169
  cssProcessed = true;
170
170
  }
171
- if (jsContent.includes('%') && /[\d.]+%/.test(jsContent)) {
171
+ if(jsContent.includes('%') && /[\d.]+%/.test(jsContent)) {
172
172
  console.log('✅ CSS processed and inlined in JS (PostCSS percentage() detected)');
173
173
  cssProcessed = true;
174
174
  }
175
175
  }
176
- if (!cssProcessed) {
176
+ if(!cssProcessed) {
177
177
  console.log('⚠️ CSS file not found (may be inlined or named differently)');
178
178
  }
179
179
  }
180
180
 
181
181
  const staticFile = join(buildDir, 'test.txt');
182
- if (existsSync(staticFile)) {
182
+ if(existsSync(staticFile)) {
183
183
  const staticContent = readFileSync(staticFile, 'utf8');
184
- if (staticContent === 'Static file content') {
184
+ if(staticContent === 'Static file content') {
185
185
  console.log('✅ Static file copied correctly');
186
186
  } else {
187
187
  console.log('❌ Static file content incorrect');
@@ -194,7 +194,7 @@ try {
194
194
 
195
195
  const testPort = 3001;
196
196
 
197
- if (!existsSync(buildDir)) {
197
+ if(!existsSync(buildDir)) {
198
198
  console.log('⚠️ Build directory does not exist, creating it...');
199
199
  mkdirSync(buildDir, {recursive: true});
200
200
  }
@@ -220,7 +220,7 @@ try {
220
220
  const output = data.toString();
221
221
  serverOutput += output;
222
222
  // Check for server ready indicators
223
- if (output.includes('compiled') || output.includes('Local:') || output.includes('http://') || output.includes('webpack compiled')) {
223
+ if(output.includes('compiled') || output.includes('Local:') || output.includes('http://') || output.includes('webpack compiled')) {
224
224
  serverStartedOutput = true;
225
225
  }
226
226
  });
@@ -228,11 +228,11 @@ try {
228
228
  devServerProcess.stderr.on('data', (data) => {
229
229
  const output = data.toString();
230
230
  serverOutput += output;
231
- if (output.includes('error') || output.includes('Error') || output.includes('ERROR')) {
231
+ if(output.includes('error') || output.includes('Error') || output.includes('ERROR')) {
232
232
  serverError = output;
233
233
  }
234
234
  // Sometimes webpack outputs to stderr but it's not an error
235
- if (output.includes('compiled') || output.includes('webpack')) {
235
+ if(output.includes('compiled') || output.includes('webpack')) {
236
236
  serverStartedOutput = true;
237
237
  }
238
238
  });
@@ -244,31 +244,29 @@ try {
244
244
  console.log(`⏳ Waiting for dev server to start on port ${testPort}...`);
245
245
  console.log(' (This may take 30-60 seconds for initial compilation)');
246
246
 
247
- const checkPort = (port) => {
248
- return new Promise((resolve) => {
249
- const socket = createConnection(port, 'localhost');
250
- socket.on('connect', () => {
251
- socket.destroy();
252
- resolve(true);
253
- });
254
- socket.on('error', () => {
255
- resolve(false);
256
- });
257
- socket.setTimeout(1000, () => {
258
- socket.destroy();
259
- resolve(false);
260
- });
247
+ const checkPort = (port) => new Promise((resolve) => {
248
+ const socket = createConnection(port, 'localhost');
249
+ socket.on('connect', () => {
250
+ socket.destroy();
251
+ resolve(true);
261
252
  });
262
- };
253
+ socket.on('error', () => {
254
+ resolve(false);
255
+ });
256
+ socket.setTimeout(1000, () => {
257
+ socket.destroy();
258
+ resolve(false);
259
+ });
260
+ });
263
261
 
264
262
  const waitForServer = async () => {
265
- for (let i = 0; i < 90; i++) {
266
- await new Promise(resolve => setTimeout(resolve, 1000));
263
+ for(let i = 0; i < 90; i++) {
264
+ await new Promise((resolve) => setTimeout(resolve, 1000));
267
265
 
268
266
  const portOpen = await checkPort(testPort);
269
- if (portOpen || serverStartedOutput) {
267
+ if(portOpen || serverStartedOutput) {
270
268
  // Give it a bit more time to fully initialize
271
- await new Promise(resolve => setTimeout(resolve, 3000));
269
+ await new Promise((resolve) => setTimeout(resolve, 3000));
272
270
 
273
271
  // Try to access the static file directly
274
272
  try {
@@ -278,14 +276,14 @@ try {
278
276
  signal: controller.signal
279
277
  });
280
278
  clearTimeout(timeoutId);
281
- if (response.ok && response.status === 200) {
279
+ if(response.ok && response.status === 200) {
282
280
  const content = await response.text();
283
- if (content.includes('Static file content')) {
281
+ if(content.includes('Static file content')) {
284
282
  return true;
285
283
  }
286
284
  }
287
- } catch (error) {
288
- if (error.name !== 'AbortError' && i > 5) {
285
+ } catch(error) {
286
+ if(error.name !== 'AbortError' && i > 5) {
289
287
  // Only log after a few attempts
290
288
  }
291
289
  }
@@ -298,28 +296,28 @@ try {
298
296
  signal: controller.signal
299
297
  });
300
298
  clearTimeout(timeoutId);
301
- if (response.ok || response.status === 200) {
299
+ if(response.ok || response.status === 200) {
302
300
  // Server is up, even if static file test didn't work yet
303
- if (i > 10) {
301
+ if(i > 10) {
304
302
  // After 10 seconds, if server is up, try static file again
305
303
  try {
306
304
  const staticResponse = await fetch(`http://localhost:${testPort}/test.txt`, {
307
305
  signal: controller.signal
308
306
  });
309
- if (staticResponse.ok) {
307
+ if(staticResponse.ok) {
310
308
  return true;
311
309
  }
312
- } catch {
310
+ } catch{
313
311
  }
314
312
  }
315
313
  }
316
- } catch (error) {
317
- if (error.name !== 'AbortError') {
314
+ } catch(error) {
315
+ if(error.name !== 'AbortError') {
318
316
  }
319
317
  }
320
318
  }
321
319
 
322
- if (i % 10 === 9 && i > 0) {
320
+ if(i % 10 === 9 && i > 0) {
323
321
  console.log(` Still waiting... (${i + 1}/90 seconds)`);
324
322
  }
325
323
  }
@@ -328,21 +326,21 @@ try {
328
326
 
329
327
  serverReady = await waitForServer();
330
328
 
331
- if (serverError) {
329
+ if(serverError) {
332
330
  console.log(`❌ Dev server error: ${serverError}`);
333
331
  console.log('❌ HTTP tests cannot run due to server error');
334
332
  console.log('💡 Note: Static files are copied to build directory and should be accessible via dev server');
335
333
  throw new Error(`Dev server failed to start: ${serverError}`);
336
- } else if (!serverReady) {
334
+ } else if(!serverReady) {
337
335
  console.log('❌ Dev server did not start within 60 seconds');
338
336
  console.log('❌ HTTP tests cannot run - this is a required test');
339
337
  console.log('💡 To test manually, run: cd <test-dir> && lex dev --port 3001');
340
- if (serverOutput) {
338
+ if(serverOutput) {
341
339
  const lastOutput = serverOutput.slice(-2000);
342
340
  console.log('\nServer output (last 2000 chars):');
343
341
  console.log(lastOutput);
344
342
  // Check if there are any obvious errors
345
- if (lastOutput.includes('Error') || lastOutput.includes('error') || lastOutput.includes('Cannot find')) {
343
+ if(lastOutput.includes('Error') || lastOutput.includes('error') || lastOutput.includes('Cannot find')) {
346
344
  console.log('\n⚠️ Potential errors detected in server output above');
347
345
  }
348
346
  } else {
@@ -351,11 +349,11 @@ try {
351
349
  }
352
350
 
353
351
  // Check if process is still running
354
- if (devServerProcess && !devServerProcess.killed) {
352
+ if(devServerProcess && !devServerProcess.killed) {
355
353
  try {
356
354
  devServerProcess.kill(0); // Check if process exists
357
355
  console.log(' (Dev server process is still running but not responding)');
358
- } catch {
356
+ } catch{
359
357
  console.log(' (Dev server process has exited)');
360
358
  }
361
359
  }
@@ -372,17 +370,17 @@ try {
372
370
  let httpTestFailed = false;
373
371
  const httpTestErrors = [];
374
372
 
375
- for (const test of testUrls) {
373
+ for(const test of testUrls) {
376
374
  try {
377
375
  const response = await fetch(`http://localhost:${testPort}${test.url}`);
378
- if (response.ok) {
376
+ if(response.ok) {
379
377
  const content = await response.text();
380
- if (content.includes(test.expectedContent)) {
378
+ if(content.includes(test.expectedContent)) {
381
379
  console.log(`✅ ${test.description} accessible via HTTP (${test.url})`);
382
380
  } else {
383
381
  const errorMsg = `${test.description} accessible but content doesn't match (${test.url})`;
384
382
  console.log(`❌ ${errorMsg}`);
385
- if (test.required) {
383
+ if(test.required) {
386
384
  httpTestFailed = true;
387
385
  httpTestErrors.push(errorMsg);
388
386
  }
@@ -390,25 +388,25 @@ try {
390
388
  } else {
391
389
  const errorMsg = `${test.description} returned status ${response.status} (${test.url})`;
392
390
  console.log(`❌ ${errorMsg}`);
393
- if (test.required) {
391
+ if(test.required) {
394
392
  httpTestFailed = true;
395
393
  httpTestErrors.push(errorMsg);
396
394
  }
397
395
  }
398
- } catch (error) {
396
+ } catch(error) {
399
397
  const errorMsg = `Failed to fetch ${test.description}: ${error.message}`;
400
398
  console.log(`❌ ${errorMsg}`);
401
- if (test.required) {
399
+ if(test.required) {
402
400
  httpTestFailed = true;
403
401
  httpTestErrors.push(errorMsg);
404
402
  }
405
403
  }
406
404
  }
407
405
 
408
- if (httpTestFailed) {
406
+ if(httpTestFailed) {
409
407
  console.log('\n❌ HTTP static file access test FAILED!');
410
408
  console.log('Errors:');
411
- httpTestErrors.forEach(err => console.log(` - ${err}`));
409
+ httpTestErrors.forEach((err) => console.log(` - ${err}`));
412
410
  console.log('\n💡 The dev server must be able to serve static files from the staticPath directory.');
413
411
  console.log('💡 Check that the middleware in webpack.config.js is correctly serving files from staticPathFull.');
414
412
  throw new Error('HTTP static file access test failed');
@@ -416,17 +414,16 @@ try {
416
414
  console.log('\n✅ All HTTP static file access tests passed!');
417
415
  }
418
416
  }
419
-
420
- } catch (error) {
417
+ } catch(error) {
421
418
  console.error(`\n❌ Dev server HTTP test failed: ${error.message}`);
422
419
  console.error('This test is required and must pass.');
423
420
  throw error;
424
421
  } finally {
425
- if (devServerProcess) {
422
+ if(devServerProcess) {
426
423
  console.log('🛑 Stopping dev server...');
427
424
  devServerProcess.kill('SIGTERM');
428
- await new Promise(resolve => setTimeout(resolve, 1000));
429
- if (devServerProcess.killed === false) {
425
+ await new Promise((resolve) => setTimeout(resolve, 1000));
426
+ if(devServerProcess.killed === false) {
430
427
  devServerProcess.kill('SIGKILL');
431
428
  }
432
429
  console.log('✅ Dev server stopped');
@@ -437,10 +434,9 @@ try {
437
434
  console.log('\n🎉 All tests passed!');
438
435
  console.log(`\n📁 Test project location: ${testDir}`);
439
436
  console.log('💡 You can inspect the build output in the build/ directory');
440
-
441
- } catch (error) {
437
+ } catch(error) {
442
438
  console.error('\n❌ Test suite failed:', error.message);
443
- if (error.stack) {
439
+ if(error.stack) {
444
440
  console.error('\nStack trace:');
445
441
  console.error(error.stack);
446
442
  }
@@ -450,7 +446,7 @@ try {
450
446
  try {
451
447
  rmSync(testDir, {recursive: true, force: true});
452
448
  console.log('✅ Cleanup complete');
453
- } catch {
449
+ } catch{
454
450
  console.log('⚠️ Could not clean up test directory:', testDir);
455
451
  }
456
452
  }
@@ -134,6 +134,7 @@ describe('DataLayer', () => {
134
134
  expect(result.headers['Access-Control-Allow-Origin']).toBe('*');
135
135
 
136
136
  const body = JSON.parse(result.body);
137
+
137
138
  expect(body.id).toBe('test-id');
138
139
  });
139
140
 
@@ -148,7 +149,9 @@ describe('DataLayer', () => {
148
149
  const result = await dataLayer.handleRequest(event, mockContext);
149
150
 
150
151
  expect(result.statusCode).toBe(200);
152
+
151
153
  const body = JSON.parse(result.body);
154
+
152
155
  expect(Array.isArray(body)).toBe(true);
153
156
  });
154
157
 
@@ -166,7 +169,9 @@ describe('DataLayer', () => {
166
169
  const result = await dataLayer.handleRequest(event, mockContext);
167
170
 
168
171
  expect(result.statusCode).toBe(200);
172
+
169
173
  const body = JSON.parse(result.body);
174
+
170
175
  expect(body.name).toBe('New Item');
171
176
  expect(body.description).toBe('A new item');
172
177
  });
@@ -184,7 +189,9 @@ describe('DataLayer', () => {
184
189
  const result = await dataLayer.handleRequest(event, mockContext);
185
190
 
186
191
  expect(result.statusCode).toBe(200);
192
+
187
193
  const body = JSON.parse(result.body);
194
+
188
195
  expect(body.id).toBe('test-id');
189
196
  expect(body.name).toBe('Updated Item');
190
197
  });
@@ -200,7 +207,9 @@ describe('DataLayer', () => {
200
207
  const result = await dataLayer.handleRequest(event, mockContext);
201
208
 
202
209
  expect(result.statusCode).toBe(200);
210
+
203
211
  const body = JSON.parse(result.body);
212
+
204
213
  expect(body.message).toBe('Item deleted successfully');
205
214
  });
206
215
 
@@ -215,7 +224,9 @@ describe('DataLayer', () => {
215
224
  const result = await dataLayer.handleRequest(event, mockContext);
216
225
 
217
226
  expect(result.statusCode).toBe(400);
227
+
218
228
  const body = JSON.parse(result.body);
229
+
219
230
  expect(body.error).toBe('ID is required for update operations');
220
231
  });
221
232
 
@@ -230,7 +241,9 @@ describe('DataLayer', () => {
230
241
  const result = await dataLayer.handleRequest(event, mockContext);
231
242
 
232
243
  expect(result.statusCode).toBe(400);
244
+
233
245
  const body = JSON.parse(result.body);
246
+
234
247
  expect(body.error).toBe('ID is required for delete operations');
235
248
  });
236
249
 
@@ -245,7 +258,9 @@ describe('DataLayer', () => {
245
258
  const result = await dataLayer.handleRequest(event, mockContext);
246
259
 
247
260
  expect(result.statusCode).toBe(405);
261
+
248
262
  const body = JSON.parse(result.body);
263
+
249
264
  expect(body.error).toBe('Method not allowed');
250
265
  });
251
266
  });
package/webpack.config.js CHANGED
@@ -3,19 +3,20 @@
3
3
  * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
4
  */
5
5
  import {StaticSitePlugin} from '@nlabs/webpack-plugin-static-site';
6
- import tailwindcss from '@tailwindcss/postcss';
7
6
  import tailwindNesting from '@tailwindcss/nesting';
7
+ import tailwindcss from '@tailwindcss/postcss';
8
8
  import autoprefixer from 'autoprefixer';
9
9
  import CompressionWebpackPlugin from 'compression-webpack-plugin';
10
10
  import CopyWebpackPlugin from 'copy-webpack-plugin';
11
+ import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
11
12
  import cssnano from 'cssnano';
12
13
  import DotenvPlugin from 'dotenv-webpack';
13
- import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
14
14
  import FaviconsWebpackPlugin from 'favicons-webpack-plugin';
15
15
  import {existsSync} from 'fs';
16
16
  import {sync as globSync} from 'glob';
17
17
  import HtmlWebPackPlugin from 'html-webpack-plugin';
18
18
  import isEmpty from 'lodash/isEmpty.js';
19
+ import {createRequire} from 'module';
19
20
  import {resolve as pathResolve} from 'path';
20
21
  import postcssBrowserReporter from 'postcss-browser-reporter';
21
22
  import postcssCustomProperties from 'postcss-custom-properties';
@@ -26,15 +27,14 @@ import postcssPresetEnv from 'postcss-preset-env';
26
27
  import postcssUrl from 'postcss-url';
27
28
  import SVGSpriteMapPlugin from 'svg-spritemap-webpack-plugin';
28
29
  import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
29
- import {createRequire} from 'module';
30
30
  import {URL} from 'url';
31
31
  import {default as webpack} from 'webpack';
32
32
  import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer';
33
33
  import {merge} from 'webpack-merge';
34
34
  import {WebpackPluginServe} from 'webpack-plugin-serve';
35
35
 
36
- import {relativeFilePath, relativeNodePath} from './lib/utils/file.js';
37
36
  import {LexConfig} from './lib/LexConfig.js';
37
+ import {relativeFilePath, relativeNodePath} from './lib/utils/file.js';
38
38
  import postcssFor from './lib/utils/postcss/postcss-for.js';
39
39
  import postcssPercentage from './lib/utils/postcss/postcss-percentage.js';
40
40
 
@@ -53,14 +53,13 @@ const {
53
53
  libraryName,
54
54
  libraryTarget,
55
55
  preset,
56
- tailwindContent,
57
56
  targetEnvironment = 'es2015',
58
57
  webpack: webpackCustom
59
58
  } = lexConfig;
60
59
 
61
60
  const webpackStaticPath = webpackCustom?.staticPath || './src/static';
62
61
 
63
- const { publicPath: _, staticPath: __, ...webpackConfigFiltered } = webpackCustom || {};
62
+ const {publicPath: _, staticPath: __, ...webpackConfigFiltered} = webpackCustom || {};
64
63
 
65
64
  const plugins = [
66
65
  new ProgressPlugin({
@@ -90,7 +89,7 @@ const plugins = [
90
89
  }),
91
90
  new webpack.DefinePlugin({
92
91
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
93
- 'global': 'global'
92
+ global: 'global'
94
93
  }),
95
94
  {
96
95
  apply: (compiler) => {
@@ -98,7 +97,7 @@ const plugins = [
98
97
  console.log('\x1b[36m[webpack]\x1b[0m Detected file change. Rebuilding...');
99
98
  });
100
99
  compiler.hooks.done.tap('NotifyOnRebuild', (stats) => {
101
- if (stats.hasErrors()) {
100
+ if(stats.hasErrors()) {
102
101
  console.log('\x1b[31m[webpack]\x1b[0m Build failed with errors.');
103
102
  } else {
104
103
  console.log('\x1b[32m[webpack]\x1b[0m Build complete. Watching for changes...');
@@ -287,13 +286,13 @@ const webpackPath = relativeNodePath('webpack', dirName) || 'webpack';
287
286
  const aliasPaths = {
288
287
  '@nlabs/arkhamjs': relativeNodePath('@nlabs/arkhamjs', process.cwd()),
289
288
  '@nlabs/arkhamjs-utils-react': relativeNodePath('@nlabs/arkhamjs-utils-react', process.cwd()),
290
- 'buffer': relativeNodePath('buffer', dirName),
289
+ buffer: relativeNodePath('buffer', dirName),
291
290
  'core-js': relativeNodePath('core-js', dirName),
292
291
  process: relativeNodePath('process', dirName),
293
292
  react: relativeNodePath('react', process.cwd()),
294
293
  'react-dom': relativeNodePath('react-dom', process.cwd()),
295
294
  'regenerator-runtime': relativeNodePath('regenerator-runtime', dirName),
296
- 'Buffer': relativeNodePath('buffer', dirName)
295
+ Buffer: relativeNodePath('buffer', dirName)
297
296
  };
298
297
  const aliasKeys = Object.keys(aliasPaths);
299
298
  const alias = aliasKeys.reduce((aliases, key) => {
@@ -323,19 +322,19 @@ export default (webpackEnv, webpackOptions) => {
323
322
  : 'eval-cheap-module-source-map',
324
323
  entry: entryValue
325
324
  ? {
326
- index: [
327
- 'buffer',
328
- 'process/browser',
329
- entryValue
330
- ]
331
- }
325
+ index: [
326
+ 'buffer',
327
+ 'process/browser',
328
+ entryValue
329
+ ]
330
+ }
332
331
  : {
333
- index: [
334
- 'buffer',
335
- 'process/browser',
336
- `${sourceFullPath}/${lexConfig.entryJs}`
337
- ]
338
- },
332
+ index: [
333
+ 'buffer',
334
+ 'process/browser',
335
+ `${sourceFullPath}/${lexConfig.entryJs}`
336
+ ]
337
+ },
339
338
  externals: isReactNative ? {'react-native': true} : undefined,
340
339
  ignoreWarnings: [/Failed to parse source map/],
341
340
  mode: isProduction ? 'production' : 'development',
@@ -481,8 +480,8 @@ export default (webpackEnv, webpackOptions) => {
481
480
  use: [
482
481
  ...(isProduction && isWeb
483
482
  ? [{
484
- loader: require(miniCssExtractPluginPath).loader
485
- }]
483
+ loader: require(miniCssExtractPluginPath).loader
484
+ }]
486
485
  : [styleLoaderPath]),
487
486
  {
488
487
  loader: cssLoaderPath,
@@ -538,7 +537,7 @@ export default (webpackEnv, webpackOptions) => {
538
537
  }),
539
538
  tailwindNesting(),
540
539
  postcssNesting(),
541
- tailwindcss(tailwindContent ? {content: tailwindContent} : undefined),
540
+ tailwindcss(),
542
541
  autoprefixer(),
543
542
  postcssFlexbugsFixes(),
544
543
  postcssPresetEnv({
@@ -735,20 +734,20 @@ export default (webpackEnv, webpackOptions) => {
735
734
  if(existsSync(filePath)) {
736
735
  try {
737
736
  ctx.type = path.match(/\.svg$/i) ? 'image/svg+xml' :
738
- path.match(/\.(jpg|jpeg|png|gif)$/i) ? 'image/' + path.split('.').pop() :
739
- path.match(/\.css$/i) ? 'text/css' :
740
- 'application/octet-stream';
737
+ path.match(/\.(jpg|jpeg|png|gif)$/i) ? `image/${path.split('.').pop()}` :
738
+ path.match(/\.css$/i) ? 'text/css' :
739
+ 'application/octet-stream';
741
740
  ctx.body = readFileSync(filePath);
742
741
  ctx.status = 200;
743
742
 
744
743
  return;
745
744
  } catch(err) {
746
- if (process.env.LEX_CONFIG_DEBUG) {
745
+ if(process.env.LEX_CONFIG_DEBUG) {
747
746
  console.log(`[LEX_DEBUG] Error reading file ${filePath}:`, err.message);
748
747
  }
749
748
  }
750
749
  } else {
751
- if (process.env.LEX_CONFIG_DEBUG) {
750
+ if(process.env.LEX_CONFIG_DEBUG) {
752
751
  console.log(`[LEX_DEBUG] File not found at: ${filePath}, outputFullPath: ${outputFullPath}, path: ${path}`);
753
752
  }
754
753
  }
@@ -758,7 +757,7 @@ export default (webpackEnv, webpackOptions) => {
758
757
  });
759
758
 
760
759
  if(outputFullPath && existsSync(outputFullPath)) {
761
- if (process.env.LEX_CONFIG_DEBUG) {
760
+ if(process.env.LEX_CONFIG_DEBUG) {
762
761
  console.log(`[LEX_DEBUG] Setting up static file serving from output: ${outputFullPath}`);
763
762
  }
764
763
 
@@ -772,7 +771,7 @@ export default (webpackEnv, webpackOptions) => {
772
771
  }
773
772
 
774
773
  if(existsSync(staticPathFull)) {
775
- if (process.env.LEX_CONFIG_DEBUG) {
774
+ if(process.env.LEX_CONFIG_DEBUG) {
776
775
  console.log(`[LEX_DEBUG] Setting up static file serving from: ${staticPathFull}`);
777
776
  }
778
777
 
@@ -784,20 +783,20 @@ export default (webpackEnv, webpackOptions) => {
784
783
  br: false
785
784
  }));
786
785
 
787
- if (process.env.LEX_CONFIG_DEBUG) {
786
+ if(process.env.LEX_CONFIG_DEBUG) {
788
787
  app.use(async (ctx, next) => {
789
788
  const path = ctx.path || ctx.url || '';
790
- if (path && !path.match(/^\/wps/) && !path.match(/^\/webpack/)) {
789
+ if(path && !path.match(/^\/wps/) && !path.match(/^\/webpack/)) {
791
790
  console.log(`[LEX_DEBUG] Request: ${path}`);
792
791
  }
793
792
  await next();
794
- if (ctx.status === 404 && path && path.includes('.')) {
793
+ if(ctx.status === 404 && path && path.includes('.')) {
795
794
  console.log(`[LEX_DEBUG] 404 for: ${path}, body set: ${ctx.body !== undefined}`);
796
795
  }
797
796
  });
798
797
  }
799
798
  } else {
800
- if (process.env.LEX_CONFIG_DEBUG) {
799
+ if(process.env.LEX_CONFIG_DEBUG) {
801
800
  console.log(`[LEX_DEBUG] Static path does not exist: ${staticPathFull}`);
802
801
  }
803
802
  }
@@ -887,17 +886,17 @@ export default (webpackEnv, webpackOptions) => {
887
886
  }
888
887
  }
889
888
 
890
- if (process.env.LEX_CONFIG_DEBUG) {
889
+ if(process.env.LEX_CONFIG_DEBUG) {
891
890
  console.log('\n\x1b[36m[LEX_CONFIG_DEBUG] Webpack mode:', process.env.NODE_ENV, 'isProduction:', isProduction, '\x1b[0m');
892
- if (webpackConfig && webpackConfig.module && Array.isArray(webpackConfig.module.rules)) {
891
+ if(webpackConfig && webpackConfig.module && Array.isArray(webpackConfig.module.rules)) {
893
892
  console.log('\x1b[36m[LEX_CONFIG_DEBUG] Loader chains:\x1b[0m');
894
893
  webpackConfig.module.rules.forEach((rule, idx) => {
895
- if (rule.test) {
896
- let testStr = rule.test.toString();
894
+ if(rule.test) {
895
+ const testStr = rule.test.toString();
897
896
  let use = rule.use || rule.loader || rule.type;
898
- if (Array.isArray(use)) {
899
- use = use.map(u => (typeof u === 'string' ? u : u.loader || u.type)).join(' -> ');
900
- } else if (typeof use === 'object' && use !== null) {
897
+ if(Array.isArray(use)) {
898
+ use = use.map((u) => (typeof u === 'string' ? u : u.loader || u.type)).join(' -> ');
899
+ } else if(typeof use === 'object' && use !== null) {
901
900
  use = use.loader || use.type;
902
901
  }
903
902
  console.log(` [${idx}] ${testStr}: ${use}`);
@@ -905,23 +904,27 @@ export default (webpackEnv, webpackOptions) => {
905
904
  });
906
905
  }
907
906
 
908
- if (webpackConfig && Array.isArray(webpackConfig.plugins)) {
907
+ if(webpackConfig && Array.isArray(webpackConfig.plugins)) {
909
908
  console.log('\x1b[36m[LEX_CONFIG_DEBUG] Plugins:\x1b[0m');
910
909
  webpackConfig.plugins.forEach((plugin, idx) => {
911
910
  let name = plugin.constructor && plugin.constructor.name;
912
- if (!name && typeof plugin === 'object' && plugin.apply) name = 'CustomPlugin';
913
- if (!name && typeof plugin === 'function') name = 'FunctionPlugin';
911
+ if(!name && typeof plugin === 'object' && plugin.apply) {
912
+ name = 'CustomPlugin';
913
+ }
914
+ if(!name && typeof plugin === 'function') {
915
+ name = 'FunctionPlugin';
916
+ }
914
917
  console.log(` [${idx}] ${name}`);
915
918
  });
916
919
  }
917
920
 
918
- if (webpackConfig && webpackConfig.module && Array.isArray(webpackConfig.module.rules)) {
919
- const cssRule = webpackConfig.module.rules.find(rule => rule.test && rule.test.toString().includes('css'));
920
- if (cssRule) {
921
+ if(webpackConfig && webpackConfig.module && Array.isArray(webpackConfig.module.rules)) {
922
+ const cssRule = webpackConfig.module.rules.find((rule) => rule.test && rule.test.toString().includes('css'));
923
+ if(cssRule) {
921
924
  let use = cssRule.use || cssRule.loader || cssRule.type;
922
- if (Array.isArray(use)) {
923
- use = use.map(u => (typeof u === 'string' ? u : u.loader || u.type)).join(' -> ');
924
- } else if (typeof use === 'object' && use !== null) {
925
+ if(Array.isArray(use)) {
926
+ use = use.map((u) => (typeof u === 'string' ? u : u.loader || u.type)).join(' -> ');
927
+ } else if(typeof use === 'object' && use !== null) {
925
928
  use = use.loader || use.type;
926
929
  }
927
930
  console.log('\x1b[36m[LEX_CONFIG_DEBUG] CSS Loader Chain:\x1b[0m', use);
@@ -933,13 +936,13 @@ export default (webpackEnv, webpackOptions) => {
933
936
 
934
937
  const mergedConfig = merge(webpackConfig, webpackConfigFiltered);
935
938
 
936
- if (Array.isArray(mergedConfig.plugins)) {
939
+ if(Array.isArray(mergedConfig.plugins)) {
937
940
  mergedConfig.plugins = mergedConfig.plugins.filter((plugin) => {
938
- if (typeof plugin === 'function' || (plugin && typeof plugin.apply === 'function')) {
941
+ if(typeof plugin === 'function' || (plugin && typeof plugin.apply === 'function')) {
939
942
  return true;
940
943
  }
941
944
 
942
- if (plugin && typeof plugin === 'object' && 'postcssPlugin' in plugin) {
945
+ if(plugin && typeof plugin === 'object' && 'postcssPlugin' in plugin) {
943
946
  return false;
944
947
  }
945
948