@limetech/n8n-nodes-lime 2.5.5-dev.1 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +19 -2
  2. package/credentials/LimeFormsApi.credentials.ts +100 -0
  3. package/credentials/index.ts +1 -0
  4. package/dist/credentials/LimeFormsApi.credentials.d.ts +10 -0
  5. package/dist/credentials/LimeFormsApi.credentials.js +65 -0
  6. package/dist/credentials/LimeFormsApi.credentials.js.map +1 -0
  7. package/dist/credentials/index.d.ts +1 -0
  8. package/dist/credentials/index.js +1 -0
  9. package/dist/credentials/index.js.map +1 -1
  10. package/dist/nodes/{lime-crm/utils/hmac.js → common.js} +1 -1
  11. package/dist/nodes/common.js.map +1 -0
  12. package/dist/nodes/index.d.ts +1 -0
  13. package/dist/nodes/index.js +1 -0
  14. package/dist/nodes/index.js.map +1 -1
  15. package/dist/nodes/lime-crm/LimeCrmTrigger.node.js +2 -1
  16. package/dist/nodes/lime-crm/LimeCrmTrigger.node.js.map +1 -1
  17. package/dist/nodes/lime-crm/utils/index.d.ts +0 -1
  18. package/dist/nodes/lime-crm/utils/index.js +1 -3
  19. package/dist/nodes/lime-crm/utils/index.js.map +1 -1
  20. package/dist/nodes/lime-forms/LimeFormsTrigger.node.d.ts +17 -0
  21. package/dist/nodes/lime-forms/LimeFormsTrigger.node.js +187 -0
  22. package/dist/nodes/lime-forms/LimeFormsTrigger.node.js.map +1 -0
  23. package/dist/nodes/lime-forms/index.d.ts +1 -0
  24. package/dist/nodes/lime-forms/index.js +18 -0
  25. package/dist/nodes/lime-forms/index.js.map +1 -0
  26. package/dist/nodes/lime-forms/lime-forms.svg +6 -0
  27. package/dist/nodes/lime-forms/transport/request.d.ts +11 -0
  28. package/dist/nodes/lime-forms/transport/request.js +42 -0
  29. package/dist/nodes/lime-forms/transport/request.js.map +1 -0
  30. package/dist/nodes/lime-forms/types/enums/ObservableAction.d.ts +6 -0
  31. package/dist/nodes/lime-forms/types/enums/ObservableAction.js +11 -0
  32. package/dist/nodes/lime-forms/types/enums/ObservableAction.js.map +1 -0
  33. package/dist/nodes/lime-forms/types/enums/ObservableType.d.ts +3 -0
  34. package/dist/nodes/lime-forms/types/enums/ObservableType.js +8 -0
  35. package/dist/nodes/lime-forms/types/enums/ObservableType.js.map +1 -0
  36. package/dist/nodes/lime-forms/types/resources/BaseResponse.d.ts +4 -0
  37. package/dist/nodes/lime-forms/types/resources/BaseResponse.js +3 -0
  38. package/dist/nodes/lime-forms/types/resources/BaseResponse.js.map +1 -0
  39. package/dist/nodes/lime-forms/types/resources/FormExternalIntegrationSimpleResource.d.ts +4 -0
  40. package/dist/nodes/lime-forms/types/resources/FormExternalIntegrationSimpleResource.js +3 -0
  41. package/dist/nodes/lime-forms/types/resources/FormExternalIntegrationSimpleResource.js.map +1 -0
  42. package/dist/nodes/lime-forms/types/resources/ObservableWebhookResources.d.ts +13 -0
  43. package/dist/nodes/lime-forms/types/resources/ObservableWebhookResources.js +3 -0
  44. package/dist/nodes/lime-forms/types/resources/ObservableWebhookResources.js.map +1 -0
  45. package/dist/nodes/lime-forms/utils/workflow.d.ts +2 -0
  46. package/dist/nodes/lime-forms/utils/workflow.js +13 -0
  47. package/dist/nodes/lime-forms/utils/workflow.js.map +1 -0
  48. package/dist/package.json +7 -2
  49. package/dist/tsconfig.tsbuildinfo +1 -1
  50. package/docker-compose.yml +0 -0
  51. package/nodes/index.ts +1 -0
  52. package/nodes/lime-crm/LimeCrmTrigger.node.ts +2 -1
  53. package/nodes/lime-crm/utils/index.ts +0 -1
  54. package/nodes/lime-forms/LimeFormsTrigger.node.ts +258 -0
  55. package/nodes/lime-forms/index.ts +1 -0
  56. package/nodes/lime-forms/lime-forms.svg +6 -0
  57. package/nodes/lime-forms/transport/request.ts +60 -0
  58. package/nodes/lime-forms/types/enums/ObservableAction.ts +7 -0
  59. package/nodes/lime-forms/types/enums/ObservableType.ts +3 -0
  60. package/nodes/lime-forms/types/resources/BaseResponse.ts +4 -0
  61. package/nodes/lime-forms/types/resources/FormExternalIntegrationSimpleResource.ts +4 -0
  62. package/nodes/lime-forms/types/resources/ObservableWebhookResources.ts +16 -0
  63. package/nodes/lime-forms/utils/workflow.ts +17 -0
  64. package/package.json +8 -3
  65. package/.prettierignore +0 -6
  66. package/dist/nodes/lime-crm/utils/hmac.js.map +0 -1
  67. /package/dist/nodes/{lime-crm/utils/hmac.d.ts → common.d.ts} +0 -0
  68. /package/nodes/{lime-crm/utils/hmac.ts → common.ts} +0 -0
File without changes
package/nodes/index.ts CHANGED
@@ -2,3 +2,4 @@ export * from './response';
2
2
  export * from './lime-crm';
3
3
  export * from './fortnox';
4
4
  export * from './modules';
5
+ export * from './lime-forms';
@@ -20,7 +20,8 @@ import {
20
20
  listSubscriptionsWithExistingData,
21
21
  } from './transport';
22
22
 
23
- import { getWebhook, verifyHmac } from './utils';
23
+ import { getWebhook } from './utils';
24
+ import { verifyHmac } from '../common';
24
25
 
25
26
  /**
26
27
  * Trigger node for handling incoming webhooks from **Lime CRM**.
@@ -5,6 +5,5 @@ export {
5
5
  processFileResponse,
6
6
  setFileProperties,
7
7
  } from './files';
8
- export { verifyHmac } from './hmac';
9
8
  export { getWebhook } from './webhook';
10
9
  export { handleWorkflowError, WorkflowErrorContext } from '../../errorHandling';
@@ -0,0 +1,258 @@
1
+ import {
2
+ IHookFunctions,
3
+ ILoadOptionsFunctions,
4
+ INodePropertyOptions,
5
+ INodeType,
6
+ INodeTypeDescription,
7
+ IWebhookFunctions,
8
+ IWebhookResponseData,
9
+ NodeConnectionTypes,
10
+ LoggerProxy as Logger,
11
+ NodeOperationError,
12
+ NodeApiError,
13
+ IDataObject,
14
+ } from 'n8n-workflow';
15
+ import { LimeFormsRequest } from './transport/request';
16
+ import { FormExternalIntegrationSimpleResource } from './types/resources/FormExternalIntegrationSimpleResource';
17
+ import {
18
+ ObservableWebhookDetailedResource,
19
+ ObservableWebhookSimpleResource,
20
+ } from './types/resources/ObservableWebhookResources';
21
+ import { ObservableActionType } from './types/enums/ObservableAction';
22
+ import { ObservableType } from './types/enums/ObservableType';
23
+ import { FORMS_API_CREDENTIALS_NAME } from '../../credentials';
24
+ import { getWorkflowUrl } from './utils/workflow';
25
+ import { verifyHmac } from '../common';
26
+ import { handleWorkflowError } from '../errorHandling';
27
+
28
+ const FORMS_OBSERVABLE_WEBHOOK_NAME_PREFIX = 'N8N';
29
+
30
+ export class LimeFormsTrigger implements INodeType {
31
+ description: INodeTypeDescription = {
32
+ displayName: 'Lime Forms Trigger',
33
+ name: 'limeFormsTrigger',
34
+ group: ['trigger'],
35
+ version: 1,
36
+ icon: 'file:lime-forms.svg',
37
+ description: 'Handle webhooks from Lime Forms',
38
+ defaults: {
39
+ name: 'Lime Forms',
40
+ },
41
+ credentials: [
42
+ {
43
+ name: FORMS_API_CREDENTIALS_NAME,
44
+ required: true,
45
+ },
46
+ ],
47
+ inputs: [],
48
+ outputs: [NodeConnectionTypes.Main],
49
+ webhooks: [
50
+ {
51
+ name: 'default',
52
+ httpMethod: 'POST',
53
+ responseMode: 'onReceived',
54
+ path: 'lime-forms',
55
+ },
56
+ ],
57
+ properties: [
58
+ {
59
+ displayName: 'Trigger Name',
60
+ name: 'name',
61
+ type: 'string',
62
+ default: '',
63
+ placeholder: 'my-lime-webhook',
64
+ required: true,
65
+ description: 'Name for this webhook subscription',
66
+ },
67
+ {
68
+ displayName: 'Form to monitor',
69
+ name: 'formId',
70
+ type: 'options',
71
+ typeOptions: {
72
+ loadOptionsMethod: 'getForms',
73
+ },
74
+ default: '',
75
+ description:
76
+ 'Lime Forms to observe submissions for. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
77
+ },
78
+ ],
79
+ };
80
+
81
+ methods = {
82
+ loadOptions: {
83
+ async getForms(
84
+ this: ILoadOptionsFunctions
85
+ ): Promise<INodePropertyOptions[]> {
86
+ const response = await new LimeFormsRequest<
87
+ FormExternalIntegrationSimpleResource[]
88
+ >(this).get('/api/v1/external-integrations/forms/');
89
+
90
+ if (!response.success) {
91
+ Logger.error(`Lime Forms: Failed to load list of forms`);
92
+ return [];
93
+ }
94
+
95
+ return response.data.map((form) => {
96
+ return {
97
+ name: form.name,
98
+ value: form.id,
99
+ };
100
+ });
101
+ },
102
+ },
103
+ };
104
+
105
+ webhookMethods = {
106
+ default: {
107
+ async checkExists(this: IHookFunctions): Promise<boolean> {
108
+ const webhookData = this.getWorkflowStaticData('node');
109
+ const webhookId = webhookData.id;
110
+ if (webhookId === undefined) {
111
+ return false;
112
+ }
113
+ try {
114
+ const response =
115
+ await new LimeFormsRequest<ObservableWebhookSimpleResource>(
116
+ this
117
+ ).get(`/api/v1/observable-webhooks/${webhookId}`);
118
+ return response.data !== null;
119
+ } catch (error) {
120
+ if (error?.response && error.response?.status === 404) {
121
+ return false;
122
+ }
123
+ if (error.message) {
124
+ Logger.error(`Lime Forms: ${error.message}`);
125
+ }
126
+ throw new NodeApiError(this.getNode(), {
127
+ message:
128
+ 'Failed to check if webhook exists in Lime Forms',
129
+ });
130
+ }
131
+ },
132
+
133
+ async create(this: IHookFunctions): Promise<boolean> {
134
+ const credentials = await this.getCredentials(
135
+ FORMS_API_CREDENTIALS_NAME
136
+ );
137
+ const data = {
138
+ name: `${FORMS_OBSERVABLE_WEBHOOK_NAME_PREFIX}: ${this.getNodeParameter('name')}`,
139
+ observableType: ObservableType.FORM,
140
+ observableId: this.getNodeParameter('formId'),
141
+ action: ObservableActionType.FORM_SUBMITTED,
142
+ webhookUrl: this.getNodeWebhookUrl('default'),
143
+ secret: credentials.webhookSecret as string,
144
+ workflowUrl: getWorkflowUrl(
145
+ this.getNode(),
146
+ this.getWorkflow().id
147
+ ),
148
+ };
149
+ const webhookData = this.getWorkflowStaticData('node');
150
+
151
+ try {
152
+ const response =
153
+ await new LimeFormsRequest<ObservableWebhookDetailedResource>(
154
+ this
155
+ ).post('/api/v1/observable-webhooks', data);
156
+
157
+ if (!response.success) {
158
+ throw new NodeApiError(this.getNode(), {
159
+ message: 'Failed to create webhook in Lime Forms',
160
+ });
161
+ }
162
+
163
+ webhookData.id = response.data.id;
164
+
165
+ return true;
166
+ } catch (error) {
167
+ // 409 Indicates duplicate exists
168
+ if (error?.httpCode == '409') {
169
+ Logger.info(
170
+ `Webhook ${webhookData.name} already exists in Lime Forms, retrieving existing webhook ID`,
171
+ { errorResponse: error.context?.data }
172
+ );
173
+ /**
174
+ * Error response structure reference:
175
+ * @see https://github.com/n8n-io/n8n/blob/n8n%401.120.0/packages/core/src/execution-engine/node-execution-context/utils/request-helper-functions.ts#L1280
176
+ */
177
+ const errorResponse = error.context?.data?.error;
178
+ webhookData.id = errorResponse.id;
179
+ webhookData.name = errorResponse.name.replace(
180
+ `${FORMS_OBSERVABLE_WEBHOOK_NAME_PREFIX}: `,
181
+ ''
182
+ );
183
+ return true;
184
+ }
185
+ throw new NodeApiError(this.getNode(), {
186
+ message: 'Failed to create webhook in Lime Forms',
187
+ });
188
+ }
189
+ },
190
+
191
+ async delete(this: IHookFunctions): Promise<boolean> {
192
+ const webhookData = this.getWorkflowStaticData('node');
193
+ const webhookId = webhookData.id;
194
+ if (webhookId === undefined) {
195
+ return false;
196
+ }
197
+
198
+ const response =
199
+ await new LimeFormsRequest<ObservableWebhookSimpleResource>(
200
+ this
201
+ ).delete(`/api/v1/observable-webhooks/${webhookId}`);
202
+
203
+ if (!response.success) {
204
+ throw new NodeApiError(this.getNode(), {
205
+ message: 'Failed to delete webhook in Lime Forms',
206
+ });
207
+ }
208
+
209
+ delete webhookData.id;
210
+ delete webhookData.secret;
211
+
212
+ return true;
213
+ },
214
+ },
215
+ };
216
+
217
+ async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
218
+ const body = this.getBodyData();
219
+ const headers = this.getHeaderData();
220
+ const returnData: IDataObject[] = [];
221
+
222
+ try {
223
+ if (!('x-signature' in headers)) {
224
+ throw new NodeOperationError(
225
+ this.getNode(),
226
+ 'No signature header passed. Unable to verify integrity of the data.'
227
+ );
228
+ }
229
+
230
+ const webhookSecret = await this.getCredentials(
231
+ FORMS_API_CREDENTIALS_NAME
232
+ ).then((c) => c.webhookSecret as string);
233
+ const isValidSignature = verifyHmac(
234
+ webhookSecret,
235
+ Buffer.from(JSON.stringify(body)),
236
+ ('sha256=' + headers['x-signature']) as string
237
+ );
238
+
239
+ if (!isValidSignature) {
240
+ throw new NodeOperationError(
241
+ this.getNode(),
242
+ 'Invalid signature'
243
+ );
244
+ }
245
+ returnData.push(body);
246
+ } catch (error) {
247
+ const response = handleWorkflowError(this, {
248
+ message: error.message,
249
+ });
250
+
251
+ returnData.push(response as IDataObject);
252
+ }
253
+
254
+ return {
255
+ workflowData: [this.helpers.returnJsonArray(returnData)],
256
+ };
257
+ }
258
+ }
@@ -0,0 +1 @@
1
+ export * from './LimeFormsTrigger.node';
@@ -0,0 +1,6 @@
1
+ <svg viewBox="0 0 1025 1025" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"><clipPath id="a"><path d="M.067.03h1024v1024H.067z"/></clipPath>
2
+ <g clip-path="url(#a)"><path d="M92.466 480.888c0-257.059 208.718-465.779 465.78-465.779 257.101 0 465.821 208.72 465.821 465.779 0 133.713-55.806 271.139-193.404 385.355-166.779 138.45-390.389 157.35-736.149 134.525-102.653-6.785-117.502-24.319-64.469-63.444C196.74 814.277 92.466 720.157 92.466 480.888Z" style="fill:#a6efff"/>
3
+ <clipPath id="b"><path d="M92.466 480.888c0-257.059 208.718-465.779 465.78-465.779 257.101 0 465.821 208.72 465.821 465.779 0 133.713-55.806 271.139-193.404 385.355-166.779 138.45-390.389 157.35-736.149 134.525-102.653-6.785-117.502-24.319-64.469-63.444C196.74 814.277 92.466 720.157 92.466 480.888Z"/></clipPath>
4
+ <g clip-path="url(#b)"><path d="M-810.991 1517.47c-520.197-174.655 602.109-1999.19 1122.31-1824.54 520.198 174.652 347.26 364.038 243.982 791.188-103.277 427.149-846.091 1208-1366.29 1033.35Z" style="fill:#ffa6ea;filter:blur(200px)"/></g>
5
+ <path d="M415.273 301.267c-40.49 0-73.342 32.894-73.342 73.385 0 40.489 32.852 73.342 73.342 73.342 40.489 0 73.384-32.853 73.384-73.342 0-40.491-32.895-73.385-73.384-73.385Zm168.017 96.552h175.653c12.8 0 23.168-10.368 23.168-23.167 0-12.801-10.368-23.168-23.168-23.168H583.29c-12.8 0-23.168 10.367-23.168 23.168 0 12.799 10.368 23.167 23.168 23.167Zm0 212.345h175.653c12.8 0 23.168-10.367 23.168-23.167 0-12.756-10.368-23.166-23.168-23.166H583.29c-12.8 0-23.168 10.41-23.168 23.166 0 12.8 10.368 23.167 23.168 23.167Zm-168.017-96.509c-40.49 0-73.342 32.853-73.342 73.342 0 40.49 32.852 73.385 73.342 73.385 40.489 0 73.384-32.895 73.384-73.385 0-40.489-32.895-73.342-73.384-73.342Z"
6
+ style="fill:#fff"/></g></svg>
@@ -0,0 +1,60 @@
1
+ import {
2
+ IHookFunctions,
3
+ ILoadOptionsFunctions,
4
+ IHttpRequestMethods,
5
+ NodeApiError,
6
+ } from 'n8n-workflow';
7
+ import { FORMS_API_CREDENTIALS_NAME } from '../../../credentials';
8
+ import { BaseResponse } from '../types/resources/BaseResponse';
9
+
10
+ export class LimeFormsRequest<T = unknown> {
11
+ constructor(
12
+ private readonly loader: ILoadOptionsFunctions | IHookFunctions
13
+ ) {}
14
+
15
+ public async get(url: string): Promise<BaseResponse<T>> {
16
+ return this.baseRequest('GET', url, undefined);
17
+ }
18
+
19
+ public async post(url: string, data: object): Promise<BaseResponse<T>> {
20
+ return this.baseRequest('POST', url, data);
21
+ }
22
+
23
+ public async put(url: string, data: object): Promise<BaseResponse<T>> {
24
+ return this.baseRequest('PUT', url, data);
25
+ }
26
+
27
+ public async delete(url: string): Promise<BaseResponse<T>> {
28
+ return this.baseRequest('DELETE', url);
29
+ }
30
+
31
+ private async baseRequest(
32
+ method: string,
33
+ url: string,
34
+ data: object | undefined = undefined
35
+ ): Promise<BaseResponse<T>> {
36
+ // Get credentials for the API
37
+ const credentials = await this.loader.getCredentials(
38
+ FORMS_API_CREDENTIALS_NAME
39
+ );
40
+ if (credentials === undefined) {
41
+ throw new NodeApiError(this.loader.getNode(), {
42
+ message: 'No credentials provided',
43
+ });
44
+ }
45
+ return await this.loader.helpers.httpRequestWithAuthentication.call(
46
+ this.loader,
47
+ FORMS_API_CREDENTIALS_NAME,
48
+ {
49
+ method: method as IHttpRequestMethods,
50
+ url: url,
51
+ json: true,
52
+ body: data,
53
+ baseURL: credentials.url as string,
54
+ headers: {
55
+ Accept: 'application/json',
56
+ },
57
+ }
58
+ );
59
+ }
60
+ }
@@ -0,0 +1,7 @@
1
+ export enum ObservableActionType {
2
+ GENERIC_CREATE = 'GENERIC_CREATE',
3
+ GENERIC_UPDATE = 'GENERIC_UPDATE',
4
+ GENERIC_DELETE = 'GENERIC_DELETE',
5
+
6
+ FORM_SUBMITTED = 'FORM_SUBMITTED',
7
+ }
@@ -0,0 +1,3 @@
1
+ export enum ObservableType {
2
+ FORM = 'FORM',
3
+ }
@@ -0,0 +1,4 @@
1
+ export type BaseResponse<T = null> = {
2
+ success: boolean;
3
+ data: T;
4
+ };
@@ -0,0 +1,4 @@
1
+ export type FormExternalIntegrationSimpleResource = {
2
+ id: number;
3
+ name: string;
4
+ };
@@ -0,0 +1,16 @@
1
+ import { ObservableActionType } from '../enums/ObservableAction';
2
+ import { ObservableType } from '../enums/ObservableType';
3
+
4
+ export type ObservableWebhookSimpleResource = {
5
+ id: number;
6
+ name: string;
7
+ observableType: ObservableType;
8
+ observableId: number;
9
+ action: ObservableActionType;
10
+ webhookUrl: string;
11
+ };
12
+
13
+ export type ObservableWebhookDetailedResource =
14
+ ObservableWebhookSimpleResource & {
15
+ secret: string;
16
+ };
@@ -0,0 +1,17 @@
1
+ import { URL } from 'node:url';
2
+ import { INode, NodeOperationError } from 'n8n-workflow';
3
+
4
+ export function getWorkflowUrl(
5
+ node: INode,
6
+ workflowId: string | undefined
7
+ ): string | undefined {
8
+ const baseUrl = process.env.WEBHOOK_URL;
9
+ if (baseUrl === undefined || workflowId === undefined) {
10
+ throw new NodeOperationError(
11
+ node,
12
+ 'WEBHOOK_URL is not set or workflowId is undefined'
13
+ );
14
+ }
15
+
16
+ return new URL(`${baseUrl}/workflow/${workflowId}`).href;
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@limetech/n8n-nodes-lime",
3
- "version": "2.5.5-dev.1",
3
+ "version": "2.6.0",
4
4
  "description": "n8n node to connect to Lime CRM",
5
5
  "license": "Apache-2.0",
6
6
  "main": "nodes/index.ts",
@@ -22,19 +22,24 @@
22
22
  "n8n-node",
23
23
  "lime-crm",
24
24
  "crm",
25
+ "lime-forms",
26
+ "lime-technologies",
27
+ "lundalogik",
25
28
  "n8n-community-node-package"
26
29
  ],
27
30
  "n8n": {
28
31
  "n8nNodesApiVersion": 1,
29
32
  "credentials": [
30
33
  "dist/credentials/LimeCrmApi.credentials.js",
31
- "dist/credentials/FortnoxApi.credentials.js"
34
+ "dist/credentials/FortnoxApi.credentials.js",
35
+ "dist/credentials/LimeFormsApi.credentials.js"
32
36
  ],
33
37
  "nodes": [
34
38
  "dist/nodes/lime-crm/LimeCrmNode.node.js",
35
39
  "dist/nodes/lime-crm/LimeCrmTrigger.node.js",
36
40
  "dist/nodes/fortnox/Fortnox.node.js",
37
- "dist/nodes/fortnox/FortnoxTrigger.node.js"
41
+ "dist/nodes/fortnox/FortnoxTrigger.node.js",
42
+ "dist/nodes/lime-forms/LimeFormsTrigger.node.js"
38
43
  ]
39
44
  },
40
45
  "devDependencies": {
package/.prettierignore DELETED
@@ -1,6 +0,0 @@
1
- dist/
2
- node_modules/
3
- restore_script/
4
- package-lock.json
5
- CHANGELOG.md
6
- README
@@ -1 +0,0 @@
1
- {"version":3,"file":"hmac.js","sourceRoot":"","sources":["../../../../nodes/lime-crm/utils/hmac.ts"],"names":[],"mappings":";;AA4BA,gCAMC;AAlCD,6CAAyC;AAYzC,SAAS,YAAY,CAAC,GAAW,EAAE,IAAY;IAC3C,OAAO,SAAS,GAAG,IAAA,wBAAU,EAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5E,CAAC;AAcD,SAAgB,UAAU,CACtB,GAAW,EACX,IAAY,EACZ,YAAoB;IAEpB,OAAO,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,YAAY,CAAC;AACpD,CAAC"}
File without changes