@vicaniddouglas/js_aide 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -3
- package/declarations.d.ts +4 -1
- package/dist/js_aide.cjs.js +1 -1
- package/dist/js_aide.cjs.js.map +2 -2
- package/dist/js_aide.esm.js +1 -1
- package/dist/js_aide.esm.js.map +2 -2
- package/dist/js_aide.min.js +1 -1
- package/dist/js_aide.min.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -230,13 +230,32 @@ Every call returns a Promise that always resolves to this structure:
|
|
|
230
230
|
#### New Proactive Options
|
|
231
231
|
| Option | Type | Default | Description |
|
|
232
232
|
| :--- | :--- | :--- | :--- |
|
|
233
|
-
| `onSuccess` | `Function` | `null` | Runs automatically if `status` is `true`. |
|
|
234
|
-
| `onError` | `Function` | `null` | Runs automatically if `status` is `false`. |
|
|
233
|
+
| `onSuccess` | `Function` | `null` | Runs automatically if `status` is `true`. **Strictly awaited.** |
|
|
234
|
+
| `onError` | `Function` | `null` | Runs automatically if `status` is `false`. **Strictly awaited.** |
|
|
235
|
+
| `showLoading` | `Function` | `null` | Called with `true`/`false`. **Strictly awaited.** |
|
|
235
236
|
| `silent` | `Boolean` | `false` | If `true`, disables the automatic Red Popup on error. |
|
|
236
237
|
|
|
237
238
|
#### Usage Patterns
|
|
238
239
|
|
|
239
|
-
**1. The "
|
|
240
|
+
**1. The "Sequential Async Flow" (Awaiting Callbacks)**
|
|
241
|
+
Because `sendRequest` **strictly awaits** your callbacks, you can safely use `async/await` inside them without worrying about race conditions or premature page reloads.
|
|
242
|
+
```javascript
|
|
243
|
+
import { sendRequest, popup } from "@vicaniddouglas/js_aide";
|
|
244
|
+
|
|
245
|
+
await sendRequest({
|
|
246
|
+
endpoint: '/api/save',
|
|
247
|
+
onSuccess: async (data) => {
|
|
248
|
+
// This popup is BEAUTIFUL and BLOCKING.
|
|
249
|
+
// sendRequest will NOT finish until the user clicks OK.
|
|
250
|
+
await popup.success("Settings Saved!");
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// This reload is GUARANTEED to happen only after the popup is closed.
|
|
255
|
+
window.location.reload();
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**2. The "Fire and Forget" (Proactive Success)**
|
|
240
259
|
No need to check status if you only care about success. If it fails, the user gets a popup automatically.
|
|
241
260
|
```javascript
|
|
242
261
|
import { sendRequest } from "@vicaniddouglas/js_aide";
|
package/declarations.d.ts
CHANGED
|
@@ -313,7 +313,10 @@ declare module "@vicaniddouglas/js_aide" {
|
|
|
313
313
|
useQueue?: boolean;
|
|
314
314
|
priority?: number;
|
|
315
315
|
responseType?: "json" | "text";
|
|
316
|
-
showLoading?: (isLoading: boolean) => void
|
|
316
|
+
showLoading?: (isLoading: boolean) => void | Promise<void>;
|
|
317
|
+
onSuccess?: (data: any) => void | Promise<void>;
|
|
318
|
+
onError?: (log: string) => void | Promise<void>;
|
|
319
|
+
silent?: boolean;
|
|
317
320
|
}
|
|
318
321
|
|
|
319
322
|
type RequestInterceptor = (
|
package/dist/js_aide.cjs.js
CHANGED
|
@@ -1048,7 +1048,7 @@ var CA=Object.defineProperty;var L2=Object.getOwnPropertyDescriptor;var G2=Objec
|
|
|
1048
1048
|
@keyframes popupFadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
1049
1049
|
#modal-close-btn:hover { color: #475569 !important; }
|
|
1050
1050
|
.custom-popup-overlay:focus-within { outline: none; }
|
|
1051
|
-
`,document.head.appendChild(N)}var KA={error:(N,A)=>gA("error",N,A),success:(N,A)=>gA("success",N,A),info:(N,A)=>gA("info",N,A),close:()=>{EA&&EA.close()}};var J=(function(){let N={apiUrl:null,timeout:6e5,maxRetries:3,retryStrategy:"exponential",csrfToken:null,authToken:null,environment:"development",keys:{globalConfig:"APP_CONFIG",authToken:"auth_token",csrfToken:"csrf-token",csrfCookie:"XSRF-TOKEN"}};return{init(A={}){A.keys&&(N.keys={...N.keys,...A.keys}),window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"?N.environment="development":N.environment="production";let I=N.keys.globalConfig;window[I]&&window[I].apiUrl&&(N.apiUrl=window[I].apiUrl,window[I].environment&&(N.environment=window[I].environment));let O=document.querySelector('meta[name="api-url"]');O&&(N.apiUrl=O.getAttribute("content")),Object.assign(N,A),this.validate()},validate(){!N.apiUrl&&N.environment==="production"&&console.warn("RequestHandler: API URL is missing in production environment.")},get:()=>N}})(),fA={getCsrfToken(){let N=J.get().keys;if(J.get().csrfToken)return J.get().csrfToken;let A=document.querySelector(`meta[name="${N.csrfToken}"]`);if(A)return A.getAttribute("content");let I=N.csrfCookie+"=",U=decodeURIComponent(document.cookie).split(";");for(let E=0;E<U.length;E++){let B=U[E].trim();if(B.indexOf(I)===0)return B.substring(I.length,B.length)}return null},getAuthToken(){let N=J.get().keys;return J.get().authToken?J.get().authToken:sessionStorage.getItem(N.authToken)||localStorage.getItem(N.authToken)},sanitizePayload(N){if(!N||typeof N!="object"||N instanceof FormData)return N;let A=JSON.parse(JSON.stringify(N)),I=O=>{for(let U in O)typeof O[U]=="string"?O[U]=O[U].replace(/<script\b[^>]*>([\s\S]*?)<\/script>/gim,"").replace(/javascript:/gim,""):typeof O[U]=="object"&&O[U]!==null&&I(O[U])};return I(A),A}},x={request:[],response:[],error:[],addRequest(N,A){let I=Date.now()+Math.random();return this.request.push({id:I,onFulfilled:N,onRejected:A}),I},addResponse(N,A){let I=Date.now()+Math.random();return this.response.push({id:I,onFulfilled:N,onRejected:A}),I},addError(N){this.error.push(N)},clear(){this.request=[],this.response=[],this.error=[]}},C1=(function(){let N=[],A=0,I=3,O=()=>{if(A>=I||N.length===0)return;N.sort((E,B)=>B.priority-E.priority);let U=N.shift();A++,U.execute().finally(()=>{A--,O()})};return{add(U,E=0){return new Promise((B,R)=>{N.push({priority:E,execute:()=>U().then(B).catch(R)}),O()})},getStatus:()=>({active:A,pending:N.length}),clear:()=>{N.length=0}}})(),a1=async function(N={}){let I={...{method:"POST",endpoint:"",payload:null,headers:{},timeout:J.get().timeout,maxRetries:J.get().maxRetries,retryStrategy:J.get().retryStrategy,useQueue:!1,priority:0,responseType:"json",showLoading:null,onSuccess:null,onError:null,silent:!1},...N};for(let R of x.request)try{R.onFulfilled&&(I=await R.onFulfilled(I))}catch(K){if(R.onRejected)return R.onRejected(K);throw K}let O=(R,K)=>{let M=K>=200&&K<300;if(R&&typeof R=="object"&&"status"in R){let L=R.status===!0;return{status:L&&M,log:L&&M?"":R.log||"Error",data:R.data!==void 0?R.data:R,httpCode:K}}return{status:M,log:M?"":(R==null?void 0:R.message)||(R==null?void 0:R.error)||`Request failed with status ${K}`,data:M?R:null,httpCode:K}},U=async(R=0)=>{I.showLoading&&I.showLoading(!0);try{let K=new XMLHttpRequest,M=I.endpoint.startsWith("http")?I.endpoint:`${J.get().apiUrl}/${I.endpoint.replace(/^\//,"")}`;return await new Promise(L=>{K.open(I.method,M,!0),K.timeout=I.timeout;let G=fA.getCsrfToken();G&&K.setRequestHeader("X-CSRF-Token",G);let T=fA.getAuthToken();T&&K.setRequestHeader("Authorization",`Bearer ${T}`),K.setRequestHeader("X-Requested-With","XMLHttpRequest");let W=I.headers||{};!Object.keys(W).some(r=>r.toLowerCase()==="content-type")&&!(I.payload instanceof FormData)&&K.setRequestHeader("Content-Type","application/json"),Object.keys(W).forEach(r=>{K.setRequestHeader(r,W[r])}),K.onload=async()=>{I.showLoading&&I.showLoading(!1);let r;try{r=I.responseType==="json"?JSON.parse(K.responseText):K.response}catch{r=K.responseText}let s={},a=K.getAllResponseHeaders();a&&a.trim().split(/[\r\n]+/).forEach(NA=>{let v=NA.split(": "),j=v.shift(),OA=v.join(": ");s[j.toLowerCase()]=OA});let n=O(r,K.status);if(K.status>=200&&K.status<300){if(n.status===!1){I.onError&&I.onError(n.log),I.silent||KA.error(n.log);for(let v of x.response)v.onFulfilled&&await v.onFulfilled({...n,url:M});L(n);return}let NA={data:r.data||r,status:K.status,url:M,headers:s};for(let v of x.response)v.onFulfilled&&(NA=await v.onFulfilled(NA));I.onSuccess&&I.onSuccess(n.data),L(n)}else E(K,R,U,s,r,L)},K.onerror=()=>E(K,R,U,{},null,L),K.ontimeout=()=>E({status:408},R,U,{},null,L);let Y=fA.sanitizePayload(I.payload),o=Y;!(Y instanceof FormData)&&typeof Y=="object"&&Y!==null&&(o=JSON.stringify(Y)),K.send(o)})}catch(K){I.showLoading&&I.showLoading(!1);let M=K.message||"Critical Runtime Error";return I.onError&&I.onError(M),I.silent||KA.error(M),{status:!1,log:M,data:null}}},E=async(R,K,M,L,G,T)=>{let W=I.endpoint.startsWith("http")?I.endpoint:`${J.get().apiUrl}/${I.endpoint.replace(/^\//,"")}`;if(K<I.maxRetries&&(R.status>=500||R.status===408||R.status===0)){let S=B(K,I.retryStrategy);setTimeout(()=>M(K+1).then(T),S)}else{let S=O(G,R.status);I.onError&&I.onError(S.log),I.silent||KA.error(S.log),x.error.forEach(Y=>Y(R));for(let Y of x.response)Y.onFulfilled&&await Y.onFulfilled({...S,url:W});T(S)}},B=(R,K)=>{switch(K){case"linear":return(R+1)*1e3;case"fibonacci":return([1,1,2,3,5,8][R]||13)*1e3;case"exponential":return Math.pow(2,R)*1e3;default:return 1e3}};return I.useQueue?C1.add(()=>U(),I.priority):U()},P1=N=>J.init(N),c1={request:(N,A)=>x.addRequest(N,A),response:(N,A)=>x.addResponse(N,A),error:N=>x.addError(N),clear:()=>x.clear()},l1=()=>C1.getStatus();document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>J.init()):J.init();function Q(N,A={}){let{showAlert:I=!1}=A;if(typeof N!="string")return I&&console.error("Invalid input: Date must be a string."),!1;let O=N.trim().split("-");if(O.length!==3||O[0].length!==4||O[1].length!==2||O[2].length!==2)return I&&alert("Invalid date format. Use YYYY-MM-DD."),!1;let U=Number(O[0]),E=Number(O[1]),B=Number(O[2]);if(isNaN(U)||isNaN(E)||isNaN(B))return I&&alert("Date must contain only numbers."),!1;if(E<1||E>12||B<1||B>31)return I&&alert("Invalid month or day range."),!1;let R=new Date(U,E-1,B);return R.getFullYear()!==U||R.getMonth()+1!==E||R.getDate()!==B?(I&&alert("Invalid date. Please enter a real date."),!1):!0}function h1(N,A={}){let{format:I="weekday",locale:O="en-US",includeYear:U=!0}=A;if(!Q(N,{showAlert:!1}))throw new Error("Invalid date format. Use YYYY-MM-DD.");let E=N.split("-"),B=new Date(E[0],E[1]-1,E[2]),R={short:{year:"numeric",month:"numeric",day:"numeric"},medium:{year:"numeric",month:"short",day:"numeric"},long:{year:"numeric",month:"long",day:"numeric"},full:{weekday:"long",year:"numeric",month:"long",day:"numeric"},weekday:{weekday:"short",year:"numeric",month:"short",day:"numeric"}},K=R[I]||R.weekday;return U||(K={...K},delete K.year),B.toLocaleString(O,K)}function J1(N,A={}){let{locale:I="en-US"}=A;if(!Q(N,{showAlert:!1}))throw new Error("Invalid date format. Use YYYY-MM-DD.");let O=N.split("-"),B=new Date(O[0],O[1]-1,O[2])-new Date,R=Math.round(B/(1e3*60*60*24)),K=new Intl.RelativeTimeFormat(I,{numeric:"auto"});if(Math.abs(R)<1){let M=Math.round(B/36e5);return K.format(M,"hour")}else{if(Math.abs(R)<7)return K.format(R,"day");if(Math.abs(R)<30){let M=Math.round(R/7);return K.format(M,"week")}else if(Math.abs(R)<365){let M=Math.round(R/30);return K.format(M,"month")}else{let M=Math.round(R/365);return K.format(M,"year")}}}function d1(){let N=new Date,A=N.getFullYear(),I=String(N.getMonth()+1).padStart(2,"0"),O=String(N.getDate()).padStart(2,"0");return`${A}-${I}-${O}`}function u1(){let N=new Date;N.setDate(N.getDate()-1);let A=N.getFullYear(),I=String(N.getMonth()+1).padStart(2,"0"),O=String(N.getDate()).padStart(2,"0");return`${A}-${I}-${O}`}function Z1(N,A={}){let{showSeconds:I=!0}=A,O=new Date,U=new Date(N);if(isNaN(U.getTime()))return"Invalid timestamp";let E=O-U,B=Math.floor(E/1e3),R=Math.floor(B/60),K=Math.floor(R/60),M=Math.floor(K/24),L=Math.floor(M/7),G=Math.floor(M/30),T=Math.floor(M/365);return B<60?I?`${B} second${B!==1?"s":""} ago`:"now":R<60?`${R} minute${R!==1?"s":""} ago`:K<24?`${K} hour${K!==1?"s":""} ago`:M<7?`${M} day${M!==1?"s":""} ago`:L<4?`${L} week${L!==1?"s":""} ago`:G<12?`${G} month${G!==1?"s":""} ago`:`${T} year${T!==1?"s":""} ago`}function p1(N,A,I){if(!Q(N,{showAlert:!1}))throw new Error("Invalid date format. Use YYYY-MM-DD.");let O=new Date(N),E={days:()=>O.setDate(O.getDate()+A),weeks:()=>O.setDate(O.getDate()+A*7),months:()=>O.setMonth(O.getMonth()+A),years:()=>O.setFullYear(O.getFullYear()+A)}[I.toLowerCase()];if(!E)throw new Error(`Invalid unit: ${I}. Use: days, weeks, months, years`);return E(),O.toISOString().split("T")[0]}function m1(N){let A=new Date,I=K=>{let M=K.getFullYear(),L=String(K.getMonth()+1).padStart(2,"0"),G=String(K.getDate()).padStart(2,"0");return`${M}-${L}-${G}`},O=K=>{let M=K.getDay(),L=K.getDate()-M+(M===0?-6:1),G=new Date(K);return G.setDate(L),G},U=K=>new Date(K.getFullYear(),K.getMonth(),1),E=K=>new Date(K.getFullYear(),K.getMonth()+1,0),B,R;switch(N.toLowerCase()){case"today":{B=I(A),R=I(A);break}case"yesterday":{let K=new Date(A);K.setDate(A.getDate()-1),B=I(K),R=I(K);break}case"thisweek":{let K=O(A);B=I(K),R=I(A);break}case"lastweek":{let K=new Date(A);K.setDate(A.getDate()-7);let M=O(K),L=new Date(M);L.setDate(M.getDate()+6),B=I(M),R=I(L);break}case"thismonth":{let K=U(A);B=I(K),R=I(A);break}case"lastmonth":{let K=new Date(A.getFullYear(),A.getMonth()-1,1),M=U(K),L=E(K);B=I(M),R=I(L);break}default:throw new Error(`Unknown keyword: ${N}. Use: today, yesterday, thisWeek, lastWeek, thisMonth, lastMonth`)}return[B,R]}function g1(N,A){let I=new Date,U={days:()=>I.setDate(I.getDate()-N),weeks:()=>I.setDate(I.getDate()-N*7),months:()=>I.setMonth(I.getMonth()-N),years:()=>I.setFullYear(I.getFullYear()-N)}[A.toLowerCase()];if(!U)throw new Error(`Invalid unit: ${A}. Use: days, weeks, months, years`);U();let E=I.getFullYear(),B=String(I.getMonth()+1).padStart(2,"0"),R=String(I.getDate()).padStart(2,"0");return`${E}-${B}-${R}`}function f1(){let N=new Date;N.setDate(N.getDate()+1);let A=N.getFullYear(),I=String(N.getMonth()+1).padStart(2,"0"),O=String(N.getDate()).padStart(2,"0");return`${A}-${I}-${O}`}function w1(N){let A=new Date,I=M=>{let L=M.getFullYear(),G=String(M.getMonth()+1).padStart(2,"0"),T=String(M.getDate()).padStart(2,"0");return`${L}-${G}-${T}`},O=M=>{let L=M.getDay(),G=M.getDate()-L+(L===0?-6:1),T=new Date(M);return T.setDate(G),T},U=M=>{let L=O(M),G=new Date(L);return G.setDate(L.getDate()+6),G},E=M=>new Date(M.getFullYear(),M.getMonth(),1),B=M=>new Date(M.getFullYear(),M.getMonth()+1,0),R,K;switch(N.toLowerCase()){case"tomorrow":{let M=new Date(A);M.setDate(A.getDate()+1),R=I(M),K=I(M);break}case"nextweek":{let M=new Date(A);M.setDate(A.getDate()+7);let L=O(M),G=U(M);R=I(L),K=I(G);break}case"nextmonth":{let M=new Date(A.getFullYear(),A.getMonth()+1,1),L=E(M),G=B(M);R=I(L),K=I(G);break}case"nextyear":{let M=new Date(A.getFullYear()+1,0,1),L=new Date(A.getFullYear()+1,11,31);R=I(M),K=I(L);break}default:throw new Error(`Unknown keyword: ${N}. Use: tomorrow, nextWeek, nextMonth, nextYear`)}return[R,K]}function v1(N,A,I={}){let{inclusiveEndDate:O=!1}=I;if(!Q(N,{showAlert:!1})||!Q(A,{showAlert:!1}))throw new Error("Invalid date format. Use YYYY-MM-DD.");let U=new Date(N),E=new Date(A);if(U>E)throw new Error("Start date cannot be after end date.");let B=E-U,R=Math.floor(B/(1e3*60*60*24));return O&&(R+=1),R}function V1(N,A,I={}){let{startDate:O}=I,U;if(O){if(!Q(O,{showAlert:!1}))throw new Error("Invalid start date format. Use YYYY-MM-DD.");U=new Date(O)}else U=new Date;if(typeof N!="number"||N<0)throw new Error("Amount must be a positive number.");let B={days:()=>U.setDate(U.getDate()+N),weeks:()=>U.setDate(U.getDate()+N*7),months:()=>U.setMonth(U.getMonth()+N),years:()=>U.setFullYear(U.getFullYear()+N)}[A.toLowerCase()];if(!B)throw new Error(`Invalid unit: ${A}. Use: days, weeks, months, years`);B();let R=U.getFullYear(),K=String(U.getMonth()+1).padStart(2,"0"),M=String(U.getDate()).padStart(2,"0");return`${R}-${K}-${M}`}function y1(N){let A=new Date;return A.setHours(0,0,0,0),new Date(N)>A}function F1(N){let A=new Date;return A.setHours(0,0,0,0),new Date(N)<A}var wA=class{constructor(){this.dependencies={sheetjs:{name:"SheetJS",cdn:"https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js",check:()=>typeof XLSX<"u"&&!!XLSX.utils},jspdf:{name:"jsPDF",cdn:"https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js",check:()=>typeof(window.jsPDF||window.jspdf&&window.jspdf.jsPDF)<"u"},jspdfAutotable:{name:"jsPDF AutoTable",cdn:"https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.28/jspdf.plugin.autotable.min.js",check:()=>{let A=window.jsPDF||window.jspdf&&window.jspdf.jsPDF;return typeof A<"u"&&(typeof A.autoTable<"u"||A.API&&typeof A.API.autoTable<"u")},requires:["jspdf"]}},this.loadingPromises=new Map}register(A,I){this.dependencies[A]&&console.warn(`Dependency "${A}" is already registered. Overwriting.`),this.dependencies[A]=I}hasDependency(A){let I=this.dependencies[A];if(!I)return!1;if(I.requires){for(let O of I.requires)if(!this.hasDependency(O))return!1}return I.check()}async loadDependency(A,I=0){if(this.loadingPromises.has(A))return this.loadingPromises.get(A);let O=this.dependencies[A];if(!O)throw new Error(`Unknown dependency: ${A}`);if(this.hasDependency(A))return!0;if(O.requires)for(let R of O.requires)await this.loadDependency(R);let U=O.maxRetries||2,E=[O.cdn,...O.fallbacks||[]],B=(async()=>{let R;for(let K of E)try{return await this._injectScript(O,K),this.loadingPromises.delete(A),!0}catch(M){R=M,console.warn(`Failed to load ${O.name} from ${K}:`,M.message)}if(I<U)return this.loadingPromises.delete(A),this.loadDependency(A,I+1);throw this.loadingPromises.delete(A),R||new Error(`Failed to load ${O.name} after all attempts.`)})();return this.loadingPromises.set(A,B),B}_injectScript(A,I){return new Promise((O,U)=>{let E=document.createElement("script");E.src=I,E.async=!0,A.integrity&&(E.integrity=A.integrity,E.crossOrigin=A.crossorigin||"anonymous"),E.onload=()=>{let B=0,R=setInterval(()=>{A.check()?(clearInterval(R),O(!0)):B>20&&(clearInterval(R),U(new Error(`Library ${A.name} loaded but failed verification.`))),B++},50)},E.onerror=()=>U(new Error("Network error or CSP violation")),document.head.appendChild(E),setTimeout(()=>{E.parentNode&&(E.remove(),U(new Error(`Timeout (10s) reached for ${I}`)))},1e4)})}async ensureDependency(A,I=null){try{return this.hasDependency(A)||await this.loadDependency(A),!0}catch(O){if(console.error(`Dependency Manager error [${A}]:`,O.message),I)return I();throw O}}},BA=new wA;async function vA(N,A,I="download",O={}){let{maxSize:U=50*1024*1024,onProgress:E=null,fallbackFormats:B=!0,csvDelimiter:R=",",pdfOptions:K={}}=O;try{if(!N)throw new Error("No data provided for download");if(!I||typeof I!="string")throw new Error("Invalid file name");let M,L=I,G=A.toLowerCase();E==null||E(10);try{G==="excel"?await BA.ensureDependency("sheetjs"):G==="pdf"&&await Promise.all([BA.ensureDependency("jspdf"),BA.ensureDependency("jspdfAutotable")])}catch(W){if(B){if(console.warn(`Dependency missing for ${G}, falling back to print/csv...`),G==="excel")G="csv";else if(G==="pdf")return await T3(N,I,K)}else throw W}switch(E==null||E(30),G){case"csv":M=await B3(N,R,{onProgress:E}),L.toLowerCase().endsWith(".csv")||(L+=".csv");break;case"json":M=await R3(N,{onProgress:E}),L.toLowerCase().endsWith(".json")||(L+=".json");break;case"txt":M=await M3(N,{onProgress:E}),L.toLowerCase().endsWith(".txt")||(L+=".txt");break;case"excel":M=await L3(N,{onProgress:E}),L.toLowerCase().endsWith(".xlsx")||(L+=".xlsx");break;case"pdf":M=await G3(N,K,{onProgress:E}),L.toLowerCase().endsWith(".pdf")||(L+=".pdf");break;default:throw new Error(`Unsupported file type: ${A}`)}if(E==null||E(80),M.size>U)throw new Error(`File size ${(M.size/1024/1024).toFixed(2)}MB exceeds limit.`);if(G==="pdf"){W3(M,L),E==null||E(100);return}let T=URL.createObjectURL(M);try{let W=document.createElement("a");W.href=T,W.download=L,W.style.display="none",document.body.appendChild(W),W.click(),document.body.removeChild(W)}finally{setTimeout(()=>URL.revokeObjectURL(T),1e3)}E==null||E(100)}catch(M){throw console.error("Download failed:",M),M}}var cA=class{constructor(A="export"){this.defaultFilename=A}async exportToExcel(A,I={}){let O=this.extractTableData(A,I),U=[...O.headers,...O.rows,...O.footers];await vA(U,"excel",I.filename||this.defaultFilename,I)}async exportToCSV(A,I={}){let O=this.extractTableData(A,I),U=this.generateCsvContent(O,I.delimiter||",",`
|
|
1051
|
+
`,document.head.appendChild(N)}var KA={error:(N,A)=>gA("error",N,A),success:(N,A)=>gA("success",N,A),info:(N,A)=>gA("info",N,A),close:()=>{EA&&EA.close()}};var J=(function(){let N={apiUrl:null,timeout:6e5,maxRetries:3,retryStrategy:"exponential",csrfToken:null,authToken:null,environment:"development",keys:{globalConfig:"APP_CONFIG",authToken:"auth_token",csrfToken:"csrf-token",csrfCookie:"XSRF-TOKEN"}};return{init(A={}){A.keys&&(N.keys={...N.keys,...A.keys}),window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"?N.environment="development":N.environment="production";let I=N.keys.globalConfig;window[I]&&window[I].apiUrl&&(N.apiUrl=window[I].apiUrl,window[I].environment&&(N.environment=window[I].environment));let O=document.querySelector('meta[name="api-url"]');O&&(N.apiUrl=O.getAttribute("content")),Object.assign(N,A),this.validate()},validate(){!N.apiUrl&&N.environment==="production"&&console.warn("RequestHandler: API URL is missing in production environment.")},get:()=>N}})(),fA={getCsrfToken(){let N=J.get().keys;if(J.get().csrfToken)return J.get().csrfToken;let A=document.querySelector(`meta[name="${N.csrfToken}"]`);if(A)return A.getAttribute("content");let I=N.csrfCookie+"=",U=decodeURIComponent(document.cookie).split(";");for(let E=0;E<U.length;E++){let B=U[E].trim();if(B.indexOf(I)===0)return B.substring(I.length,B.length)}return null},getAuthToken(){let N=J.get().keys;return J.get().authToken?J.get().authToken:sessionStorage.getItem(N.authToken)||localStorage.getItem(N.authToken)},sanitizePayload(N){if(!N||typeof N!="object"||N instanceof FormData)return N;let A=JSON.parse(JSON.stringify(N)),I=O=>{for(let U in O)typeof O[U]=="string"?O[U]=O[U].replace(/<script\b[^>]*>([\s\S]*?)<\/script>/gim,"").replace(/javascript:/gim,""):typeof O[U]=="object"&&O[U]!==null&&I(O[U])};return I(A),A}},x={request:[],response:[],error:[],addRequest(N,A){let I=Date.now()+Math.random();return this.request.push({id:I,onFulfilled:N,onRejected:A}),I},addResponse(N,A){let I=Date.now()+Math.random();return this.response.push({id:I,onFulfilled:N,onRejected:A}),I},addError(N){this.error.push(N)},clear(){this.request=[],this.response=[],this.error=[]}},C1=(function(){let N=[],A=0,I=3,O=()=>{if(A>=I||N.length===0)return;N.sort((E,B)=>B.priority-E.priority);let U=N.shift();A++,U.execute().finally(()=>{A--,O()})};return{add(U,E=0){return new Promise((B,R)=>{N.push({priority:E,execute:()=>U().then(B).catch(R)}),O()})},getStatus:()=>({active:A,pending:N.length}),clear:()=>{N.length=0}}})(),a1=async function(N={}){let I={...{method:"POST",endpoint:"",payload:null,headers:{},timeout:J.get().timeout,maxRetries:J.get().maxRetries,retryStrategy:J.get().retryStrategy,useQueue:!1,priority:0,responseType:"json",showLoading:null,onSuccess:null,onError:null,silent:!1},...N};for(let R of x.request)try{R.onFulfilled&&(I=await R.onFulfilled(I))}catch(K){if(R.onRejected)return R.onRejected(K);throw K}let O=(R,K)=>{let M=K>=200&&K<300;if(R&&typeof R=="object"&&"status"in R){let L=R.status===!0;return{status:L&&M,log:L&&M?"":R.log||"Error",data:R.data!==void 0?R.data:R,httpCode:K}}return{status:M,log:M?"":(R==null?void 0:R.message)||(R==null?void 0:R.error)||`Request failed with status ${K}`,data:M?R:null,httpCode:K}},U=async(R=0)=>{I.showLoading&&await I.showLoading(!0);try{let K=new XMLHttpRequest,M=I.endpoint.startsWith("http")?I.endpoint:`${J.get().apiUrl}/${I.endpoint.replace(/^\//,"")}`;return await new Promise(L=>{K.open(I.method,M,!0),K.timeout=I.timeout;let G=fA.getCsrfToken();G&&K.setRequestHeader("X-CSRF-Token",G);let T=fA.getAuthToken();T&&K.setRequestHeader("Authorization",`Bearer ${T}`),K.setRequestHeader("X-Requested-With","XMLHttpRequest");let W=I.headers||{};!Object.keys(W).some(r=>r.toLowerCase()==="content-type")&&!(I.payload instanceof FormData)&&K.setRequestHeader("Content-Type","application/json"),Object.keys(W).forEach(r=>{K.setRequestHeader(r,W[r])}),K.onload=async()=>{I.showLoading&&await I.showLoading(!1);let r;try{r=I.responseType==="json"?JSON.parse(K.responseText):K.response}catch{r=K.responseText}let s={},a=K.getAllResponseHeaders();a&&a.trim().split(/[\r\n]+/).forEach(NA=>{let v=NA.split(": "),j=v.shift(),OA=v.join(": ");s[j.toLowerCase()]=OA});let n=O(r,K.status);if(K.status>=200&&K.status<300){if(n.status===!1){I.onError&&await I.onError(n.log),I.silent||await KA.error(n.log);for(let v of x.response)v.onFulfilled&&await v.onFulfilled({...n,url:M});L(n);return}let NA={data:r.data||r,status:K.status,url:M,headers:s};for(let v of x.response)v.onFulfilled&&(NA=await v.onFulfilled(NA));I.onSuccess&&await I.onSuccess(n.data),L(n)}else await E(K,R,U,s,r,L)},K.onerror=()=>E(K,R,U,{},null,L),K.ontimeout=()=>E({status:408},R,U,{},null,L);let Y=fA.sanitizePayload(I.payload),o=Y;!(Y instanceof FormData)&&typeof Y=="object"&&Y!==null&&(o=JSON.stringify(Y)),K.send(o)})}catch(K){I.showLoading&&await I.showLoading(!1);let M=K.message||"Critical Runtime Error";return I.onError&&await I.onError(M),I.silent||await KA.error(M),{status:!1,log:M,data:null}}},E=async(R,K,M,L,G,T)=>{let W=I.endpoint.startsWith("http")?I.endpoint:`${J.get().apiUrl}/${I.endpoint.replace(/^\//,"")}`;if(K<I.maxRetries&&(R.status>=500||R.status===408||R.status===0)){let S=B(K,I.retryStrategy);setTimeout(()=>M(K+1).then(T),S)}else{I.showLoading&&await I.showLoading(!1);let S=O(G,R.status);I.onError&&await I.onError(S.log),I.silent||await KA.error(S.log),x.error.forEach(Y=>Y(R));for(let Y of x.response)Y.onFulfilled&&await Y.onFulfilled({...S,url:W});T(S)}},B=(R,K)=>{switch(K){case"linear":return(R+1)*1e3;case"fibonacci":return([1,1,2,3,5,8][R]||13)*1e3;case"exponential":return Math.pow(2,R)*1e3;default:return 1e3}};return I.useQueue?C1.add(()=>U(),I.priority):U()},P1=N=>J.init(N),c1={request:(N,A)=>x.addRequest(N,A),response:(N,A)=>x.addResponse(N,A),error:N=>x.addError(N),clear:()=>x.clear()},l1=()=>C1.getStatus();document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>J.init()):J.init();function Q(N,A={}){let{showAlert:I=!1}=A;if(typeof N!="string")return I&&console.error("Invalid input: Date must be a string."),!1;let O=N.trim().split("-");if(O.length!==3||O[0].length!==4||O[1].length!==2||O[2].length!==2)return I&&alert("Invalid date format. Use YYYY-MM-DD."),!1;let U=Number(O[0]),E=Number(O[1]),B=Number(O[2]);if(isNaN(U)||isNaN(E)||isNaN(B))return I&&alert("Date must contain only numbers."),!1;if(E<1||E>12||B<1||B>31)return I&&alert("Invalid month or day range."),!1;let R=new Date(U,E-1,B);return R.getFullYear()!==U||R.getMonth()+1!==E||R.getDate()!==B?(I&&alert("Invalid date. Please enter a real date."),!1):!0}function h1(N,A={}){let{format:I="weekday",locale:O="en-US",includeYear:U=!0}=A;if(!Q(N,{showAlert:!1}))throw new Error("Invalid date format. Use YYYY-MM-DD.");let E=N.split("-"),B=new Date(E[0],E[1]-1,E[2]),R={short:{year:"numeric",month:"numeric",day:"numeric"},medium:{year:"numeric",month:"short",day:"numeric"},long:{year:"numeric",month:"long",day:"numeric"},full:{weekday:"long",year:"numeric",month:"long",day:"numeric"},weekday:{weekday:"short",year:"numeric",month:"short",day:"numeric"}},K=R[I]||R.weekday;return U||(K={...K},delete K.year),B.toLocaleString(O,K)}function J1(N,A={}){let{locale:I="en-US"}=A;if(!Q(N,{showAlert:!1}))throw new Error("Invalid date format. Use YYYY-MM-DD.");let O=N.split("-"),B=new Date(O[0],O[1]-1,O[2])-new Date,R=Math.round(B/(1e3*60*60*24)),K=new Intl.RelativeTimeFormat(I,{numeric:"auto"});if(Math.abs(R)<1){let M=Math.round(B/36e5);return K.format(M,"hour")}else{if(Math.abs(R)<7)return K.format(R,"day");if(Math.abs(R)<30){let M=Math.round(R/7);return K.format(M,"week")}else if(Math.abs(R)<365){let M=Math.round(R/30);return K.format(M,"month")}else{let M=Math.round(R/365);return K.format(M,"year")}}}function d1(){let N=new Date,A=N.getFullYear(),I=String(N.getMonth()+1).padStart(2,"0"),O=String(N.getDate()).padStart(2,"0");return`${A}-${I}-${O}`}function u1(){let N=new Date;N.setDate(N.getDate()-1);let A=N.getFullYear(),I=String(N.getMonth()+1).padStart(2,"0"),O=String(N.getDate()).padStart(2,"0");return`${A}-${I}-${O}`}function Z1(N,A={}){let{showSeconds:I=!0}=A,O=new Date,U=new Date(N);if(isNaN(U.getTime()))return"Invalid timestamp";let E=O-U,B=Math.floor(E/1e3),R=Math.floor(B/60),K=Math.floor(R/60),M=Math.floor(K/24),L=Math.floor(M/7),G=Math.floor(M/30),T=Math.floor(M/365);return B<60?I?`${B} second${B!==1?"s":""} ago`:"now":R<60?`${R} minute${R!==1?"s":""} ago`:K<24?`${K} hour${K!==1?"s":""} ago`:M<7?`${M} day${M!==1?"s":""} ago`:L<4?`${L} week${L!==1?"s":""} ago`:G<12?`${G} month${G!==1?"s":""} ago`:`${T} year${T!==1?"s":""} ago`}function p1(N,A,I){if(!Q(N,{showAlert:!1}))throw new Error("Invalid date format. Use YYYY-MM-DD.");let O=new Date(N),E={days:()=>O.setDate(O.getDate()+A),weeks:()=>O.setDate(O.getDate()+A*7),months:()=>O.setMonth(O.getMonth()+A),years:()=>O.setFullYear(O.getFullYear()+A)}[I.toLowerCase()];if(!E)throw new Error(`Invalid unit: ${I}. Use: days, weeks, months, years`);return E(),O.toISOString().split("T")[0]}function m1(N){let A=new Date,I=K=>{let M=K.getFullYear(),L=String(K.getMonth()+1).padStart(2,"0"),G=String(K.getDate()).padStart(2,"0");return`${M}-${L}-${G}`},O=K=>{let M=K.getDay(),L=K.getDate()-M+(M===0?-6:1),G=new Date(K);return G.setDate(L),G},U=K=>new Date(K.getFullYear(),K.getMonth(),1),E=K=>new Date(K.getFullYear(),K.getMonth()+1,0),B,R;switch(N.toLowerCase()){case"today":{B=I(A),R=I(A);break}case"yesterday":{let K=new Date(A);K.setDate(A.getDate()-1),B=I(K),R=I(K);break}case"thisweek":{let K=O(A);B=I(K),R=I(A);break}case"lastweek":{let K=new Date(A);K.setDate(A.getDate()-7);let M=O(K),L=new Date(M);L.setDate(M.getDate()+6),B=I(M),R=I(L);break}case"thismonth":{let K=U(A);B=I(K),R=I(A);break}case"lastmonth":{let K=new Date(A.getFullYear(),A.getMonth()-1,1),M=U(K),L=E(K);B=I(M),R=I(L);break}default:throw new Error(`Unknown keyword: ${N}. Use: today, yesterday, thisWeek, lastWeek, thisMonth, lastMonth`)}return[B,R]}function g1(N,A){let I=new Date,U={days:()=>I.setDate(I.getDate()-N),weeks:()=>I.setDate(I.getDate()-N*7),months:()=>I.setMonth(I.getMonth()-N),years:()=>I.setFullYear(I.getFullYear()-N)}[A.toLowerCase()];if(!U)throw new Error(`Invalid unit: ${A}. Use: days, weeks, months, years`);U();let E=I.getFullYear(),B=String(I.getMonth()+1).padStart(2,"0"),R=String(I.getDate()).padStart(2,"0");return`${E}-${B}-${R}`}function f1(){let N=new Date;N.setDate(N.getDate()+1);let A=N.getFullYear(),I=String(N.getMonth()+1).padStart(2,"0"),O=String(N.getDate()).padStart(2,"0");return`${A}-${I}-${O}`}function w1(N){let A=new Date,I=M=>{let L=M.getFullYear(),G=String(M.getMonth()+1).padStart(2,"0"),T=String(M.getDate()).padStart(2,"0");return`${L}-${G}-${T}`},O=M=>{let L=M.getDay(),G=M.getDate()-L+(L===0?-6:1),T=new Date(M);return T.setDate(G),T},U=M=>{let L=O(M),G=new Date(L);return G.setDate(L.getDate()+6),G},E=M=>new Date(M.getFullYear(),M.getMonth(),1),B=M=>new Date(M.getFullYear(),M.getMonth()+1,0),R,K;switch(N.toLowerCase()){case"tomorrow":{let M=new Date(A);M.setDate(A.getDate()+1),R=I(M),K=I(M);break}case"nextweek":{let M=new Date(A);M.setDate(A.getDate()+7);let L=O(M),G=U(M);R=I(L),K=I(G);break}case"nextmonth":{let M=new Date(A.getFullYear(),A.getMonth()+1,1),L=E(M),G=B(M);R=I(L),K=I(G);break}case"nextyear":{let M=new Date(A.getFullYear()+1,0,1),L=new Date(A.getFullYear()+1,11,31);R=I(M),K=I(L);break}default:throw new Error(`Unknown keyword: ${N}. Use: tomorrow, nextWeek, nextMonth, nextYear`)}return[R,K]}function v1(N,A,I={}){let{inclusiveEndDate:O=!1}=I;if(!Q(N,{showAlert:!1})||!Q(A,{showAlert:!1}))throw new Error("Invalid date format. Use YYYY-MM-DD.");let U=new Date(N),E=new Date(A);if(U>E)throw new Error("Start date cannot be after end date.");let B=E-U,R=Math.floor(B/(1e3*60*60*24));return O&&(R+=1),R}function V1(N,A,I={}){let{startDate:O}=I,U;if(O){if(!Q(O,{showAlert:!1}))throw new Error("Invalid start date format. Use YYYY-MM-DD.");U=new Date(O)}else U=new Date;if(typeof N!="number"||N<0)throw new Error("Amount must be a positive number.");let B={days:()=>U.setDate(U.getDate()+N),weeks:()=>U.setDate(U.getDate()+N*7),months:()=>U.setMonth(U.getMonth()+N),years:()=>U.setFullYear(U.getFullYear()+N)}[A.toLowerCase()];if(!B)throw new Error(`Invalid unit: ${A}. Use: days, weeks, months, years`);B();let R=U.getFullYear(),K=String(U.getMonth()+1).padStart(2,"0"),M=String(U.getDate()).padStart(2,"0");return`${R}-${K}-${M}`}function y1(N){let A=new Date;return A.setHours(0,0,0,0),new Date(N)>A}function F1(N){let A=new Date;return A.setHours(0,0,0,0),new Date(N)<A}var wA=class{constructor(){this.dependencies={sheetjs:{name:"SheetJS",cdn:"https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js",check:()=>typeof XLSX<"u"&&!!XLSX.utils},jspdf:{name:"jsPDF",cdn:"https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js",check:()=>typeof(window.jsPDF||window.jspdf&&window.jspdf.jsPDF)<"u"},jspdfAutotable:{name:"jsPDF AutoTable",cdn:"https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.28/jspdf.plugin.autotable.min.js",check:()=>{let A=window.jsPDF||window.jspdf&&window.jspdf.jsPDF;return typeof A<"u"&&(typeof A.autoTable<"u"||A.API&&typeof A.API.autoTable<"u")},requires:["jspdf"]}},this.loadingPromises=new Map}register(A,I){this.dependencies[A]&&console.warn(`Dependency "${A}" is already registered. Overwriting.`),this.dependencies[A]=I}hasDependency(A){let I=this.dependencies[A];if(!I)return!1;if(I.requires){for(let O of I.requires)if(!this.hasDependency(O))return!1}return I.check()}async loadDependency(A,I=0){if(this.loadingPromises.has(A))return this.loadingPromises.get(A);let O=this.dependencies[A];if(!O)throw new Error(`Unknown dependency: ${A}`);if(this.hasDependency(A))return!0;if(O.requires)for(let R of O.requires)await this.loadDependency(R);let U=O.maxRetries||2,E=[O.cdn,...O.fallbacks||[]],B=(async()=>{let R;for(let K of E)try{return await this._injectScript(O,K),this.loadingPromises.delete(A),!0}catch(M){R=M,console.warn(`Failed to load ${O.name} from ${K}:`,M.message)}if(I<U)return this.loadingPromises.delete(A),this.loadDependency(A,I+1);throw this.loadingPromises.delete(A),R||new Error(`Failed to load ${O.name} after all attempts.`)})();return this.loadingPromises.set(A,B),B}_injectScript(A,I){return new Promise((O,U)=>{let E=document.createElement("script");E.src=I,E.async=!0,A.integrity&&(E.integrity=A.integrity,E.crossOrigin=A.crossorigin||"anonymous"),E.onload=()=>{let B=0,R=setInterval(()=>{A.check()?(clearInterval(R),O(!0)):B>20&&(clearInterval(R),U(new Error(`Library ${A.name} loaded but failed verification.`))),B++},50)},E.onerror=()=>U(new Error("Network error or CSP violation")),document.head.appendChild(E),setTimeout(()=>{E.parentNode&&(E.remove(),U(new Error(`Timeout (10s) reached for ${I}`)))},1e4)})}async ensureDependency(A,I=null){try{return this.hasDependency(A)||await this.loadDependency(A),!0}catch(O){if(console.error(`Dependency Manager error [${A}]:`,O.message),I)return I();throw O}}},BA=new wA;async function vA(N,A,I="download",O={}){let{maxSize:U=50*1024*1024,onProgress:E=null,fallbackFormats:B=!0,csvDelimiter:R=",",pdfOptions:K={}}=O;try{if(!N)throw new Error("No data provided for download");if(!I||typeof I!="string")throw new Error("Invalid file name");let M,L=I,G=A.toLowerCase();E==null||E(10);try{G==="excel"?await BA.ensureDependency("sheetjs"):G==="pdf"&&await Promise.all([BA.ensureDependency("jspdf"),BA.ensureDependency("jspdfAutotable")])}catch(W){if(B){if(console.warn(`Dependency missing for ${G}, falling back to print/csv...`),G==="excel")G="csv";else if(G==="pdf")return await T3(N,I,K)}else throw W}switch(E==null||E(30),G){case"csv":M=await B3(N,R,{onProgress:E}),L.toLowerCase().endsWith(".csv")||(L+=".csv");break;case"json":M=await R3(N,{onProgress:E}),L.toLowerCase().endsWith(".json")||(L+=".json");break;case"txt":M=await M3(N,{onProgress:E}),L.toLowerCase().endsWith(".txt")||(L+=".txt");break;case"excel":M=await L3(N,{onProgress:E}),L.toLowerCase().endsWith(".xlsx")||(L+=".xlsx");break;case"pdf":M=await G3(N,K,{onProgress:E}),L.toLowerCase().endsWith(".pdf")||(L+=".pdf");break;default:throw new Error(`Unsupported file type: ${A}`)}if(E==null||E(80),M.size>U)throw new Error(`File size ${(M.size/1024/1024).toFixed(2)}MB exceeds limit.`);if(G==="pdf"){W3(M,L),E==null||E(100);return}let T=URL.createObjectURL(M);try{let W=document.createElement("a");W.href=T,W.download=L,W.style.display="none",document.body.appendChild(W),W.click(),document.body.removeChild(W)}finally{setTimeout(()=>URL.revokeObjectURL(T),1e3)}E==null||E(100)}catch(M){throw console.error("Download failed:",M),M}}var cA=class{constructor(A="export"){this.defaultFilename=A}async exportToExcel(A,I={}){let O=this.extractTableData(A,I),U=[...O.headers,...O.rows,...O.footers];await vA(U,"excel",I.filename||this.defaultFilename,I)}async exportToCSV(A,I={}){let O=this.extractTableData(A,I),U=this.generateCsvContent(O,I.delimiter||",",`
|
|
1052
1052
|
`,!0);await vA(U,"csv",I.filename||this.defaultFilename,I)}async exportToPDF(A,I={}){let O=this.extractTableData(A,I);await vA(O,"pdf",I.filename||this.defaultFilename,I)}extractTableData(A,I={}){let{rowClass:O,cellClass:U,headerRowClass:E,footerRowClass:B,includeFooter:R=!0}=I,K={headers:[],rows:[],footers:[]},M=L=>Array.from(A.querySelectorAll(L)).map(T=>Array.from(T.querySelectorAll(U||"th, td")).map(W=>(W.textContent||"").trim().replace(/\s+/g," ")));if(E?K.headers=M(`.${E}`):(K.headers=M("thead tr"),K.headers.length===0&&(K.headers=M("tr:has(th)"))),O)K.rows=M(`.${O}`);else{let L=M("tbody tr");L.length>0?K.rows=L:K.rows=M("tr:not(thead tr):not(tfoot tr)")}return R&&(B?K.footers=M(`.${B}`):K.footers=M("tfoot tr")),K}generateCsvContent(A,I,O,U){let B=[...A.headers,...A.rows,...A.footers].map(R=>R.map(K=>this.escapeCsvValue(K,I)).join(I)).join(O);return U?"\uFEFF"+B:B}escapeCsvValue(A,I){let O=String(A||"");return O.includes('"')||O.includes(I)||O.includes(`
|
|
1053
1053
|
`)?`"${O.replace(/"/g,'""')}"`:O}};async function B3(N,A){let I;return Array.isArray(N)?I=N.map(O=>Array.isArray(O)?O.map(U=>String(U)).join(A):JSON.stringify(O)).join(`
|
|
1054
1054
|
`):I=String(N),new Blob(["\uFEFF"+I],{type:"text/csv;charset=utf-8"})}async function R3(N){return new Blob([JSON.stringify(N,null,2)],{type:"application/json"})}async function M3(N){return new Blob([String(N)],{type:"text/plain"})}async function L3(N){if(typeof XLSX>"u")throw new Error("SheetJS not loaded");let A=XLSX.utils.book_new(),I=XLSX.utils.aoa_to_sheet(N);XLSX.utils.book_append_sheet(A,I,"Sheet1");let O=XLSX.write(A,{bookType:"xlsx",type:"array"});return new Blob([O],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})}async function G3(N,A){let I=window.jspdf?window.jspdf.jsPDF:window.jsPDF;if(!I)throw new Error("jsPDF library not found");let O=new I({orientation:A.orientation||"portrait",unit:"mm",format:A.format||"a4"}),U=A.title||"";if(U&&(O.setFontSize(16),O.text(U,14,15)),typeof N=="string"||Array.isArray(N)&&typeof N[0]=="string"&&!Array.isArray(N[0])){O.setFontSize(11);let B=Array.isArray(N)?N.join(`
|