@uxland/primary-shell 8.0.0-rc.0 → 8.0.0-rc.2

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 (84) hide show
  1. package/dist/component-BQj4158z.js +68 -0
  2. package/dist/component-BQj4158z.js.map +1 -0
  3. package/dist/{index-8n9_rIYI.js → index-BwN0QusL.js} +19320 -19795
  4. package/dist/index-BwN0QusL.js.map +1 -0
  5. package/dist/index.js +28 -17
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.umd.cjs +2667 -2694
  8. package/dist/index.umd.cjs.map +1 -1
  9. package/dist/{plugin-B5E6LZ4X.js → plugin-BE23BSP6.js} +5817 -5685
  10. package/dist/plugin-BE23BSP6.js.map +1 -0
  11. package/dist/primary/shell/src/UI/components/clinical-pathways-action-menu/clinical-pathways-action-menu.d.ts +4 -12
  12. package/dist/primary/shell/src/UI/components/communication-action-menu/communication-action-menu.d.ts +4 -12
  13. package/dist/primary/shell/src/UI/components/petitioner-action-menu/petitioner-action-menu.d.ts +4 -12
  14. package/dist/primary/shell/src/UI/components/sidenav-action-menu/sidenav-action-menu.d.ts +27 -0
  15. package/dist/primary/shell/src/UI/components/sidenav-action-menu/template.d.ts +2 -0
  16. package/dist/primary/shell/src/UI/shared-components/primaria-text-editor/primaria-rich-text-editor.d.ts +7 -1
  17. package/dist/primary/shell/src/api/broker/broker-events.d.ts +15 -0
  18. package/dist/primary/shell/src/api/broker/broker-requests.d.ts +20 -0
  19. package/dist/primary/shell/src/api/broker/primaria-broker.d.ts +4 -0
  20. package/dist/primary/shell/src/api/ecap-event-manager/ecap-event-manager.d.ts +2 -2
  21. package/dist/primary/shell/src/api/import-data-manager/component/component.d.ts +1 -0
  22. package/dist/primary/shell/src/api/region-manager/region-manager.d.ts +10 -3
  23. package/dist/primary/shell/src/api/region-manager/remove-view-idempotency.test.d.ts +1 -0
  24. package/dist/primary/shell/src/disposer.d.ts +1 -1
  25. package/dist/primary/shell/src/features/bootstrapper.d.ts +1 -1
  26. package/dist/primary/shell/src/features/exit/handler.d.ts +12 -0
  27. package/dist/primary/shell/src/features/get-user-info/backend-adapter.d.ts +4 -2
  28. package/dist/primary/shell/src/features/get-user-info/pds-token.d.ts +26 -0
  29. package/dist/primary/shell/src/features/get-visi-id/action.d.ts +2 -0
  30. package/dist/primary/shell/src/index.d.ts +5 -0
  31. package/dist/primary/shell/src/locales.d.ts +1 -0
  32. package/package.json +5 -8
  33. package/src/UI/components/clinical-pathways-action-menu/clinical-pathways-action-menu.ts +6 -41
  34. package/src/UI/components/communication-action-menu/communication-action-menu.ts +6 -41
  35. package/src/UI/components/petitioner-action-menu/petitioner-action-menu.ts +6 -41
  36. package/src/UI/components/primaria-shell/primaria-shell.ts +3 -1
  37. package/src/UI/components/sidenav-action-menu/sidenav-action-menu.ts +62 -0
  38. package/src/UI/components/{petitioner-action-menu → sidenav-action-menu}/template.ts +3 -3
  39. package/src/UI/internal-views/doctor-nav-menu.ts +9 -2
  40. package/src/UI/shared-components/bootstrapper.ts +3 -1
  41. package/src/UI/shared-components/primaria-nav-item/primaria-nav-item.ts +3 -1
  42. package/src/UI/shared-components/primaria-text-editor/primaria-rich-text-editor.ts +34 -21
  43. package/src/api/activity-monitor/activity-monitor.test.ts +1 -1
  44. package/src/api/broker/broker-events.ts +9 -0
  45. package/src/api/broker/broker-requests.ts +20 -0
  46. package/src/api/broker/factory.ts +2 -0
  47. package/src/api/broker/primaria-broker.ts +4 -0
  48. package/src/api/ecap-event-manager/ecap-event-manager.test.ts +12 -4
  49. package/src/api/ecap-event-manager/ecap-event-manager.ts +5 -1
  50. package/src/api/http-client/http-client.test.ts +12 -31
  51. package/src/api/import-data-manager/component/component.ts +3 -0
  52. package/src/api/import-data-manager/component/styles.css +25 -32
  53. package/src/api/import-data-manager/component/template.ts +16 -0
  54. package/src/api/import-data-manager/import-data-manager-impl.test.ts +2 -0
  55. package/src/api/interaction-service/interaction-service-impl.tsx +19 -8
  56. package/src/api/localization/localization.ts +44 -40
  57. package/src/api/notification-service/notification-service-impl.test.ts +2 -1
  58. package/src/api/region-manager/region-manager.test.ts +112 -3
  59. package/src/api/region-manager/region-manager.ts +85 -10
  60. package/src/api/region-manager/remove-view-idempotency.test.ts +98 -0
  61. package/src/api/token-manager/token-manager.test.ts +3 -6
  62. package/src/disposer.ts +2 -2
  63. package/src/features/bootstrapper.ts +2 -2
  64. package/src/features/exit/handler.test.ts +60 -0
  65. package/src/features/exit/handler.ts +19 -3
  66. package/src/features/get-user-info/backend-adapter.ts +30 -18
  67. package/src/features/get-user-info/handler.test.ts +8 -2
  68. package/src/features/get-user-info/pds-token.ts +28 -0
  69. package/src/features/get-visi-id/action.ts +11 -0
  70. package/src/index.ts +40 -1
  71. package/src/locales.ts +1 -0
  72. package/src/types/custom.d.ts +30 -0
  73. package/dist/component-Bt_gBs5e.js +0 -52
  74. package/dist/component-Bt_gBs5e.js.map +0 -1
  75. package/dist/index-8n9_rIYI.js.map +0 -1
  76. package/dist/plugin-B5E6LZ4X.js.map +0 -1
  77. package/dist/primary/shell/src/UI/components/clinical-pathways-action-menu/template.d.ts +0 -2
  78. package/dist/primary/shell/src/UI/components/communication-action-menu/template.d.ts +0 -2
  79. package/dist/primary/shell/src/UI/components/petitioner-action-menu/template.d.ts +0 -2
  80. package/src/UI/components/clinical-pathways-action-menu/template.ts +0 -24
  81. package/src/UI/components/communication-action-menu/styles.css +0 -29
  82. package/src/UI/components/communication-action-menu/template.ts +0 -24
  83. package/src/UI/components/petitioner-action-menu/styles.css +0 -29
  84. /package/src/UI/components/{clinical-pathways-action-menu → sidenav-action-menu}/styles.css +0 -0
@@ -1,8 +1,12 @@
1
1
  import { inject, injectable } from "inversify";
2
- import { IUserInfo } from "./model";
3
2
  import { jwtDecode } from "jwt-decode";
4
- import { TYPES } from "../../infrastructure/ioc/types";
5
3
  import { shellApi } from "../../api/api";
4
+ import { TYPES } from "../../infrastructure/ioc/types";
5
+ import { IUserInfo } from "./model";
6
+ import { PdsAccessInfo, PdsToken } from "./pds-token";
7
+
8
+ /** Ordre de preferència dels identificadors del professional dins del token. */
9
+ const USER_ID_TYPES = ["DNI", "NIE", "PASS"];
6
10
 
7
11
  export abstract class UserInfoBackendAdapter {
8
12
  abstract getUserInfo(): Promise<IUserInfo>;
@@ -11,26 +15,34 @@ export abstract class UserInfoBackendAdapter {
11
15
  export class GetUserInfoBackendAdapter implements UserInfoBackendAdapter {
12
16
  constructor(@inject(TYPES.primaryApi) private api: typeof shellApi) {}
13
17
  getUserInfo(): Promise<IUserInfo> {
14
- const decodedToken = jwtDecode(this.api.tokenManager.getToken());
18
+ const decodedToken = jwtDecode<PdsToken>(this.api.tokenManager.getToken());
19
+ const accessInfo = decodedToken.access_info;
20
+
21
+ // `IUserInfo` declara `string` a tots els camps, però el token no en garanteix cap. Abans
22
+ // el token era `any` i els absents arribaven com a `undefined` amb tipus `string`; ara es
23
+ // normalitzen a cadena buida perquè el tipus digui la veritat.
15
24
  const userInfo: IUserInfo = {
16
- userId: this.getUserId(decodedToken.access_info),
17
- firstName: decodedToken.access_info.trace_user_given_name,
18
- familyName: decodedToken.access_info.trace_user_family_name,
19
- lastName: decodedToken.access_info.trace_user_last_name,
20
- registrationNumber: decodedToken.access_info.identifier.find((id: { type: string; value: string }) => id.type === "NUMCOL")
21
- ?.value,
22
- workCenter: decodedToken.access_info.center_code,
23
- role: decodedToken.access_info.role_type,
24
- speciality: decodedToken.access_info.professional_category,
25
+ userId: this.getUserId(accessInfo) ?? "",
26
+ firstName: accessInfo?.trace_user_given_name ?? "",
27
+ familyName: accessInfo?.trace_user_family_name ?? "",
28
+ lastName: accessInfo?.trace_user_last_name ?? "",
29
+ registrationNumber: this.findIdentifier(accessInfo, "NUMCOL") ?? "",
30
+ workCenter: accessInfo?.center_code ?? "",
31
+ role: accessInfo?.role_type ?? "",
32
+ speciality: accessInfo?.professional_category ?? "",
25
33
  };
26
34
  return Promise.resolve(userInfo);
27
35
  }
28
36
 
29
- getUserId(access_info) {
30
- return (
31
- access_info.identifier?.find((identifierItem: { type: string; value: string }) => identifierItem.type === "DNI")?.value ||
32
- access_info.identifier?.find((identifierItem: { type: string; value: string }) => identifierItem.type === "NIE")?.value ||
33
- access_info.identifier?.find((identifierItem: { type: string; value: string }) => identifierItem.type === "PASS")?.value
34
- );
37
+ private findIdentifier(accessInfo: PdsAccessInfo | undefined, type: string) {
38
+ return accessInfo?.identifier?.find((identifier) => identifier.type === type)?.value;
39
+ }
40
+
41
+ getUserId(accessInfo: PdsAccessInfo | undefined) {
42
+ for (const type of USER_ID_TYPES) {
43
+ const value = this.findIdentifier(accessInfo, type);
44
+ if (value) return value;
45
+ }
46
+ return undefined;
35
47
  }
36
48
  }
@@ -27,8 +27,14 @@ describe("GetUserInfoHandler", () => {
27
27
 
28
28
  const message = {} as GetUserInfo;
29
29
  const mockUserInfo: IUserInfo = {
30
- name: "John Doe",
31
- email: "john@example.com",
30
+ userId: "12345678Z",
31
+ firstName: "John",
32
+ familyName: "Doe",
33
+ lastName: "Smith",
34
+ registrationNumber: "081234",
35
+ workCenter: "CAP",
36
+ role: "assist",
37
+ speciality: "MF",
32
38
  };
33
39
 
34
40
  beforeEach(() => {
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Els camps del token del PDS que aquest adaptador llegeix.
3
+ *
4
+ * Es declara aquí, i no s'importa `PDSToken` de `@pds/core`, per dues raons: el shell no depèn
5
+ * d'aquell package, i el seu `AccessInfo` no inclou `trace_user_last_name`, que sí que es fa
6
+ * servir. Si algun dia s'unifiquen els dos contractes, aquest fitxer hauria de desaparèixer.
7
+ *
8
+ * Tot és opcional perquè el token no en garanteix cap: fins ara el tipus era `any` i
9
+ * `IUserInfo` prometia `string` a tot arreu, cosa que no era certa en runtime.
10
+ */
11
+ export interface PdsAccessInfo {
12
+ trace_user_given_name?: string;
13
+ trace_user_family_name?: string;
14
+ trace_user_last_name?: string;
15
+ center_code?: string;
16
+ role_type?: string;
17
+ professional_category?: string;
18
+ identifier?: PdsIdentifier[];
19
+ }
20
+
21
+ export interface PdsIdentifier {
22
+ type: string;
23
+ value: string;
24
+ }
25
+
26
+ export interface PdsToken {
27
+ access_info?: PdsAccessInfo;
28
+ }
@@ -0,0 +1,11 @@
1
+ import { PrimariaApi } from "../../api/api";
2
+
3
+ export const getVisiId = async (api: PrimariaApi): Promise<string | undefined> => {
4
+ const context = api.contextManager.getContext();
5
+ if (context.visi_id) return context.visi_id as string;
6
+ try {
7
+ return (await api.broker.send("get_visi_id")) as string;
8
+ } catch {
9
+ return undefined;
10
+ }
11
+ };
package/src/index.ts CHANGED
@@ -5,11 +5,15 @@ import fontsCSS from "./UI/fonts/fonts.css?inline";
5
5
  // Inject CSS automatically
6
6
  if (typeof document !== "undefined") {
7
7
  const style = document.createElement("style");
8
- style.textContent = fontsCSS + "\n" + dssCSS;
8
+ style.textContent = `${fontsCSS}\n${dssCSS}`;
9
9
  document.head.appendChild(style);
10
10
  }
11
11
  export * from "./bootstrapper";
12
12
  export * from "./disposer";
13
+ export * from "./api/region-manager/regions";
14
+ // Tipus de retorn de `regionManager.getRegisteredMainViews()`. El regionManager
15
+ // arriba als plugins tipat via `PrimariaApi`; això només és per poder-lo anomenar.
16
+ export type { RegisteredMainView } from "./api/region-manager/region-manager";
13
17
  export * from "./handle-plugins";
14
18
  // Superfície pública explícita: `primariaApiFactory`, `activityMonitor` i
15
19
  // `sessionRefreshTimer` són singletons interns del shell i no s'exposen.
@@ -24,6 +28,16 @@ export { PrimariaRegionHost, shellApi } from "./api/api";
24
28
  export type { TokenManager, InternalTokenManager } from "./api/token-manager/token-manager";
25
29
  export * from "./api/broker/primaria-broker";
26
30
  export type { PrimariaContextManager, EcapContext } from "./api/context-manager/context-manager";
31
+ // Contractes de l'importador de dades estructurades. Una iniciativa que crida
32
+ // `importDataManager.import(...)` necessita `ImportParams` per tipar-ho, i la que
33
+ // s'injecta dins del modal la rep de `getCurrentImportParams()`. La implementació
34
+ // (`ImportDataManagerImpl`) es queda dins: els plugins reben el mànager per la
35
+ // `PrimariaApi`, no l'instancien.
36
+ export type {
37
+ PrimariaImportDataManager,
38
+ ImportParams,
39
+ ImportParamsDiagnostic,
40
+ } from "./api/import-data-manager/import-data-manager";
27
41
  export * from "./UI/index";
28
42
  export { PrimariaNavItem } from "./UI/shared-components/primaria-nav-item/primaria-nav-item";
29
43
  export { QuickActionItem } from "./UI/shared-components/quick-action-item/quick-action-item";
@@ -51,3 +65,28 @@ export type {
51
65
  IActivityHistoryCustomFilterGroup,
52
66
  IActivityHistoryCustomFilter,
53
67
  } from "@primaria/plugins-core";
68
+ // Contractes de broker entre iniciatives. Es declaren a `@primaria/plugins-core`
69
+ // perquè el shell no hi és part, i es re-exporten aquí perquè és l'únic paquet
70
+ // que instal·len les iniciatives externes. Els noms també són a
71
+ // `api.broker.requests` i `api.broker.events`, agrupats per propietari.
72
+ export {
73
+ REQUEST_DIAGNOSTICS_SELECTOR,
74
+ CIPDS_SELECTION_REQUEST,
75
+ CIPDS_DIAGNOSTIC_FILTER_HISTORIC_REQUESTED,
76
+ LAST_WORKED_DIAGNOSTICS_KEY,
77
+ CLINICAL_COURSE_DRAFT_APPEND_REQUESTED,
78
+ HELP_REQUESTED,
79
+ } from "@primaria/plugins-core";
80
+ export type {
81
+ Diagnostic,
82
+ ConfigFilterDiagnosticParams,
83
+ DiagnosticsUpdater,
84
+ DiagnosticsSelectorPayload,
85
+ CipdsSelectionRequestPayload,
86
+ CipdsSelectionResponse,
87
+ DiagnosticRelation,
88
+ DiagnosticWithRelations,
89
+ DiagnosticFilterHistoricPayload,
90
+ ClinicalCourseDraftAppendRequestedPayload,
91
+ HelpRequestedPayload,
92
+ } from "@primaria/plugins-core";
package/src/locales.ts CHANGED
@@ -61,6 +61,7 @@ export const locales = {
61
61
  title: "Importar dades",
62
62
  actions: {
63
63
  cancel: "Cancel·lar",
64
+ close: "Tancar",
64
65
  import: "Importar dades",
65
66
  },
66
67
  },
@@ -0,0 +1,30 @@
1
+ import "react";
2
+
3
+ /**
4
+ * Els components web del Design System de Salut (`dss-*`) no porten tipus, així que s'obre
5
+ * `JSX.IntrinsicElements` per acceptar qualsevol element personalitzat.
6
+ *
7
+ * S'amplien els dos especificadors: amb `jsx: "react-jsx"`, la cerca del namespace JSX passa per
8
+ * `react/jsx-runtime`, que hereta de `React.JSX`.
9
+ *
10
+ * Aquest fitxer és idèntic a tots els plugins i no es pot compartir des de l'arrel: sota pnpm,
11
+ * l'arrel no té `react` a `node_modules`, així que l'especificador no resoldria i el
12
+ * `declare module` no ampliaria res.
13
+ */
14
+ declare module "react" {
15
+ namespace JSX {
16
+ interface IntrinsicElements {
17
+ // biome-ignore lint/suspicious/noExplicitAny: els components del DSS no estan tipats
18
+ [key: string]: any;
19
+ }
20
+ }
21
+ }
22
+
23
+ declare module "react/jsx-runtime" {
24
+ namespace JSX {
25
+ interface IntrinsicElements {
26
+ // biome-ignore lint/suspicious/noExplicitAny: els components del DSS no estan tipats
27
+ [key: string]: any;
28
+ }
29
+ }
30
+ }
@@ -1,52 +0,0 @@
1
- import { s, u as d, k as l, h as p, r as m, b as g, c as h } from "./index-8n9_rIYI.js";
2
- const v = ".container{background-color:#fff;display:flex;flex-direction:column;min-width:500px;width:95vw;height:95vh;border-radius:var(--dss-radius-sm);overflow:hidden}.content{display:grid;flex:1;min-height:0;grid-template-columns:1fr 1fr;gap:16px;padding:16px}.content>primaria-region{width:100%;height:100%;min-height:0}.content primaria-region>div{width:100%;height:100%;border:1px solid var(--color-neutral-200);border-radius:8px;padding:16px;box-sizing:border-box}.content>primaria-region[name=import-data-region]>div{overflow-y:auto}.content>primaria-region[name=import-data-activity-history-region]>div{display:flex;flex-direction:column;gap:16px;overflow:hidden}.content>primaria-region[name=import-data-activity-history-region]>div>*{flex-shrink:0}.content>primaria-region[name=import-data-activity-history-region]>div>*:last-child{flex:1;min-height:0}.footer{display:flex;flex-direction:row;align-items:center;background:#fff;justify-content:end;gap:12px;height:56px;border-top:1px solid var(--color-neutral-100);padding:var(--dss-spacing-sm)}", f = (i) => l`
3
- <div class="container">
4
- <div class="content">
5
- <primaria-region name="${s.regionManager.regions.shell.importDataActivityHistory}"></primaria-region>
6
- <primaria-region name="${s.regionManager.regions.shell.importData}"></primaria-region>
7
- </div>
8
- <div class="footer">
9
- <dss-button
10
- label="${d("importDataManager.actions.cancel")}"
11
- @click="${() => {
12
- i.cancel();
13
- }}"
14
- size="md"
15
- variant="secondary"
16
- ></dss-button>
17
- <dss-button
18
- label="${d("importDataManager.actions.import")}"
19
- @click="${() => {
20
- i._accept();
21
- }}"
22
- size="md"
23
- variant="primary"
24
- ></dss-button>
25
- </div>
26
- </div>
27
- `;
28
- var u = Object.getOwnPropertyDescriptor, x = (i, e, c, n) => {
29
- for (var r = n > 1 ? void 0 : n ? u(e, c) : e, a = i.length - 1, o; a >= 0; a--)
30
- (o = i[a]) && (r = o(r) || r);
31
- return r;
32
- };
33
- let t = class extends p {
34
- constructor() {
35
- super(...arguments), this._accept = () => {
36
- this.confirm();
37
- };
38
- }
39
- render() {
40
- return l`${f(this)}`;
41
- }
42
- };
43
- t.styles = g`
44
- ${m(v)}
45
- `;
46
- t = x([
47
- h("import-data-manager-modal")
48
- ], t);
49
- export {
50
- t as ImportDataManagerModal
51
- };
52
- //# sourceMappingURL=component-Bt_gBs5e.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component-Bt_gBs5e.js","sources":["../src/api/import-data-manager/component/template.ts","../src/api/import-data-manager/component/component.ts"],"sourcesContent":["import { html } from \"lit\";\nimport { translate } from \"../../../locales\";\nimport { shellApi } from \"../../api\";\nimport { ImportDataManagerModal } from \"./component\";\n\nexport const template = (props: ImportDataManagerModal) => {\n return html`\n <div class=\"container\">\n <div class=\"content\">\n <primaria-region name=\"${shellApi.regionManager.regions.shell.importDataActivityHistory}\"></primaria-region>\n <primaria-region name=\"${shellApi.regionManager.regions.shell.importData}\"></primaria-region>\n </div>\n <div class=\"footer\">\n <dss-button\n label=\"${translate(\"importDataManager.actions.cancel\")}\"\n @click=\"${() => {\n props.cancel();\n }}\"\n size=\"md\"\n variant=\"secondary\"\n ></dss-button>\n <dss-button\n label=\"${translate(\"importDataManager.actions.import\")}\"\n @click=\"${() => {\n props._accept();\n }}\"\n size=\"md\"\n variant=\"primary\"\n ></dss-button>\n </div>\n </div>\n `;\n};\n","import { LitElement, css, html, unsafeCSS } from \"lit\";\nimport { customElement } from \"lit/decorators.js\";\nimport { ConfirmationContentProps } from \"../../interaction-service\";\nimport styles from \"./styles.css?inline\";\nimport { template } from \"./template\";\n\n@customElement(\"import-data-manager-modal\")\nexport class ImportDataManagerModal extends LitElement implements ConfirmationContentProps<undefined, undefined> {\n data: undefined;\n setResult: (result: undefined) => void;\n setIsValid: (isValid: boolean) => void;\n confirm: () => void;\n cancel: () => void;\n\n render() {\n return html`${template(this)}`;\n }\n\n static styles = css`\n ${unsafeCSS(styles)}\n `;\n\n _accept = () => {\n this.confirm();\n };\n}\n"],"names":["template","props","html","shellApi","translate","ImportDataManagerModal","LitElement","css","unsafeCSS","styles","__decorateClass","customElement"],"mappings":";kiCAKaA,IAAW,CAACC,MAChBC;AAAAA;AAAAA;AAAAA,iCAGwBC,EAAS,cAAc,QAAQ,MAAM,yBAAyB;AAAA,iCAC9DA,EAAS,cAAc,QAAQ,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,mBAI7DC,EAAU,kCAAkC,CAAC;AAAA,oBAC5C,MAAM;AACd,EAAAH,EAAM,OAAA;AACR,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,mBAKQG,EAAU,kCAAkC,CAAC;AAAA,oBAC5C,MAAM;AACd,EAAAH,EAAM,QAAA;AACR,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AClBJ,IAAMI,IAAN,cAAqCC,EAAqE;AAAA,EAA1G,cAAA;AAAA,UAAA,GAAA,SAAA,GAeL,KAAA,UAAU,MAAM;AACd,WAAK,QAAA;AAAA,IACP;AAAA,EAAA;AAAA,EAVA,SAAS;AACP,WAAOJ,IAAOF,EAAS,IAAI,CAAC;AAAA,EAC9B;AASF;AAlBaK,EAWJ,SAASE;AAAAA,MACZC,EAAUC,CAAM,CAAC;AAAA;AAZVJ,IAANK,EAAA;AAAA,EADNC,EAAc,2BAA2B;AAAA,GAC7BN,CAAA;"}