dolphin-client 1.0.6 → 1.1.1
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/.vscode/dolphin-tags.json +586 -0
- package/README.md +24 -0
- package/bin/cli.cjs +60 -0
- package/dist/dolphin-client.js +143 -4
- package/dist/dolphin-client.min.js +18 -18
- package/dist/index.cjs +143 -4
- package/dist/index.js +143 -4
- package/package.json +10 -3
- package/scripts/postinstall.js +57 -0
package/dist/dolphin-client.js
CHANGED
|
@@ -41,7 +41,7 @@ var DolphinModule = (() => {
|
|
|
41
41
|
target.patch = (pathOrBody, bodyOrOptions, options) => typeof pathOrBody === "string" ? this.request("PATCH", pathOrBody, bodyOrOptions, options) : this.request("PATCH", joined, pathOrBody, bodyOrOptions);
|
|
42
42
|
target.del = (pathOrOptions, options) => typeof pathOrOptions === "string" ? this.request("DELETE", pathOrOptions, null, options) : this.request("DELETE", joined, null, pathOrOptions);
|
|
43
43
|
target.request = (method, subPath, body, options) => {
|
|
44
|
-
const finalPath = subPath ? `${joined}/${subPath.startsWith("/") ? subPath.slice(1) : subPath}` : joined;
|
|
44
|
+
const finalPath = subPath ? joined ? `${joined}/${subPath.startsWith("/") ? subPath.slice(1) : subPath}` : subPath : joined;
|
|
45
45
|
return this.request(method, finalPath, body, options);
|
|
46
46
|
};
|
|
47
47
|
target.requestDirect = (method, path, body, options) => {
|
|
@@ -225,8 +225,9 @@ var DolphinModule = (() => {
|
|
|
225
225
|
const _isRetry = options._isRetry === true;
|
|
226
226
|
let finalMethod = method.toUpperCase();
|
|
227
227
|
let finalBody = body;
|
|
228
|
+
const hasBody = !["GET", "HEAD"].includes(finalMethod);
|
|
228
229
|
const headers = {
|
|
229
|
-
"Content-Type": "application/json",
|
|
230
|
+
...hasBody ? { "Content-Type": "application/json" } : {},
|
|
230
231
|
...options.headers || {}
|
|
231
232
|
};
|
|
232
233
|
if (["PUT", "PATCH", "DELETE"].includes(finalMethod)) {
|
|
@@ -1376,6 +1377,86 @@ var DolphinModule = (() => {
|
|
|
1376
1377
|
console.error("%cFailed Expression:", "color: #3b82f6; font-style: italic;", expression);
|
|
1377
1378
|
}
|
|
1378
1379
|
};
|
|
1380
|
+
clientProto._showAlert = function(id, duration) {
|
|
1381
|
+
if (typeof document === "undefined") return;
|
|
1382
|
+
const el = document.getElementById(id) || document.querySelector(`[id="${id}"]`);
|
|
1383
|
+
if (!el) return;
|
|
1384
|
+
el.removeAttribute("hidden");
|
|
1385
|
+
el.style.display = "";
|
|
1386
|
+
if (duration && duration > 0) {
|
|
1387
|
+
setTimeout(() => {
|
|
1388
|
+
el.setAttribute("hidden", "");
|
|
1389
|
+
}, duration);
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1392
|
+
clientProto._showToast = function(message, type = "success") {
|
|
1393
|
+
if (typeof document === "undefined") return;
|
|
1394
|
+
const colors = {
|
|
1395
|
+
success: { bg: "rgba(16,185,129,0.15)", border: "#10b981", icon: "\u2705" },
|
|
1396
|
+
error: { bg: "rgba(239,68,68,0.15)", border: "#ef4444", icon: "\u274C" },
|
|
1397
|
+
info: { bg: "rgba(59,130,246,0.15)", border: "#3b82f6", icon: "\u2139\uFE0F" }
|
|
1398
|
+
};
|
|
1399
|
+
const c = colors[type] || colors.success;
|
|
1400
|
+
const toast = document.createElement("div");
|
|
1401
|
+
toast.setAttribute("data-dolphin-toast", "");
|
|
1402
|
+
const existing = document.querySelectorAll("[data-dolphin-toast]");
|
|
1403
|
+
const offset = existing.length * 72;
|
|
1404
|
+
toast.style.cssText = [
|
|
1405
|
+
"position:fixed",
|
|
1406
|
+
`bottom:${24 + offset}px`,
|
|
1407
|
+
"right:24px",
|
|
1408
|
+
"z-index:2147483647",
|
|
1409
|
+
`background:${c.bg}`,
|
|
1410
|
+
`border:1px solid ${c.border}`,
|
|
1411
|
+
"color:#fff",
|
|
1412
|
+
"padding:14px 20px",
|
|
1413
|
+
"border-radius:14px",
|
|
1414
|
+
"font-size:14px",
|
|
1415
|
+
"font-weight:600",
|
|
1416
|
+
"font-family:system-ui,sans-serif",
|
|
1417
|
+
"box-shadow:0 8px 32px rgba(0,0,0,0.4)",
|
|
1418
|
+
"display:flex",
|
|
1419
|
+
"align-items:center",
|
|
1420
|
+
"gap:10px",
|
|
1421
|
+
"max-width:380px",
|
|
1422
|
+
"word-break:break-word",
|
|
1423
|
+
"transform:translateY(80px)",
|
|
1424
|
+
"opacity:0",
|
|
1425
|
+
"transition:transform 0.35s cubic-bezier(0.34,1.56,0.64,1),opacity 0.3s ease",
|
|
1426
|
+
"pointer-events:auto",
|
|
1427
|
+
"backdrop-filter:blur(12px)"
|
|
1428
|
+
].join(";");
|
|
1429
|
+
toast.innerHTML = `<span style="font-size:18px">${c.icon}</span><span>${message}</span>`;
|
|
1430
|
+
document.body.appendChild(toast);
|
|
1431
|
+
const restack = () => {
|
|
1432
|
+
const remaining = document.querySelectorAll("[data-dolphin-toast]");
|
|
1433
|
+
remaining.forEach((el, i) => {
|
|
1434
|
+
el.style.bottom = `${24 + i * 72}px`;
|
|
1435
|
+
});
|
|
1436
|
+
};
|
|
1437
|
+
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
1438
|
+
raf(() => raf(() => {
|
|
1439
|
+
toast.style.transform = "translateY(0)";
|
|
1440
|
+
toast.style.opacity = "1";
|
|
1441
|
+
}));
|
|
1442
|
+
const removeToast = () => {
|
|
1443
|
+
clearTimeout(toast._removeTimer);
|
|
1444
|
+
if (toast.parentNode) {
|
|
1445
|
+
toast.parentNode.removeChild(toast);
|
|
1446
|
+
restack();
|
|
1447
|
+
}
|
|
1448
|
+
};
|
|
1449
|
+
const hideTimer = setTimeout(() => {
|
|
1450
|
+
toast.style.transform = "translateY(80px)";
|
|
1451
|
+
toast.style.opacity = "0";
|
|
1452
|
+
toast._removeTimer = setTimeout(removeToast, 400);
|
|
1453
|
+
}, 3500);
|
|
1454
|
+
toast._hideTimer = hideTimer;
|
|
1455
|
+
toast.addEventListener("click", () => {
|
|
1456
|
+
clearTimeout(toast._hideTimer);
|
|
1457
|
+
removeToast();
|
|
1458
|
+
}, { once: true });
|
|
1459
|
+
};
|
|
1379
1460
|
clientProto._initDOMBinding = function() {
|
|
1380
1461
|
if (this._domInitialized) return;
|
|
1381
1462
|
this._domInitialized = true;
|
|
@@ -1474,6 +1555,11 @@ var DolphinModule = (() => {
|
|
|
1474
1555
|
resolvedTopic = resolvedTopic.replace(new RegExp(`\\{\\{${escapedK}\\}\\}`, "g"), parentCtx[k] !== void 0 && parentCtx[k] !== null ? parentCtx[k] : "");
|
|
1475
1556
|
}
|
|
1476
1557
|
this.publish(resolvedTopic, data);
|
|
1558
|
+
const rtSuccessId = e.target.getAttribute("data-rt-api-success");
|
|
1559
|
+
if (rtSuccessId) {
|
|
1560
|
+
const rtSuccessEl = document.getElementById(rtSuccessId);
|
|
1561
|
+
if (rtSuccessEl) this._showToast(rtSuccessEl.textContent || rtSuccessEl.innerText || "", "success");
|
|
1562
|
+
}
|
|
1477
1563
|
} else if (apiTarget) {
|
|
1478
1564
|
let resolvedTarget = apiTarget;
|
|
1479
1565
|
for (const k in parentCtx) {
|
|
@@ -1490,16 +1576,40 @@ var DolphinModule = (() => {
|
|
|
1490
1576
|
const result = await this.api.request(method, path, data);
|
|
1491
1577
|
const resultBind = e.target.getAttribute("data-api-result");
|
|
1492
1578
|
if (resultBind) this._updateDOM(resultBind, result);
|
|
1579
|
+
const successToast = e.target.getAttribute("data-api-toast");
|
|
1580
|
+
if (successToast) this._showToast(successToast, "success");
|
|
1581
|
+
const successElId = e.target.getAttribute("data-rt-api-success");
|
|
1582
|
+
if (successElId) {
|
|
1583
|
+
const duration = parseInt(e.target.getAttribute("data-rt-alert-duration") || "0", 10);
|
|
1584
|
+
this._showAlert(successElId, duration);
|
|
1585
|
+
const errElId = e.target.getAttribute("data-rt-api-error");
|
|
1586
|
+
if (errElId) {
|
|
1587
|
+
const errEl = document.getElementById(errElId);
|
|
1588
|
+
if (errEl) errEl.setAttribute("hidden", "");
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1493
1591
|
const redirect = e.target.getAttribute("data-api-redirect");
|
|
1494
1592
|
if (redirect) window.location.href = redirect;
|
|
1495
1593
|
if (e.target.hasAttribute("data-api-reload")) window.location.reload();
|
|
1496
1594
|
} catch (err) {
|
|
1497
1595
|
console.error("[Dolphin] API Submit Error:", err);
|
|
1596
|
+
const errorToast = e.target.getAttribute("data-api-error-toast");
|
|
1597
|
+
if (errorToast) this._showToast(errorToast, "error");
|
|
1598
|
+
const errorElId = e.target.getAttribute("data-rt-api-error");
|
|
1599
|
+
if (errorElId) {
|
|
1600
|
+
const duration = parseInt(e.target.getAttribute("data-rt-alert-duration") || "0", 10);
|
|
1601
|
+
this._showAlert(errorElId, duration);
|
|
1602
|
+
const sucElId = e.target.getAttribute("data-rt-api-success");
|
|
1603
|
+
if (sucElId) {
|
|
1604
|
+
const sucEl = document.getElementById(sucElId);
|
|
1605
|
+
if (sucEl) sucEl.setAttribute("hidden", "");
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1498
1608
|
}
|
|
1499
1609
|
}
|
|
1500
1610
|
}
|
|
1501
1611
|
});
|
|
1502
|
-
const INTERACTION_EVENTS = ["click", "change", "
|
|
1612
|
+
const INTERACTION_EVENTS = ["click", "change", "input", "keydown", "keyup", "dblclick", "focus", "blur", "mouseenter", "mouseleave"];
|
|
1503
1613
|
INTERACTION_EVENTS.forEach((evtName) => {
|
|
1504
1614
|
this.addDomListener(document, evtName, async (e) => {
|
|
1505
1615
|
if (!e.target || !e.target.closest) return;
|
|
@@ -1530,7 +1640,12 @@ var DolphinModule = (() => {
|
|
|
1530
1640
|
const apiTarget = apiBtn.getAttribute(`data-api-${evtName}`);
|
|
1531
1641
|
const actionData = apiBtn.getAttribute("data-api-payload");
|
|
1532
1642
|
const parentCtx = this.getClosestContext(apiBtn) || {};
|
|
1533
|
-
|
|
1643
|
+
let resolvedApiTarget = apiTarget;
|
|
1644
|
+
for (const k in parentCtx) {
|
|
1645
|
+
const escapedK = escapeRegExp(k);
|
|
1646
|
+
resolvedApiTarget = resolvedApiTarget.replace(new RegExp(`\\{\\{${escapedK}\\}\\}`, "g"), parentCtx[k] !== void 0 && parentCtx[k] !== null ? parentCtx[k] : "");
|
|
1647
|
+
}
|
|
1648
|
+
const parts = resolvedApiTarget.trim().split(" ");
|
|
1534
1649
|
const method = parts.length > 1 ? parts[0].toUpperCase() : "POST";
|
|
1535
1650
|
const path = parts.length > 1 ? parts[1] : parts[0];
|
|
1536
1651
|
let payload = null;
|
|
@@ -1550,11 +1665,35 @@ var DolphinModule = (() => {
|
|
|
1550
1665
|
const result = await this.api.request(method, path, payload);
|
|
1551
1666
|
const resultBind = apiBtn.getAttribute("data-api-result");
|
|
1552
1667
|
if (resultBind) this._updateDOM(resultBind, result);
|
|
1668
|
+
const successToast = apiBtn.getAttribute("data-api-toast");
|
|
1669
|
+
if (successToast) this._showToast(successToast, "success");
|
|
1670
|
+
const successElId = apiBtn.getAttribute("data-rt-api-success");
|
|
1671
|
+
if (successElId) {
|
|
1672
|
+
const duration = parseInt(apiBtn.getAttribute("data-rt-alert-duration") || "0", 10);
|
|
1673
|
+
this._showAlert(successElId, duration);
|
|
1674
|
+
const errElId = apiBtn.getAttribute("data-rt-api-error");
|
|
1675
|
+
if (errElId) {
|
|
1676
|
+
const errEl = document.getElementById(errElId);
|
|
1677
|
+
if (errEl) errEl.setAttribute("hidden", "");
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1553
1680
|
const redirect = apiBtn.getAttribute("data-api-redirect");
|
|
1554
1681
|
if (redirect) window.location.href = redirect;
|
|
1555
1682
|
if (apiBtn.hasAttribute("data-api-reload")) window.location.reload();
|
|
1556
1683
|
} catch (err) {
|
|
1557
1684
|
console.error(`[Dolphin] API ${evtName} Error:`, err);
|
|
1685
|
+
const errorToast = apiBtn.getAttribute("data-api-error-toast");
|
|
1686
|
+
if (errorToast) this._showToast(errorToast, "error");
|
|
1687
|
+
const errorElId = apiBtn.getAttribute("data-rt-api-error");
|
|
1688
|
+
if (errorElId) {
|
|
1689
|
+
const duration = parseInt(apiBtn.getAttribute("data-rt-alert-duration") || "0", 10);
|
|
1690
|
+
this._showAlert(errorElId, duration);
|
|
1691
|
+
const sucElId = apiBtn.getAttribute("data-rt-api-success");
|
|
1692
|
+
if (sucElId) {
|
|
1693
|
+
const sucEl = document.getElementById(sucElId);
|
|
1694
|
+
if (sucEl) sucEl.setAttribute("hidden", "");
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1558
1697
|
}
|
|
1559
1698
|
}
|
|
1560
1699
|
const storeActionBtn = e.target.closest(`[data-store-${evtName}]`);
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
var DolphinModule=(()=>{var R=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var Z=Object.getOwnPropertyNames;var tt=Object.prototype.hasOwnProperty;var et=(A,t)=>{for(var e in t)R(A,e,{get:t[e],enumerable:!0})},nt=(A,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Z(t))!tt.call(A,s)&&s!==e&&R(A,s,{get:()=>t[s],enumerable:!(n=Y(t,s))||n.enumerable});return A};var st=A=>nt(R({},"__esModule",{value:!0}),A);var rt={};et(rt,{DolphinClient:()=>C});var x=class{client;constructor(t){return this.client=t,this._createProxy([])}_createProxy(t){let e=t.join("/"),n=i=>this.request("GET",e,null,i);n.get=(i,a)=>typeof i=="string"?this.request("GET",i,null,a):this.request("GET",e,null,i),n.post=(i,a,l)=>typeof i=="string"?this.request("POST",i,a,l):this.request("POST",e,i,a),n.put=(i,a,l)=>typeof i=="string"?this.request("PUT",i,a,l):this.request("PUT",e,i,a),n.patch=(i,a,l)=>typeof i=="string"?this.request("PATCH",i,a,l):this.request("PATCH",e,i,a),n.del=(i,a)=>typeof i=="string"?this.request("DELETE",i,null,a):this.request("DELETE",e,null,i),n.request=(i,a,l,_)=>{let v=a?`${e}/${a.startsWith("/")?a.slice(1):a}`:e;return this.request(i,v,l,_)},n.requestDirect=(i,a,l,_)=>this.requestDirect(i,a,l,_),n._findCSRFToken=()=>this._findCSRFToken(),n._resolveBaseUrl=i=>this._resolveBaseUrl(i),n._normalizeValidationErrors=i=>this._normalizeValidationErrors(i);let s=["get","post","put","patch","del","request","requestDirect","_findCSRFToken","_resolveBaseUrl","_normalizeValidationErrors"];return new Proxy(n,{get:(i,a)=>typeof a=="string"&&!s.includes(a)?this._createProxy([...t,a]):i[a]})}_findCSRFToken(){if(typeof document>"u")return null;let t=["csrf-token","_csrf","xsrf-token","csrf_token"];for(let i of t){let a=document.querySelector(`meta[name="${i}"], meta[content][name$="${i}"]`);if(a){let l=a.getAttribute("content");if(l)return l}}let e=["_csrfToken","_token","_csrf","csrf_token"];for(let i of e){let a=document.querySelector(`input[type="hidden"][name="${i}"]`);if(a&&a.value)return a.value}let n=["csrfToken","XSRF-TOKEN","_csrf","csrf_token"];for(let i of n){let a=document.cookie.match(new RegExp("(^|;\\s*)"+i+"=([^;]*)"));if(a)return decodeURIComponent(a[2])}let s=typeof window<"u"&&window.wpApiSettings?.nonce;return s||null}_resolveBaseUrl(t){if(t.startsWith("http://")||t.startsWith("https://"))return t;let e=this.client.httpUrl;if(typeof document<"u"){let s=document.querySelector("base[href]");if(s){let i=s.getAttribute("href")||"";if(i&&i!=="/"){let a=i.endsWith("/")?i.slice(0,-1):i;e=`${this.client.httpUrl}${a.startsWith("/")?a:"/"+a}`}}else{let i=document.querySelector('meta[name="base-path"]');if(i){let a=i.getAttribute("content")||"";if(a&&a!=="/"){let l=a.endsWith("/")?a.slice(0,-1):a;e=`${this.client.httpUrl}${l.startsWith("/")?l:"/"+l}`}}}}let n=t.startsWith("/")?t:"/"+t;return`${e}${n}`}_normalizeValidationErrors(t){let e={};if(!t||typeof t!="object")return e;let n=t.errors||t.validationErrors||t;if(Array.isArray(n)){for(let s of n)if(s&&typeof s=="object"){let i=s.path||s.param||s.field||s.property,a=s.msg||s.message||s.error;i&&a&&(e[i]=Array.isArray(a)?a[0]:a)}return e}if(typeof n=="object"&&n!==null)for(let s in n){let i=n[s];if(i)if(Array.isArray(i))i.length>0&&(e[s]=String(i[0]));else if(typeof i=="object"){let a=Object.keys(i);if(a.length>0){let l=a[0];e[s]=String(i[l])}}else e[s]=String(i)}return e}async request(t,e,n=null,s={}){if(this.client.offline){let i=this.client.offline.isOnline,a=`${t.toUpperCase()}:${e}`;if(t.toUpperCase()==="GET")if(i)try{let l=await this.requestDirect(t,e,n,s);return await this.client.offline.setCache(a,l),l}catch(l){let _=await this.client.offline.getCache(a);if(_!=null)return _;throw l}else{let l=await this.client.offline.getCache(a);if(l!=null)return l;throw{status:503,data:{error:"Offline, no cache available"}}}else return i?this.requestDirect(t,e,n,s):(await this.client.offline.queueMutation(t,e,n),this.client._dispatch("offline:queued",{method:t,path:e,body:n}),{success:!0,offline:!0,message:"Mutation queued offline"})}return this.requestDirect(t,e,n,s)}async requestDirect(t,e,n=null,s={}){let i=s._isRetry===!0,a=t.toUpperCase(),l=n,_={"Content-Type":"application/json",...s.headers||{}};["PUT","PATCH","DELETE"].includes(a)&&(this.client.options.methodSpoofing||s.methodSpoofing)&&(_["X-HTTP-Method-Override"]=a,l instanceof FormData?l.append("_method",a):l&&typeof l=="object"?l={...l,_method:a}:l||(l={_method:a}),a="POST");let v=this._resolveBaseUrl(e);this.client.options.debug&&console.log("%c\u{1F680} [Dolphin API Request]:","color: #3b82f6; font-weight: bold;",t.toUpperCase(),e,l||"");let k=new AbortController,h=setTimeout(()=>k.abort(),this.client.options.timeout);if(this.client.accessToken&&(_.Authorization=`Bearer ${this.client.accessToken}`),["POST","PUT","PATCH","DELETE"].includes(t.toUpperCase())){let c=this._findCSRFToken();c&&(_["X-CSRF-Token"]=c,_["X-XSRF-TOKEN"]=c,_["X-CSRFToken"]=c,_["X-WP-Nonce"]=c,l&&typeof l=="object"&&!l._csrfToken&&!l._token&&!l._csrf&&(l={...l,_csrfToken:c,_token:c,_csrf:c}))}let d={...s};delete d._isRetry,delete d.methodSpoofing;try{let c=await fetch(v,{method:a,headers:_,signal:k.signal,...l?{body:JSON.stringify(l)}:{},...d});if(clearTimeout(h),c.status===401&&!i&&this.client.options.autoRefreshToken&&await this.client.auth._silentRefresh())return this.request(t,e,n,{...s,_isRetry:!0});let o=(c.headers.get("content-type")||"").includes("application/json")?await c.json():await c.text();if(!c.ok)throw{status:c.status,data:o};if(this.client.options.debug&&console.log("%c\u2705 [Dolphin API Success]:","color: #10b981; font-weight: bold;",t.toUpperCase(),e,o),o&&typeof o=="object"&&o.accessToken&&(this.client.setToken(o.accessToken),o.user&&(this.client.auth.user=o.user)),this.client.options.autoBroadcast&&["POST","PUT","PATCH","DELETE"].includes(t.toUpperCase())){let u=e.startsWith("/")?e.substring(1):e;this.client.publish(u,{method:t.toUpperCase(),payload:n,result:o})}return o}catch(c){if(clearTimeout(h),this.client.options.debug&&console.error("%c\u274C [Dolphin API Error]:","color: #ef4444; font-weight: bold;",t.toUpperCase(),e,c),c&&typeof c=="object"&&c.data){let r=this._normalizeValidationErrors(c.data);if(Object.keys(r).length>0)for(let o in r)this.client.publish(`errors/${o}`,r[o])}throw c.name==="AbortError"?{status:408,data:{error:"Request timed out"}}:c}}};var $=class{client;user;_refreshing;constructor(t){this.client=t,this.user=null,this._refreshing=!1}async login(t,e){let n=await this.client.api.post("/api/auth/login",{email:t,password:e});return n.accessToken&&(this.client.setToken(n.accessToken),this.user=n.user||null),n}async register(t){return this.client.api.post("/api/auth/register",t)}async me(){let t=await this.client.api.get("/api/auth/me");return t.success&&(this.user=t.data),t}async logout(){try{await this.client.api.post("/api/auth/logout")}catch{}this.client.setToken(null),this.user=null}async refresh(){return this._silentRefresh()}async _silentRefresh(){if(this._refreshing)return!1;this._refreshing=!0;try{let t=await this.client.api.post("/api/auth/refresh",null,{_isRetry:!0});return t.accessToken?(this.client.setToken(t.accessToken),!0):!1}catch{return this.client.setToken(null),!1}finally{this._refreshing=!1}}async verify2FA(t,e){let n={code:t,email:e||this.user?.email},s=await this.client.api.post("/api/auth/2fa/verify",n);return s.accessToken&&(this.client.setToken(s.accessToken),s.user&&(this.user=s.user)),s}async enable2FA(){return this.client.api.post("/api/auth/2fa/enable")}async disable2FA(t){return this.client.api.post("/api/auth/2fa/disable",{code:t})}async forgotPassword(t){return this.client.api.post("/api/auth/forgot-password",{email:t})}async resetPassword(t,e){return this.client.api.post("/api/auth/reset-password",{token:t,newPassword:e})}};var P=class{client;data;listeners;subscribed;_unsubscribers;constructor(t){return this.client=t,this.data=new Map,this.listeners=new Set,this.subscribed=new Set,this._unsubscribers=new Map,new Proxy(this,{get:(e,n)=>{if(n in e)return e[n];if(typeof n=="string")return this._getCollection(n)}})}_getCollection(t){if(!this.data.has(t)){let e={_rawItems:[],items:[],loading:!0,error:null,success:!1,_filter:null,_sort:null,where:n=>(e._filter=n,this._applyTransform(e),e),orderBy:(n,s="asc")=>(e._sort={key:n,direction:s},this._applyTransform(e),e),reset:()=>(e._filter=null,e._sort=null,this._applyTransform(e),e)};this.data.set(t,e),this._fetchAndSync(t)}return this.data.get(t)}async _fetchAndSync(t){let e=this.data.get(t);try{let n=await this.client.api.get(`/${t.toLowerCase()}`);if(e._rawItems=Array.isArray(n)?n:n.data||[],e.loading=!1,e.success=!0,e.error=null,this._applyTransform(e),!this.subscribed.has(t)){let s=()=>this.client.unsubscribe(`db:sync/${t.toLowerCase()}`,i),i=a=>{this._handleRemoteUpdate(t,a)};this.client.subscribe(`db:sync/${t.toLowerCase()}`,i),this._unsubscribers.set(t,s),this.subscribed.add(t)}}catch(n){e.loading=!1,e.success=!1,e.error=n.data?.error||n.message||"Fetch failed",this._notify()}}_applyTransform(t){let e=[...t._rawItems];if(t._filter&&(e=e.filter(t._filter)),t._sort){let{key:n,direction:s}=t._sort;e.sort((i,a)=>i[n]===a[n]?0:(i[n]>a[n]?1:-1)*(s==="asc"?1:-1))}t.items=e,this._notify()}_handleRemoteUpdate(t,e){let n=this.data.get(t);if(!n)return;let{type:s,data:i}=e,a=n._rawItems;s==="create"?a=[...a,i]:s==="update"?a=a.map(l=>l.id===i.id||l._id===i._id?{...l,...i}:l):s==="delete"&&(a=a.filter(l=>!(i.id!=null&&l.id===i.id||i._id!=null&&l._id===i._id))),n._rawItems=a,this._applyTransform(n)}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}getSnapshot(t){return this.data.get(t)||{items:[],loading:!1,error:null,success:!1}}_notify(){this.listeners.forEach(t=>t())}destroy(){this._unsubscribers.forEach(t=>{try{t()}catch{}}),this._unsubscribers.clear(),this.subscribed.clear(),this.listeners.clear(),this.data.clear()}};var C=class{host;httpUrl;deviceId;options;socket;storage;accessToken;api;auth;store;handlers;signalHandlers;fileHandlers;_offlineQueue;reconnectAttempts;_reconnectTimer;_attachedListeners;constructor(t="",e="",n={}){!t&&typeof window<"u"&&(t=window.location.host);let s="http:";t.startsWith("https://")?s="https:":t.startsWith("http://")?s="http:":typeof window<"u"&&(s=window.location.protocol),this.host=(t||"localhost").replace(/\/$/,"").replace(/^https?:\/\//,""),this.httpUrl=`${s}//${this.host}`,this.deviceId=e||(typeof crypto<"u"&&typeof crypto.randomUUID=="function"?"web_"+crypto.randomUUID().replace(/-/g,"").slice(0,8):"web_"+Math.random().toString(36).slice(2,10)),this.options={timeout:15e3,chunkSize:65536,maxReconnect:5,autoRefreshToken:!0,debug:!1,methodSpoofing:!1,routerViewport:"main, #viewport, body",routerTransitions:!0,...n},this.socket=null,this.storage=typeof localStorage<"u"?localStorage:{getItem:()=>null,setItem:()=>{},removeItem:()=>{}},this.accessToken=this.storage.getItem("dolphin_token"),this.api=new x(this),this.auth=new $(this),this.store=new P(this),this.handlers=new Map,this.signalHandlers=new Set,this.fileHandlers=new Set,this._offlineQueue=[],this.reconnectAttempts=0,this._reconnectTimer=null,this._attachedListeners=[],typeof window<"u"&&typeof this._initDOMBinding=="function"&&this._initDOMBinding(),typeof this._initOffline=="function"&&this._initOffline(),typeof this._initA11y=="function"&&this._initA11y(),typeof this._initI18n=="function"&&this._initI18n(),typeof this._initDragDrop=="function"&&this._initDragDrop(),typeof this._initCollab=="function"&&this._initCollab()}setToken(t){this.accessToken=t,t?this.storage.setItem("dolphin_token",t):this.storage.removeItem("dolphin_token")}async connect(){return this.socket&&(this.socket.readyState===WebSocket.OPEN||this.socket.readyState===WebSocket.CONNECTING)?Promise.resolve():new Promise((t,e)=>{let s=`${this.httpUrl.startsWith("https")?"wss:":"ws:"}//${this.host}/realtime?deviceId=${this.deviceId}`;console.log(`[Dolphin] Connecting to ${s}...`),this.socket=new WebSocket(s),this.socket.onopen=()=>{console.log(`[Dolphin] Connected as "${this.deviceId}" \u{1F42C}`),this.reconnectAttempts=0,this._flushOfflineQueue(),t()},this.socket.onmessage=i=>this._handleMessage(i.data),this.socket.onclose=()=>{console.warn("[Dolphin] Connection closed"),this._maybeReconnect()},this.socket.onerror=i=>{console.error("[Dolphin] WebSocket error:",i),e(i)}})}disconnect(){this._reconnectTimer!==null&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null),this.socket&&(this.socket.onclose=null,this.socket.close(),this.socket=null),typeof this._collabCleanup=="function"&&this._collabCleanup(),this.cleanupDomListeners()}_handleMessage(t){try{let e=JSON.parse(t);this.options.debug&&console.log("%c\u{1F4E5} [Dolphin WS Incoming]:","color: #eab308; font-weight: bold;",e),e.type&&e.from&&(e.to===this.deviceId||e.to==="all")&&(e.msgId&&e.type!=="ACK"&&this._sendAck(e.from,e.msgId),this.signalHandlers.forEach(n=>n(e))),e.type==="FILE_AVAILABLE"&&this.fileHandlers.forEach(n=>n(e)),e.type==="FILE_CHUNK"&&(this.saveFileProgress(e.fileId,e.chunkIndex),this._dispatch("file:chunk",e),this._dispatch(`file:chunk/${e.fileId}`,e)),e.type==="FILE_UPLOAD_ACK"&&this._dispatch(`file:upload:ack/${e.fileId}`,e),e.type==="PULL_RESPONSE"&&(this._dispatch("pull:response",e.payload,e.topic),this._dispatch(`pull:response/${e.topic}`,e.payload,e.topic)),e.topic&&e.payload!==void 0&&this.handlers.forEach((n,s)=>{this._matchTopic(s,e.topic)&&n.forEach(i=>i(e.payload,e.topic))})}catch{this._dispatch("raw",t)}}_dispatch(t,e,n){let s=this.handlers.get(t);s&&s.forEach(i=>i(e,n||t))}_sendRaw(t){this.options.debug&&console.log("%c\u{1F4E4} [Dolphin WS Outgoing]:","color: #8b5cf6; font-weight: bold;",t);let e=typeof t=="string"?t:JSON.stringify(t);this.socket&&this.socket.readyState===WebSocket.OPEN?this.socket.send(e):this._offlineQueue.length<100&&this._offlineQueue.push(e)}_flushOfflineQueue(){for(;this._offlineQueue.length>0;){let t=this._offlineQueue.shift();this.socket&&this.socket.readyState===WebSocket.OPEN&&this.socket.send(t)}}_sendAck(t,e){this._sendRaw({type:"ACK",from:this.deviceId,to:t,data:{ackId:e},timestamp:Date.now()})}_matchTopic(t,e){if(t===e||t==="#")return!0;let n=t.split("/"),s=e.split("/");if(n.length!==s.length&&!t.includes("#"))return!1;for(let i=0;i<n.length;i++){if(n[i]==="#")return!0;if(n[i]!=="+"&&n[i]!==s[i])return!1}return n.length===s.length}_maybeReconnect(){if(this.reconnectAttempts<this.options.maxReconnect){this.reconnectAttempts++;let t=Math.pow(2,this.reconnectAttempts)*1e3;console.log(`[Dolphin] Reconnecting in ${t/1e3}s (attempt ${this.reconnectAttempts})...`),this._reconnectTimer=setTimeout(()=>{this._reconnectTimer=null,this.connect().catch(()=>{})},t)}else console.error("[Dolphin] Max reconnect attempts reached.")}subscribe(t,e){this.handlers.has(t)||(this.handlers.set(t,new Set),this._sendRaw({type:"sub",topic:t})),this.handlers.get(t).add(e)}unsubscribe(t,e){if(this.handlers.has(t)){let n=this.handlers.get(t);n.delete(e),n.size===0&&(this.handlers.delete(t),this._sendRaw({type:"unsub",topic:t}))}}publish(t,e){this._sendRaw({topic:t,payload:e})}pubPush(t,e){this._sendRaw({type:"pub",topic:t,payload:e})}subPull(t,e=10){this._sendRaw({type:"PULL_REQUEST",topic:t,count:e})}async pubFile(t,e,n="",s){let i;e instanceof Blob?i=await e.arrayBuffer():e instanceof ArrayBuffer?i=e:i=e.buffer||e;let a=new Uint8Array(i),l=this.options.chunkSize,_=Math.ceil(a.length/l);this._sendRaw({type:"FILE_UPLOAD_START",fileId:t,name:n,size:a.length,totalChunks:_,chunkSize:l});for(let v=0;v<_;v++){let k=a.slice(v*l,(v+1)*l),h=this._uint8ToBase64(k);this._sendRaw({type:"FILE_UPLOAD_CHUNK",fileId:t,chunkIndex:v,totalChunks:_,data:h}),s&&s(Math.round((v+1)/_*100)),v%10===0&&await new Promise(d=>setTimeout(d,0))}this._sendRaw({type:"FILE_UPLOAD_DONE",fileId:t})}_uint8ToBase64(t){let e="";for(let n=0;n<t.length;n++)e+=String.fromCharCode(t[n]);return typeof btoa<"u"?btoa(e):Buffer.from(e,"binary").toString("base64")}subFile(t,e=0){this._sendRaw({type:"FILE_REQUEST",fileId:t,startChunk:e})}resumeFile(t){let e=parseInt(this.storage.getItem(`dolphin_file_${t}`)||"-1");this.subFile(t,e+1)}saveFileProgress(t,e){this.storage.setItem(`dolphin_file_${t}`,e.toString())}onSignal(t){this.signalHandlers.add(t)}offSignal(t){this.signalHandlers.delete(t)}onFileAvailable(t){this.fileHandlers.add(t)}offFileAvailable(t){this.fileHandlers.delete(t)}addDomListener(t,e,n){t&&(t.addEventListener(e,n),this._attachedListeners=this._attachedListeners||[],this._attachedListeners.push({target:t,event:e,cb:n}))}cleanupDomListeners(){this._attachedListeners&&(this._attachedListeners.forEach(({target:t,event:e,cb:n})=>{try{t.removeEventListener(e,n)}catch{}}),this._attachedListeners=[])}};function U(A){let t=new Map;function e(h){return h.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function n(h){let d=h.getAttribute("data-rt-template");if(!d)return null;if(typeof document<"u"&&!d.includes("<"))try{let c=document.querySelector(d);if(c)return c.innerHTML}catch{}return d}function s(h,d){if(!h.includes("{#if")&&!h.includes("{#each")){let c=h;for(let r in d){let o=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");c=c.replace(new RegExp(`\\{\\{${o}\\}\\}`,"g"),d[r]!==void 0&&d[r]!==null?d[r]:"")}return c}try{let c=p=>p.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t"),r=`let out = "";
|
|
2
|
-
`,o=0,
|
|
3
|
-
`);let
|
|
4
|
-
`}else if(
|
|
5
|
-
`}else if(
|
|
6
|
-
`}else if(
|
|
7
|
-
`;else if(
|
|
8
|
-
`;else if(
|
|
9
|
-
`,
|
|
10
|
-
`),
|
|
11
|
-
`}else if(
|
|
12
|
-
`),
|
|
1
|
+
var DolphinModule=(()=>{var U=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var Z=Object.getOwnPropertyNames;var tt=Object.prototype.hasOwnProperty;var et=(A,t)=>{for(var e in t)U(A,e,{get:t[e],enumerable:!0})},nt=(A,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Z(t))!tt.call(A,i)&&i!==e&&U(A,i,{get:()=>t[i],enumerable:!(s=G(t,i))||s.enumerable});return A};var st=A=>nt(U({},"__esModule",{value:!0}),A);var rt={};et(rt,{DolphinClient:()=>C});var N=class{client;constructor(t){return this.client=t,this._createProxy([])}_createProxy(t){let e=t.join("/"),s=r=>this.request("GET",e,null,r);s.get=(r,a)=>typeof r=="string"?this.request("GET",r,null,a):this.request("GET",e,null,r),s.post=(r,a,d)=>typeof r=="string"?this.request("POST",r,a,d):this.request("POST",e,r,a),s.put=(r,a,d)=>typeof r=="string"?this.request("PUT",r,a,d):this.request("PUT",e,r,a),s.patch=(r,a,d)=>typeof r=="string"?this.request("PATCH",r,a,d):this.request("PATCH",e,r,a),s.del=(r,a)=>typeof r=="string"?this.request("DELETE",r,null,a):this.request("DELETE",e,null,r),s.request=(r,a,d,E)=>{let S=a?e?`${e}/${a.startsWith("/")?a.slice(1):a}`:a:e;return this.request(r,S,d,E)},s.requestDirect=(r,a,d,E)=>this.requestDirect(r,a,d,E),s._findCSRFToken=()=>this._findCSRFToken(),s._resolveBaseUrl=r=>this._resolveBaseUrl(r),s._normalizeValidationErrors=r=>this._normalizeValidationErrors(r);let i=["get","post","put","patch","del","request","requestDirect","_findCSRFToken","_resolveBaseUrl","_normalizeValidationErrors"];return new Proxy(s,{get:(r,a)=>typeof a=="string"&&!i.includes(a)?this._createProxy([...t,a]):r[a]})}_findCSRFToken(){if(typeof document>"u")return null;let t=["csrf-token","_csrf","xsrf-token","csrf_token"];for(let r of t){let a=document.querySelector(`meta[name="${r}"], meta[content][name$="${r}"]`);if(a){let d=a.getAttribute("content");if(d)return d}}let e=["_csrfToken","_token","_csrf","csrf_token"];for(let r of e){let a=document.querySelector(`input[type="hidden"][name="${r}"]`);if(a&&a.value)return a.value}let s=["csrfToken","XSRF-TOKEN","_csrf","csrf_token"];for(let r of s){let a=document.cookie.match(new RegExp("(^|;\\s*)"+r+"=([^;]*)"));if(a)return decodeURIComponent(a[2])}let i=typeof window<"u"&&window.wpApiSettings?.nonce;return i||null}_resolveBaseUrl(t){if(t.startsWith("http://")||t.startsWith("https://"))return t;let e=this.client.httpUrl;if(typeof document<"u"){let i=document.querySelector("base[href]");if(i){let r=i.getAttribute("href")||"";if(r&&r!=="/"){let a=r.endsWith("/")?r.slice(0,-1):r;e=`${this.client.httpUrl}${a.startsWith("/")?a:"/"+a}`}}else{let r=document.querySelector('meta[name="base-path"]');if(r){let a=r.getAttribute("content")||"";if(a&&a!=="/"){let d=a.endsWith("/")?a.slice(0,-1):a;e=`${this.client.httpUrl}${d.startsWith("/")?d:"/"+d}`}}}}let s=t.startsWith("/")?t:"/"+t;return`${e}${s}`}_normalizeValidationErrors(t){let e={};if(!t||typeof t!="object")return e;let s=t.errors||t.validationErrors||t;if(Array.isArray(s)){for(let i of s)if(i&&typeof i=="object"){let r=i.path||i.param||i.field||i.property,a=i.msg||i.message||i.error;r&&a&&(e[r]=Array.isArray(a)?a[0]:a)}return e}if(typeof s=="object"&&s!==null)for(let i in s){let r=s[i];if(r)if(Array.isArray(r))r.length>0&&(e[i]=String(r[0]));else if(typeof r=="object"){let a=Object.keys(r);if(a.length>0){let d=a[0];e[i]=String(r[d])}}else e[i]=String(r)}return e}async request(t,e,s=null,i={}){if(this.client.offline){let r=this.client.offline.isOnline,a=`${t.toUpperCase()}:${e}`;if(t.toUpperCase()==="GET")if(r)try{let d=await this.requestDirect(t,e,s,i);return await this.client.offline.setCache(a,d),d}catch(d){let E=await this.client.offline.getCache(a);if(E!=null)return E;throw d}else{let d=await this.client.offline.getCache(a);if(d!=null)return d;throw{status:503,data:{error:"Offline, no cache available"}}}else return r?this.requestDirect(t,e,s,i):(await this.client.offline.queueMutation(t,e,s),this.client._dispatch("offline:queued",{method:t,path:e,body:s}),{success:!0,offline:!0,message:"Mutation queued offline"})}return this.requestDirect(t,e,s,i)}async requestDirect(t,e,s=null,i={}){let r=i._isRetry===!0,a=t.toUpperCase(),d=s,S={...!["GET","HEAD"].includes(a)?{"Content-Type":"application/json"}:{},...i.headers||{}};["PUT","PATCH","DELETE"].includes(a)&&(this.client.options.methodSpoofing||i.methodSpoofing)&&(S["X-HTTP-Method-Override"]=a,d instanceof FormData?d.append("_method",a):d&&typeof d=="object"?d={...d,_method:a}:d||(d={_method:a}),a="POST");let k=this._resolveBaseUrl(e);this.client.options.debug&&console.log("%c\u{1F680} [Dolphin API Request]:","color: #3b82f6; font-weight: bold;",t.toUpperCase(),e,d||"");let f=new AbortController,u=setTimeout(()=>f.abort(),this.client.options.timeout);if(this.client.accessToken&&(S.Authorization=`Bearer ${this.client.accessToken}`),["POST","PUT","PATCH","DELETE"].includes(t.toUpperCase())){let n=this._findCSRFToken();n&&(S["X-CSRF-Token"]=n,S["X-XSRF-TOKEN"]=n,S["X-CSRFToken"]=n,S["X-WP-Nonce"]=n,d&&typeof d=="object"&&!d._csrfToken&&!d._token&&!d._csrf&&(d={...d,_csrfToken:n,_token:n,_csrf:n}))}let l={...i};delete l._isRetry,delete l.methodSpoofing;try{let n=await fetch(k,{method:a,headers:S,signal:f.signal,...d?{body:JSON.stringify(d)}:{},...l});if(clearTimeout(u),n.status===401&&!r&&this.client.options.autoRefreshToken&&await this.client.auth._silentRefresh())return this.request(t,e,s,{...i,_isRetry:!0});let c=(n.headers.get("content-type")||"").includes("application/json")?await n.json():await n.text();if(!n.ok)throw{status:n.status,data:c};if(this.client.options.debug&&console.log("%c\u2705 [Dolphin API Success]:","color: #10b981; font-weight: bold;",t.toUpperCase(),e,c),c&&typeof c=="object"&&c.accessToken&&(this.client.setToken(c.accessToken),c.user&&(this.client.auth.user=c.user)),this.client.options.autoBroadcast&&["POST","PUT","PATCH","DELETE"].includes(t.toUpperCase())){let y=e.startsWith("/")?e.substring(1):e;this.client.publish(y,{method:t.toUpperCase(),payload:s,result:c})}return c}catch(n){if(clearTimeout(u),this.client.options.debug&&console.error("%c\u274C [Dolphin API Error]:","color: #ef4444; font-weight: bold;",t.toUpperCase(),e,n),n&&typeof n=="object"&&n.data){let o=this._normalizeValidationErrors(n.data);if(Object.keys(o).length>0)for(let c in o)this.client.publish(`errors/${c}`,o[c])}throw n.name==="AbortError"?{status:408,data:{error:"Request timed out"}}:n}}};var q=class{client;user;_refreshing;constructor(t){this.client=t,this.user=null,this._refreshing=!1}async login(t,e){let s=await this.client.api.post("/api/auth/login",{email:t,password:e});return s.accessToken&&(this.client.setToken(s.accessToken),this.user=s.user||null),s}async register(t){return this.client.api.post("/api/auth/register",t)}async me(){let t=await this.client.api.get("/api/auth/me");return t.success&&(this.user=t.data),t}async logout(){try{await this.client.api.post("/api/auth/logout")}catch{}this.client.setToken(null),this.user=null}async refresh(){return this._silentRefresh()}async _silentRefresh(){if(this._refreshing)return!1;this._refreshing=!0;try{let t=await this.client.api.post("/api/auth/refresh",null,{_isRetry:!0});return t.accessToken?(this.client.setToken(t.accessToken),!0):!1}catch{return this.client.setToken(null),!1}finally{this._refreshing=!1}}async verify2FA(t,e){let s={code:t,email:e||this.user?.email},i=await this.client.api.post("/api/auth/2fa/verify",s);return i.accessToken&&(this.client.setToken(i.accessToken),i.user&&(this.user=i.user)),i}async enable2FA(){return this.client.api.post("/api/auth/2fa/enable")}async disable2FA(t){return this.client.api.post("/api/auth/2fa/disable",{code:t})}async forgotPassword(t){return this.client.api.post("/api/auth/forgot-password",{email:t})}async resetPassword(t,e){return this.client.api.post("/api/auth/reset-password",{token:t,newPassword:e})}};var O=class{client;data;listeners;subscribed;_unsubscribers;constructor(t){return this.client=t,this.data=new Map,this.listeners=new Set,this.subscribed=new Set,this._unsubscribers=new Map,new Proxy(this,{get:(e,s)=>{if(s in e)return e[s];if(typeof s=="string")return this._getCollection(s)}})}_getCollection(t){if(!this.data.has(t)){let e={_rawItems:[],items:[],loading:!0,error:null,success:!1,_filter:null,_sort:null,where:s=>(e._filter=s,this._applyTransform(e),e),orderBy:(s,i="asc")=>(e._sort={key:s,direction:i},this._applyTransform(e),e),reset:()=>(e._filter=null,e._sort=null,this._applyTransform(e),e)};this.data.set(t,e),this._fetchAndSync(t)}return this.data.get(t)}async _fetchAndSync(t){let e=this.data.get(t);try{let s=await this.client.api.get(`/${t.toLowerCase()}`);if(e._rawItems=Array.isArray(s)?s:s.data||[],e.loading=!1,e.success=!0,e.error=null,this._applyTransform(e),!this.subscribed.has(t)){let i=()=>this.client.unsubscribe(`db:sync/${t.toLowerCase()}`,r),r=a=>{this._handleRemoteUpdate(t,a)};this.client.subscribe(`db:sync/${t.toLowerCase()}`,r),this._unsubscribers.set(t,i),this.subscribed.add(t)}}catch(s){e.loading=!1,e.success=!1,e.error=s.data?.error||s.message||"Fetch failed",this._notify()}}_applyTransform(t){let e=[...t._rawItems];if(t._filter&&(e=e.filter(t._filter)),t._sort){let{key:s,direction:i}=t._sort;e.sort((r,a)=>r[s]===a[s]?0:(r[s]>a[s]?1:-1)*(i==="asc"?1:-1))}t.items=e,this._notify()}_handleRemoteUpdate(t,e){let s=this.data.get(t);if(!s)return;let{type:i,data:r}=e,a=s._rawItems;i==="create"?a=[...a,r]:i==="update"?a=a.map(d=>d.id===r.id||d._id===r._id?{...d,...r}:d):i==="delete"&&(a=a.filter(d=>!(r.id!=null&&d.id===r.id||r._id!=null&&d._id===r._id))),s._rawItems=a,this._applyTransform(s)}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}getSnapshot(t){return this.data.get(t)||{items:[],loading:!1,error:null,success:!1}}_notify(){this.listeners.forEach(t=>t())}destroy(){this._unsubscribers.forEach(t=>{try{t()}catch{}}),this._unsubscribers.clear(),this.subscribed.clear(),this.listeners.clear(),this.data.clear()}};var C=class{host;httpUrl;deviceId;options;socket;storage;accessToken;api;auth;store;handlers;signalHandlers;fileHandlers;_offlineQueue;reconnectAttempts;_reconnectTimer;_attachedListeners;constructor(t="",e="",s={}){!t&&typeof window<"u"&&(t=window.location.host);let i="http:";t.startsWith("https://")?i="https:":t.startsWith("http://")?i="http:":typeof window<"u"&&(i=window.location.protocol),this.host=(t||"localhost").replace(/\/$/,"").replace(/^https?:\/\//,""),this.httpUrl=`${i}//${this.host}`,this.deviceId=e||(typeof crypto<"u"&&typeof crypto.randomUUID=="function"?"web_"+crypto.randomUUID().replace(/-/g,"").slice(0,8):"web_"+Math.random().toString(36).slice(2,10)),this.options={timeout:15e3,chunkSize:65536,maxReconnect:5,autoRefreshToken:!0,debug:!1,methodSpoofing:!1,routerViewport:"main, #viewport, body",routerTransitions:!0,...s},this.socket=null,this.storage=typeof localStorage<"u"?localStorage:{getItem:()=>null,setItem:()=>{},removeItem:()=>{}},this.accessToken=this.storage.getItem("dolphin_token"),this.api=new N(this),this.auth=new q(this),this.store=new O(this),this.handlers=new Map,this.signalHandlers=new Set,this.fileHandlers=new Set,this._offlineQueue=[],this.reconnectAttempts=0,this._reconnectTimer=null,this._attachedListeners=[],typeof window<"u"&&typeof this._initDOMBinding=="function"&&this._initDOMBinding(),typeof this._initOffline=="function"&&this._initOffline(),typeof this._initA11y=="function"&&this._initA11y(),typeof this._initI18n=="function"&&this._initI18n(),typeof this._initDragDrop=="function"&&this._initDragDrop(),typeof this._initCollab=="function"&&this._initCollab()}setToken(t){this.accessToken=t,t?this.storage.setItem("dolphin_token",t):this.storage.removeItem("dolphin_token")}async connect(){return this.socket&&(this.socket.readyState===WebSocket.OPEN||this.socket.readyState===WebSocket.CONNECTING)?Promise.resolve():new Promise((t,e)=>{let i=`${this.httpUrl.startsWith("https")?"wss:":"ws:"}//${this.host}/realtime?deviceId=${this.deviceId}`;console.log(`[Dolphin] Connecting to ${i}...`),this.socket=new WebSocket(i),this.socket.onopen=()=>{console.log(`[Dolphin] Connected as "${this.deviceId}" \u{1F42C}`),this.reconnectAttempts=0,this._flushOfflineQueue(),t()},this.socket.onmessage=r=>this._handleMessage(r.data),this.socket.onclose=()=>{console.warn("[Dolphin] Connection closed"),this._maybeReconnect()},this.socket.onerror=r=>{console.error("[Dolphin] WebSocket error:",r),e(r)}})}disconnect(){this._reconnectTimer!==null&&(clearTimeout(this._reconnectTimer),this._reconnectTimer=null),this.socket&&(this.socket.onclose=null,this.socket.close(),this.socket=null),typeof this._collabCleanup=="function"&&this._collabCleanup(),this.cleanupDomListeners()}_handleMessage(t){try{let e=JSON.parse(t);this.options.debug&&console.log("%c\u{1F4E5} [Dolphin WS Incoming]:","color: #eab308; font-weight: bold;",e),e.type&&e.from&&(e.to===this.deviceId||e.to==="all")&&(e.msgId&&e.type!=="ACK"&&this._sendAck(e.from,e.msgId),this.signalHandlers.forEach(s=>s(e))),e.type==="FILE_AVAILABLE"&&this.fileHandlers.forEach(s=>s(e)),e.type==="FILE_CHUNK"&&(this.saveFileProgress(e.fileId,e.chunkIndex),this._dispatch("file:chunk",e),this._dispatch(`file:chunk/${e.fileId}`,e)),e.type==="FILE_UPLOAD_ACK"&&this._dispatch(`file:upload:ack/${e.fileId}`,e),e.type==="PULL_RESPONSE"&&(this._dispatch("pull:response",e.payload,e.topic),this._dispatch(`pull:response/${e.topic}`,e.payload,e.topic)),e.topic&&e.payload!==void 0&&this.handlers.forEach((s,i)=>{this._matchTopic(i,e.topic)&&s.forEach(r=>r(e.payload,e.topic))})}catch{this._dispatch("raw",t)}}_dispatch(t,e,s){let i=this.handlers.get(t);i&&i.forEach(r=>r(e,s||t))}_sendRaw(t){this.options.debug&&console.log("%c\u{1F4E4} [Dolphin WS Outgoing]:","color: #8b5cf6; font-weight: bold;",t);let e=typeof t=="string"?t:JSON.stringify(t);this.socket&&this.socket.readyState===WebSocket.OPEN?this.socket.send(e):this._offlineQueue.length<100&&this._offlineQueue.push(e)}_flushOfflineQueue(){for(;this._offlineQueue.length>0;){let t=this._offlineQueue.shift();this.socket&&this.socket.readyState===WebSocket.OPEN&&this.socket.send(t)}}_sendAck(t,e){this._sendRaw({type:"ACK",from:this.deviceId,to:t,data:{ackId:e},timestamp:Date.now()})}_matchTopic(t,e){if(t===e||t==="#")return!0;let s=t.split("/"),i=e.split("/");if(s.length!==i.length&&!t.includes("#"))return!1;for(let r=0;r<s.length;r++){if(s[r]==="#")return!0;if(s[r]!=="+"&&s[r]!==i[r])return!1}return s.length===i.length}_maybeReconnect(){if(this.reconnectAttempts<this.options.maxReconnect){this.reconnectAttempts++;let t=Math.pow(2,this.reconnectAttempts)*1e3;console.log(`[Dolphin] Reconnecting in ${t/1e3}s (attempt ${this.reconnectAttempts})...`),this._reconnectTimer=setTimeout(()=>{this._reconnectTimer=null,this.connect().catch(()=>{})},t)}else console.error("[Dolphin] Max reconnect attempts reached.")}subscribe(t,e){this.handlers.has(t)||(this.handlers.set(t,new Set),this._sendRaw({type:"sub",topic:t})),this.handlers.get(t).add(e)}unsubscribe(t,e){if(this.handlers.has(t)){let s=this.handlers.get(t);s.delete(e),s.size===0&&(this.handlers.delete(t),this._sendRaw({type:"unsub",topic:t}))}}publish(t,e){this._sendRaw({topic:t,payload:e})}pubPush(t,e){this._sendRaw({type:"pub",topic:t,payload:e})}subPull(t,e=10){this._sendRaw({type:"PULL_REQUEST",topic:t,count:e})}async pubFile(t,e,s="",i){let r;e instanceof Blob?r=await e.arrayBuffer():e instanceof ArrayBuffer?r=e:r=e.buffer||e;let a=new Uint8Array(r),d=this.options.chunkSize,E=Math.ceil(a.length/d);this._sendRaw({type:"FILE_UPLOAD_START",fileId:t,name:s,size:a.length,totalChunks:E,chunkSize:d});for(let S=0;S<E;S++){let k=a.slice(S*d,(S+1)*d),f=this._uint8ToBase64(k);this._sendRaw({type:"FILE_UPLOAD_CHUNK",fileId:t,chunkIndex:S,totalChunks:E,data:f}),i&&i(Math.round((S+1)/E*100)),S%10===0&&await new Promise(u=>setTimeout(u,0))}this._sendRaw({type:"FILE_UPLOAD_DONE",fileId:t})}_uint8ToBase64(t){let e="";for(let s=0;s<t.length;s++)e+=String.fromCharCode(t[s]);return typeof btoa<"u"?btoa(e):Buffer.from(e,"binary").toString("base64")}subFile(t,e=0){this._sendRaw({type:"FILE_REQUEST",fileId:t,startChunk:e})}resumeFile(t){let e=parseInt(this.storage.getItem(`dolphin_file_${t}`)||"-1");this.subFile(t,e+1)}saveFileProgress(t,e){this.storage.setItem(`dolphin_file_${t}`,e.toString())}onSignal(t){this.signalHandlers.add(t)}offSignal(t){this.signalHandlers.delete(t)}onFileAvailable(t){this.fileHandlers.add(t)}offFileAvailable(t){this.fileHandlers.delete(t)}addDomListener(t,e,s){t&&(t.addEventListener(e,s),this._attachedListeners=this._attachedListeners||[],this._attachedListeners.push({target:t,event:e,cb:s}))}cleanupDomListeners(){this._attachedListeners&&(this._attachedListeners.forEach(({target:t,event:e,cb:s})=>{try{t.removeEventListener(e,s)}catch{}}),this._attachedListeners=[])}};function B(A){let t=new Map;function e(f){return f.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s(f){let u=f.getAttribute("data-rt-template");if(!u)return null;if(typeof document<"u"&&!u.includes("<"))try{let l=document.querySelector(u);if(l)return l.innerHTML}catch{}return u}function i(f,u){if(!f.includes("{#if")&&!f.includes("{#each")){let l=f;for(let n in u){let o=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");l=l.replace(new RegExp(`\\{\\{${o}\\}\\}`,"g"),u[n]!==void 0&&u[n]!==null?u[n]:"")}return l}try{let l=p=>p.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t"),n=`let out = "";
|
|
2
|
+
`,o=0,c=/(\{\{([\s\S]*?)\}\}|\{#if\s+([\s\S]*?)\}|\{:else\s+if\s+([\s\S]*?)\}|\{:else\}|\{\/if\}|\{#each\s+([\s\S]*?)\s+as\s+([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\s*,\s*([a-zA-Z_$][a-zA-Z0-9_$]*))?\}|\{\/each\}|\{([^{}]+?)\})/g,y=[],h;for(;(h=c.exec(f))!==null;){let p=f.slice(o,h.index);p&&(n+=`out += "${l(p)}";
|
|
3
|
+
`);let b=h[0];if(b.startsWith("{{")){let T=h[2];n+=`out += (${T} !== undefined && ${T} !== null ? ${T} : "");
|
|
4
|
+
`}else if(b.startsWith("{#if")){let T=h[3];n+=`if (${T}) {
|
|
5
|
+
`}else if(b.startsWith("{:else if")){let T=h[4];n+=`} else if (${T}) {
|
|
6
|
+
`}else if(b.startsWith("{:else}"))n+=`} else {
|
|
7
|
+
`;else if(b.startsWith("{/if}"))n+=`}
|
|
8
|
+
`;else if(b.startsWith("{#each")){let T=h[5],x=h[6],v=h[7];y.push({indexVar:v}),n+=`if (typeof ${T} !== "undefined" && ${T} !== null && Array.isArray(${T})) {
|
|
9
|
+
`,v&&(n+=` let ${v} = 0;
|
|
10
|
+
`),n+=` for (let ${x} of ${T}) {
|
|
11
|
+
`}else if(b.startsWith("{/each}")){let T=y.pop();T&&T.indexVar&&(n+=` ${T.indexVar}++;
|
|
12
|
+
`),n+=` }
|
|
13
13
|
}
|
|
14
|
-
`}else if(
|
|
15
|
-
`)}o=
|
|
16
|
-
`),
|
|
14
|
+
`}else if(b.startsWith("{")){let T=h[8];T&&(n+=`out += (${T} !== undefined && ${T} !== null ? ${T} : "");
|
|
15
|
+
`)}o=c.lastIndex}let m=f.slice(o);m&&(n+=`out += "${l(m)}";
|
|
16
|
+
`),n+=`return out;
|
|
17
17
|
`;let w=`
|
|
18
18
|
with (context) {
|
|
19
19
|
try {
|
|
20
|
-
${
|
|
20
|
+
${n}
|
|
21
21
|
} catch (innerErr) {
|
|
22
22
|
console.warn('[Dolphin Template Eval Warning]:', innerErr);
|
|
23
23
|
return '';
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
`,S=d;return typeof Proxy<"u"&&d!==null&&typeof d=="object"&&(S=new Proxy(d,{has(p,y){return typeof y!="symbol"},get(p,y){if(y!==Symbol.unscopables){if(y in p)return p[y];if(typeof globalThis<"u"&&y in globalThis)return globalThis[y];if(typeof window<"u"&&y in window)return window[y]}}})),new Function("context",w)(S)}catch(c){console.error("[Dolphin Template Compiler Error]:",c);let r=h;for(let o in d){let u=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");r=r.replace(new RegExp(`\\{\\{${u}\\}\\}`,"g"),d[o]!==void 0&&d[o]!==null?d[o]:"")}return r}}function i(h){if(typeof document>"u")return h;try{let r=new DOMParser().parseFromString(h,"text/html").body,o=u=>{let b=u.tagName.toLowerCase();if(["script","iframe","object","embed","link","style","meta","applet","svg"].includes(b)){u.parentNode?.removeChild(u);return}let f=u.attributes;for(let m=f.length-1;m>=0;m--){let w=f[m].name.toLowerCase(),S=f[m].value.toLowerCase();(w.startsWith("on")||["src","href","data"].includes(w)&&(S.includes("javascript:")||S.includes("data:text/html")))&&u.removeAttribute(f[m].name)}Array.from(u.children).forEach(o)};return Array.from(r.children).forEach(o),r.innerHTML}catch{return h}}function a(h,d){if(h.nodeType!==d.nodeType){h.parentNode?.replaceChild(d.cloneNode(!0),h);return}if(h.nodeType===Node.TEXT_NODE){h.textContent!==d.textContent&&(h.textContent=d.textContent);return}if(h.nodeType===Node.ELEMENT_NODE){let c=h,r=d;if(c.tagName!==r.tagName){c.parentNode?.replaceChild(r.cloneNode(!0),c);return}let o=c.attributes,u=r.attributes;for(let g=o.length-1;g>=0;g--){let p=o[g].name;r.hasAttribute(p)||c.removeAttribute(p)}for(let g=0;g<u.length;g++){let p=u[g].name,y=u[g].value;c.getAttribute(p)!==y&&c.setAttribute(p,y)}c.tagName==="INPUT"||c.tagName==="TEXTAREA"?(c.value!==r.value&&(c.value=r.value),c.checked!==r.checked&&(c.checked=r.checked)):c.tagName==="SELECT"&&c.value!==r.value&&(c.value=r.value);let b=Array.from(c.childNodes),f=Array.from(r.childNodes),m=b.length,w=f.length,S=Math.max(m,w);for(let g=0;g<S;g++)g>=m?c.appendChild(f[g].cloneNode(!0)):g>=w?c.removeChild(b[g]):a(b[g],f[g])}}function l(h,d){if(typeof document>"u")return;let c=document.createElement(h.tagName);c.innerHTML=d;let r=Array.from(h.childNodes),o=Array.from(c.childNodes),u=r.length,b=o.length,f=Math.max(u,b);for(let m=0;m<f;m++)m>=u?h.appendChild(o[m].cloneNode(!0)):m>=b?h.removeChild(r[m]):a(r[m],o[m])}let _=new Map,v=!1;function k(h,d){_.set(h,d),v||(v=!0,(typeof requestAnimationFrame<"u"?requestAnimationFrame:r=>setTimeout(r,0))(()=>{_.forEach((r,o)=>{o.isConnected!==!1&&l(o,r)}),_.clear(),v=!1}))}A.setStoreState=function(h,d,c){this.uiStores=this.uiStores||new Map,this.uiStores.has(h)||this.uiStores.set(h,{});let r=this.uiStores.get(h);r[d]=c,this.options.debug&&console.log("%c\u{1F4BE} [Dolphin Store Update]:","color: #ec4899; font-weight: bold;",`${h}.${d}`,"=",c),typeof document<"u"&&document.querySelectorAll(`[data-store-read="${h}.${d}"]`).forEach(u=>{u.tagName==="INPUT"||u.tagName==="TEXTAREA"?u.type==="checkbox"?u.checked=!!c:u.value=c??"":u.textContent=c??""}),this.publish(`store/${h}`,r),typeof this._updateDOM=="function"&&this._updateDOM(`store/${h}`,r)},A.getStoreState=function(h,d){this.uiStores=this.uiStores||new Map;let c=this.uiStores.get(h);return c?c[d]:void 0},A._scanStoreBinds=function(){if(typeof document>"u")return;document.querySelectorAll("[data-store-write]").forEach(c=>{let r=c.getAttribute("data-store-write");if(r){let o=r.split(".");if(o.length===2){let u=o[0],b=o[1],f=c.type==="checkbox"?c.checked:c.value;this.uiStores=this.uiStores||new Map,this.uiStores.has(u)||this.uiStores.set(u,{});let m=this.uiStores.get(u);m[b]===void 0&&(m[b]=f)}}}),document.querySelectorAll("[data-store-read]").forEach(c=>{let r=c.getAttribute("data-store-read");if(r){let o=r.split(".");if(o.length===2){let u=o[0],b=o[1],f=this.getStoreState(u,b);f!=null&&(c.tagName==="INPUT"||c.tagName==="TEXTAREA"?c.type==="checkbox"?c.checked=!!f:c.value=f:c.textContent=f)}}})},A.getClosestContext=function(h,d){let c=h;for(;c;){if(c._rtContext){let r=c._rtContext;return d?r[d]:r}c=c.parentElement}return null},A._executeStoreAction=function(h,d){this.uiStores=this.uiStores||new Map;let c=new Proxy({},{has:(r,o)=>!0,get:(r,o)=>{if(typeof o=="string")return new Proxy({},{get:(u,b)=>{if(typeof b=="string")return this.getStoreState(o,b)},set:(u,b,f)=>typeof b=="string"?(this.setStoreState(o,b,f),!0):!1})}});try{new Function("ctx",`with(ctx) { ${h} }`)(c)}catch(r){console.error("%c[Dolphin Store Action Error]:","color: #ef4444; font-weight: bold;",r),d&&console.error("%cFailed Element:","color: #f97316; font-weight: bold;",d),console.error("%cFailed Expression:","color: #3b82f6; font-style: italic;",h)}},A._initDOMBinding=function(){if(this._domInitialized)return;this._domInitialized=!0;let h=["input","change","keyup","paste","blur"],d=new WeakMap;h.forEach(r=>{this.addDomListener(document,r,o=>{if(!o.target||!o.target.getAttribute)return;let u=o.target.getAttribute("data-store-write");if(u){let w=u.split(".");if(w.length===2){let S=w[0],g=w[1],p=o.target.type==="checkbox"?o.target.checked:o.target.value;this.setStoreState(S,g,p)}}let b=o.target.getAttribute("data-rt-validate"),f=o.target.name;if(b&&f&&typeof this.validateField=="function"){let w=o.target.closest("form"),S=w?Object.fromEntries(new FormData(w).entries()):{},g=this.validateField(o.target.value,b,S);g?(o.target.classList.add("invalid"),this.publish(`errors/${f}`,g)):(o.target.classList.remove("invalid"),this.publish(`errors/${f}`,""))}let m=o.target.getAttribute("data-rt-push");if(m){let w=o.target.getAttribute("data-rt-debounce"),S=w?parseInt(w,10):0,g=()=>{let p={name:o.target.name,value:o.target.value};this.pubPush(m,p)};if(S>0){d.has(o.target)&&clearTimeout(d.get(o.target));let p=setTimeout(g,S);d.set(o.target,p)}else g()}})}),this.addDomListener(document,"submit",async r=>{if(!r.target||!r.target.getAttribute)return;let o=r.target.getAttribute("data-rt-submit"),u=r.target.getAttribute("data-api-submit");if(o||u){r.target.querySelectorAll("[name]").forEach(p=>{let y=p.name;y&&(this.publish(`errors/${y}`,""),p.classList.remove("invalid"))});let f=r.target.querySelectorAll("[data-rt-validate]"),m=!0;if(f.length>0&&typeof this.validateField=="function"){let p=Object.fromEntries(new FormData(r.target).entries());f.forEach(y=>{let T=y.getAttribute("data-rt-validate"),D=y.name;if(T&&D){let E=this.validateField(y.value,T,p);E&&(m=!1,y.classList.add("invalid"),this.publish(`errors/${D}`,E))}})}if(!m){r.preventDefault(),r.stopPropagation();return}r.preventDefault();let w=this.getClosestContext(r.target)||{},S=new FormData(r.target),g=Object.fromEntries(S.entries());if(o){let p=o;for(let y in w){let T=e(y);p=p.replace(new RegExp(`\\{\\{${T}\\}\\}`,"g"),w[y]!==void 0&&w[y]!==null?w[y]:"")}this.publish(p,g)}else if(u){let p=u;for(let E in w){let L=e(E);p=p.replace(new RegExp(`\\{\\{${L}\\}\\}`,"g"),w[E]!==void 0&&w[E]!==null?w[E]:"")}let y=p.trim().split(" "),T=y.length>1?y[0].toUpperCase():"POST",D=y.length>1?y[1]:y[0];g._method&&(T=String(g._method).toUpperCase());try{let E=await this.api.request(T,D,g),L=r.target.getAttribute("data-api-result");L&&this._updateDOM(L,E);let M=r.target.getAttribute("data-api-redirect");M&&(window.location.href=M),r.target.hasAttribute("data-api-reload")&&window.location.reload()}catch(E){console.error("[Dolphin] API Submit Error:",E)}}}}),["click","change","submit","input","keydown","keyup","dblclick","focus","blur","mouseenter","mouseleave"].forEach(r=>{this.addDomListener(document,r,async o=>{if(!o.target||!o.target.closest)return;let u=o.target.closest(`[data-rt-${r}]`),b=o.target.closest(`[data-api-${r}]`);if(u){r==="submit"&&o.preventDefault();let m=u.getAttribute(`data-rt-${r}`),w=u.getAttribute("data-rt-payload"),S=this.getClosestContext(u)||{},g={};if(w){let p=w;for(let y in S){let T=e(y);p=p.replace(new RegExp(`\\{\\{${T}\\}\\}`,"g"),S[y]!==void 0&&S[y]!==null?S[y]:"")}try{g=JSON.parse(p)}catch{g={}}}this.publish(m,g)}if(b){r==="submit"&&o.preventDefault();let m=b.getAttribute(`data-api-${r}`),w=b.getAttribute("data-api-payload"),S=this.getClosestContext(b)||{},g=m.trim().split(" "),p=g.length>1?g[0].toUpperCase():"POST",y=g.length>1?g[1]:g[0],T=null;if(w){let D=w;for(let E in S){let L=e(E);D=D.replace(new RegExp(`\\{\\{${L}\\}\\}`,"g"),S[E]!==void 0&&S[E]!==null?S[E]:"")}try{T=JSON.parse(D)}catch{T=null}}try{let D=await this.api.request(p,y,T),E=b.getAttribute("data-api-result");E&&this._updateDOM(E,D);let L=b.getAttribute("data-api-redirect");L&&(window.location.href=L),b.hasAttribute("data-api-reload")&&window.location.reload()}catch(D){console.error(`[Dolphin] API ${r} Error:`,D)}}let f=o.target.closest(`[data-store-${r}]`);if(f){r==="submit"&&o.preventDefault();let m=f.getAttribute(`data-store-${r}`);m&&this._executeStoreAction(m,f)}})}),this.subscribe("#",(r,o)=>{this._updateDOM(o,r)}),this._scanAndFetchAPIBinds(),this._scanStoreBinds(),this._resolveImports(),this._initSPARouter()},A._scanAndFetchAPIBinds=async function(){if(typeof document>"u")return;let h=document.querySelectorAll("[data-api-get]");for(let d of Array.from(h)){let c=d.getAttribute("data-api-get");if(c&&!(typeof d.hasAttribute=="function"&&d.hasAttribute("data-api-initialized"))){typeof d.setAttribute=="function"&&d.setAttribute("data-api-initialized","true");try{let r=await this.api.get(c),o=d.getAttribute("data-api-store");if(o){let b=o.split(".");b.length===2&&this.setStoreState(b[0],b[1],r)}let u=d.getAttribute("data-rt-bind");if(u&&!o)this._updateDOM(u,r);else if(!o){let b=n(d);if(b&&typeof r=="object"&&r!==null){let f=this._applyDeclarativeDirectives(d,r);if(Array.isArray(f)){let m="";for(let w of f)m+=s(b,w);k(d,m)}else k(d,s(b,f))}else if(d.tagName==="INPUT"||d.tagName==="TEXTAREA")d.value=typeof r=="object"?r.value!==void 0?r.value:"":r;else{let f=typeof r=="object"?r.html||r.text||JSON.stringify(r):String(r);d.innerHTML=i(f)}}}catch(r){console.error("[Dolphin] API Get Error:",r)}}}},A._applyDeclarativeDirectives=function(h,d){let c=d;if(typeof d=="object"&&d!==null){let r=o=>{let u=[...o],b=h.getAttribute("data-rt-filter");if(b){let w=b.split("==");if(w.length===2){let S=w[0].trim(),g=w[1].trim(),p,y=g.split(".");y.length===2?p=this.getStoreState(y[0],y[1]):p=d[g]!==void 0?d[g]:this.getStoreState("app",g),p!=null&&p!==""&&(u=u.filter(T=>T[S]===p))}}let f=h.getAttribute("data-rt-search");if(f){let w=f.split("==");if(w.length===2){let S=w[0].trim(),g=w[1].trim(),p,y=g.split(".");if(y.length===2?p=this.getStoreState(y[0],y[1]):p=d[g]!==void 0?d[g]:this.getStoreState("app",g),p!=null&&p!==""){let T=String(p).toLowerCase();u=u.filter(D=>{let E=D[S];return E!=null&&String(E).toLowerCase().includes(T)})}}}let m=h.getAttribute("data-rt-sort");if(m){let w,S=m.split(".");if(S.length===2?w=this.getStoreState(S[0],S[1]):w=d[m]!==void 0?d[m]:this.getStoreState("app",m),w&&w!=="")if(w==="popular")u.sort((g,p)=>{let y=g.rating?.rate||g.rate||0;return(p.rating?.rate||p.rate||0)-y});else{let g="",p="asc";w.endsWith("-low")||w.endsWith("-asc")?(g=w.replace("-low","").replace("-asc",""),p="asc"):(w.endsWith("-high")||w.endsWith("-desc"))&&(g=w.replace("-high","").replace("-desc",""),p="desc"),g&&u.sort((y,T)=>{let D=(J,Q)=>Q.split(".").reduce((q,G)=>q&&q[G],J),E=D(y,g),L=D(T,g);if(E===void 0&&(E=y[g]),L===void 0&&(L=T[g]),typeof E=="string"&&typeof L=="string")return p==="asc"?E.localeCompare(L):L.localeCompare(E);let M=Number(E),I=Number(L);return!isNaN(M)&&!isNaN(I)?p==="asc"?M-I:I-M:0})}}return u};if(Array.isArray(d))c=r(d);else{let o="";for(let u in d)if(Array.isArray(d[u])){o=u;break}if(o){let u=r(d[o]);c={...d,[o]:u}}}}return c},A._updateDOM=function(h,d){if(typeof document>"u")return;document.querySelectorAll(`[data-rt-bind="${h}"]`).forEach(r=>{let o=this._applyDeclarativeDirectives(r,d);if(r.getAttribute("data-rt-type")==="context"&&typeof o=="object"&&o!==null){r._rtContext=o;let b=f=>{if(f.hasAttribute("data-rt-text")){let m=f.getAttribute("data-rt-text");m&&o[m]!==void 0&&o[m]!==null&&(f.textContent=o[m])}if(f.hasAttribute("data-rt-html")){let m=f.getAttribute("data-rt-html");m&&o[m]!==void 0&&o[m]!==null&&(f.innerHTML=i(o[m]))}if(f.hasAttribute("data-rt-attr")){let m=f.getAttribute("data-rt-attr");m&&m.split(",").forEach(w=>{let S=w.split(":");if(S.length===2){let g=S[0].trim(),p=S[1].trim();g&&p&&o[p]!==void 0&&o[p]!==null&&f.setAttribute(g,o[p])}})}if(f.hasAttribute("data-rt-class")){let m=f.getAttribute("data-rt-class");m&&m.split(",").forEach(w=>{let S=w.split(":");if(S.length===2){let g=S[0].trim(),p=S[1].trim(),y=g.split(/\s+/).filter(Boolean);o[p]?y.forEach(T=>f.classList.add(T)):y.forEach(T=>f.classList.remove(T))}})}if(f.hasAttribute("data-rt-if")){let m=f.getAttribute("data-rt-if");m&&(o[m]?f.style.display="":f.style.display="none")}if(f.hasAttribute("data-rt-hide")){let m=f.getAttribute("data-rt-hide");m&&(o[m]?f.style.display="none":f.style.display="")}};b(r),r.querySelectorAll("[data-rt-text], [data-rt-html], [data-rt-attr], [data-rt-class], [data-rt-if], [data-rt-hide]").forEach(b);return}let u=n(r);if(u&&typeof o=="object"&&o!==null){if(Array.isArray(o)){let b="";for(let f of o)b+=s(u,f);k(r,b)}else k(r,s(u,o));return}if(r.tagName==="INPUT"||r.tagName==="TEXTAREA")r.value=typeof o=="object"?o.value!==void 0?o.value:"":o;else if(u)r.innerHTML=typeof o=="object"?o.html||o.text||JSON.stringify(o):String(o);else{let b=typeof o=="object"?o.html||o.text||JSON.stringify(o):String(o);r.innerHTML=i(b)}})},A._resolveImports=async function(h){if(typeof document>"u")return;let d=h||document.body||document;if(!d||typeof d.querySelectorAll!="function")return;let c=d.querySelectorAll("[data-import]");if(c.length===0)return;let r=async(u,b)=>{let f=u.getAttribute("data-import");if(!f)return;if(b.has(f)){console.warn(`[Dolphin Component Warning]: Circular import detected for "${f}". Skipping resolving.`),u.innerHTML=`<span style="color:red;font-weight:bold;">Circular import: ${f}</span>`;return}b.add(f);let m=t.get(f);m||(m=fetch(f).then(g=>{if(!g.ok)throw new Error(`HTTP ${g.status}`);return g.text()}),m.catch(()=>t.delete(f)),t.set(f,m));let w="";try{w=await m}catch(g){console.error(`[Dolphin Component Error]: Failed to fetch component "${f}":`,g),w=`<span style="color:red;font-weight:bold;">Failed to import ${f}</span>`}u.innerHTML=i(w),u.removeAttribute("data-import");let S=u.querySelectorAll("[data-import]");if(S.length>0){let g=Array.from(S).map(p=>r(p,new Set(b)));await Promise.all(g)}this._scanStoreBinds(),this._scanAndFetchAPIBinds()},o=Array.from(c).map(u=>r(u,new Set));await Promise.all(o)},A._initSPARouter=function(){if(typeof window>"u"||typeof document>"u"||this._routerInitialized)return;this._routerInitialized=!0;let h=null,d=()=>{let o=(this.options.routerViewport||"main, #viewport, body").split(",").map(u=>u.trim());for(let u of o){let b=document.querySelector(u);if(b)return b}return document.body},c=async(r,o=!0)=>{try{this.options.debug&&console.log(`%c\u{1F6E3}\uFE0F [Dolphin Router]: Navigating to ${r}...`,"color: #3b82f6; font-weight: bold;"),h&&h.abort(),h=new AbortController;let u=h.signal,b=d();this.options.routerTransitions&&b&&(b.classList.add("dolphin-fade-out"),await new Promise(y=>setTimeout(y,150)));let f=await fetch(r,{signal:u});if(!f.ok)throw new Error(`HTTP ${f.status}`);let m=await f.text();h=null;let S=new DOMParser().parseFromString(m,"text/html");S.title&&(document.title=S.title);let g=S.querySelector(this.options.routerViewport||"main, #viewport, body"),p=d();g&&p?(p.innerHTML=g.innerHTML,Array.from(g.attributes).forEach(y=>{p.setAttribute(y.name,y.value)})):p&&(p.innerHTML=S.body.innerHTML),o&&window.history.pushState({dolphinSpa:!0,url:r},"",r),this.options.routerTransitions&&p&&(p.classList.remove("dolphin-fade-out"),p.classList.add("dolphin-fade-in"),setTimeout(()=>p.classList.remove("dolphin-fade-in"),300)),await this._resolveImports(p),this._scanStoreBinds(),this._scanAndFetchAPIBinds()}catch(u){if(u&&u.name==="AbortError")return;console.error("[Dolphin Router Error]: Failed to route page:",u),window.location.href=r}};if(this.addDomListener(document,"click",r=>{let o=r.target.closest("a");if(!o||!o.hasAttribute("data-spa")&&o.getAttribute("data-spa")!=="true")return;let u=o.getAttribute("href");!u||u.startsWith("#")||u.startsWith("javascript:")||u.startsWith("mailto:")||u.startsWith("tel:")||new URL(u,window.location.href).origin!==window.location.origin||(r.preventDefault(),c(u))}),this.addDomListener(window,"popstate",r=>{r.state&&r.state.dolphinSpa?c(r.state.url,!1):r.state===null&&c(window.location.pathname,!1)}),this.options.routerTransitions){let r=document.createElement("style");r.innerHTML=`
|
|
26
|
+
`,_=u;return typeof Proxy<"u"&&u!==null&&typeof u=="object"&&(_=new Proxy(u,{has(p,b){return typeof b!="symbol"},get(p,b){if(b!==Symbol.unscopables){if(b in p)return p[b];if(typeof globalThis<"u"&&b in globalThis)return globalThis[b];if(typeof window<"u"&&b in window)return window[b]}}})),new Function("context",w)(_)}catch(l){console.error("[Dolphin Template Compiler Error]:",l);let n=f;for(let o in u){let c=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");n=n.replace(new RegExp(`\\{\\{${c}\\}\\}`,"g"),u[o]!==void 0&&u[o]!==null?u[o]:"")}return n}}function r(f){if(typeof document>"u")return f;try{let n=new DOMParser().parseFromString(f,"text/html").body,o=c=>{let y=c.tagName.toLowerCase();if(["script","iframe","object","embed","link","style","meta","applet","svg"].includes(y)){c.parentNode?.removeChild(c);return}let h=c.attributes;for(let m=h.length-1;m>=0;m--){let w=h[m].name.toLowerCase(),_=h[m].value.toLowerCase();(w.startsWith("on")||["src","href","data"].includes(w)&&(_.includes("javascript:")||_.includes("data:text/html")))&&c.removeAttribute(h[m].name)}Array.from(c.children).forEach(o)};return Array.from(n.children).forEach(o),n.innerHTML}catch{return f}}function a(f,u){if(f.nodeType!==u.nodeType){f.parentNode?.replaceChild(u.cloneNode(!0),f);return}if(f.nodeType===Node.TEXT_NODE){f.textContent!==u.textContent&&(f.textContent=u.textContent);return}if(f.nodeType===Node.ELEMENT_NODE){let l=f,n=u;if(l.tagName!==n.tagName){l.parentNode?.replaceChild(n.cloneNode(!0),l);return}let o=l.attributes,c=n.attributes;for(let g=o.length-1;g>=0;g--){let p=o[g].name;n.hasAttribute(p)||l.removeAttribute(p)}for(let g=0;g<c.length;g++){let p=c[g].name,b=c[g].value;l.getAttribute(p)!==b&&l.setAttribute(p,b)}l.tagName==="INPUT"||l.tagName==="TEXTAREA"?(l.value!==n.value&&(l.value=n.value),l.checked!==n.checked&&(l.checked=n.checked)):l.tagName==="SELECT"&&l.value!==n.value&&(l.value=n.value);let y=Array.from(l.childNodes),h=Array.from(n.childNodes),m=y.length,w=h.length,_=Math.max(m,w);for(let g=0;g<_;g++)g>=m?l.appendChild(h[g].cloneNode(!0)):g>=w?l.removeChild(y[g]):a(y[g],h[g])}}function d(f,u){if(typeof document>"u")return;let l=document.createElement(f.tagName);l.innerHTML=u;let n=Array.from(f.childNodes),o=Array.from(l.childNodes),c=n.length,y=o.length,h=Math.max(c,y);for(let m=0;m<h;m++)m>=c?f.appendChild(o[m].cloneNode(!0)):m>=y?f.removeChild(n[m]):a(n[m],o[m])}let E=new Map,S=!1;function k(f,u){E.set(f,u),S||(S=!0,(typeof requestAnimationFrame<"u"?requestAnimationFrame:n=>setTimeout(n,0))(()=>{E.forEach((n,o)=>{o.isConnected!==!1&&d(o,n)}),E.clear(),S=!1}))}A.setStoreState=function(f,u,l){this.uiStores=this.uiStores||new Map,this.uiStores.has(f)||this.uiStores.set(f,{});let n=this.uiStores.get(f);n[u]=l,this.options.debug&&console.log("%c\u{1F4BE} [Dolphin Store Update]:","color: #ec4899; font-weight: bold;",`${f}.${u}`,"=",l),typeof document<"u"&&document.querySelectorAll(`[data-store-read="${f}.${u}"]`).forEach(c=>{c.tagName==="INPUT"||c.tagName==="TEXTAREA"?c.type==="checkbox"?c.checked=!!l:c.value=l??"":c.textContent=l??""}),this.publish(`store/${f}`,n),typeof this._updateDOM=="function"&&this._updateDOM(`store/${f}`,n)},A.getStoreState=function(f,u){this.uiStores=this.uiStores||new Map;let l=this.uiStores.get(f);return l?l[u]:void 0},A._scanStoreBinds=function(){if(typeof document>"u")return;document.querySelectorAll("[data-store-write]").forEach(l=>{let n=l.getAttribute("data-store-write");if(n){let o=n.split(".");if(o.length===2){let c=o[0],y=o[1],h=l.type==="checkbox"?l.checked:l.value;this.uiStores=this.uiStores||new Map,this.uiStores.has(c)||this.uiStores.set(c,{});let m=this.uiStores.get(c);m[y]===void 0&&(m[y]=h)}}}),document.querySelectorAll("[data-store-read]").forEach(l=>{let n=l.getAttribute("data-store-read");if(n){let o=n.split(".");if(o.length===2){let c=o[0],y=o[1],h=this.getStoreState(c,y);h!=null&&(l.tagName==="INPUT"||l.tagName==="TEXTAREA"?l.type==="checkbox"?l.checked=!!h:l.value=h:l.textContent=h)}}})},A.getClosestContext=function(f,u){let l=f;for(;l;){if(l._rtContext){let n=l._rtContext;return u?n[u]:n}l=l.parentElement}return null},A._executeStoreAction=function(f,u){this.uiStores=this.uiStores||new Map;let l=new Proxy({},{has:(n,o)=>!0,get:(n,o)=>{if(typeof o=="string")return new Proxy({},{get:(c,y)=>{if(typeof y=="string")return this.getStoreState(o,y)},set:(c,y,h)=>typeof y=="string"?(this.setStoreState(o,y,h),!0):!1})}});try{new Function("ctx",`with(ctx) { ${f} }`)(l)}catch(n){console.error("%c[Dolphin Store Action Error]:","color: #ef4444; font-weight: bold;",n),u&&console.error("%cFailed Element:","color: #f97316; font-weight: bold;",u),console.error("%cFailed Expression:","color: #3b82f6; font-style: italic;",f)}},A._showAlert=function(f,u){if(typeof document>"u")return;let l=document.getElementById(f)||document.querySelector(`[id="${f}"]`);l&&(l.removeAttribute("hidden"),l.style.display="",u&&u>0&&setTimeout(()=>{l.setAttribute("hidden","")},u))},A._showToast=function(f,u="success"){if(typeof document>"u")return;let l={success:{bg:"rgba(16,185,129,0.15)",border:"#10b981",icon:"\u2705"},error:{bg:"rgba(239,68,68,0.15)",border:"#ef4444",icon:"\u274C"},info:{bg:"rgba(59,130,246,0.15)",border:"#3b82f6",icon:"\u2139\uFE0F"}},n=l[u]||l.success,o=document.createElement("div");o.setAttribute("data-dolphin-toast","");let y=document.querySelectorAll("[data-dolphin-toast]").length*72;o.style.cssText=["position:fixed",`bottom:${24+y}px`,"right:24px","z-index:2147483647",`background:${n.bg}`,`border:1px solid ${n.border}`,"color:#fff","padding:14px 20px","border-radius:14px","font-size:14px","font-weight:600","font-family:system-ui,sans-serif","box-shadow:0 8px 32px rgba(0,0,0,0.4)","display:flex","align-items:center","gap:10px","max-width:380px","word-break:break-word","transform:translateY(80px)","opacity:0","transition:transform 0.35s cubic-bezier(0.34,1.56,0.64,1),opacity 0.3s ease","pointer-events:auto","backdrop-filter:blur(12px)"].join(";"),o.innerHTML=`<span style="font-size:18px">${n.icon}</span><span>${f}</span>`,document.body.appendChild(o);let h=()=>{document.querySelectorAll("[data-dolphin-toast]").forEach((p,b)=>{p.style.bottom=`${24+b*72}px`})},m=typeof requestAnimationFrame<"u"?requestAnimationFrame:g=>setTimeout(g,0);m(()=>m(()=>{o.style.transform="translateY(0)",o.style.opacity="1"}));let w=()=>{clearTimeout(o._removeTimer),o.parentNode&&(o.parentNode.removeChild(o),h())},_=setTimeout(()=>{o.style.transform="translateY(80px)",o.style.opacity="0",o._removeTimer=setTimeout(w,400)},3500);o._hideTimer=_,o.addEventListener("click",()=>{clearTimeout(o._hideTimer),w()},{once:!0})},A._initDOMBinding=function(){if(this._domInitialized)return;this._domInitialized=!0;let f=["input","change","keyup","paste","blur"],u=new WeakMap;f.forEach(n=>{this.addDomListener(document,n,o=>{if(!o.target||!o.target.getAttribute)return;let c=o.target.getAttribute("data-store-write");if(c){let w=c.split(".");if(w.length===2){let _=w[0],g=w[1],p=o.target.type==="checkbox"?o.target.checked:o.target.value;this.setStoreState(_,g,p)}}let y=o.target.getAttribute("data-rt-validate"),h=o.target.name;if(y&&h&&typeof this.validateField=="function"){let w=o.target.closest("form"),_=w?Object.fromEntries(new FormData(w).entries()):{},g=this.validateField(o.target.value,y,_);g?(o.target.classList.add("invalid"),this.publish(`errors/${h}`,g)):(o.target.classList.remove("invalid"),this.publish(`errors/${h}`,""))}let m=o.target.getAttribute("data-rt-push");if(m){let w=o.target.getAttribute("data-rt-debounce"),_=w?parseInt(w,10):0,g=()=>{let p={name:o.target.name,value:o.target.value};this.pubPush(m,p)};if(_>0){u.has(o.target)&&clearTimeout(u.get(o.target));let p=setTimeout(g,_);u.set(o.target,p)}else g()}})}),this.addDomListener(document,"submit",async n=>{if(!n.target||!n.target.getAttribute)return;let o=n.target.getAttribute("data-rt-submit"),c=n.target.getAttribute("data-api-submit");if(o||c){n.target.querySelectorAll("[name]").forEach(p=>{let b=p.name;b&&(this.publish(`errors/${b}`,""),p.classList.remove("invalid"))});let h=n.target.querySelectorAll("[data-rt-validate]"),m=!0;if(h.length>0&&typeof this.validateField=="function"){let p=Object.fromEntries(new FormData(n.target).entries());h.forEach(b=>{let T=b.getAttribute("data-rt-validate"),x=b.name;if(T&&x){let v=this.validateField(b.value,T,p);v&&(m=!1,b.classList.add("invalid"),this.publish(`errors/${x}`,v))}})}if(!m){n.preventDefault(),n.stopPropagation();return}n.preventDefault();let w=this.getClosestContext(n.target)||{},_=new FormData(n.target),g=Object.fromEntries(_.entries());if(o){let p=o;for(let T in w){let x=e(T);p=p.replace(new RegExp(`\\{\\{${x}\\}\\}`,"g"),w[T]!==void 0&&w[T]!==null?w[T]:"")}this.publish(p,g);let b=n.target.getAttribute("data-rt-api-success");if(b){let T=document.getElementById(b);T&&this._showToast(T.textContent||T.innerText||"","success")}}else if(c){let p=c;for(let v in w){let D=e(v);p=p.replace(new RegExp(`\\{\\{${D}\\}\\}`,"g"),w[v]!==void 0&&w[v]!==null?w[v]:"")}let b=p.trim().split(" "),T=b.length>1?b[0].toUpperCase():"POST",x=b.length>1?b[1]:b[0];g._method&&(T=String(g._method).toUpperCase());try{let v=await this.api.request(T,x,g),D=n.target.getAttribute("data-api-result");D&&this._updateDOM(D,v);let L=n.target.getAttribute("data-api-toast");L&&this._showToast(L,"success");let M=n.target.getAttribute("data-rt-api-success");if(M){let I=parseInt(n.target.getAttribute("data-rt-alert-duration")||"0",10);this._showAlert(M,I);let P=n.target.getAttribute("data-rt-api-error");if(P){let R=document.getElementById(P);R&&R.setAttribute("hidden","")}}let $=n.target.getAttribute("data-api-redirect");$&&(window.location.href=$),n.target.hasAttribute("data-api-reload")&&window.location.reload()}catch(v){console.error("[Dolphin] API Submit Error:",v);let D=n.target.getAttribute("data-api-error-toast");D&&this._showToast(D,"error");let L=n.target.getAttribute("data-rt-api-error");if(L){let M=parseInt(n.target.getAttribute("data-rt-alert-duration")||"0",10);this._showAlert(L,M);let $=n.target.getAttribute("data-rt-api-success");if($){let I=document.getElementById($);I&&I.setAttribute("hidden","")}}}}}}),["click","change","input","keydown","keyup","dblclick","focus","blur","mouseenter","mouseleave"].forEach(n=>{this.addDomListener(document,n,async o=>{if(!o.target||!o.target.closest)return;let c=o.target.closest(`[data-rt-${n}]`),y=o.target.closest(`[data-api-${n}]`);if(c){n==="submit"&&o.preventDefault();let m=c.getAttribute(`data-rt-${n}`),w=c.getAttribute("data-rt-payload"),_=this.getClosestContext(c)||{},g={};if(w){let p=w;for(let b in _){let T=e(b);p=p.replace(new RegExp(`\\{\\{${T}\\}\\}`,"g"),_[b]!==void 0&&_[b]!==null?_[b]:"")}try{g=JSON.parse(p)}catch{g={}}}this.publish(m,g)}if(y){n==="submit"&&o.preventDefault();let m=y.getAttribute(`data-api-${n}`),w=y.getAttribute("data-api-payload"),_=this.getClosestContext(y)||{},g=m;for(let v in _){let D=e(v);g=g.replace(new RegExp(`\\{\\{${D}\\}\\}`,"g"),_[v]!==void 0&&_[v]!==null?_[v]:"")}let p=g.trim().split(" "),b=p.length>1?p[0].toUpperCase():"POST",T=p.length>1?p[1]:p[0],x=null;if(w){let v=w;for(let D in _){let L=e(D);v=v.replace(new RegExp(`\\{\\{${L}\\}\\}`,"g"),_[D]!==void 0&&_[D]!==null?_[D]:"")}try{x=JSON.parse(v)}catch{x=null}}try{let v=await this.api.request(b,T,x),D=y.getAttribute("data-api-result");D&&this._updateDOM(D,v);let L=y.getAttribute("data-api-toast");L&&this._showToast(L,"success");let M=y.getAttribute("data-rt-api-success");if(M){let I=parseInt(y.getAttribute("data-rt-alert-duration")||"0",10);this._showAlert(M,I);let P=y.getAttribute("data-rt-api-error");if(P){let R=document.getElementById(P);R&&R.setAttribute("hidden","")}}let $=y.getAttribute("data-api-redirect");$&&(window.location.href=$),y.hasAttribute("data-api-reload")&&window.location.reload()}catch(v){console.error(`[Dolphin] API ${n} Error:`,v);let D=y.getAttribute("data-api-error-toast");D&&this._showToast(D,"error");let L=y.getAttribute("data-rt-api-error");if(L){let M=parseInt(y.getAttribute("data-rt-alert-duration")||"0",10);this._showAlert(L,M);let $=y.getAttribute("data-rt-api-success");if($){let I=document.getElementById($);I&&I.setAttribute("hidden","")}}}}let h=o.target.closest(`[data-store-${n}]`);if(h){n==="submit"&&o.preventDefault();let m=h.getAttribute(`data-store-${n}`);m&&this._executeStoreAction(m,h)}})}),this.subscribe("#",(n,o)=>{this._updateDOM(o,n)}),this._scanAndFetchAPIBinds(),this._scanStoreBinds(),this._resolveImports(),this._initSPARouter()},A._scanAndFetchAPIBinds=async function(){if(typeof document>"u")return;let f=document.querySelectorAll("[data-api-get]");for(let u of Array.from(f)){let l=u.getAttribute("data-api-get");if(l&&!(typeof u.hasAttribute=="function"&&u.hasAttribute("data-api-initialized"))){typeof u.setAttribute=="function"&&u.setAttribute("data-api-initialized","true");try{let n=await this.api.get(l),o=u.getAttribute("data-api-store");if(o){let y=o.split(".");y.length===2&&this.setStoreState(y[0],y[1],n)}let c=u.getAttribute("data-rt-bind");if(c&&!o)this._updateDOM(c,n);else if(!o){let y=s(u);if(y&&typeof n=="object"&&n!==null){let h=this._applyDeclarativeDirectives(u,n);if(Array.isArray(h)){let m="";for(let w of h)m+=i(y,w);k(u,m)}else k(u,i(y,h))}else if(u.tagName==="INPUT"||u.tagName==="TEXTAREA")u.value=typeof n=="object"?n.value!==void 0?n.value:"":n;else{let h=typeof n=="object"?n.html||n.text||JSON.stringify(n):String(n);u.innerHTML=r(h)}}}catch(n){console.error("[Dolphin] API Get Error:",n)}}}},A._applyDeclarativeDirectives=function(f,u){let l=u;if(typeof u=="object"&&u!==null){let n=o=>{let c=[...o],y=f.getAttribute("data-rt-filter");if(y){let w=y.split("==");if(w.length===2){let _=w[0].trim(),g=w[1].trim(),p,b=g.split(".");b.length===2?p=this.getStoreState(b[0],b[1]):p=u[g]!==void 0?u[g]:this.getStoreState("app",g),p!=null&&p!==""&&(c=c.filter(T=>T[_]===p))}}let h=f.getAttribute("data-rt-search");if(h){let w=h.split("==");if(w.length===2){let _=w[0].trim(),g=w[1].trim(),p,b=g.split(".");if(b.length===2?p=this.getStoreState(b[0],b[1]):p=u[g]!==void 0?u[g]:this.getStoreState("app",g),p!=null&&p!==""){let T=String(p).toLowerCase();c=c.filter(x=>{let v=x[_];return v!=null&&String(v).toLowerCase().includes(T)})}}}let m=f.getAttribute("data-rt-sort");if(m){let w,_=m.split(".");if(_.length===2?w=this.getStoreState(_[0],_[1]):w=u[m]!==void 0?u[m]:this.getStoreState("app",m),w&&w!=="")if(w==="popular")c.sort((g,p)=>{let b=g.rating?.rate||g.rate||0;return(p.rating?.rate||p.rate||0)-b});else{let g="",p="asc";w.endsWith("-low")||w.endsWith("-asc")?(g=w.replace("-low","").replace("-asc",""),p="asc"):(w.endsWith("-high")||w.endsWith("-desc"))&&(g=w.replace("-high","").replace("-desc",""),p="desc"),g&&c.sort((b,T)=>{let x=($,I)=>I.split(".").reduce((P,R)=>P&&P[R],$),v=x(b,g),D=x(T,g);if(v===void 0&&(v=b[g]),D===void 0&&(D=T[g]),typeof v=="string"&&typeof D=="string")return p==="asc"?v.localeCompare(D):D.localeCompare(v);let L=Number(v),M=Number(D);return!isNaN(L)&&!isNaN(M)?p==="asc"?L-M:M-L:0})}}return c};if(Array.isArray(u))l=n(u);else{let o="";for(let c in u)if(Array.isArray(u[c])){o=c;break}if(o){let c=n(u[o]);l={...u,[o]:c}}}}return l},A._updateDOM=function(f,u){if(typeof document>"u")return;document.querySelectorAll(`[data-rt-bind="${f}"]`).forEach(n=>{let o=this._applyDeclarativeDirectives(n,u);if(n.getAttribute("data-rt-type")==="context"&&typeof o=="object"&&o!==null){n._rtContext=o;let y=h=>{if(h.hasAttribute("data-rt-text")){let m=h.getAttribute("data-rt-text");m&&o[m]!==void 0&&o[m]!==null&&(h.textContent=o[m])}if(h.hasAttribute("data-rt-html")){let m=h.getAttribute("data-rt-html");m&&o[m]!==void 0&&o[m]!==null&&(h.innerHTML=r(o[m]))}if(h.hasAttribute("data-rt-attr")){let m=h.getAttribute("data-rt-attr");m&&m.split(",").forEach(w=>{let _=w.split(":");if(_.length===2){let g=_[0].trim(),p=_[1].trim();g&&p&&o[p]!==void 0&&o[p]!==null&&h.setAttribute(g,o[p])}})}if(h.hasAttribute("data-rt-class")){let m=h.getAttribute("data-rt-class");m&&m.split(",").forEach(w=>{let _=w.split(":");if(_.length===2){let g=_[0].trim(),p=_[1].trim(),b=g.split(/\s+/).filter(Boolean);o[p]?b.forEach(T=>h.classList.add(T)):b.forEach(T=>h.classList.remove(T))}})}if(h.hasAttribute("data-rt-if")){let m=h.getAttribute("data-rt-if");m&&(o[m]?h.style.display="":h.style.display="none")}if(h.hasAttribute("data-rt-hide")){let m=h.getAttribute("data-rt-hide");m&&(o[m]?h.style.display="none":h.style.display="")}};y(n),n.querySelectorAll("[data-rt-text], [data-rt-html], [data-rt-attr], [data-rt-class], [data-rt-if], [data-rt-hide]").forEach(y);return}let c=s(n);if(c&&typeof o=="object"&&o!==null){if(Array.isArray(o)){let y="";for(let h of o)y+=i(c,h);k(n,y)}else k(n,i(c,o));return}if(n.tagName==="INPUT"||n.tagName==="TEXTAREA")n.value=typeof o=="object"?o.value!==void 0?o.value:"":o;else if(c)n.innerHTML=typeof o=="object"?o.html||o.text||JSON.stringify(o):String(o);else{let y=typeof o=="object"?o.html||o.text||JSON.stringify(o):String(o);n.innerHTML=r(y)}})},A._resolveImports=async function(f){if(typeof document>"u")return;let u=f||document.body||document;if(!u||typeof u.querySelectorAll!="function")return;let l=u.querySelectorAll("[data-import]");if(l.length===0)return;let n=async(c,y)=>{let h=c.getAttribute("data-import");if(!h)return;if(y.has(h)){console.warn(`[Dolphin Component Warning]: Circular import detected for "${h}". Skipping resolving.`),c.innerHTML=`<span style="color:red;font-weight:bold;">Circular import: ${h}</span>`;return}y.add(h);let m=t.get(h);m||(m=fetch(h).then(g=>{if(!g.ok)throw new Error(`HTTP ${g.status}`);return g.text()}),m.catch(()=>t.delete(h)),t.set(h,m));let w="";try{w=await m}catch(g){console.error(`[Dolphin Component Error]: Failed to fetch component "${h}":`,g),w=`<span style="color:red;font-weight:bold;">Failed to import ${h}</span>`}c.innerHTML=r(w),c.removeAttribute("data-import");let _=c.querySelectorAll("[data-import]");if(_.length>0){let g=Array.from(_).map(p=>n(p,new Set(y)));await Promise.all(g)}this._scanStoreBinds(),this._scanAndFetchAPIBinds()},o=Array.from(l).map(c=>n(c,new Set));await Promise.all(o)},A._initSPARouter=function(){if(typeof window>"u"||typeof document>"u"||this._routerInitialized)return;this._routerInitialized=!0;let f=null,u=()=>{let o=(this.options.routerViewport||"main, #viewport, body").split(",").map(c=>c.trim());for(let c of o){let y=document.querySelector(c);if(y)return y}return document.body},l=async(n,o=!0)=>{try{this.options.debug&&console.log(`%c\u{1F6E3}\uFE0F [Dolphin Router]: Navigating to ${n}...`,"color: #3b82f6; font-weight: bold;"),f&&f.abort(),f=new AbortController;let c=f.signal,y=u();this.options.routerTransitions&&y&&(y.classList.add("dolphin-fade-out"),await new Promise(b=>setTimeout(b,150)));let h=await fetch(n,{signal:c});if(!h.ok)throw new Error(`HTTP ${h.status}`);let m=await h.text();f=null;let _=new DOMParser().parseFromString(m,"text/html");_.title&&(document.title=_.title);let g=_.querySelector(this.options.routerViewport||"main, #viewport, body"),p=u();g&&p?(p.innerHTML=g.innerHTML,Array.from(g.attributes).forEach(b=>{p.setAttribute(b.name,b.value)})):p&&(p.innerHTML=_.body.innerHTML),o&&window.history.pushState({dolphinSpa:!0,url:n},"",n),this.options.routerTransitions&&p&&(p.classList.remove("dolphin-fade-out"),p.classList.add("dolphin-fade-in"),setTimeout(()=>p.classList.remove("dolphin-fade-in"),300)),await this._resolveImports(p),this._scanStoreBinds(),this._scanAndFetchAPIBinds()}catch(c){if(c&&c.name==="AbortError")return;console.error("[Dolphin Router Error]: Failed to route page:",c),window.location.href=n}};if(this.addDomListener(document,"click",n=>{let o=n.target.closest("a");if(!o||!o.hasAttribute("data-spa")&&o.getAttribute("data-spa")!=="true")return;let c=o.getAttribute("href");!c||c.startsWith("#")||c.startsWith("javascript:")||c.startsWith("mailto:")||c.startsWith("tel:")||new URL(c,window.location.href).origin!==window.location.origin||(n.preventDefault(),l(c))}),this.addDomListener(window,"popstate",n=>{n.state&&n.state.dolphinSpa?l(n.state.url,!1):n.state===null&&l(window.location.pathname,!1)}),this.options.routerTransitions){let n=document.createElement("style");n.innerHTML=`
|
|
27
27
|
.dolphin-fade-out {
|
|
28
28
|
opacity: 0;
|
|
29
29
|
transition: opacity 0.15s ease-in-out;
|
|
@@ -34,4 +34,4 @@ var DolphinModule=(()=>{var R=Object.defineProperty;var Y=Object.getOwnPropertyD
|
|
|
34
34
|
main, #viewport, body {
|
|
35
35
|
transition: opacity 0.15s ease-in-out;
|
|
36
36
|
}
|
|
37
|
-
`,document.head.appendChild(r)}}}var N=class{client;db;isOnline;memoryCache=new Map;memoryMutations=[];constructor(t){this.client=t,this.isOnline=typeof window<"u"&&typeof navigator<"u"?navigator.onLine:!0,this.initDB(),this.setupNetworkListeners()}initDB(){if(!(typeof indexedDB>"u"))try{let t=indexedDB.open("dolphin_offline",1);t.onupgradeneeded=e=>{let n=e.target.result;n.objectStoreNames.contains("cache")||n.createObjectStore("cache"),n.objectStoreNames.contains("mutations")||n.createObjectStore("mutations",{keyPath:"id",autoIncrement:!0})},t.onsuccess=e=>{this.db=e.target.result,this.isOnline&&this.syncMutations()}}catch(t){console.warn("[Dolphin Offline] Failed to initialize IndexedDB:",t)}}setupNetworkListeners(){typeof window>"u"||(this.client.addDomListener(window,"online",()=>{this.isOnline=!0,this.client._dispatch("network:status",{online:!0}),this.syncMutations()}),this.client.addDomListener(window,"offline",()=>{this.isOnline=!1,this.client._dispatch("network:status",{online:!1})}))}async getCache(t){return this.db?new Promise(e=>{try{let i=this.db.transaction("cache","readonly").objectStore("cache").get(t);i.onsuccess=()=>e(i.result?i.result.data:null),i.onerror=()=>e(null)}catch{e(null)}}):this.memoryCache.get(t)}async setCache(t,e){if(!this.db){this.memoryCache.set(t,e);return}return new Promise(n=>{try{let s=this.db.transaction("cache","readwrite");s.objectStore("cache").put({data:e,timestamp:Date.now()},t),s.oncomplete=()=>n(),s.onerror=()=>{console.warn("[Dolphin Offline] setCache write failed for key:",t),n()}}catch{n()}})}async queueMutation(t,e,n){let s={method:t,path:e,payload:n,timestamp:Date.now()};if(!this.db){this.memoryMutations.push(s);return}return new Promise(i=>{try{let a=this.db.transaction("mutations","readwrite");a.objectStore("mutations").add(s),a.oncomplete=()=>i(),a.onerror=()=>{console.warn("[Dolphin Offline] queueMutation write failed:",t,e),this.memoryMutations.push(s),i()}}catch{i()}})}async getMutations(){return this.db?new Promise(t=>{try{let s=this.db.transaction("mutations","readonly").objectStore("mutations").getAll();s.onsuccess=()=>t(s.result||[]),s.onerror=()=>t([])}catch{t([])}}):[...this.memoryMutations]}async removeMutation(t){if(!this.db){this.memoryMutations=this.memoryMutations.filter(e=>e.id!==t);return}return new Promise(e=>{try{let n=this.db.transaction("mutations","readwrite");n.objectStore("mutations").delete(t),n.oncomplete=()=>e(),n.onerror=()=>{console.warn("[Dolphin Offline] removeMutation failed for id:",t),e()}}catch{e()}})}async syncMutations(){let t=await this.getMutations();if(t.length!==0){console.log(`[Dolphin Offline] Syncing ${t.length} queued mutations...`);for(let e of t)try{await this.client.api.requestDirect(e.method,e.path,e.payload),e.id!==void 0?await this.removeMutation(e.id):this.memoryMutations.shift()}catch(n){if(console.error(`[Dolphin Offline] Sync failed for mutation ${e.method} ${e.path}:`,n),n&&n.status&&n.status>=400&&n.status<500)console.warn("[Dolphin Offline] Discarding invalid mutation."),e.id!==void 0?await this.removeMutation(e.id):this.memoryMutations.shift();else break}}}};function H(A){A._initOffline=function(){this.offline=new N(this)}}function it(A,t,e){let n=t.split(",");for(let s of n){let i=s.trim().split(":"),a=i[0],l=i[1];if(a==="required"){if(!A||A.trim()==="")return"This field is required"}else if(a==="email"){if(A&&A.trim()!==""&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(A))return"Please enter a valid email address"}else if(a==="min"){let _=parseInt(l,10);if(!A||A.length<_)return`Must be at least ${_} characters`}else if(a==="match"&&e&&A!==e[l])return`Must match ${l}`}return null}function F(A){A.validateField=it}function W(A){A.animateElement=function(t,e,n=300){if(typeof t.animate!="function"){t.classList.add(e),setTimeout(()=>t.classList.remove(e),n);return}e==="fade-in"?t.animate([{opacity:0,transform:"translateY(10px)"},{opacity:1,transform:"translateY(0)"}],{duration:n,easing:"ease-out"}):e==="fade-out"&&t.animate([{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(10px)"}],{duration:n,easing:"ease-in"})},A.staggerListItems=function(t,e,n=50){if(typeof document>"u")return;t.querySelectorAll(e).forEach((i,a)=>{i.style.animationDelay=`${a*n}ms`,i.classList.add("staggered-item")})}}function j(A){A._initA11y=function(){typeof document>"u"||(this.addDomListener(document,"keydown",t=>{if(t.key!=="Tab")return;document.querySelectorAll("[data-rt-a11y-focus-trap]").forEach(n=>{if(n.style.display==="none"||n.hasAttribute("aria-hidden")&&n.getAttribute("aria-hidden")==="true")return;let i=Array.from(n.querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable]'));if(i.length===0)return;let a=i[0],l=i[i.length-1];t.shiftKey?document.activeElement===a&&(l.focus(),t.preventDefault()):document.activeElement===l&&(a.focus(),t.preventDefault())})}),this.addDomListener(document,"keydown",t=>{if(!["ArrowUp","ArrowDown","Enter"].includes(t.key))return;document.querySelectorAll("[data-rt-keynav]").forEach(n=>{let s=Array.from(n.children);if(s.length===0)return;let i=s.findIndex(a=>a.classList.contains("active")||document.activeElement===a);t.key==="ArrowDown"?(i=(i+1)%s.length,s[i].focus(),s.forEach((a,l)=>{l===i?a.classList.add("active"):a.classList.remove("active")}),t.preventDefault()):t.key==="ArrowUp"?(i=(i-1+s.length)%s.length,s[i].focus(),s.forEach((a,l)=>{l===i?a.classList.add("active"):a.classList.remove("active")}),t.preventDefault()):t.key==="Enter"&&i!==-1&&(s[i].click(),t.preventDefault())})}))},A.autoAriaModal=function(t,e){e?(t.setAttribute("role","dialog"),t.setAttribute("aria-modal","true"),t.setAttribute("aria-hidden","false"),t.focus()):t.setAttribute("aria-hidden","true")}}function B(A){A._initI18n=function(){if(this.i18n=this.i18n||{locale:"en",dicts:{}},typeof document>"u")return;if(document.querySelectorAll("[data-i18n-dict]").forEach(e=>{let n=e.getAttribute("data-i18n-dict");if(n)try{let s=JSON.parse(e.textContent||"{}");this.i18n.dicts[n]={...this.i18n.dicts[n]||{},...s}}catch(s){console.warn("[Dolphin i18n] Failed to parse dictionary for locale:",n,s)}}),!this.i18n.locale&&typeof navigator<"u"){let e=navigator.language.split("-")[0];this.i18n.dicts[e]&&(this.i18n.locale=e)}this.addDomListener(document,"click",e=>{let n=e.target.closest("[data-i18n-switch]");if(n){let s=n.getAttribute("data-i18n-switch");s&&this.setLocale(s)}}),this.translateDOM()},A.setLocale=function(t){this.i18n=this.i18n||{locale:"en",dicts:{}},this.i18n.locale=t,this.translateDOM(),this.publish("i18n/locale",t)},A.translateDOM=function(){if(typeof document>"u")return;this.i18n=this.i18n||{locale:"en",dicts:{}};let t=this.i18n.locale||"en",e=this.i18n.dicts[t]||{};document.querySelectorAll("[data-i18n-key]").forEach(s=>{let i=s.getAttribute("data-i18n-key");if(!i)return;let a=i.split(".").reduce((_,v)=>_?_[v]:null,e);a==null&&(a=i);let l=s.getAttribute("data-i18n-params");if(l)try{let _=JSON.parse(l),v=k=>k.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");for(let k in _){let h=v(k);a=a.replace(new RegExp(`\\{\\{${h}\\}\\}`,"g"),_[k])}}catch{}s.tagName==="INPUT"||s.tagName==="TEXTAREA"?s.placeholder=a:s.textContent=a})}}function V(A){A._initDragDrop=function(){typeof document>"u"||(this.addDomListener(document,"dragstart",t=>{let e=t.target.closest("[data-drag]");if(!e)return;let n=e.getAttribute("data-drag");n&&(t.dataTransfer.setData("text/plain",n),t.dataTransfer.effectAllowed="move",e.classList.add("dragging"))}),this.addDomListener(document,"dragend",t=>{let e=t.target.closest("[data-drag]");e&&e.classList.remove("dragging")}),this.addDomListener(document,"dragover",t=>{let e=t.target.closest("[data-drop]");e&&(t.preventDefault(),e.classList.add("drag-over"))}),this.addDomListener(document,"dragleave",t=>{let e=t.target.closest("[data-drop]");e&&e.classList.remove("drag-over")}),this.addDomListener(document,"drop",t=>{let e=t.target.closest("[data-drop]");if(!e)return;t.preventDefault(),e.classList.remove("drag-over");let n=e.getAttribute("data-drop"),s=t.dataTransfer.getData("text/plain");if(n&&s)try{let i=JSON.parse(s);this.publish(n,i)}catch{this.publish(n,{value:s})}}),this.addDomListener(document,"dragover",t=>{let e=t.target.closest("[data-sortable]");if(!e)return;t.preventDefault();let n=e.querySelector(".dragging");if(!n)return;let i=Array.from(e.querySelectorAll("[data-drag]:not(.dragging)")).find(a=>{let l=a.getBoundingClientRect();return t.clientY-l.top-l.height/2<0});i?e.insertBefore(n,i):e.appendChild(n)}),this.addDomListener(document,"drop",t=>{let e=t.target.closest("[data-sortable]");if(!e)return;let n=e.getAttribute("data-sortable");if(!n)return;let i=Array.from(e.querySelectorAll("[data-drag]")).map((a,l)=>{let _=a.getAttribute("data-drag");try{return{index:l,payload:JSON.parse(_||"{}")}}catch{return{index:l,payload:_}}});this.publish(n,i)}))}}function z(A){A._initCollab=function(){if(typeof document>"u")return;let t=new Map,e=new Map,n=5e3;this.addDomListener(document,"mousemove",s=>{document.querySelectorAll("[data-rt-cursor-share]").forEach(a=>{let l=a.getAttribute("data-rt-cursor-share");if(!l)return;let _=a.getBoundingClientRect(),v=(s.clientX-_.left)/_.width,k=(s.clientY-_.top)/_.height,h=Date.now();(!a._lastSent||h-a._lastSent>50)&&(a._lastSent=h,this.pubPush(`collab/${l}/cursor/${this.deviceId}`,{deviceId:this.deviceId,x:v,y:k}))})}),this.addDomListener(document,"input",s=>{let i=s.target.getAttribute("data-rt-typing");if(!i)return;let a=i,l=_=>{this.pubPush(`collab/${a}/typing/${this.deviceId}`,{deviceId:this.deviceId,typing:_})};s.target._isTyping||(s.target._isTyping=!0,l(!0)),s.target._typingTimer&&clearTimeout(s.target._typingTimer),s.target._typingTimer=setTimeout(()=>{s.target._isTyping=!1,s.target._typingTimer=null,l(!1)},2e3)}),this.addDomListener(document,"input",s=>{let i=s.target.getAttribute("data-rt-crdt");if(!i)return;let a=i,l=s.target.value,_=Date.now();this.publish(`collab/${a}/crdt`,{deviceId:this.deviceId,value:l,timestamp:_,cursorPos:s.target.selectionStart})}),this.subscribe("collab/+/cursor/+",(s,i)=>{let a=i.split("/"),l=a[1],_=a[3];if(_===this.deviceId)return;let v=document.querySelector(`[data-rt-cursor-share="${l}"]`);if(!v)return;let k=`${l}::${_}`,h=t.get(k);(!h||!document.contains(h))&&(h=document.createElement("div"),h.className=`rt-cursor rt-cursor-${_}`,h.style.position="absolute",h.style.width="10px",h.style.height="10px",h.style.borderRadius="50%",h.style.backgroundColor="#"+Math.floor(Math.random()*16777215).toString(16).padStart(6,"0"),h.style.pointerEvents="none",v.appendChild(h),t.set(k,h));let d=v.getBoundingClientRect();h.style.left=s.x*d.width+"px",h.style.top=s.y*d.height+"px",e.has(k)&&clearTimeout(e.get(k)),e.set(k,setTimeout(()=>{let c=t.get(k);c&&c.parentNode&&c.parentNode.removeChild(c),t.delete(k),e.delete(k)},n))}),this.subscribe("collab/+/crdt",(s,i)=>{if(s.deviceId===this.deviceId)return;let l=i.split("/")[1];document.querySelectorAll(`[data-rt-crdt="${l}"]`).forEach(v=>{if(!v._lastUpdate||s.timestamp>v._lastUpdate){v._lastUpdate=s.timestamp;let k=v.selectionStart;v.value=s.value,document.activeElement===v&&v.setSelectionRange(k,k)}})}),this._collabCleanup=()=>{e.forEach(s=>clearTimeout(s)),e.clear(),t.forEach(s=>{s&&s.parentNode&&s.parentNode.removeChild(s)}),t.clear()}}}function K(A){A.registerServiceWorker=async function(t="/sw.js"){if(typeof navigator>"u"||!("serviceWorker"in navigator))return console.warn("[Dolphin PWA] Service Workers are not supported in this browser."),null;try{let e=await navigator.serviceWorker.register(t);return console.log("[Dolphin PWA] Service Worker registered successfully with scope:",e.scope),e}catch(e){return console.error("[Dolphin PWA] Service Worker registration failed:",e),null}},A.subscribePushNotifications=async function(t){if(typeof window>"u"||!("serviceWorker"in navigator)||!("PushManager"in window))return console.warn("[Dolphin PWA] Push notifications are not supported in this browser."),null;try{let e=await navigator.serviceWorker.ready,n=await e.pushManager.getSubscription();if(!n){let s="=".repeat((4-t.length%4)%4),i=(t+s).replace(/\-/g,"+").replace(/_/g,"/"),a=window.atob(i),l=new Uint8Array(a.length);for(let _=0;_<a.length;++_)l[_]=a.charCodeAt(_);n=await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:l})}return console.log("[Dolphin PWA] Subscribed to push notifications:",n),n}catch(e){return console.error("[Dolphin PWA] Push notification subscription failed:",e),null}}}var O=class{static render(t){if(typeof document>"u")throw new Error("DolphinTestUtils.render requires a DOM document environment to execute.");let e=document.createElement("div");return e.innerHTML=t,document.body.appendChild(e),{container:e,find:n=>e.querySelector(n),fireEvent:(n,s)=>{let i=document.createEvent("Event");i.initEvent(s,!0,!0),n.dispatchEvent(i)}}}static mockWebSocket(){let t=[],e={readyState:1,send:n=>{t.push(n)},close:jest.fn(),onopen:jest.fn(),onmessage:jest.fn(),onclose:jest.fn(),onerror:jest.fn(),sentMessages:t};return global.WebSocket=class{static OPEN=1;readyState=e.readyState;send=e.send;close=e.close;set onopen(n){e.onopen=n}get onopen(){return e.onopen}set onmessage(n){e.onmessage=n}get onmessage(){return e.onmessage}set onclose(n){e.onclose=n}get getonclose(){return e.onclose}constructor(){setTimeout(()=>e.onopen&&e.onopen(),0)}},e}static simulateClick(t){let e={target:t,preventDefault:jest.fn(),stopPropagation:jest.fn()};(global.document._listeners?.click||[]).forEach(s=>s(e))}static simulateChange(t,e){t.value=e;let n={target:t,preventDefault:jest.fn(),stopPropagation:jest.fn()};(global.document._listeners?.change||[]).forEach(i=>i(n))}};function X(A){A.testing=O}U(C.prototype);H(C.prototype);F(C.prototype);W(C.prototype);j(C.prototype);B(C.prototype);V(C.prototype);z(C.prototype);K(C.prototype);X(C.prototype);typeof window<"u"&&(window.DolphinClient=C,document.addEventListener("DOMContentLoaded",()=>{if(!window.dolphin){let A=document.querySelector('script[src*="dolphin-client"]'),t=A?A.getAttribute("data-debug")==="true":!1,e=new C(void 0,void 0,{debug:t});window.dolphin=e,t&&(console.log("%c\u{1F42C} [Dolphin Client] Auto-initialized local reactive engine!","color: #06b6d4; font-weight: bold; font-size: 14px;"),console.log('%c\u{1F449} Tip: You can access the client instance via "window.dolphin" in console.',"color: #94a3b8; font-style: italic;")),document.querySelector('[data-store-write="app.username"]')&&e.setStoreState("app","username","\u0928\u092E\u0938\u094D\u0924\u0947 \u0938\u093E\u0925\u0940!")}}));return st(rt);})();
|
|
37
|
+
`,document.head.appendChild(n)}}}var H=class{client;db;isOnline;memoryCache=new Map;memoryMutations=[];constructor(t){this.client=t,this.isOnline=typeof window<"u"&&typeof navigator<"u"?navigator.onLine:!0,this.initDB(),this.setupNetworkListeners()}initDB(){if(!(typeof indexedDB>"u"))try{let t=indexedDB.open("dolphin_offline",1);t.onupgradeneeded=e=>{let s=e.target.result;s.objectStoreNames.contains("cache")||s.createObjectStore("cache"),s.objectStoreNames.contains("mutations")||s.createObjectStore("mutations",{keyPath:"id",autoIncrement:!0})},t.onsuccess=e=>{this.db=e.target.result,this.isOnline&&this.syncMutations()}}catch(t){console.warn("[Dolphin Offline] Failed to initialize IndexedDB:",t)}}setupNetworkListeners(){typeof window>"u"||(this.client.addDomListener(window,"online",()=>{this.isOnline=!0,this.client._dispatch("network:status",{online:!0}),this.syncMutations()}),this.client.addDomListener(window,"offline",()=>{this.isOnline=!1,this.client._dispatch("network:status",{online:!1})}))}async getCache(t){return this.db?new Promise(e=>{try{let r=this.db.transaction("cache","readonly").objectStore("cache").get(t);r.onsuccess=()=>e(r.result?r.result.data:null),r.onerror=()=>e(null)}catch{e(null)}}):this.memoryCache.get(t)}async setCache(t,e){if(!this.db){this.memoryCache.set(t,e);return}return new Promise(s=>{try{let i=this.db.transaction("cache","readwrite");i.objectStore("cache").put({data:e,timestamp:Date.now()},t),i.oncomplete=()=>s(),i.onerror=()=>{console.warn("[Dolphin Offline] setCache write failed for key:",t),s()}}catch{s()}})}async queueMutation(t,e,s){let i={method:t,path:e,payload:s,timestamp:Date.now()};if(!this.db){this.memoryMutations.push(i);return}return new Promise(r=>{try{let a=this.db.transaction("mutations","readwrite");a.objectStore("mutations").add(i),a.oncomplete=()=>r(),a.onerror=()=>{console.warn("[Dolphin Offline] queueMutation write failed:",t,e),this.memoryMutations.push(i),r()}}catch{r()}})}async getMutations(){return this.db?new Promise(t=>{try{let i=this.db.transaction("mutations","readonly").objectStore("mutations").getAll();i.onsuccess=()=>t(i.result||[]),i.onerror=()=>t([])}catch{t([])}}):[...this.memoryMutations]}async removeMutation(t){if(!this.db){this.memoryMutations=this.memoryMutations.filter(e=>e.id!==t);return}return new Promise(e=>{try{let s=this.db.transaction("mutations","readwrite");s.objectStore("mutations").delete(t),s.oncomplete=()=>e(),s.onerror=()=>{console.warn("[Dolphin Offline] removeMutation failed for id:",t),e()}}catch{e()}})}async syncMutations(){let t=await this.getMutations();if(t.length!==0){console.log(`[Dolphin Offline] Syncing ${t.length} queued mutations...`);for(let e of t)try{await this.client.api.requestDirect(e.method,e.path,e.payload),e.id!==void 0?await this.removeMutation(e.id):this.memoryMutations.shift()}catch(s){if(console.error(`[Dolphin Offline] Sync failed for mutation ${e.method} ${e.path}:`,s),s&&s.status&&s.status>=400&&s.status<500)console.warn("[Dolphin Offline] Discarding invalid mutation."),e.id!==void 0?await this.removeMutation(e.id):this.memoryMutations.shift();else break}}}};function W(A){A._initOffline=function(){this.offline=new H(this)}}function it(A,t,e){let s=t.split(",");for(let i of s){let r=i.trim().split(":"),a=r[0],d=r[1];if(a==="required"){if(!A||A.trim()==="")return"This field is required"}else if(a==="email"){if(A&&A.trim()!==""&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(A))return"Please enter a valid email address"}else if(a==="min"){let E=parseInt(d,10);if(!A||A.length<E)return`Must be at least ${E} characters`}else if(a==="match"&&e&&A!==e[d])return`Must match ${d}`}return null}function j(A){A.validateField=it}function z(A){A.animateElement=function(t,e,s=300){if(typeof t.animate!="function"){t.classList.add(e),setTimeout(()=>t.classList.remove(e),s);return}e==="fade-in"?t.animate([{opacity:0,transform:"translateY(10px)"},{opacity:1,transform:"translateY(0)"}],{duration:s,easing:"ease-out"}):e==="fade-out"&&t.animate([{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(10px)"}],{duration:s,easing:"ease-in"})},A.staggerListItems=function(t,e,s=50){if(typeof document>"u")return;t.querySelectorAll(e).forEach((r,a)=>{r.style.animationDelay=`${a*s}ms`,r.classList.add("staggered-item")})}}function V(A){A._initA11y=function(){typeof document>"u"||(this.addDomListener(document,"keydown",t=>{if(t.key!=="Tab")return;document.querySelectorAll("[data-rt-a11y-focus-trap]").forEach(s=>{if(s.style.display==="none"||s.hasAttribute("aria-hidden")&&s.getAttribute("aria-hidden")==="true")return;let r=Array.from(s.querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable]'));if(r.length===0)return;let a=r[0],d=r[r.length-1];t.shiftKey?document.activeElement===a&&(d.focus(),t.preventDefault()):document.activeElement===d&&(a.focus(),t.preventDefault())})}),this.addDomListener(document,"keydown",t=>{if(!["ArrowUp","ArrowDown","Enter"].includes(t.key))return;document.querySelectorAll("[data-rt-keynav]").forEach(s=>{let i=Array.from(s.children);if(i.length===0)return;let r=i.findIndex(a=>a.classList.contains("active")||document.activeElement===a);t.key==="ArrowDown"?(r=(r+1)%i.length,i[r].focus(),i.forEach((a,d)=>{d===r?a.classList.add("active"):a.classList.remove("active")}),t.preventDefault()):t.key==="ArrowUp"?(r=(r-1+i.length)%i.length,i[r].focus(),i.forEach((a,d)=>{d===r?a.classList.add("active"):a.classList.remove("active")}),t.preventDefault()):t.key==="Enter"&&r!==-1&&(i[r].click(),t.preventDefault())})}))},A.autoAriaModal=function(t,e){e?(t.setAttribute("role","dialog"),t.setAttribute("aria-modal","true"),t.setAttribute("aria-hidden","false"),t.focus()):t.setAttribute("aria-hidden","true")}}function K(A){A._initI18n=function(){if(this.i18n=this.i18n||{locale:"en",dicts:{}},typeof document>"u")return;if(document.querySelectorAll("[data-i18n-dict]").forEach(e=>{let s=e.getAttribute("data-i18n-dict");if(s)try{let i=JSON.parse(e.textContent||"{}");this.i18n.dicts[s]={...this.i18n.dicts[s]||{},...i}}catch(i){console.warn("[Dolphin i18n] Failed to parse dictionary for locale:",s,i)}}),!this.i18n.locale&&typeof navigator<"u"){let e=navigator.language.split("-")[0];this.i18n.dicts[e]&&(this.i18n.locale=e)}this.addDomListener(document,"click",e=>{let s=e.target.closest("[data-i18n-switch]");if(s){let i=s.getAttribute("data-i18n-switch");i&&this.setLocale(i)}}),this.translateDOM()},A.setLocale=function(t){this.i18n=this.i18n||{locale:"en",dicts:{}},this.i18n.locale=t,this.translateDOM(),this.publish("i18n/locale",t)},A.translateDOM=function(){if(typeof document>"u")return;this.i18n=this.i18n||{locale:"en",dicts:{}};let t=this.i18n.locale||"en",e=this.i18n.dicts[t]||{};document.querySelectorAll("[data-i18n-key]").forEach(i=>{let r=i.getAttribute("data-i18n-key");if(!r)return;let a=r.split(".").reduce((E,S)=>E?E[S]:null,e);a==null&&(a=r);let d=i.getAttribute("data-i18n-params");if(d)try{let E=JSON.parse(d),S=k=>k.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");for(let k in E){let f=S(k);a=a.replace(new RegExp(`\\{\\{${f}\\}\\}`,"g"),E[k])}}catch{}i.tagName==="INPUT"||i.tagName==="TEXTAREA"?i.placeholder=a:i.textContent=a})}}function X(A){A._initDragDrop=function(){typeof document>"u"||(this.addDomListener(document,"dragstart",t=>{let e=t.target.closest("[data-drag]");if(!e)return;let s=e.getAttribute("data-drag");s&&(t.dataTransfer.setData("text/plain",s),t.dataTransfer.effectAllowed="move",e.classList.add("dragging"))}),this.addDomListener(document,"dragend",t=>{let e=t.target.closest("[data-drag]");e&&e.classList.remove("dragging")}),this.addDomListener(document,"dragover",t=>{let e=t.target.closest("[data-drop]");e&&(t.preventDefault(),e.classList.add("drag-over"))}),this.addDomListener(document,"dragleave",t=>{let e=t.target.closest("[data-drop]");e&&e.classList.remove("drag-over")}),this.addDomListener(document,"drop",t=>{let e=t.target.closest("[data-drop]");if(!e)return;t.preventDefault(),e.classList.remove("drag-over");let s=e.getAttribute("data-drop"),i=t.dataTransfer.getData("text/plain");if(s&&i)try{let r=JSON.parse(i);this.publish(s,r)}catch{this.publish(s,{value:i})}}),this.addDomListener(document,"dragover",t=>{let e=t.target.closest("[data-sortable]");if(!e)return;t.preventDefault();let s=e.querySelector(".dragging");if(!s)return;let r=Array.from(e.querySelectorAll("[data-drag]:not(.dragging)")).find(a=>{let d=a.getBoundingClientRect();return t.clientY-d.top-d.height/2<0});r?e.insertBefore(s,r):e.appendChild(s)}),this.addDomListener(document,"drop",t=>{let e=t.target.closest("[data-sortable]");if(!e)return;let s=e.getAttribute("data-sortable");if(!s)return;let r=Array.from(e.querySelectorAll("[data-drag]")).map((a,d)=>{let E=a.getAttribute("data-drag");try{return{index:d,payload:JSON.parse(E||"{}")}}catch{return{index:d,payload:E}}});this.publish(s,r)}))}}function J(A){A._initCollab=function(){if(typeof document>"u")return;let t=new Map,e=new Map,s=5e3;this.addDomListener(document,"mousemove",i=>{document.querySelectorAll("[data-rt-cursor-share]").forEach(a=>{let d=a.getAttribute("data-rt-cursor-share");if(!d)return;let E=a.getBoundingClientRect(),S=(i.clientX-E.left)/E.width,k=(i.clientY-E.top)/E.height,f=Date.now();(!a._lastSent||f-a._lastSent>50)&&(a._lastSent=f,this.pubPush(`collab/${d}/cursor/${this.deviceId}`,{deviceId:this.deviceId,x:S,y:k}))})}),this.addDomListener(document,"input",i=>{let r=i.target.getAttribute("data-rt-typing");if(!r)return;let a=r,d=E=>{this.pubPush(`collab/${a}/typing/${this.deviceId}`,{deviceId:this.deviceId,typing:E})};i.target._isTyping||(i.target._isTyping=!0,d(!0)),i.target._typingTimer&&clearTimeout(i.target._typingTimer),i.target._typingTimer=setTimeout(()=>{i.target._isTyping=!1,i.target._typingTimer=null,d(!1)},2e3)}),this.addDomListener(document,"input",i=>{let r=i.target.getAttribute("data-rt-crdt");if(!r)return;let a=r,d=i.target.value,E=Date.now();this.publish(`collab/${a}/crdt`,{deviceId:this.deviceId,value:d,timestamp:E,cursorPos:i.target.selectionStart})}),this.subscribe("collab/+/cursor/+",(i,r)=>{let a=r.split("/"),d=a[1],E=a[3];if(E===this.deviceId)return;let S=document.querySelector(`[data-rt-cursor-share="${d}"]`);if(!S)return;let k=`${d}::${E}`,f=t.get(k);(!f||!document.contains(f))&&(f=document.createElement("div"),f.className=`rt-cursor rt-cursor-${E}`,f.style.position="absolute",f.style.width="10px",f.style.height="10px",f.style.borderRadius="50%",f.style.backgroundColor="#"+Math.floor(Math.random()*16777215).toString(16).padStart(6,"0"),f.style.pointerEvents="none",S.appendChild(f),t.set(k,f));let u=S.getBoundingClientRect();f.style.left=i.x*u.width+"px",f.style.top=i.y*u.height+"px",e.has(k)&&clearTimeout(e.get(k)),e.set(k,setTimeout(()=>{let l=t.get(k);l&&l.parentNode&&l.parentNode.removeChild(l),t.delete(k),e.delete(k)},s))}),this.subscribe("collab/+/crdt",(i,r)=>{if(i.deviceId===this.deviceId)return;let d=r.split("/")[1];document.querySelectorAll(`[data-rt-crdt="${d}"]`).forEach(S=>{if(!S._lastUpdate||i.timestamp>S._lastUpdate){S._lastUpdate=i.timestamp;let k=S.selectionStart;S.value=i.value,document.activeElement===S&&S.setSelectionRange(k,k)}})}),this._collabCleanup=()=>{e.forEach(i=>clearTimeout(i)),e.clear(),t.forEach(i=>{i&&i.parentNode&&i.parentNode.removeChild(i)}),t.clear()}}}function Q(A){A.registerServiceWorker=async function(t="/sw.js"){if(typeof navigator>"u"||!("serviceWorker"in navigator))return console.warn("[Dolphin PWA] Service Workers are not supported in this browser."),null;try{let e=await navigator.serviceWorker.register(t);return console.log("[Dolphin PWA] Service Worker registered successfully with scope:",e.scope),e}catch(e){return console.error("[Dolphin PWA] Service Worker registration failed:",e),null}},A.subscribePushNotifications=async function(t){if(typeof window>"u"||!("serviceWorker"in navigator)||!("PushManager"in window))return console.warn("[Dolphin PWA] Push notifications are not supported in this browser."),null;try{let e=await navigator.serviceWorker.ready,s=await e.pushManager.getSubscription();if(!s){let i="=".repeat((4-t.length%4)%4),r=(t+i).replace(/\-/g,"+").replace(/_/g,"/"),a=window.atob(r),d=new Uint8Array(a.length);for(let E=0;E<a.length;++E)d[E]=a.charCodeAt(E);s=await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:d})}return console.log("[Dolphin PWA] Subscribed to push notifications:",s),s}catch(e){return console.error("[Dolphin PWA] Push notification subscription failed:",e),null}}}var F=class{static render(t){if(typeof document>"u")throw new Error("DolphinTestUtils.render requires a DOM document environment to execute.");let e=document.createElement("div");return e.innerHTML=t,document.body.appendChild(e),{container:e,find:s=>e.querySelector(s),fireEvent:(s,i)=>{let r=document.createEvent("Event");r.initEvent(i,!0,!0),s.dispatchEvent(r)}}}static mockWebSocket(){let t=[],e={readyState:1,send:s=>{t.push(s)},close:jest.fn(),onopen:jest.fn(),onmessage:jest.fn(),onclose:jest.fn(),onerror:jest.fn(),sentMessages:t};return global.WebSocket=class{static OPEN=1;readyState=e.readyState;send=e.send;close=e.close;set onopen(s){e.onopen=s}get onopen(){return e.onopen}set onmessage(s){e.onmessage=s}get onmessage(){return e.onmessage}set onclose(s){e.onclose=s}get getonclose(){return e.onclose}constructor(){setTimeout(()=>e.onopen&&e.onopen(),0)}},e}static simulateClick(t){let e={target:t,preventDefault:jest.fn(),stopPropagation:jest.fn()};(global.document._listeners?.click||[]).forEach(i=>i(e))}static simulateChange(t,e){t.value=e;let s={target:t,preventDefault:jest.fn(),stopPropagation:jest.fn()};(global.document._listeners?.change||[]).forEach(r=>r(s))}};function Y(A){A.testing=F}B(C.prototype);W(C.prototype);j(C.prototype);z(C.prototype);V(C.prototype);K(C.prototype);X(C.prototype);J(C.prototype);Q(C.prototype);Y(C.prototype);typeof window<"u"&&(window.DolphinClient=C,document.addEventListener("DOMContentLoaded",()=>{if(!window.dolphin){let A=document.querySelector('script[src*="dolphin-client"]'),t=A?A.getAttribute("data-debug")==="true":!1,e=new C(void 0,void 0,{debug:t});window.dolphin=e,t&&(console.log("%c\u{1F42C} [Dolphin Client] Auto-initialized local reactive engine!","color: #06b6d4; font-weight: bold; font-size: 14px;"),console.log('%c\u{1F449} Tip: You can access the client instance via "window.dolphin" in console.',"color: #94a3b8; font-style: italic;")),document.querySelector('[data-store-write="app.username"]')&&e.setStoreState("app","username","\u0928\u092E\u0938\u094D\u0924\u0947 \u0938\u093E\u0925\u0940!")}}));return st(rt);})();
|