@herb-tools/language-server 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +74 -7
  2. package/bin/herb-language-server +0 -16
  3. package/dist/cli.js +27 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/config.js.map +1 -1
  6. package/dist/diagnostics.js +17 -50
  7. package/dist/diagnostics.js.map +1 -1
  8. package/dist/formatting_service.js +124 -0
  9. package/dist/formatting_service.js.map +1 -0
  10. package/dist/herb-language-server.js +16118 -6762
  11. package/dist/herb-language-server.js.map +1 -1
  12. package/dist/index.cjs +29900 -0
  13. package/dist/index.cjs.map +1 -0
  14. package/dist/index.js +27 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/linter_service.js +44 -0
  17. package/dist/linter_service.js.map +1 -0
  18. package/dist/parser_service.js +47 -0
  19. package/dist/parser_service.js.map +1 -0
  20. package/dist/project.js +2 -1
  21. package/dist/project.js.map +1 -1
  22. package/dist/server.js +72 -61
  23. package/dist/server.js.map +1 -1
  24. package/dist/service.js +16 -4
  25. package/dist/service.js.map +1 -1
  26. package/dist/settings.js +11 -1
  27. package/dist/settings.js.map +1 -1
  28. package/dist/types/cli.d.ts +4 -0
  29. package/dist/types/config.d.ts +9 -1
  30. package/dist/types/diagnostics.d.ts +9 -7
  31. package/dist/types/formatting_service.d.ts +19 -0
  32. package/dist/types/herb-language-server.d.ts +2 -0
  33. package/dist/types/index.d.ts +10 -0
  34. package/dist/types/linter_service.d.ts +14 -0
  35. package/dist/types/parser_service.d.ts +10 -0
  36. package/dist/types/project.d.ts +2 -0
  37. package/dist/types/server.d.ts +7 -1
  38. package/dist/types/service.d.ts +6 -0
  39. package/dist/types/settings.d.ts +11 -0
  40. package/package.json +22 -24
  41. package/src/cli.ts +23 -0
  42. package/src/config.ts +9 -1
  43. package/src/diagnostics.ts +22 -79
  44. package/src/formatting_service.ts +150 -0
  45. package/src/herb-language-server.ts +6 -0
  46. package/src/index.ts +10 -0
  47. package/src/linter_service.ts +63 -0
  48. package/src/parser_service.ts +59 -0
  49. package/src/project.ts +4 -2
  50. package/src/server.ts +83 -65
  51. package/src/service.ts +21 -6
  52. package/src/settings.ts +24 -2
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
- ## Herb Language Server
1
+ # Herb Language Server
2
2
 
3
- ##### Package: [`@herb-tools/language-server`](https://www.npmjs.com/package/@herb-tools/language-server)
3
+ **Package**: [`@herb-tools/language-server`](https://www.npmjs.com/package/@herb-tools/language-server)
4
4
 
5
5
  ---
6
6
 
7
- [Language Server Protocol](https://github.com/Microsoft/language-server-protocol) integration for HTML-aware ERB parsing using the [Herb Parser](https://herb-tools.dev).
7
+ [Language Server Protocol](https://github.com/Microsoft/language-server-protocol) integration for HTML-aware ERB parsing using the [Herb Parser](/projects/parser).
8
8
 
9
- ![](./assets/herb-lsp.png)
9
+ ![Herb Language Server in action](https://github.com/marcoroth/herb/raw/main/javascript/packages/language-server/assets/herb-lsp.png)
10
10
 
11
11
  ### Installation
12
12
 
@@ -26,14 +26,48 @@ Read more in the [documentation](https://zed.dev/docs/languages/ruby).
26
26
 
27
27
  #### Neovim (using `nvim-lspconfig`)
28
28
 
29
- Coming soon, see [#3925](https://github.com/neovim/nvim-lspconfig/pull/3925).
29
+ After installing the Herb Language Server (see below), add `herb_ls` to your Neovim config (requires nvim 0.11+):
30
+
31
+ ```lua
32
+ require('lspconfig')
33
+ vim.lsp.enable('herb_ls')
34
+ ```
35
+
36
+ #### Sublime Text (using Sublime LSP)
37
+
38
+ After installing the Herb Language Server (see below) and [Sublime LSP](http://lsp.sublimetext.io), update the preferences for the `LSP` package:
39
+
40
+ ```json
41
+ // LSP.sublime-settings
42
+ {
43
+ "clients": {
44
+ "herb": {
45
+ "enabled": true,
46
+ "command": [
47
+ "herb-language-server",
48
+ "--stdio"
49
+ ],
50
+ "selector": "text.html.ruby | text.html.rails",
51
+ "settings": {
52
+ "languageServerHerb.linter": {
53
+ "enabled": true
54
+ }
55
+ },
56
+ "initializationOptions": {
57
+ "enabledFeatures": {
58
+ "diagnostics": true,
59
+ },
60
+ "experimentalFeaturesEnabled": true
61
+ }
62
+ }
63
+ },
64
+ }
65
+ ```
30
66
 
31
67
  #### Manual Installation
32
68
 
33
69
  You can use the language server in any editor that supports the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/).
34
70
 
35
- ##### Install
36
-
37
71
  ###### NPM (Global)
38
72
 
39
73
  ```bash
@@ -52,6 +86,8 @@ yarn global add @herb-tools/language-server
52
86
  herb-language-server --stdio
53
87
  ```
54
88
 
89
+ ##### Usage
90
+
55
91
  ```
56
92
  Usage: herb-language-server [options]
57
93
 
@@ -69,3 +105,34 @@ Alternatively you can also run the language server directly with `npx` without i
69
105
  ```bash
70
106
  npx @herb-tools/language-server --stdio
71
107
  ```
108
+
109
+ ## Configuration
110
+
111
+ The language server can be configured using a `.herb-lsp/config.json` file in your project root. This file is automatically created when the language server starts if it doesn't exist.
112
+
113
+ ### Formatter Configuration
114
+
115
+ You can configure formatting behavior by adding a `formatter` section to your config:
116
+
117
+ ```json
118
+ {
119
+ "version": "0.3.1",
120
+ "createdAt": "2025-06-29T00:00:00.000Z",
121
+ "updatedAt": "2025-06-29T00:00:00.000Z",
122
+ "options": {
123
+ "formatter": {
124
+ "enabled": true,
125
+ "indentWidth": 2,
126
+ "maxLineLength": 80
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ #### `formatter` Options
133
+
134
+ - `enabled` (`boolean`): Enable or disable formatting for this project. Defaults to `false`.
135
+ - `indentWidth` (`number`): Number of spaces for each indentation level. Defaults to `2`.
136
+ - `maxLineLength` (`number`): Maximum line length before wrapping. Defaults to `80`.
137
+
138
+ **Note**: VS Code users can also control formatting globally through the `languageServerHerb.formatter.enabled` setting in VS Code preferences. Formatting is currently in **Beta** and disabled by default.
@@ -1,19 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const usage = `
4
- Usage: herb-language-server [options]
5
-
6
- Options:
7
- --stdio use stdio
8
- --node-ipc use node-ipc
9
- --socket=<port> use socket
10
- `
11
-
12
- if (process.argv.length <= 2) {
13
- console.error(`Error: Connection input stream is not set. Set command line parameters: '--node-ipc', '--stdio' or '--socket=<port>'`)
14
- console.error(usage)
15
-
16
- process.exit(1)
17
- }
18
-
19
3
  import("../dist/herb-language-server.js")
package/dist/cli.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLI = void 0;
4
+ const server_1 = require("./server");
5
+ class CLI {
6
+ constructor() {
7
+ this.usage = `
8
+ Usage: herb-language-server [options]
9
+
10
+ Options:
11
+ --stdio use stdio
12
+ --node-ipc use node-ipc
13
+ --socket=<port> use socket
14
+ `;
15
+ }
16
+ run() {
17
+ if (process.argv.length <= 2) {
18
+ console.error(`Error: Connection input stream is not set. Set command line parameters: '--node-ipc', '--stdio' or '--socket=<port>'`);
19
+ console.error(this.usage);
20
+ process.exit(1);
21
+ }
22
+ const server = new server_1.Server();
23
+ server.listen();
24
+ }
25
+ }
26
+ exports.CLI = CLI;
27
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AAEjC,MAAa,GAAG;IAAhB;QACU,UAAK,GAAG;;;;;;;CAOjB,CAAA;IAYD,CAAC;IAVC,GAAG;QACD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,sHAAsH,CAAC,CAAA;YACrI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,eAAM,EAAE,CAAA;QAC3B,MAAM,CAAC,MAAM,EAAE,CAAA;IACjB,CAAC;CACF;AApBD,kBAoBC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1,63 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Diagnostics = void 0;
4
- const node_1 = require("vscode-languageserver/node");
5
- const node_wasm_1 = require("@herb-tools/node-wasm");
6
- class ErrorVisitor extends node_wasm_1.Visitor {
7
- constructor(diagnostics, textDocument) {
8
- super();
9
- this.diagnostics = diagnostics;
10
- this.textDocument = textDocument;
11
- }
12
- visitChildNodes(node) {
13
- super.visitChildNodes(node);
14
- node.errors.forEach(error => this.publishDiagnosticForError(error, node));
15
- }
16
- publishDiagnosticForError(error, node) {
17
- this.diagnostics.pushDiagnostic(error.message, error.type, this.rangeFromHerbError(error), this.textDocument, {
18
- error: error.toJSON(),
19
- node: node.toJSON()
20
- }, node_1.DiagnosticSeverity.Error);
21
- }
22
- rangeFromHerbError(error) {
23
- return node_1.Range.create(node_1.Position.create(error.location.start.line - 1, error.location.start.column), node_1.Position.create(error.location.end.line - 1, error.location.end.column));
24
- }
25
- }
26
4
  class Diagnostics {
27
- constructor(connection, documentService) {
28
- this.diagnosticsSource = "Herb LSP ";
5
+ constructor(connection, documentService, parserService, linterService) {
29
6
  this.diagnostics = new Map();
30
7
  this.connection = connection;
31
8
  this.documentService = documentService;
32
- }
33
- validate(textDocument) {
34
- const content = textDocument.getText();
35
- const result = node_wasm_1.Herb.parse(content);
36
- const visitor = new ErrorVisitor(this, textDocument);
37
- result.visit(visitor);
9
+ this.parserService = parserService;
10
+ this.linterService = linterService;
11
+ }
12
+ async validate(textDocument) {
13
+ const parseResult = this.parserService.parseDocument(textDocument);
14
+ const lintResult = await this.linterService.lintDocument(parseResult.document, textDocument);
15
+ const allDiagnostics = [
16
+ ...parseResult.diagnostics,
17
+ ...lintResult.diagnostics,
18
+ ];
19
+ this.diagnostics.set(textDocument, allDiagnostics);
38
20
  this.sendDiagnosticsFor(textDocument);
39
21
  }
40
- refreshDocument(document) {
41
- this.validate(document);
42
- }
43
- refreshAllDocuments() {
44
- this.documentService.getAll().forEach((document) => {
45
- this.refreshDocument(document);
46
- });
22
+ async refreshDocument(document) {
23
+ await this.validate(document);
47
24
  }
48
- pushDiagnostic(message, code, range, textDocument, data = {}, severity = node_1.DiagnosticSeverity.Error) {
49
- const diagnostic = {
50
- source: this.diagnosticsSource,
51
- severity,
52
- range,
53
- message,
54
- code,
55
- data,
56
- };
57
- const diagnostics = this.diagnostics.get(textDocument) || [];
58
- diagnostics.push(diagnostic);
59
- this.diagnostics.set(textDocument, diagnostics);
60
- return diagnostic;
25
+ async refreshAllDocuments() {
26
+ const documents = this.documentService.getAll();
27
+ await Promise.all(documents.map(document => this.refreshDocument(document)));
61
28
  }
62
29
  sendDiagnosticsFor(textDocument) {
63
30
  const diagnostics = this.diagnostics.get(textDocument) || [];
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":";;;AAOA,MAAa,WAAW;IAOtB,YACE,UAAsB,EACtB,eAAgC,EAChC,aAA4B,EAC5B,aAA4B;QANtB,gBAAW,GAAoC,IAAI,GAAG,EAAE,CAAA;QAQ9D,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAA;QACtC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAClC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,YAA0B;QACvC,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC,CAAA;QAClE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAE5F,MAAM,cAAc,GAAG;YACrB,GAAG,WAAW,CAAC,WAAW;YAC1B,GAAG,UAAU,CAAC,WAAW;SAC1B,CAAA;QAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,cAAc,CAAC,CAAA;QAClD,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAA;IACvC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,QAAsB;QAC1C,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAA;QAC/C,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC9E,CAAC;IAEO,kBAAkB,CAAC,YAA0B;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAA;QAE5D,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;YAC9B,GAAG,EAAE,YAAY,CAAC,GAAG;YACrB,WAAW;SACZ,CAAC,CAAA;QAEF,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACvC,CAAC;CACF;AAnDD,kCAmDC"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FormattingService = void 0;
4
+ const node_1 = require("vscode-languageserver/node");
5
+ const formatter_1 = require("@herb-tools/formatter");
6
+ const config_1 = require("./config");
7
+ const glob_1 = require("glob");
8
+ class FormattingService {
9
+ constructor(connection, documents, project, settings) {
10
+ this.connection = connection;
11
+ this.documents = documents;
12
+ this.project = project;
13
+ this.settings = settings;
14
+ }
15
+ async initialize() {
16
+ try {
17
+ this.config = await config_1.Config.fromPathOrNew(this.project.projectPath);
18
+ this.connection.console.log("Herb formatter initialized successfully");
19
+ }
20
+ catch (error) {
21
+ this.connection.console.error(`Failed to initialize Herb formatter: ${error}`);
22
+ }
23
+ }
24
+ async refreshConfig() {
25
+ this.config = await config_1.Config.fromPathOrNew(this.project.projectPath);
26
+ }
27
+ async shouldFormatFile(filePath) {
28
+ var _a;
29
+ if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.options.formatter)) {
30
+ return true;
31
+ }
32
+ const formatter = this.config.options.formatter;
33
+ // Check if formatting is disabled in project config
34
+ if (formatter.enabled === false) {
35
+ return false;
36
+ }
37
+ // Check exclude patterns first
38
+ if (formatter.exclude) {
39
+ for (const pattern of formatter.exclude) {
40
+ try {
41
+ const matches = await new Promise((resolve, reject) => {
42
+ (0, glob_1.glob)(pattern, { cwd: this.project.projectPath }).then(resolve).catch(reject);
43
+ });
44
+ if (Array.isArray(matches) && matches.some((match) => filePath.includes(match) || filePath.endsWith(match))) {
45
+ return false;
46
+ }
47
+ }
48
+ catch (error) {
49
+ continue;
50
+ }
51
+ }
52
+ }
53
+ if (formatter.include && formatter.include.length > 0) {
54
+ for (const pattern of formatter.include) {
55
+ try {
56
+ const matches = await new Promise((resolve, reject) => {
57
+ (0, glob_1.glob)(pattern, { cwd: this.project.projectPath }).then(resolve).catch(reject);
58
+ });
59
+ if (Array.isArray(matches) && matches.some((match) => filePath.includes(match) || filePath.endsWith(match))) {
60
+ return true;
61
+ }
62
+ }
63
+ catch (error) {
64
+ continue;
65
+ }
66
+ }
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ async getFormatterOptions(uri) {
72
+ var _a, _b, _c, _d, _e, _f, _g;
73
+ const settings = await this.settings.getDocumentSettings(uri);
74
+ const projectFormatter = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.options.formatter) || {};
75
+ return {
76
+ indentWidth: (_d = (_b = projectFormatter.indentWidth) !== null && _b !== void 0 ? _b : (_c = settings.formatter) === null || _c === void 0 ? void 0 : _c.indentWidth) !== null && _d !== void 0 ? _d : formatter_1.defaultFormatOptions.indentWidth,
77
+ maxLineLength: (_g = (_e = projectFormatter.maxLineLength) !== null && _e !== void 0 ? _e : (_f = settings.formatter) === null || _f === void 0 ? void 0 : _f.maxLineLength) !== null && _g !== void 0 ? _g : formatter_1.defaultFormatOptions.maxLineLength
78
+ };
79
+ }
80
+ async performFormatting(params) {
81
+ const document = this.documents.get(params.textDocument.uri);
82
+ if (!document) {
83
+ return [];
84
+ }
85
+ try {
86
+ const options = await this.getFormatterOptions(params.textDocument.uri);
87
+ const formatter = new formatter_1.Formatter(this.project.herbBackend, options);
88
+ const text = document.getText();
89
+ let newText = formatter.format(text);
90
+ if (!newText.endsWith('\n')) {
91
+ newText = newText + '\n';
92
+ }
93
+ if (newText === text) {
94
+ return [];
95
+ }
96
+ const range = {
97
+ start: node_1.Position.create(0, 0),
98
+ end: node_1.Position.create(document.lineCount, 0)
99
+ };
100
+ return [{ range, newText }];
101
+ }
102
+ catch (error) {
103
+ this.connection.console.error(`Formatting failed: ${error}`);
104
+ return [];
105
+ }
106
+ }
107
+ async formatDocument(params) {
108
+ var _a;
109
+ const settings = await this.settings.getDocumentSettings(params.textDocument.uri);
110
+ if (((_a = settings.formatter) === null || _a === void 0 ? void 0 : _a.enabled) === false) {
111
+ return [];
112
+ }
113
+ const filePath = params.textDocument.uri.replace(/^file:\/\//, '');
114
+ if (!(await this.shouldFormatFile(filePath))) {
115
+ return [];
116
+ }
117
+ return this.performFormatting(params);
118
+ }
119
+ async formatDocumentIgnoreConfig(params) {
120
+ return this.performFormatting(params);
121
+ }
122
+ }
123
+ exports.FormattingService = FormattingService;
124
+ //# sourceMappingURL=formatting_service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting_service.js","sourceRoot":"","sources":["../src/formatting_service.ts"],"names":[],"mappings":";;;AAAA,qDAA2H;AAE3H,qDAAuE;AAGvE,qCAAiC;AACjC,+BAA2B;AAE3B,MAAa,iBAAiB;IAO5B,YAAY,UAAsB,EAAE,SAAsC,EAAE,OAAgB,EAAE,QAAkB;QAC9G,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,GAAG,MAAM,eAAM,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;YAClE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAA;QACxE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,wCAAwC,KAAK,EAAE,CAAC,CAAA;QAChF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,eAAM,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACpE,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,QAAgB;;QAC7C,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,OAAO,CAAC,SAAS,CAAA,EAAE,CAAC;YACpC,OAAO,IAAI,CAAA;QACb,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAA;QAE/C,oDAAoD;QACpD,IAAI,SAAS,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAChC,OAAO,KAAK,CAAA;QACd,CAAC;QAED,+BAA+B;QAC/B,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gBACxC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBAC9D,IAAA,WAAI,EAAC,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;oBAC9E,CAAC,CAAC,CAAA;oBAEF,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBACpH,OAAO,KAAK,CAAA;oBACd,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,SAAQ;gBACV,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtD,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gBACxC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBAC9D,IAAA,WAAI,EAAC,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;oBAC9E,CAAC,CAAC,CAAA;oBACF,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBACpH,OAAO,IAAI,CAAA;oBACb,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,SAAQ;gBACV,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,GAAW;;QAC3C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAA;QAE7D,MAAM,gBAAgB,GAAG,CAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,OAAO,CAAC,SAAS,KAAI,EAAE,CAAA;QAE7D,OAAO;YACL,WAAW,EAAE,MAAA,MAAA,gBAAgB,CAAC,WAAW,mCAAI,MAAA,QAAQ,CAAC,SAAS,0CAAE,WAAW,mCAAI,gCAAoB,CAAC,WAAW;YAChH,aAAa,EAAE,MAAA,MAAA,gBAAgB,CAAC,aAAa,mCAAI,MAAA,QAAQ,CAAC,SAAS,0CAAE,aAAa,mCAAI,gCAAoB,CAAC,aAAa;SACzH,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,MAAgC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QAE5D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,EAAE,CAAA;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;YACvE,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;YAElE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAA;YAC/B,IAAI,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAEpC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,OAAO,GAAG,OAAO,GAAG,IAAI,CAAA;YAC1B,CAAC;YAED,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,EAAE,CAAA;YACX,CAAC;YAED,MAAM,KAAK,GAAU;gBACnB,KAAK,EAAE,eAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC5B,GAAG,EAAE,eAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;aAC5C,CAAA;YAED,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAA;YAE5D,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,MAAgC;;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QAEjF,IAAI,CAAA,MAAA,QAAQ,CAAC,SAAS,0CAAE,OAAO,MAAK,KAAK,EAAE,CAAC;YAC1C,OAAO,EAAE,CAAA;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;QAElE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC7C,OAAO,EAAE,CAAA;QACX,CAAC;QAED,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;IAED,KAAK,CAAC,0BAA0B,CAAC,MAAgC;QAC/D,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;CACF;AA7ID,8CA6IC"}