@limrun/api 0.59.0 → 0.61.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.
- package/CHANGELOG.md +90 -0
- package/destination-tunnel-dialer.d.mts +15 -0
- package/destination-tunnel-dialer.d.mts.map +1 -1
- package/destination-tunnel-dialer.d.ts +15 -0
- package/destination-tunnel-dialer.d.ts.map +1 -1
- package/destination-tunnel-dialer.js +21 -9
- package/destination-tunnel-dialer.js.map +1 -1
- package/destination-tunnel-dialer.mjs +18 -8
- package/destination-tunnel-dialer.mjs.map +1 -1
- package/destination-tunnel.d.mts +4 -0
- package/destination-tunnel.d.mts.map +1 -1
- package/destination-tunnel.d.ts +4 -0
- package/destination-tunnel.d.ts.map +1 -1
- package/destination-tunnel.js +2 -0
- package/destination-tunnel.js.map +1 -1
- package/destination-tunnel.mjs +2 -0
- package/destination-tunnel.mjs.map +1 -1
- package/index.d.mts +1 -0
- package/index.d.mts.map +1 -1
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +4 -2
- package/index.js.map +1 -1
- package/index.mjs +1 -0
- package/index.mjs.map +1 -1
- package/internal/destination-tunnel-management.d.mts +2 -0
- package/internal/destination-tunnel-management.d.mts.map +1 -1
- package/internal/destination-tunnel-management.d.ts +2 -0
- package/internal/destination-tunnel-management.d.ts.map +1 -1
- package/internal/destination-tunnel-management.js +5 -0
- package/internal/destination-tunnel-management.js.map +1 -1
- package/internal/destination-tunnel-management.mjs +6 -1
- package/internal/destination-tunnel-management.mjs.map +1 -1
- package/internal/destination-tunnel-url.d.mts +2 -0
- package/internal/destination-tunnel-url.d.mts.map +1 -1
- package/internal/destination-tunnel-url.d.ts +2 -0
- package/internal/destination-tunnel-url.d.ts.map +1 -1
- package/internal/destination-tunnel-url.js +9 -2
- package/internal/destination-tunnel-url.js.map +1 -1
- package/internal/destination-tunnel-url.mjs +8 -2
- package/internal/destination-tunnel-url.mjs.map +1 -1
- package/internal/destination-tunnel-wire-reader.d.mts +2 -0
- package/internal/destination-tunnel-wire-reader.d.mts.map +1 -1
- package/internal/destination-tunnel-wire-reader.d.ts +2 -0
- package/internal/destination-tunnel-wire-reader.d.ts.map +1 -1
- package/internal/destination-tunnel-wire-reader.js +17 -0
- package/internal/destination-tunnel-wire-reader.js.map +1 -1
- package/internal/destination-tunnel-wire-reader.mjs +15 -0
- package/internal/destination-tunnel-wire-reader.mjs.map +1 -1
- package/ios-client.d.mts +6 -4
- package/ios-client.d.mts.map +1 -1
- package/ios-client.d.ts +6 -4
- package/ios-client.d.ts.map +1 -1
- package/ios-client.js +3 -1
- package/ios-client.js.map +1 -1
- package/ios-client.mjs +3 -1
- package/ios-client.mjs.map +1 -1
- package/ios-launch-environment.d.mts +3 -0
- package/ios-launch-environment.d.mts.map +1 -0
- package/ios-launch-environment.d.ts +3 -0
- package/ios-launch-environment.d.ts.map +1 -0
- package/ios-launch-environment.js +14 -0
- package/ios-launch-environment.js.map +1 -0
- package/ios-launch-environment.mjs +11 -0
- package/ios-launch-environment.mjs.map +1 -0
- package/package.json +22 -2
- package/resources/android-instances.d.mts +12 -0
- package/resources/android-instances.d.mts.map +1 -1
- package/resources/android-instances.d.ts +12 -0
- package/resources/android-instances.d.ts.map +1 -1
- package/resources/ios-instances.d.mts +12 -0
- package/resources/ios-instances.d.mts.map +1 -1
- package/resources/ios-instances.d.ts +12 -0
- package/resources/ios-instances.d.ts.map +1 -1
- package/src/destination-tunnel-dialer.ts +24 -8
- package/src/destination-tunnel.ts +6 -0
- package/src/index.ts +6 -0
- package/src/internal/destination-tunnel-management.ts +15 -1
- package/src/internal/destination-tunnel-url.ts +15 -2
- package/src/internal/destination-tunnel-wire-reader.ts +17 -0
- package/src/ios-client.ts +12 -5
- package/src/ios-launch-environment.ts +11 -0
- package/src/resources/android-instances.ts +14 -0
- package/src/resources/ios-instances.ts +14 -0
- package/src/tunnel-connector.ts +767 -0
- package/src/tunnel.ts +8 -6
- package/src/version.ts +1 -1
- package/tunnel-connector.d.mts +88 -0
- package/tunnel-connector.d.mts.map +1 -0
- package/tunnel-connector.d.ts +88 -0
- package/tunnel-connector.d.ts.map +1 -0
- package/tunnel-connector.js +628 -0
- package/tunnel-connector.js.map +1 -0
- package/tunnel-connector.mjs +624 -0
- package/tunnel-connector.mjs.map +1 -0
- package/tunnel.d.mts +2 -0
- package/tunnel.d.mts.map +1 -1
- package/tunnel.d.ts +2 -0
- package/tunnel.d.ts.map +1 -1
- package/tunnel.js +8 -6
- package/tunnel.js.map +1 -1
- package/tunnel.mjs +7 -6
- package/tunnel.mjs.map +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
package/src/tunnel.ts
CHANGED
|
@@ -1281,13 +1281,15 @@ async function startMultiplexedTcpTunnel(
|
|
|
1281
1281
|
});
|
|
1282
1282
|
}
|
|
1283
1283
|
|
|
1284
|
-
|
|
1284
|
+
/** HTTP status of a refused WebSocket upgrade, as ws reports it in the error message. */
|
|
1285
|
+
export function upgradeStatus(errMessage: string): number | undefined {
|
|
1285
1286
|
const match = errMessage.match(/Unexpected server response: (\d+)/);
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1287
|
+
return match?.[1] ? parseInt(match[1], 10) : undefined;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
export const isNonRetryableError = (errMessage: string): boolean => {
|
|
1291
|
+
const status = upgradeStatus(errMessage);
|
|
1292
|
+
return status !== undefined && status >= 400 && status < 500;
|
|
1291
1293
|
};
|
|
1292
1294
|
|
|
1293
1295
|
export function assertPort(port: number, name: string, min: number, max: number): void {
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.61.0'; // x-release-please-version
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type DestinationTunnelInspectionConfig } from "./destination-tunnel.mjs";
|
|
2
|
+
import { type LogLevel } from "./tunnel.mjs";
|
|
3
|
+
export interface TunnelConnectorOptions {
|
|
4
|
+
/** The tunnel's own key, or an admin's credential. */
|
|
5
|
+
apiKey: string;
|
|
6
|
+
/** Limrun API base URL, such as https://api.limrun.com. */
|
|
7
|
+
baseURL: string;
|
|
8
|
+
organizationId: string;
|
|
9
|
+
/**
|
|
10
|
+
* The ID of a tunnel created in the console or the API. Its name, which
|
|
11
|
+
* instances set in `spec.tunnel`, and its selectors come from the platform.
|
|
12
|
+
*/
|
|
13
|
+
tunnelId: string;
|
|
14
|
+
/** Inspection for every instance tunnel. Defaults to enabled without bodies. */
|
|
15
|
+
inspection?: Partial<DestinationTunnelInspectionConfig>;
|
|
16
|
+
/** Take the name over from the connector that holds it now. */
|
|
17
|
+
replace?: boolean;
|
|
18
|
+
/** Identifies this connector to the platform. Defaults to the OS hostname. */
|
|
19
|
+
hostname?: string;
|
|
20
|
+
/** Reported to the platform. Defaults to the SDK version. */
|
|
21
|
+
clientVersion?: string;
|
|
22
|
+
/** Log level of the per-instance tunnels. Defaults to 'warn'. */
|
|
23
|
+
logLevel?: LogLevel;
|
|
24
|
+
onEvent?: (event: TunnelConnectorEvent) => void;
|
|
25
|
+
}
|
|
26
|
+
export type TunnelConnectorEvent =
|
|
27
|
+
/** This connector holds the tunnel; emitted once per session and control connection. */
|
|
28
|
+
{
|
|
29
|
+
type: 'active';
|
|
30
|
+
sessionId: string;
|
|
31
|
+
name: string;
|
|
32
|
+
}
|
|
33
|
+
/** The connector's key expires within two weeks; emitted once a day until it does. */
|
|
34
|
+
| {
|
|
35
|
+
type: 'keyExpiring';
|
|
36
|
+
expiresAt: string;
|
|
37
|
+
}
|
|
38
|
+
/** Another connector holds the name; emitted once per holder. */
|
|
39
|
+
| {
|
|
40
|
+
type: 'standby';
|
|
41
|
+
holder: {
|
|
42
|
+
hostname: string;
|
|
43
|
+
since?: string;
|
|
44
|
+
};
|
|
45
|
+
} | {
|
|
46
|
+
type: 'attached';
|
|
47
|
+
instanceId: string;
|
|
48
|
+
tunnelId: string;
|
|
49
|
+
}
|
|
50
|
+
/** The connector gave up on the instance. */
|
|
51
|
+
| {
|
|
52
|
+
type: 'attachFailed';
|
|
53
|
+
instanceId: string;
|
|
54
|
+
code: string;
|
|
55
|
+
message: string;
|
|
56
|
+
} | {
|
|
57
|
+
type: 'detached';
|
|
58
|
+
instanceId: string;
|
|
59
|
+
reason: string;
|
|
60
|
+
} | {
|
|
61
|
+
type: 'notice';
|
|
62
|
+
code: string;
|
|
63
|
+
message: string;
|
|
64
|
+
instanceId?: string;
|
|
65
|
+
}
|
|
66
|
+
/** The control channel, or the tunnel of `instanceId`, retries after `delayMs`. */
|
|
67
|
+
| {
|
|
68
|
+
type: 'reconnecting';
|
|
69
|
+
instanceId?: string;
|
|
70
|
+
delayMs: number;
|
|
71
|
+
reason: string;
|
|
72
|
+
};
|
|
73
|
+
export interface TunnelConnector {
|
|
74
|
+
/** Resolves after close() and rejects with the terminal error that ended the connector. */
|
|
75
|
+
closed: Promise<void>;
|
|
76
|
+
/** Releases the name at once, closes every instance tunnel, and resolves when done. */
|
|
77
|
+
close: () => Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Serve a persistent tunnel: hold it through one control WebSocket to the
|
|
81
|
+
* Limrun API and open a destination tunnel to every instance created with
|
|
82
|
+
* `spec.tunnel` set to its name, with a short-lived token the API hands out
|
|
83
|
+
* for each. Instance tunnels stay up while the control channel reconnects,
|
|
84
|
+
* so an API outage never becomes a tunnel outage; one that drops re-dials
|
|
85
|
+
* once the API sends a fresh token.
|
|
86
|
+
*/
|
|
87
|
+
export declare function runTunnel(options: TunnelConnectorOptions): TunnelConnector;
|
|
88
|
+
//# sourceMappingURL=tunnel-connector.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-connector.d.mts","sourceRoot":"","sources":["src/tunnel-connector.ts"],"names":[],"mappings":"AA0BA,OAAO,EAGL,KAAK,iCAAiC,EAEvC,iCAA6B;AAC9B,OAAO,EAAiB,KAAK,QAAQ,EAAE,qBAAiB;AAyBxD,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,UAAU,CAAC,EAAE,OAAO,CAAC,iCAAiC,CAAC,CAAC;IACxD,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACjD;AAED,MAAM,MAAM,oBAAoB;AAC9B,wFAAwF;AACtF;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACrD,sFAAsF;GACpF;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;AAC5C,iEAAiE;GAC/D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AAC5D,6CAA6C;GAC3C;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE;AACxE,mFAAmF;GACjF;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC9B,2FAA2F;IAC3F,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,uFAAuF;IACvF,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAoDD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CA+gB1E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type DestinationTunnelInspectionConfig } from "./destination-tunnel.js";
|
|
2
|
+
import { type LogLevel } from "./tunnel.js";
|
|
3
|
+
export interface TunnelConnectorOptions {
|
|
4
|
+
/** The tunnel's own key, or an admin's credential. */
|
|
5
|
+
apiKey: string;
|
|
6
|
+
/** Limrun API base URL, such as https://api.limrun.com. */
|
|
7
|
+
baseURL: string;
|
|
8
|
+
organizationId: string;
|
|
9
|
+
/**
|
|
10
|
+
* The ID of a tunnel created in the console or the API. Its name, which
|
|
11
|
+
* instances set in `spec.tunnel`, and its selectors come from the platform.
|
|
12
|
+
*/
|
|
13
|
+
tunnelId: string;
|
|
14
|
+
/** Inspection for every instance tunnel. Defaults to enabled without bodies. */
|
|
15
|
+
inspection?: Partial<DestinationTunnelInspectionConfig>;
|
|
16
|
+
/** Take the name over from the connector that holds it now. */
|
|
17
|
+
replace?: boolean;
|
|
18
|
+
/** Identifies this connector to the platform. Defaults to the OS hostname. */
|
|
19
|
+
hostname?: string;
|
|
20
|
+
/** Reported to the platform. Defaults to the SDK version. */
|
|
21
|
+
clientVersion?: string;
|
|
22
|
+
/** Log level of the per-instance tunnels. Defaults to 'warn'. */
|
|
23
|
+
logLevel?: LogLevel;
|
|
24
|
+
onEvent?: (event: TunnelConnectorEvent) => void;
|
|
25
|
+
}
|
|
26
|
+
export type TunnelConnectorEvent =
|
|
27
|
+
/** This connector holds the tunnel; emitted once per session and control connection. */
|
|
28
|
+
{
|
|
29
|
+
type: 'active';
|
|
30
|
+
sessionId: string;
|
|
31
|
+
name: string;
|
|
32
|
+
}
|
|
33
|
+
/** The connector's key expires within two weeks; emitted once a day until it does. */
|
|
34
|
+
| {
|
|
35
|
+
type: 'keyExpiring';
|
|
36
|
+
expiresAt: string;
|
|
37
|
+
}
|
|
38
|
+
/** Another connector holds the name; emitted once per holder. */
|
|
39
|
+
| {
|
|
40
|
+
type: 'standby';
|
|
41
|
+
holder: {
|
|
42
|
+
hostname: string;
|
|
43
|
+
since?: string;
|
|
44
|
+
};
|
|
45
|
+
} | {
|
|
46
|
+
type: 'attached';
|
|
47
|
+
instanceId: string;
|
|
48
|
+
tunnelId: string;
|
|
49
|
+
}
|
|
50
|
+
/** The connector gave up on the instance. */
|
|
51
|
+
| {
|
|
52
|
+
type: 'attachFailed';
|
|
53
|
+
instanceId: string;
|
|
54
|
+
code: string;
|
|
55
|
+
message: string;
|
|
56
|
+
} | {
|
|
57
|
+
type: 'detached';
|
|
58
|
+
instanceId: string;
|
|
59
|
+
reason: string;
|
|
60
|
+
} | {
|
|
61
|
+
type: 'notice';
|
|
62
|
+
code: string;
|
|
63
|
+
message: string;
|
|
64
|
+
instanceId?: string;
|
|
65
|
+
}
|
|
66
|
+
/** The control channel, or the tunnel of `instanceId`, retries after `delayMs`. */
|
|
67
|
+
| {
|
|
68
|
+
type: 'reconnecting';
|
|
69
|
+
instanceId?: string;
|
|
70
|
+
delayMs: number;
|
|
71
|
+
reason: string;
|
|
72
|
+
};
|
|
73
|
+
export interface TunnelConnector {
|
|
74
|
+
/** Resolves after close() and rejects with the terminal error that ended the connector. */
|
|
75
|
+
closed: Promise<void>;
|
|
76
|
+
/** Releases the name at once, closes every instance tunnel, and resolves when done. */
|
|
77
|
+
close: () => Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Serve a persistent tunnel: hold it through one control WebSocket to the
|
|
81
|
+
* Limrun API and open a destination tunnel to every instance created with
|
|
82
|
+
* `spec.tunnel` set to its name, with a short-lived token the API hands out
|
|
83
|
+
* for each. Instance tunnels stay up while the control channel reconnects,
|
|
84
|
+
* so an API outage never becomes a tunnel outage; one that drops re-dials
|
|
85
|
+
* once the API sends a fresh token.
|
|
86
|
+
*/
|
|
87
|
+
export declare function runTunnel(options: TunnelConnectorOptions): TunnelConnector;
|
|
88
|
+
//# sourceMappingURL=tunnel-connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-connector.d.ts","sourceRoot":"","sources":["src/tunnel-connector.ts"],"names":[],"mappings":"AA0BA,OAAO,EAGL,KAAK,iCAAiC,EAEvC,gCAA6B;AAC9B,OAAO,EAAiB,KAAK,QAAQ,EAAE,oBAAiB;AAyBxD,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,UAAU,CAAC,EAAE,OAAO,CAAC,iCAAiC,CAAC,CAAC;IACxD,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACjD;AAED,MAAM,MAAM,oBAAoB;AAC9B,wFAAwF;AACtF;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACrD,sFAAsF;GACpF;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;AAC5C,iEAAiE;GAC/D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AAC5D,6CAA6C;GAC3C;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE;AACxE,mFAAmF;GACjF;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC9B,2FAA2F;IAC3F,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,uFAAuF;IACvF,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAoDD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CA+gB1E"}
|