your-ai-workflow-firebase-os 1.2.50 → 1.2.52
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/README.md +1 -1
- package/dist/{ContactPopup-BGPbJTFR.js → ContactPopup-BaGZO8GM.js} +109 -43
- package/dist/ContactPopup-D9KXCC9s.cjs +9 -0
- package/dist/{PhoneInputField-OdtJcL6V.js → PhoneInputField-D1ihCXpb.js} +1 -1
- package/dist/renderer.cjs.js +1 -1
- package/dist/renderer.es.js +1 -1
- package/dist/vite.cjs.js +7 -7
- package/dist/vite.es.js +88 -63
- package/dist/your-ai-workflow-firebase-os.cjs.js +17 -43
- package/dist/your-ai-workflow-firebase-os.css +1 -1
- package/dist/your-ai-workflow-firebase-os.es.js +4986 -5002
- package/package.json +1 -1
- package/scripts/postinstall.js +64 -15
- package/src/configs/theme.config.ts +0 -5
- package/src/index.css +23 -15
- package/dist/ContactPopup-B7q6Uk_F.cjs +0 -9
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ That's it. **One component. Zero configuration files.**
|
|
|
29
29
|
| 👥 **User Management** | Admin panel, three access levels (Free · Internal · Admin), inactive user blocking |
|
|
30
30
|
| 🗂️ **Pages** | Ask your AI assistant for a page — for anyone, signed-in users, your team or admins only — and it appears in `/pages`, where you rename it, reorder it, hide it or change its web address |
|
|
31
31
|
| 📋 **Templates** | Board (Kanban), Calendar, Table, Drive, Inline Form, Popup Form, Confirmation |
|
|
32
|
-
| 🎨 **Theme Engine** | Full dark/light mode, custom accent colours,
|
|
32
|
+
| 🎨 **Theme Engine** | Full dark/light mode, custom accent colours, corner radii, logo |
|
|
33
33
|
| 📁 **File Storage** | An admin-only Assets screen for public images, plus a drive preset any page can be built on |
|
|
34
34
|
| 📬 **Forms** | Created with their pages on `/pages` — say what a form should ask and the AI builds it with the page; see and hand-edit every form afterwards on `/forms`. Questions can ask for a file — a CV, a photo, a receipt — and the upload works signed out |
|
|
35
35
|
| 📥 **Inbox** | Every form entry in one list at `/inbox`, filtered "From anyone" or "From signed-in users"; an attached file opens from the entry by its own name |
|
|
@@ -144,7 +144,6 @@ var le = Object.defineProperty, ue = Object.getOwnPropertyDescriptor, P = Object
|
|
|
144
144
|
selectionText: "#ffffff"
|
|
145
145
|
}
|
|
146
146
|
},
|
|
147
|
-
fontFamily: "Inter",
|
|
148
147
|
cornerRounding: "default",
|
|
149
148
|
cornerRadii: {
|
|
150
149
|
buttonRadius: .75,
|
|
@@ -271,7 +270,7 @@ function Re({ children: e, scopeSelector: t }) {
|
|
|
271
270
|
let e = T(x(Ce, "sys_configs", "theme"), (e) => {
|
|
272
271
|
if (e.exists()) {
|
|
273
272
|
let t = e.data();
|
|
274
|
-
delete t.fontStyles, delete t.fontCustomization;
|
|
273
|
+
delete t.fontStyles, delete t.fontCustomization, delete t.fontFamily;
|
|
275
274
|
let r = Fe(n, t);
|
|
276
275
|
c(r), localStorage.setItem("theme_config_cache", JSON.stringify(r));
|
|
277
276
|
let a = localStorage.getItem("last-seen-default-theme");
|
|
@@ -290,19 +289,11 @@ function Re({ children: e, scopeSelector: t }) {
|
|
|
290
289
|
let i = (e, t) => !e || e.length === 0 ? t || "transparent" : e.length === 1 ? e[0] : `linear-gradient(135deg, ${e.map((t, n) => `${t} ${Math.round(n / (e.length - 1) * 100)}%`).join(", ")})`, o = a === "dark" ? "linear-gradient(135deg, #6d28d9 0%, #a78bfa 100%)" : "linear-gradient(135deg, #5b21b6 0%, #a78bfa 100%)";
|
|
291
290
|
e.style.setProperty("--button-bg", i(n.buttonGradient, o)), e.style.setProperty("--button-fg", n.buttonText || "#ffffff"), e.style.setProperty("--button-hover-bg", i(n.buttonHoverGradient || n.buttonGradient, o)), e.style.setProperty("--text-gradient", i(n.textGradient, `linear-gradient(135deg, ${n.foreground} 0%, ${n.accent} 100%)`)), e.style.setProperty("--glow-color", n.glowColor || `color-mix(in srgb, ${n.accent} 30%, transparent)`), e.style.setProperty("--notification-icon-color", n.notificationIconColor || n.accent);
|
|
292
291
|
let c = n.secondaryButton?.bg || (a === "dark" ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.03)"), l = n.secondaryButton?.border || (a === "dark" ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.06)"), u = n.secondaryButton?.text || n.foreground;
|
|
293
|
-
e.style.setProperty("--btn-sec-bg", c), e.style.setProperty("--btn-sec-border", l), e.style.setProperty("--btn-sec-text", u), e.style.setProperty("--selection-bg", n.selectionBg || "color-mix(in srgb, var(--accent-color) 40%, transparent)"), e.style.setProperty("--selection-text", n.selectionText || "#ffffff"), e.setAttribute("data-theme", a), localStorage.setItem("theme-mode", r), s.cornerRounding === "custom" && s.cornerRadii ? (e.style.setProperty("--btn-radius", `${parseFloat(String(s.cornerRadii.buttonRadius)) || 0}rem`), e.style.setProperty("--card-radius", `${parseFloat(String(s.cornerRadii.cardRadius)) || 0}rem`), e.style.setProperty("--input-radius", `${parseFloat(String(s.cornerRadii.inputRadius)) || 0}rem`), e.style.setProperty("--modal-radius", `${parseFloat(String(s.cornerRadii.modalRadius)) || 0}rem`)) : (e.style.setProperty("--btn-radius", "0.75rem"), e.style.setProperty("--card-radius", "1.5rem"), e.style.setProperty("--input-radius", "0.75rem"), e.style.setProperty("--modal-radius", "1.5rem")), (
|
|
294
|
-
let
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
"Space Grotesk": "\"Space Grotesk\", sans-serif",
|
|
299
|
-
"Plus Jakarta Sans": "\"Plus Jakarta Sans\", sans-serif",
|
|
300
|
-
"System UI": "system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif"
|
|
301
|
-
};
|
|
302
|
-
e.style.setProperty("--font-family", n[t] || n.Inter);
|
|
303
|
-
let r = document.getElementById("dynamic-google-font");
|
|
304
|
-
t === "System UI" ? r && r.remove() : (r || (r = document.createElement("link"), r.id = "dynamic-google-font", r.rel = "stylesheet", document.head.appendChild(r)), r.href = `https://fonts.googleapis.com/css2?family=${t.replace(/ /g, "+")}:wght@400;500;600;700;800;900&display=swap`), e.style.fontSize = "16px", e.style.setProperty("--weight-h1", "800"), e.style.setProperty("--weight-h2", "700"), e.style.setProperty("--weight-h3", "700"), e.style.setProperty("--leading-normal", "1.5");
|
|
305
|
-
})(s.fontFamily || "Inter");
|
|
292
|
+
if (e.style.setProperty("--btn-sec-bg", c), e.style.setProperty("--btn-sec-border", l), e.style.setProperty("--btn-sec-text", u), e.style.setProperty("--selection-bg", n.selectionBg || "color-mix(in srgb, var(--accent-color) 40%, transparent)"), e.style.setProperty("--selection-text", n.selectionText || "#ffffff"), e.setAttribute("data-theme", a), localStorage.setItem("theme-mode", r), s.cornerRounding === "custom" && s.cornerRadii ? (e.style.setProperty("--btn-radius", `${parseFloat(String(s.cornerRadii.buttonRadius)) || 0}rem`), e.style.setProperty("--card-radius", `${parseFloat(String(s.cornerRadii.cardRadius)) || 0}rem`), e.style.setProperty("--input-radius", `${parseFloat(String(s.cornerRadii.inputRadius)) || 0}rem`), e.style.setProperty("--modal-radius", `${parseFloat(String(s.cornerRadii.modalRadius)) || 0}rem`)) : (e.style.setProperty("--btn-radius", "0.75rem"), e.style.setProperty("--card-radius", "1.5rem"), e.style.setProperty("--input-radius", "0.75rem"), e.style.setProperty("--modal-radius", "1.5rem")), !document.getElementById("inter-font")) {
|
|
293
|
+
let e = document.createElement("link");
|
|
294
|
+
e.id = "inter-font", e.rel = "stylesheet", e.href = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap", document.head.appendChild(e);
|
|
295
|
+
}
|
|
296
|
+
e.style.fontSize = "16px", e.style.setProperty("--weight-h1", "800"), e.style.setProperty("--weight-h2", "700"), e.style.setProperty("--weight-h3", "700"), e.style.setProperty("--leading-normal", "1.5");
|
|
306
297
|
let d = document.querySelector("link[rel*='icon']");
|
|
307
298
|
d || (d = document.createElement("link"), d.rel = "icon", document.head.appendChild(d)), s.faviconUrl && (d.href = s.faviconUrl), s.appName && (document.title = s.appName);
|
|
308
299
|
}, [
|
|
@@ -45703,32 +45694,107 @@ function RW({ value: e, options: t, onChange: n, label: r, disabled: i, variant:
|
|
|
45703
45694
|
]
|
|
45704
45695
|
});
|
|
45705
45696
|
}
|
|
45697
|
+
var zW = /^image\/(jpe?g|png|webp)$/i, BW = [
|
|
45698
|
+
.82,
|
|
45699
|
+
.65,
|
|
45700
|
+
.5
|
|
45701
|
+
], VW = () => {
|
|
45702
|
+
try {
|
|
45703
|
+
let e = document.createElement("canvas");
|
|
45704
|
+
return e.width = 1, e.height = 1, e.toDataURL("image/webp").startsWith("data:image/webp");
|
|
45705
|
+
} catch {
|
|
45706
|
+
return !1;
|
|
45707
|
+
}
|
|
45708
|
+
}, HW = async (e) => {
|
|
45709
|
+
if (typeof createImageBitmap == "function") {
|
|
45710
|
+
let t = await createImageBitmap(e);
|
|
45711
|
+
return {
|
|
45712
|
+
source: t,
|
|
45713
|
+
width: t.width,
|
|
45714
|
+
height: t.height,
|
|
45715
|
+
done: () => t.close?.()
|
|
45716
|
+
};
|
|
45717
|
+
}
|
|
45718
|
+
let t = URL.createObjectURL(e);
|
|
45719
|
+
try {
|
|
45720
|
+
let e = await new Promise((e, n) => {
|
|
45721
|
+
let r = new Image();
|
|
45722
|
+
r.onload = () => e(r), r.onerror = () => n(/* @__PURE__ */ Error("That picture could not be read.")), r.src = t;
|
|
45723
|
+
});
|
|
45724
|
+
return {
|
|
45725
|
+
source: e,
|
|
45726
|
+
width: e.naturalWidth,
|
|
45727
|
+
height: e.naturalHeight,
|
|
45728
|
+
done: () => URL.revokeObjectURL(t)
|
|
45729
|
+
};
|
|
45730
|
+
} catch (e) {
|
|
45731
|
+
throw URL.revokeObjectURL(t), e;
|
|
45732
|
+
}
|
|
45733
|
+
}, UW = (e, t, n) => new Promise((r) => {
|
|
45734
|
+
if (typeof e.toBlob != "function") {
|
|
45735
|
+
r(null);
|
|
45736
|
+
return;
|
|
45737
|
+
}
|
|
45738
|
+
e.toBlob((e) => r(e), t, n);
|
|
45739
|
+
}), WW = (e, t) => {
|
|
45740
|
+
let n = t === "image/webp" ? "webp" : t === "image/png" ? "png" : "jpg";
|
|
45741
|
+
return `${(e || "image").replace(/\.[^.]+$/, "") || "image"}.${n}`;
|
|
45742
|
+
};
|
|
45743
|
+
async function GW(e, t = {}) {
|
|
45744
|
+
let n = t.maxSide ?? 1600, r = t.targetBytes ?? 921600;
|
|
45745
|
+
if (!e || !zW.test(e.type || "") || e.size <= 153600 || typeof document > "u") return e;
|
|
45746
|
+
try {
|
|
45747
|
+
let { source: t, width: i, height: a, done: o } = await HW(e);
|
|
45748
|
+
try {
|
|
45749
|
+
if (!i || !a) return e;
|
|
45750
|
+
let o = Math.min(1, n / Math.max(i, a)), s = document.createElement("canvas");
|
|
45751
|
+
s.width = Math.max(1, Math.round(i * o)), s.height = Math.max(1, Math.round(a * o));
|
|
45752
|
+
let c = s.getContext("2d");
|
|
45753
|
+
if (!c) return e;
|
|
45754
|
+
c.drawImage(t, 0, 0, s.width, s.height);
|
|
45755
|
+
let l = /png$/i.test(e.type), u = VW() ? "image/webp" : l ? "image/png" : "image/jpeg", d = null;
|
|
45756
|
+
for (let e of BW) {
|
|
45757
|
+
let t = await UW(s, u, e);
|
|
45758
|
+
if (!t || (d = t, t.size <= r) || u === "image/png") break;
|
|
45759
|
+
}
|
|
45760
|
+
return !d || d.size >= e.size ? e : new File([d], WW(e.name, u), {
|
|
45761
|
+
type: u,
|
|
45762
|
+
lastModified: Date.now()
|
|
45763
|
+
});
|
|
45764
|
+
} finally {
|
|
45765
|
+
o();
|
|
45766
|
+
}
|
|
45767
|
+
} catch {
|
|
45768
|
+
return e;
|
|
45769
|
+
}
|
|
45770
|
+
}
|
|
45706
45771
|
//#endregion
|
|
45707
45772
|
//#region src/lib/assetUpload.ts
|
|
45708
|
-
var
|
|
45709
|
-
async function
|
|
45773
|
+
var KW = "pub_files", qW = (e) => `${Date.now()}_${(e || "file").replace(/[^a-zA-Z0-9.-]/g, "_")}`;
|
|
45774
|
+
async function JW(e, t) {
|
|
45710
45775
|
if (!t) throw Error("Sign in again before uploading.");
|
|
45711
|
-
let n = `${
|
|
45712
|
-
await se(
|
|
45713
|
-
let
|
|
45714
|
-
return await y(b(Ce,
|
|
45715
|
-
fileName:
|
|
45716
|
-
fileType:
|
|
45717
|
-
fileSize:
|
|
45718
|
-
downloadURL:
|
|
45719
|
-
storagePath:
|
|
45776
|
+
let n = await GW(e), r = `${KW}/${qW(n.name)}`, i = k(we, r);
|
|
45777
|
+
await se(i, n, { customMetadata: { ownerId: t.uid } });
|
|
45778
|
+
let a = await ae(i);
|
|
45779
|
+
return await y(b(Ce, KW), {
|
|
45780
|
+
fileName: n.name,
|
|
45781
|
+
fileType: n.type || "unknown",
|
|
45782
|
+
fileSize: n.size,
|
|
45783
|
+
downloadURL: a,
|
|
45784
|
+
storagePath: r,
|
|
45720
45785
|
uid: t.uid,
|
|
45721
45786
|
uploaderEmail: t.email || "",
|
|
45722
45787
|
createdAt: ee()
|
|
45723
|
-
}),
|
|
45788
|
+
}), a;
|
|
45724
45789
|
}
|
|
45725
|
-
var
|
|
45726
|
-
async function
|
|
45727
|
-
|
|
45728
|
-
|
|
45729
|
-
|
|
45790
|
+
var YW = "pub_form_uploads";
|
|
45791
|
+
async function XW(e, t) {
|
|
45792
|
+
let n = await GW(e);
|
|
45793
|
+
if (n.size >= 10485760) throw Error("That file is over 10 MB. Try a smaller one.");
|
|
45794
|
+
let r = Math.random().toString(36).slice(2, 8), i = k(we, `${YW}/${Date.now()}_${r}_${(n.name || "file").replace(/[^a-zA-Z0-9.-]/g, "_")}`);
|
|
45795
|
+
return await se(i, n, t ? { customMetadata: { ownerId: t.uid } } : void 0), ae(i);
|
|
45730
45796
|
}
|
|
45731
|
-
function
|
|
45797
|
+
function ZW(e) {
|
|
45732
45798
|
try {
|
|
45733
45799
|
let t = new URL(e);
|
|
45734
45800
|
return (decodeURIComponent(t.pathname.split("/o/")[1] || t.pathname).split("/").pop() || "").replace(/^\d+_[a-z0-9]+_/, "") || t.hostname || "Attached file";
|
|
@@ -45736,15 +45802,15 @@ function WW(e) {
|
|
|
45736
45802
|
return "Attached file";
|
|
45737
45803
|
}
|
|
45738
45804
|
}
|
|
45739
|
-
var
|
|
45740
|
-
function
|
|
45805
|
+
var QW = (e) => e?.code === "storage/unauthorized" ? "You do not have permission to upload here." : e?.message || "That upload did not work. Try again.", $W = t.lazy(() => import("./PhoneInputField-D1ihCXpb.js").then((e) => e.n)), eG = /^[^\s@,;]+@[^\s@,;.]+(\.[^\s@,;.]+)*\.[a-z]{2,}$/i;
|
|
45806
|
+
function tG({ field: e, value: t, error: n, onChange: r }) {
|
|
45741
45807
|
let [i, a] = v(!1), [o, s] = v(""), c = _(null), l = async (e) => {
|
|
45742
45808
|
if (!(!e || i)) {
|
|
45743
45809
|
a(!0), s("");
|
|
45744
45810
|
try {
|
|
45745
|
-
r(await
|
|
45811
|
+
r(await XW(e, Se.currentUser));
|
|
45746
45812
|
} catch (e) {
|
|
45747
|
-
s(e?.code === "storage/unauthorized" ? "That kind of file is not accepted. Try a PDF, a document or a picture." :
|
|
45813
|
+
s(e?.code === "storage/unauthorized" ? "That kind of file is not accepted. Try a PDF, a document or a picture." : QW(e));
|
|
45748
45814
|
}
|
|
45749
45815
|
a(!1), c.current && (c.current.value = "");
|
|
45750
45816
|
}
|
|
@@ -45763,7 +45829,7 @@ function JW({ field: e, value: t, error: n, onChange: r }) {
|
|
|
45763
45829
|
i ? /* @__PURE__ */ A(I, { className: "w-4 h-4 animate-spin text-accent shrink-0" }) : /* @__PURE__ */ A(jx, { className: `w-4 h-4 shrink-0 ${t ? "text-accent" : "text-foreground/40"}` }),
|
|
45764
45830
|
/* @__PURE__ */ A("span", {
|
|
45765
45831
|
className: `flex-1 min-w-0 truncate text-[15px] ${t ? "text-foreground" : "text-foreground/40"}`,
|
|
45766
|
-
children: i ? "Uploading..." : t ?
|
|
45832
|
+
children: i ? "Uploading..." : t ? ZW(t) : e.placeholder || "Attach a file"
|
|
45767
45833
|
}),
|
|
45768
45834
|
!i && /* @__PURE__ */ j("span", {
|
|
45769
45835
|
className: "inline-flex items-center gap-1.5 text-[12.5px] font-bold text-foreground/60 shrink-0",
|
|
@@ -45799,7 +45865,7 @@ function JW({ field: e, value: t, error: n, onChange: r }) {
|
|
|
45799
45865
|
]
|
|
45800
45866
|
});
|
|
45801
45867
|
}
|
|
45802
|
-
function
|
|
45868
|
+
function nG({ onClose: e, formId: t, formConfig: n, isInline: r }) {
|
|
45803
45869
|
let [i, o] = v({}), [s, c] = v("idle"), [l, u] = v(""), [d, p] = v({}), m = _(null), [h, g] = v(n || null), [C, w] = v(!n), T = M(), E = Pe(), D = (e) => {
|
|
45804
45870
|
let t = (typeof window < "u" ? window.__FBOS_FORMS__ : null) || {};
|
|
45805
45871
|
return E?.defaultConfigs?.[e] || E?.defaultConfigs?.[`${e}Form`] || t[e] || (e === "contact" ? _e : e === "support" ? ye : null);
|
|
@@ -45873,7 +45939,7 @@ function YW({ onClose: e, formId: t, formConfig: n, isInline: r }) {
|
|
|
45873
45939
|
let a = (h?.fields || []).filter((e) => e.type === "email"), s = {}, l = {};
|
|
45874
45940
|
if (a.forEach((e) => {
|
|
45875
45941
|
let t = String(i[e.name] ?? "").trim();
|
|
45876
|
-
t && (l[e.name] = t,
|
|
45942
|
+
t && (l[e.name] = t, eG.test(t) || (s[e.name] = "That does not look like an email address — check for a typo, e.g. jane@example.com"));
|
|
45877
45943
|
}), (h?.fields || []).filter((e) => e.type === "file" && e.required && !i[e.name]).forEach((e) => {
|
|
45878
45944
|
s[e.name] = "Please attach a file before sending.";
|
|
45879
45945
|
}), Object.keys(s).length > 0) {
|
|
@@ -46009,7 +46075,7 @@ function YW({ onClose: e, formId: t, formConfig: n, isInline: r }) {
|
|
|
46009
46075
|
}).map((e, t) => {
|
|
46010
46076
|
if (e.type === "tel") return /* @__PURE__ */ A(a, {
|
|
46011
46077
|
fallback: /* @__PURE__ */ A("div", { className: "h-12 w-full glass-panel animate-pulse rounded-xl" }),
|
|
46012
|
-
children: /* @__PURE__ */ A(
|
|
46078
|
+
children: /* @__PURE__ */ A($W, {
|
|
46013
46079
|
field: e,
|
|
46014
46080
|
value: i[e.name] || "",
|
|
46015
46081
|
onChange: (t) => o({
|
|
@@ -46018,7 +46084,7 @@ function YW({ onClose: e, formId: t, formConfig: n, isInline: r }) {
|
|
|
46018
46084
|
})
|
|
46019
46085
|
})
|
|
46020
46086
|
}, t);
|
|
46021
|
-
if (e.type === "file") return /* @__PURE__ */ A(
|
|
46087
|
+
if (e.type === "file") return /* @__PURE__ */ A(tG, {
|
|
46022
46088
|
field: e,
|
|
46023
46089
|
value: i[e.name] || "",
|
|
46024
46090
|
error: d[e.name],
|
|
@@ -46240,4 +46306,4 @@ function YW({ onClose: e, formId: t, formConfig: n, isInline: r }) {
|
|
|
46240
46306
|
}), document.body);
|
|
46241
46307
|
}
|
|
46242
46308
|
//#endregion
|
|
46243
|
-
export {
|
|
46309
|
+
export { Eg as $, oT as A, wn as At, Jy as B, Se as Bt, SA as C, as as Ct, TO as D, Yr as Dt, Rk as E, $a as Et, pC as F, Ut as Ft, I as G, ye as Gt, uv as H, Ee as Ht, TS as I, Re as It, n_ as J, ge as Jt, x_ as K, ve as Kt, Vx as L, ze as Lt, Hw as M, gn as Mt, zw as N, fn as Nt, cO as O, Ln as Ot, KC as P, qt as Pt, Dg as Q, jx as R, Ne as Rt, HA as S, ls as St, zk as T, no as Tt, X_ as U, we as Ut, Bv as V, Ce as Vt, Y_ as W, be as Wt, Zg as X, $g as Y, pe as Yt, Xg as Z, nM as _, nc as _t, JW as a, Mf as at, aj as b, ds as bt, IW as c, Md as ct, uU as d, xu as dt, hg as et, cU as f, Jl as ft, vM as g, sc as gt, yM as h, Yc as ht, QW as i, Vf as it, Zw as j, bn as jt, _T as k, An as kt, PW as l, bd as lt, uV as m, hl as mt, YW as n, gh as nt, GW as o, $d as ot, oU as p, xl as pt, y_ as q, _e as qt, ZW as r, Bm as rt, RW as s, Nd as st, nG as t, fg as tt, MW as u, ed as ut, eM as v, Ps as vt, sA as w, Qo as wt, WA as x, us as xt, bj as y, ws as yt, cx as z, Pe as zt };
|