@aglyn/tenant-feature-instance 1.0.0-beta.277 → 1.0.0-beta.283
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/package.json +9 -8
- package/src/lib/hooks/use-confirmed-doc.d.ts +73 -0
- package/src/lib/hooks/use-confirmed-doc.js +204 -0
- package/src/lib/hooks/use-confirmed-doc.js.map +1 -0
- package/src/lib/hooks/use-host-component-definitions.d.ts +40 -0
- package/src/lib/hooks/use-host-component-definitions.js +92 -0
- package/src/lib/hooks/use-host-component-definitions.js.map +1 -0
- package/src/lib/hooks/use-host-form-designs.d.ts +42 -0
- package/src/lib/hooks/use-host-form-designs.js +84 -0
- package/src/lib/hooks/use-host-form-designs.js.map +1 -0
- package/src/lib/hooks/use-org-plans.d.ts +47 -0
- package/src/lib/hooks/use-org-plans.js +164 -0
- package/src/lib/hooks/use-org-plans.js.map +1 -0
- package/src/lib/hooks/use-plugin-drawer-registration.d.ts +9 -0
- package/src/lib/hooks/use-plugin-drawer-registration.js +133 -0
- package/src/lib/hooks/use-plugin-drawer-registration.js.map +1 -0
- package/src/lib/hooks/use-site-marketplace-plugins.d.ts +35 -0
- package/src/lib/hooks/use-site-marketplace-plugins.js +99 -0
- package/src/lib/hooks/use-site-marketplace-plugins.js.map +1 -0
- package/src/lib/hooks/use-theme-library.d.ts +7 -0
- package/src/lib/hooks/use-theme-library.js +58 -0
- package/src/lib/hooks/use-theme-library.js.map +1 -0
- package/src/lib/hooks/use-user-name.js +8 -10
- package/src/lib/hooks/use-user-name.js.map +1 -1
- package/src/lib/hooks/use-user-photo.js +8 -2
- package/src/lib/hooks/use-user-photo.js.map +1 -1
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
|
-
*/ import {
|
|
16
|
+
*/ import { readAccountName } from "@aglyn/aglyn/app-utils/account-preferences";
|
|
17
|
+
import { doc } from "firebase/firestore";
|
|
17
18
|
import { useFirestore, useUser } from "./firebase/firebase-services.js";
|
|
18
19
|
import { useFirestoreDoc } from "./use-firestore-doc.js";
|
|
19
20
|
/**
|
|
@@ -58,15 +59,12 @@ import { useFirestoreDoc } from "./use-firestore-doc.js";
|
|
|
58
59
|
* case that matters is one no unit test can reach through the hook, because
|
|
59
60
|
* it needs a real SSO session in a GCIP tenant.
|
|
60
61
|
*/ export function resolveUserName(sources) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
sources.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const fromAuth = String((_sources_authDisplayName = sources.authDisplayName) != null ? _sources_authDisplayName : '').trim();
|
|
68
|
-
if (fromAuth) return fromAuth;
|
|
69
|
-
return String((_sources_email = sources.email) != null ? _sources_email : '').trim();
|
|
62
|
+
// The order lives in the shared rule, which the native apps replay through
|
|
63
|
+
// the generated contracts (AGL-4010).
|
|
64
|
+
return readAccountName({
|
|
65
|
+
firstName: sources.profileFirstName,
|
|
66
|
+
lastName: sources.profileLastName
|
|
67
|
+
}, sources.authDisplayName, sources.email);
|
|
70
68
|
}
|
|
71
69
|
export function useUserName() {
|
|
72
70
|
const firestore = useFirestore();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/tenant/feature/instance/src/lib/hooks/use-user-name.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { doc } from 'firebase/firestore'\nimport { useFirestore, useUser } from './firebase/firebase-services'\nimport { useFirestoreDoc } from './use-firestore-doc'\n\n/**\n * The signed-in user's NAME, resolved the way their photo already is\n * (AGL-2486).\n *\n * ## The defect this closes\n *\n * `user.displayName` is empty for every SSO account: a SAML identity arrives\n * with `displayName: undefined`, `photoURL: undefined` and a single provider\n * entry for the SAML provider, because GCIP leaves the assertion's mapped\n * attributes under `firebase.sign_in_attributes`. A surface that reads that\n * field alone falls through to the email, so it renders the address as the\n * person's NAME and again underneath as their address — and `memberInitials`,\n * given an address with no space in it, yields a single letter where the\n * presence stack beside it shows two.\n *\n * The name is not actually missing. `users/{uid}` holds `firstName` and\n * `lastName`, the org member doc holds a `displayName`, and presence reads the\n * ID token's IdP claims. Three surfaces, three answers to \"what is this person\n * called\", and the auth record is the only one that is blank for the\n * enterprise tier.\n *\n * ## Why here, and why this order\n *\n * `users/{uid}` is the profile the user themselves edits, so it outranks the\n * provider's copy — exactly the precedence `useUserProfilePhotoUrl` already\n * establishes for the picture, on the same document, through the same\n * listener. This is that hook's sibling and is deliberately shaped like it;\n * two hooks answering \"who is signed in\" should not disagree about where to\n * look.\n *\n * The auth record is the fallback rather than the lead because it is the one\n * an IdP may never populate. The email is last and is not really a name — it\n * is what the surface shows when nothing else exists, and callers that want\n * to show an address separately should keep doing so.\n */\n/**\n * The resolution itself, without React (AGL-2486).\n *\n * Pure and exported so the ORDER can be pinned in a spec. The order is the\n * entire content of this hook and the only part that can be wrong — and the\n * case that matters is one no unit test can reach through the hook, because\n * it needs a real SSO session in a GCIP tenant.\n */\nexport function resolveUserName(sources: {\n profileFirstName?: string | null\n profileLastName?: string | null\n authDisplayName?: string | null\n email?: string | null\n}): string {\n
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/tenant/feature/instance/src/lib/hooks/use-user-name.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { readAccountName } from '@aglyn/aglyn/app-utils/account-preferences'\nimport { doc } from 'firebase/firestore'\nimport { useFirestore, useUser } from './firebase/firebase-services'\nimport { useFirestoreDoc } from './use-firestore-doc'\n\n/**\n * The signed-in user's NAME, resolved the way their photo already is\n * (AGL-2486).\n *\n * ## The defect this closes\n *\n * `user.displayName` is empty for every SSO account: a SAML identity arrives\n * with `displayName: undefined`, `photoURL: undefined` and a single provider\n * entry for the SAML provider, because GCIP leaves the assertion's mapped\n * attributes under `firebase.sign_in_attributes`. A surface that reads that\n * field alone falls through to the email, so it renders the address as the\n * person's NAME and again underneath as their address — and `memberInitials`,\n * given an address with no space in it, yields a single letter where the\n * presence stack beside it shows two.\n *\n * The name is not actually missing. `users/{uid}` holds `firstName` and\n * `lastName`, the org member doc holds a `displayName`, and presence reads the\n * ID token's IdP claims. Three surfaces, three answers to \"what is this person\n * called\", and the auth record is the only one that is blank for the\n * enterprise tier.\n *\n * ## Why here, and why this order\n *\n * `users/{uid}` is the profile the user themselves edits, so it outranks the\n * provider's copy — exactly the precedence `useUserProfilePhotoUrl` already\n * establishes for the picture, on the same document, through the same\n * listener. This is that hook's sibling and is deliberately shaped like it;\n * two hooks answering \"who is signed in\" should not disagree about where to\n * look.\n *\n * The auth record is the fallback rather than the lead because it is the one\n * an IdP may never populate. The email is last and is not really a name — it\n * is what the surface shows when nothing else exists, and callers that want\n * to show an address separately should keep doing so.\n */\n/**\n * The resolution itself, without React (AGL-2486).\n *\n * Pure and exported so the ORDER can be pinned in a spec. The order is the\n * entire content of this hook and the only part that can be wrong — and the\n * case that matters is one no unit test can reach through the hook, because\n * it needs a real SSO session in a GCIP tenant.\n */\nexport function resolveUserName(sources: {\n profileFirstName?: string | null\n profileLastName?: string | null\n authDisplayName?: string | null\n email?: string | null\n}): string {\n // The order lives in the shared rule, which the native apps replay through\n // the generated contracts (AGL-4010).\n return readAccountName(\n { firstName: sources.profileFirstName, lastName: sources.profileLastName },\n sources.authDisplayName,\n sources.email,\n )\n}\n\nexport function useUserName(): string {\n const firestore = useFirestore()\n const { data: user } = useUser()\n const uid = user?.uid\n const { data } = useFirestoreDoc<{\n firstName?: string\n lastName?: string\n }>(\n // Null ref until a uid exists, so a signed-out mount opens no listen at\n // all rather than one the rules refuse — same shape as the photo hook.\n () => (uid ? doc(firestore, 'users', uid) : null),\n [firestore, uid],\n )\n return resolveUserName({\n profileFirstName: data?.firstName,\n profileLastName: data?.lastName,\n authDisplayName: user?.displayName,\n email: user?.email,\n })\n}\n\nexport default useUserName\n"],"names":["readAccountName","doc","useFirestore","useUser","useFirestoreDoc","resolveUserName","sources","firstName","profileFirstName","lastName","profileLastName","authDisplayName","email","useUserName","firestore","data","user","uid","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD,SAASA,eAAe,QAAQ,6CAA4C;AAC5E,SAASC,GAAG,QAAQ,qBAAoB;AACxC,SAASC,YAAY,EAAEC,OAAO,QAAQ,kCAA8B;AACpE,SAASC,eAAe,QAAQ,yBAAqB;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCC,GACD;;;;;;;CAOC,GACD,OAAO,SAASC,gBAAgBC,OAK/B;IACC,2EAA2E;IAC3E,sCAAsC;IACtC,OAAON,gBACL;QAAEO,WAAWD,QAAQE,gBAAgB;QAAEC,UAAUH,QAAQI,eAAe;IAAC,GACzEJ,QAAQK,eAAe,EACvBL,QAAQM,KAAK;AAEjB;AAEA,OAAO,SAASC;IACd,MAAMC,YAAYZ;IAClB,MAAM,EAAEa,MAAMC,IAAI,EAAE,GAAGb;IACvB,MAAMc,MAAMD,wBAAAA,KAAMC,GAAG;IACrB,MAAM,EAAEF,IAAI,EAAE,GAAGX,gBAIf,wEAAwE;IACxE,uEAAuE;IACvE,IAAOa,MAAMhB,IAAIa,WAAW,SAASG,OAAO,MAC5C;QAACH;QAAWG;KAAI;IAElB,OAAOZ,gBAAgB;QACrBG,gBAAgB,EAAEO,wBAAAA,KAAMR,SAAS;QACjCG,eAAe,EAAEK,wBAAAA,KAAMN,QAAQ;QAC/BE,eAAe,EAAEK,wBAAAA,KAAME,WAAW;QAClCN,KAAK,EAAEI,wBAAAA,KAAMJ,KAAK;IACpB;AACF;AAEA,eAAeC,YAAW"}
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
|
-
*/ import {
|
|
16
|
+
*/ import { readAccountPhoto } from "@aglyn/aglyn/app-utils/account-preferences";
|
|
17
|
+
import { doc } from "firebase/firestore";
|
|
17
18
|
import { useFirestore, useUser } from "./firebase/firebase-services.js";
|
|
18
19
|
import { useFirestoreDoc } from "./use-firestore-doc.js";
|
|
19
20
|
/** The avatar on the Firebase Auth record, and only that. */ export function useUserPhotoUrl() {
|
|
@@ -78,9 +79,14 @@ import { useFirestoreDoc } from "./use-firestore-doc.js";
|
|
|
78
79
|
* between the two used to leave the console showing no avatar for a photo it
|
|
79
80
|
* had successfully stored.
|
|
80
81
|
*/ export function useUserPhoto() {
|
|
82
|
+
var _readAccountPhoto;
|
|
81
83
|
const profilePhoto = useUserProfilePhotoUrl();
|
|
82
84
|
const authPhoto = useUserPhotoUrl();
|
|
83
|
-
|
|
85
|
+
// The order lives in the shared rule, which the native apps replay through
|
|
86
|
+
// the generated contracts (AGL-4010), so all three draw the same face.
|
|
87
|
+
return (_readAccountPhoto = readAccountPhoto({
|
|
88
|
+
photoUrl: profilePhoto
|
|
89
|
+
}, authPhoto)) != null ? _readAccountPhoto : undefined;
|
|
84
90
|
}
|
|
85
91
|
export default useUserPhoto;
|
|
86
92
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/tenant/feature/instance/src/lib/hooks/use-user-photo.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2022 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { doc } from 'firebase/firestore'\nimport { useFirestore, useUser } from './firebase/firebase-services'\nimport { useFirestoreDoc } from './use-firestore-doc'\n\n/** The avatar on the Firebase Auth record, and only that. */\nexport function useUserPhotoUrl() {\n const { data } = useUser()\n return data?.photoURL\n}\n\n/**\n * The avatar on the signed-in user's own profile document, `users/{uid}`\n * (AGL-1961).\n *\n * `photoUrl`, lowercase `url` — that document's spelling deliberately differs\n * from the roster's `photoURL`, and reading the roster's casing here would\n * silently yield nothing forever. See `seedUserProfile`, which writes this\n * field and says the same.\n */\nexport function useUserProfilePhotoUrl(): string | undefined {\n const firestore = useFirestore()\n const { data: user } = useUser()\n const uid = user?.uid\n const { data } = useFirestoreDoc<{ photoUrl?: string }>(\n // Null ref until a uid exists, so a signed-out mount opens no listen at\n // all rather than one the rules refuse.\n () => (uid ? doc(firestore, 'users', uid) : null),\n [firestore, uid],\n )\n const stored = String(data?.photoUrl ?? '').trim()\n return stored || undefined\n}\n\n/**\n * The signed-in user's own avatar URL, or nothing (AGL-1683, AGL-1961).\n *\n * This used to fall back to `gravatarUrlFromEmail(email)`, so every console\n * page that showed the account chip sent gravatar.com an MD5 of the signed-in\n * user's email address along with their IP and a `Referer` naming the console.\n * An email MD5 is not an anonymisation — a gravatar hash is *designed* to be\n * looked up by anyone who has seen the address — and Automattic is on no\n * subprocessor register of ours.\n *\n * Worse than the leak itself: `gravatar.url(undefined)` still returns a URL\n * (the MD5 of the string \"undefined\"), so this hook never returned a falsy\n * value and the request fired even for a user with no email resolved yet.\n * Callers that treat \"no photo\" as \"draw the initial\" were unreachable.\n *\n * Callers now render initials themselves when this is empty — see\n * `MemberAvatar` in the console, which is the shared answer for a member's\n * face. No options: there is nothing left to size.\n *\n * THE PROFILE DOCUMENT COMES FIRST, and used not to be read here at all\n * (AGL-1961). `users/{uid}.photoUrl` is what `seedUserProfile` fills from the\n * identity provider on EVERY sign-in, and what `user-profiles.ts` calls \"the\n * avatar the console shows for you\" — but the app bar resolved the auth\n * record's `photoURL` alone, and nothing mirrors the document onto the auth\n * record except an interactive save on Manage Account. So a customer whose\n * IdP maps a picture attribute had it stored on every sign-in and still saw a\n * drawn initial in the header, while Manage Account's own card three inches\n * below showed the photo — it already resolved `photoUrl ?? photoURL`. One\n * user, two answers.\n *\n * Blank-not-null is the join, so a photo that exists in either place wins over\n * an empty one in the other. That also heals the non-atomic save: Manage\n * Account writes the document and then calls `updateProfile`, and a failure\n * between the two used to leave the console showing no avatar for a photo it\n * had successfully stored.\n */\nexport function useUserPhoto(): string | undefined {\n const profilePhoto = useUserProfilePhotoUrl()\n const authPhoto = useUserPhotoUrl()\n
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/tenant/feature/instance/src/lib/hooks/use-user-photo.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2022 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { readAccountPhoto } from '@aglyn/aglyn/app-utils/account-preferences'\nimport { doc } from 'firebase/firestore'\nimport { useFirestore, useUser } from './firebase/firebase-services'\nimport { useFirestoreDoc } from './use-firestore-doc'\n\n/** The avatar on the Firebase Auth record, and only that. */\nexport function useUserPhotoUrl() {\n const { data } = useUser()\n return data?.photoURL\n}\n\n/**\n * The avatar on the signed-in user's own profile document, `users/{uid}`\n * (AGL-1961).\n *\n * `photoUrl`, lowercase `url` — that document's spelling deliberately differs\n * from the roster's `photoURL`, and reading the roster's casing here would\n * silently yield nothing forever. See `seedUserProfile`, which writes this\n * field and says the same.\n */\nexport function useUserProfilePhotoUrl(): string | undefined {\n const firestore = useFirestore()\n const { data: user } = useUser()\n const uid = user?.uid\n const { data } = useFirestoreDoc<{ photoUrl?: string }>(\n // Null ref until a uid exists, so a signed-out mount opens no listen at\n // all rather than one the rules refuse.\n () => (uid ? doc(firestore, 'users', uid) : null),\n [firestore, uid],\n )\n const stored = String(data?.photoUrl ?? '').trim()\n return stored || undefined\n}\n\n/**\n * The signed-in user's own avatar URL, or nothing (AGL-1683, AGL-1961).\n *\n * This used to fall back to `gravatarUrlFromEmail(email)`, so every console\n * page that showed the account chip sent gravatar.com an MD5 of the signed-in\n * user's email address along with their IP and a `Referer` naming the console.\n * An email MD5 is not an anonymisation — a gravatar hash is *designed* to be\n * looked up by anyone who has seen the address — and Automattic is on no\n * subprocessor register of ours.\n *\n * Worse than the leak itself: `gravatar.url(undefined)` still returns a URL\n * (the MD5 of the string \"undefined\"), so this hook never returned a falsy\n * value and the request fired even for a user with no email resolved yet.\n * Callers that treat \"no photo\" as \"draw the initial\" were unreachable.\n *\n * Callers now render initials themselves when this is empty — see\n * `MemberAvatar` in the console, which is the shared answer for a member's\n * face. No options: there is nothing left to size.\n *\n * THE PROFILE DOCUMENT COMES FIRST, and used not to be read here at all\n * (AGL-1961). `users/{uid}.photoUrl` is what `seedUserProfile` fills from the\n * identity provider on EVERY sign-in, and what `user-profiles.ts` calls \"the\n * avatar the console shows for you\" — but the app bar resolved the auth\n * record's `photoURL` alone, and nothing mirrors the document onto the auth\n * record except an interactive save on Manage Account. So a customer whose\n * IdP maps a picture attribute had it stored on every sign-in and still saw a\n * drawn initial in the header, while Manage Account's own card three inches\n * below showed the photo — it already resolved `photoUrl ?? photoURL`. One\n * user, two answers.\n *\n * Blank-not-null is the join, so a photo that exists in either place wins over\n * an empty one in the other. That also heals the non-atomic save: Manage\n * Account writes the document and then calls `updateProfile`, and a failure\n * between the two used to leave the console showing no avatar for a photo it\n * had successfully stored.\n */\nexport function useUserPhoto(): string | undefined {\n const profilePhoto = useUserProfilePhotoUrl()\n const authPhoto = useUserPhotoUrl()\n // The order lives in the shared rule, which the native apps replay through\n // the generated contracts (AGL-4010), so all three draw the same face.\n return readAccountPhoto({ photoUrl: profilePhoto }, authPhoto) ?? undefined\n}\n\nexport default useUserPhoto\n"],"names":["readAccountPhoto","doc","useFirestore","useUser","useFirestoreDoc","useUserPhotoUrl","data","photoURL","useUserProfilePhotoUrl","firestore","user","uid","stored","String","photoUrl","trim","undefined","useUserPhoto","profilePhoto","authPhoto"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD,SAASA,gBAAgB,QAAQ,6CAA4C;AAC7E,SAASC,GAAG,QAAQ,qBAAoB;AACxC,SAASC,YAAY,EAAEC,OAAO,QAAQ,kCAA8B;AACpE,SAASC,eAAe,QAAQ,yBAAqB;AAErD,2DAA2D,GAC3D,OAAO,SAASC;IACd,MAAM,EAAEC,IAAI,EAAE,GAAGH;IACjB,OAAOG,wBAAAA,KAAMC,QAAQ;AACvB;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASC;;IACd,MAAMC,YAAYP;IAClB,MAAM,EAAEI,MAAMI,IAAI,EAAE,GAAGP;IACvB,MAAMQ,MAAMD,wBAAAA,KAAMC,GAAG;IACrB,MAAM,EAAEL,IAAI,EAAE,GAAGF,gBACf,wEAAwE;IACxE,wCAAwC;IACxC,IAAOO,MAAMV,IAAIQ,WAAW,SAASE,OAAO,MAC5C;QAACF;QAAWE;KAAI;IAElB,MAAMC,SAASC,eAAOP,wBAAAA,KAAMQ,QAAQ,mBAAI,IAAIC,IAAI;IAChD,OAAOH,UAAUI;AACnB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCC,GACD,OAAO,SAASC;QAKPjB;IAJP,MAAMkB,eAAeV;IACrB,MAAMW,YAAYd;IAClB,2EAA2E;IAC3E,uEAAuE;IACvE,QAAOL,oBAAAA,iBAAiB;QAAEc,UAAUI;IAAa,GAAGC,sBAA7CnB,oBAA2DgB;AACpE;AAEA,eAAeC,aAAY"}
|