@lightworkai.official/debug-capture 0.8.2 → 0.9.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 +23 -14
- package/dist/debug-capture.js +3 -3
- package/dist/index.mjs +5 -5
- package/dist/server.d.ts +57 -0
- package/dist/server.mjs +54 -0
- package/package.json +8 -3
- package/src/server.ts +132 -0
- package/src/submit.ts +7 -0
package/README.md
CHANGED
|
@@ -81,32 +81,41 @@ behind a public key is an endpoint that reads *everyone's* reports.
|
|
|
81
81
|
|
|
82
82
|
So your server vouches for your user. Ask the support team for the realm's
|
|
83
83
|
reporter secret (an admin sets `authConfig.reporterSecret` on the realm), keep
|
|
84
|
-
it on your **server**, and
|
|
84
|
+
it on your **server**, and mount one route:
|
|
85
85
|
|
|
86
86
|
```ts
|
|
87
|
-
//
|
|
88
|
-
import
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
87
|
+
// app/api/support-token/route.ts (Next.js app router)
|
|
88
|
+
import { supportTokenHandler } from "@lightworkai.official/debug-capture/server";
|
|
89
|
+
import { getServerSession } from "next-auth";
|
|
90
|
+
import { authOptions } from "@/lib/auth";
|
|
91
|
+
|
|
92
|
+
export const dynamic = "force-dynamic";
|
|
93
|
+
export const GET = supportTokenHandler({
|
|
94
|
+
// The one thing we cannot do for you: only you can read your session.
|
|
95
|
+
user: async () => {
|
|
96
|
+
const session = await getServerSession(authOptions);
|
|
97
|
+
return session?.user?.email ? { id: session.user.id, email: session.user.email } : null;
|
|
98
|
+
},
|
|
99
|
+
});
|
|
99
100
|
```
|
|
100
101
|
|
|
102
|
+
It returns a standard `Response`, so it works anywhere the Fetch API does — Bun,
|
|
103
|
+
Deno, Hono, Next. The secret comes from `SUPPORT_REPORTER_SECRET` unless you
|
|
104
|
+
pass one. `createSupportToken()` is the same thing without the routing, if your
|
|
105
|
+
framework wants the response built its own way.
|
|
106
|
+
|
|
101
107
|
Wire it once, as the `identity` callback:
|
|
102
108
|
|
|
103
109
|
```ts
|
|
104
110
|
configureDebugCapture({
|
|
105
|
-
host, realmKey, app: { name: "
|
|
111
|
+
host, realmKey, app: { name: "ACME" },
|
|
106
112
|
identity: async () => (await fetch("/api/support-token").then((r) => r.json())).token,
|
|
107
113
|
});
|
|
108
114
|
```
|
|
109
115
|
|
|
116
|
+
**Import from `/server`, never the package root** — it uses `node:crypto` and
|
|
117
|
+
touches the secret, while the root export is browser code.
|
|
118
|
+
|
|
110
119
|
The **secret never reaches the browser** — the callback fetches a finished token
|
|
111
120
|
from your own backend. Returning `null` means "nobody is signed in", and the
|
|
112
121
|
button says so rather than opening a dead link.
|
package/dist/debug-capture.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{var c1={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},R=null;function T0($){R=$}function f(){if(!R)throw Error("[debug-capture] configureDebugCapture() has not been called");return R}function A0(){return R!==null}function h(){let $=f().app;return{name:$.name,version:$.version??"0.0.0",environment:$.environment??l1()}}function l1(){if(typeof window>"u")return"unknown";let $=window.location.hostname;if($==="localhost"||$==="127.0.0.1"||$.endsWith(".local"))return"development";return"production"}function A($){let j=R?.capture?.[$];return typeof j==="number"?j:c1[$]}function L0($){let j=R?.module;if(!j)return null;try{return j($)??null}catch{return null}}function e(){let $=R?.redact;return{headers:$?.headers??[],queryKeys:($?.queryKeys??[]).map((j)=>j.toLowerCase()),bodyKeys:($?.bodyKeys??[]).map((j)=>j.toLowerCase())}}function E0(){return R?.capture?.overlaySelectors??[]}function x0($){if(typeof window>"u")return!1;let j;try{j=new URL($,window.location.href)}catch{return!1}if(r1(j))return!1;if(j.origin===window.location.origin)return!0;return(R?.capture?.bodyOrigins??[]).some((J)=>{try{return new URL(J).origin===j.origin}catch{return!1}})}function r1($){if(!R?.host)return!1;try{if(new URL(R.host).origin!==$.origin)return!1}catch{return!1}return $.pathname.startsWith("/ingest/")}var v="‹redacted›",s1=/^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i,n1=new Set(["access_token","token","id_token","refresh_token","code","secret","client_secret","password","apikey","api_key","signature","x-amz-signature","x-amz-credential"]),a1=/(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i,t1=/[\w.+-]+@[\w-]+\.[\w.-]+/g,e1=/\d(?:[\d\s-]{7,})\d/g;function b($){return $.replace(t1,v).replace(e1,v)}function $2($){if(s1.test($))return!0;return e().headers.some((J)=>J.toLowerCase()===$.toLowerCase())}function u($){let j={};for(let[J,Q]of Object.entries($))j[J]=$2(J)?v:Q;return j}function i($){try{let j=/^https?:\/\//i.test($),J=new URL($,j?void 0:"http://local.invalid"),Q=!1;if(J.searchParams.forEach((z,W)=>{if(n1.has(W.toLowerCase())||e().queryKeys.includes(W.toLowerCase()))J.searchParams.set(W,v),Q=!0}),!Q)return $;return j?J.toString():`${J.pathname}${J.search}`}catch{return $}}function w0($,j){if(j>6||$===null||typeof $!=="object")return $;if(Array.isArray($))return $.map((Q)=>w0(Q,j+1));let J={};for(let[Q,z]of Object.entries($)){let W=a1.test(Q)||e().bodyKeys.some((V)=>Q.toLowerCase().includes(V));J[Q]=W?v:w0(z,j+1)}return J}function o($,j){if($==null)return null;let J=$,Q=$.trim();if(Q.startsWith("{")||Q.startsWith("["))try{let z=JSON.parse(Q);J=JSON.stringify(w0(z,0))}catch{}if(J.length>j)return`${J.slice(0,j)}… [truncated ${J.length-j} chars]`;return J}var X0=120,Y0=40,m=($,j)=>$.length>j?`${$.slice(0,j)}…`:$,F0=($)=>{try{return decodeURIComponent($)}catch{return $}},p=[],h0=0,p0=!1;function d($,j,J,Q){let z=m(j,X0),W=p[p.length-1];if($==="navigate"&&W?.kind==="click"){let X=z.replace(/^ไปที่\s*/,"");if(W.detail.includes(`→ ${X}`))return W.at=new Date().toISOString(),W;let F=X.split(/[?#]/)[0]??X,H=W.source?F0(W.source.replace(/^→\s*/,"")).split(/[?#]/)[0]:null;if(H&&(F===H||F.startsWith(H)))return W.detail=m(`${W.detail} → ${X}`,X0),W.source=void 0,W.at=new Date().toISOString(),W}if(W&&W.kind===$&&W.detail===z){if(W.at=new Date().toISOString(),$!=="navigate")W.count=(W.count??1)+1;return W}h0+=1;let V={id:`act_${h0}`,at:new Date().toISOString(),kind:$,detail:z,count:1,source:J,html:j0(Q)};p.push(V);while(p.length>A("maxActions"))J2(p.shift());return V}var j2=200000,c=0;function j0($){if(!$)return;if(c+$.length>j2)return;return c+=$.length,$}function J2($){if(!$)return;if(c-=($.html?.length??0)+($.afterHtml?.length??0),c<0)c=0}function $0($){return $ instanceof Element&&Boolean($.closest("[data-debug-reporter]"))}var Q2='button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea',z2={button:"ปุ่ม",a:"ลิงก์",input:"ช่อง",textarea:"ช่อง",select:"ตัวเลือก",summary:"ส่วนขยาย"},m0={button:"ปุ่ม",tab:"แท็บ",menuitem:"เมนู",option:"ตัวเลือก",switch:"สวิตช์",checkbox:"ช่องเลือก",radio:"ตัวเลือก",link:"ลิงก์"};function Z2($){let j=$.getAttribute("role");if(j&&m0[j])return m0[j];return z2[$.tagName.toLowerCase()]??"ปุ่ม"}function W2($,j){try{let J=$,Q=0;while(J&&Q<=j){let z=i0(J);if(z&&typeof z.memoizedProps?.onClick==="function")return J;J=J.parentElement,Q+=1}}catch{}return null}function K2($){let j=$.getAttribute("aria-label")?.trim();if(j)return j;let J=$.getAttribute("title")?.trim();if(J)return J;if($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement)return($.getAttribute("placeholder")||$.getAttribute("name")||"").trim();if($ instanceof HTMLImageElement)return($.getAttribute("alt")||"").trim();let Q=($.textContent??"").replace(/\s+/g," ").trim();if(Q)return Q;if($ instanceof HTMLAnchorElement){let z=$.getAttribute("href");if(z?.startsWith("/"))return F0(z)}return""}function V2($){if(!($ instanceof Element))return null;let j=$.closest(Q2)??W2($,4);if(!j)return null;let J=j.tagName.toLowerCase();if(J==="html"||J==="body")return null;return j}function G2($){let j=b(K2($));if(!j)return null;return`${Z2($)} “${m(j,Y0)}”`}var u0=6000,w2=4000,X2=/(?:^|\s)!?(?:fixed|absolute|sticky|inset-\S+|z-\S+|top-\S+|bottom-\S+|left-\S+|right-\S+|w-screen|h-screen|min-h-screen|max-h-screen|translate-\S+|scale-\S+)(?=\s|$)/g;function Y2($){$.querySelectorAll("script, style, link, iframe, object, embed, noscript, canvas, video, audio").forEach((z)=>z.remove());let j=[$,...Array.from($.querySelectorAll("*"))];for(let z of j){for(let V of Array.from(z.attributes)){let X=V.name.toLowerCase();if(X.startsWith("on")||X==="srcdoc"||X==="value"||X.startsWith("data-"))z.removeAttribute(V.name)}if(z instanceof HTMLAnchorElement)z.setAttribute("href","#");if(z instanceof HTMLImageElement)z.removeAttribute("src");let W=z.getAttribute("class");if(W){let V=W.replace(X2," ").replace(/\s+/g," ").trim();if(V)z.setAttribute("class",V);else z.removeAttribute("class")}}let J=document.createTreeWalker($,NodeFilter.SHOW_TEXT),Q=J.nextNode();while(Q){if(Q.nodeValue)Q.nodeValue=b(Q.nodeValue);Q=J.nextNode()}}function M0($,j,J){try{let Q=$.outerHTML;if(!Q||Q.length>j)return;let z=$.cloneNode(!0);Y2(z);let W=z.outerHTML;return W&&W.length<=J?W:void 0}catch{return}}var F2=($)=>M0($,u0,w2),M2=150000,H2=40000,g0=($)=>M0($,M2,H2);function I2($){if(!($ instanceof HTMLInputElement)&&!($ instanceof HTMLTextAreaElement)&&!($ instanceof HTMLSelectElement))return null;let j=$.name||$.id||$.getAttribute("aria-label")||$.getAttribute("placeholder")||$.tagName.toLowerCase();return`ช่อง “${b(j)}”`}var y0=80;function i0($){let j=Object.keys($).find((J)=>J.startsWith("__reactFiber$")||J.startsWith("__reactInternalInstance$"));return j?$[j]:null}function U2($){if(typeof $!=="function")return null;try{let j=Function.prototype.toString.call($);return(j.match(/\.(?:push|replace)\(\s*['"`]([^'"`]+)['"`]/)??j.match(/redirect\(\s*['"`]([^'"`]+)['"`]/))?.[1]??null}catch{return null}}function v0($){if(!$)return;return`→ ${$.length>y0?`${$.slice(0,y0)}…`:$}`}function C2($){try{let j=$.closest("a[href]")?.getAttribute("href");if(j&&j.startsWith("/"))return v0(j);let J=i0($),Q=0;while(J&&Q<30){if(typeof J.memoizedProps?.onClick==="function")return v0(U2(J.memoizedProps.onClick));J=J.return,Q+=1}return}catch{return}}var P2='[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';function N2(){let $=E0();return $.length?$.join(", "):P2}function B2($){let j=$.getAttribute("role");if(j==="status"||j==="alert")return"ข้อความแจ้งเตือน";if(j==="menu")return"เมนู";if(j==="listbox")return"รายการตัวเลือก";if(j==="alertdialog")return"กล่องยืนยัน";return"กล่องโต้ตอบ"}function q2($){let j=$.getAttribute("aria-label")?.trim();if(j)return j;let J=$.getAttribute("aria-labelledby");if(J){let W=J.split(/\s+/).map((V)=>document.getElementById(V)?.textContent?.trim()??"").filter(Boolean).join(" ");if(W)return W}let z=$.querySelector('[data-slot="dialog-title"], h1, h2, h3, [role="heading"]')?.textContent?.replace(/\s+/g," ").trim();if(z)return z;return($.textContent??"").replace(/\s+/g," ").trim()}function o0($){let j=b(q2($)),J=B2($);return j?`เปิด ${J} “${m(j,Y0)}”`:`เปิด ${J}`}var D2='[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin',f2=/กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;function S2($){if($.querySelector(D2))return!0;return f2.test($.textContent??"")}var k2=400,R2=250,O2=8000;function _2($,j){if(typeof MutationObserver>"u"){j.html=j0(g0($));return}let J=Date.now(),Q=!1,z=()=>{Q=!0,V.disconnect(),window.clearInterval(X),window.clearTimeout(F)},W=()=>{if(Q)return;if(z(),!$.isConnected)return;j.detail=m(o0($),X0),j.html=j0(g0($))},V=new MutationObserver(()=>{J=Date.now()});V.observe($,{childList:!0,subtree:!0,attributes:!0,characterData:!0});let X=window.setInterval(()=>{if(Q)return;if(!$.isConnected){z();return}if(Date.now()-J>=k2&&!S2($))W()},R2),F=window.setTimeout(W,O2)}function T2($){if($0($))return;let j=d("ui",o0($));if(j)_2($,j)}function A2(){if(typeof MutationObserver>"u")return;let $=new WeakSet;new MutationObserver((J)=>{for(let Q of J)for(let z of Array.from(Q.addedNodes)){if(!(z instanceof Element))continue;let W=N2(),V=z.matches(W)?[z]:Array.from(z.querySelectorAll(W));for(let X of V){if($.has(X))continue;$.add(X),T2(X)}}}).observe(document.body,{childList:!0,subtree:!0})}var L2=1600,E2=2500;function b0($){return{disabled:$.hasAttribute("disabled")||$.getAttribute("aria-disabled")==="true",busy:$.getAttribute("aria-busy")==="true",text:m(($.textContent??"").replace(/\s+/g," ").trim(),Y0)}}function x2($,j){if(!$.disabled&&j.disabled)return"ปุ่มถูกปิดใช้งานหลังคลิก";if(!$.busy&&j.busy)return"ปุ่มเข้าสู่สถานะกำลังโหลด";if($.text!==j.text&&j.text)return`ข้อความเปลี่ยนเป็น “${j.text}”`;return null}function h2($,j){if(typeof MutationObserver>"u")return;let J=b0($),Q=!1,z=(X,F)=>{if(Q)return;if(Q=!0,W.disconnect(),window.clearTimeout(V),j.afterNote=X,F)j.afterHtml=j0(M0($,u0,E2))},W=new MutationObserver(()=>{if(!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}let X=x2(J,b0($));if(X)z(X,!0)});W.observe($,{attributes:!0,attributeFilter:["disabled","aria-disabled","aria-busy","class"],childList:!0,subtree:!0,characterData:!0});let V=window.setTimeout(()=>{if(!Q&&!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}Q=!0,W.disconnect()},L2)}function d0(){if(p0||typeof window>"u")return;p0=!0,document.addEventListener("click",(Q)=>{if($0(Q.target))return;let z=V2(Q.target);if(!z)return;let W=G2(z);if(!W)return;let V=d("click",`คลิก ${W}`,C2(z),F2(z));if(V)h2(z,V)},{capture:!0,passive:!0}),document.addEventListener("change",(Q)=>{if($0(Q.target))return;let z=I2(Q.target);if(z)d("input",`แก้ไข ${z}`)},{capture:!0,passive:!0}),document.addEventListener("submit",(Q)=>{if($0(Q.target))return;d("submit","ส่งฟอร์ม")},{capture:!0,passive:!0});let $=()=>d("navigate",`ไปที่ ${F0(i(location.pathname+location.search))}`),j=history.pushState.bind(history),J=history.replaceState.bind(history);history.pushState=(...Q)=>{let z=j(...Q);return $(),z},history.replaceState=(...Q)=>{let z=J(...Q);return $(),z},window.addEventListener("popstate",$),A2()}function c0(){return p.map(($)=>({...$}))}var l0=2000,J0=[],r0=0,s0=!1;function H0($,j){r0+=1,J0.push({id:`log_${r0}`,at:new Date().toISOString(),level:$,message:j.length>l0?`${j.slice(0,l0)}…`:j});while(J0.length>A("maxConsoleEntries"))J0.shift()}function p2(){let $=new WeakSet;return(j,J)=>{if(typeof J==="object"&&J!==null){if($.has(J))return"[Circular]";$.add(J)}if(typeof J==="bigint")return J.toString();return J}}function n0($){if(typeof $==="string")return $;if($ instanceof Error)return`${$.name}: ${$.message}`;try{return JSON.stringify($,p2())??String($)}catch{return String($)}}function a0(){if(s0||typeof window>"u")return;s0=!0;let $=["log","info","warn","error","debug"];for(let j of $){let J=console[j].bind(console);console[j]=(...Q)=>{H0(j,Q.map(n0).join(" ")),J(...Q)}}window.addEventListener("error",(j)=>{let J=j.filename?` (${j.filename}:${j.lineno}:${j.colno})`:"";H0("exception",`${j.message}${J}`)}),window.addEventListener("unhandledrejection",(j)=>{let J=j.reason instanceof Error?`${j.reason.name}: ${j.reason.message}`:n0(j.reason);H0("unhandledrejection",J)})}function t0(){return J0.map(($)=>({...$}))}var e0=new Set,$1=new Set;function j1($,j){return $.add(j),()=>$.delete(j)}function J1($,j){for(let J of[...$])J(j)}function Q1($){return j1(e0,$)}function Q0($={type:"manual"}){J1(e0,$)}function z1($){return j1($1,$)}function Z1($){J1($1,$)}var m2=15000,g2=["ResizeObserver loop","Script error.","Non-Error promise rejection captured"],W1=!1,K1=0;function y2($){return g2.some((j)=>$.includes(j))}function V1($){let j=$.message??"";if(!j||y2(j))return;let J=Date.now();if(J-K1<m2)return;K1=J,Z1({...$,message:j})}function G1(){if(W1||typeof window>"u")return;W1=!0,window.addEventListener("error",($)=>{if(!$.message&&!$.error)return;let j=$.error instanceof Error?$.error:null;V1({type:"runtime-error",message:$.message||(j?j.message:"Unknown error"),stack:j?.stack})}),window.addEventListener("unhandledrejection",($)=>{let j=$.reason;V1({type:"unhandledrejection",message:j instanceof Error?j.message:String(j),stack:j instanceof Error?j.stack:void 0})})}var F1=4000,v2=1e6,b2=1e7,z0=[],w1=0,X1=!1;function M1($){z0.push($);while(z0.length>A("maxRequests"))z0.shift()}function H1(){return w1+=1,`req_${w1}`}function Y1($){let j={};if(!$)return j;if($ instanceof Headers)$.forEach((J,Q)=>{j[Q]=J});else if(Array.isArray($))for(let[J,Q]of $)j[J]=Q;else Object.assign(j,$);return j}function u2($){let j={};return $.forEach((J,Q)=>{j[Q]=J}),j}function i2($){if($==null)return null;if(typeof $==="string")return $;if($ instanceof URLSearchParams)return $.toString();if(typeof FormData<"u"&&$ instanceof FormData)return`[FormData: ${Array.from($.keys()).join(", ")}]`;if(typeof Blob<"u"&&$ instanceof Blob)return`[Blob ${$.size} bytes]`;if($ instanceof ArrayBuffer)return`[ArrayBuffer ${$.byteLength} bytes]`;return"[binary]"}function o2($,j){let J="",Q="GET",z={},W=null;if(typeof $==="string")J=$;else if($ instanceof URL)J=$.toString();else J=$.url,Q=$.method||Q,z=Y1($.headers);if(j){if(j.method)Q=j.method;if(j.headers)z={...z,...Y1(j.headers)};if(j.body!==void 0)W=i2(j.body)}return{method:Q.toUpperCase(),url:J,headers:z,body:W}}function I1($){return!x0($)}function d2($,j){if(I1(j.url)){j.responseSnippet="[body not captured for this origin]";return}let J=$.headers.get("content-type")??"",Q=Number($.headers.get("content-length")??"0"),z=Q?`, ~${Q} bytes`:"";if(!/json|text|xml|html|javascript|urlencoded/i.test(J)){j.responseSnippet=`[binary ${J||"unknown"}${z}]`;return}if(Q>v2){j.responseSnippet=`[response ${J||"text"}${z} — omitted]`;return}try{$.clone().text().then((W)=>{j.responseSnippet=o(W,A("maxBodyChars"))}).catch(()=>{})}catch{}}function U1($,j){if(/[?&]_rsc=/.test($))return!0;for(let J of Object.keys(j)){let Q=J.toLowerCase();if(Q==="rsc"||Q==="next-router-prefetch"||Q==="next-router-state-tree")return!0}return!1}function c2(){if(typeof window>"u"||typeof window.fetch!=="function")return;let $=window.fetch.bind(window);window.fetch=Object.assign(async(j,J)=>{let Q=o2(j,J);if(U1(Q.url,Q.headers))return $(j,J);let z={id:H1(),startedAt:new Date().toISOString(),method:Q.method,url:i(Q.url),requestHeaders:u(Q.headers),requestBody:o(Q.body,F1),status:null,statusText:null,durationMs:null,via:"fetch"};M1(z);let W=performance.now();try{let V=await $(j,J);return z.status=V.status,z.statusText=V.statusText,z.durationMs=Math.round(performance.now()-W),z.responseHeaders=u(u2(V.headers)),d2(V,z),V}catch(V){throw z.durationMs=Math.round(performance.now()-W),z.error=V instanceof Error?`${V.name}: ${V.message}`:String(V),V}},$)}function l2(){if(typeof window>"u"||typeof window.XMLHttpRequest!=="function")return;let $=XMLHttpRequest.prototype,j=$.open,J=$.send,Q=function(W,V){let X=typeof V==="string"?V:V.toString();return this.__cibEntry=U1(X,{})?void 0:{id:H1(),startedAt:"",method:(W||"GET").toUpperCase(),url:i(X),requestHeaders:{},requestBody:null,status:null,statusText:null,durationMs:null,via:"xhr"},j.apply(this,arguments)},z=function(W){let V=this.__cibEntry;if(V){V.startedAt=new Date().toISOString(),V.requestBody=typeof W==="string"?o(W,F1):W==null?null:"[non-string body]";let X=performance.now();M1(V),this.addEventListener("loadend",()=>{if(V.status=this.status||null,V.statusText=this.statusText||null,V.durationMs=Math.round(performance.now()-X),I1(V.url))V.responseSnippet="[body not captured for this origin]";else if(this.responseType===""||this.responseType==="text")try{V.responseSnippet=o(this.responseText||"",A("maxBodyChars"))}catch{}else{let F=this.getResponseHeader("content-type")??this.responseType;V.responseSnippet=`[binary ${F}]`}})}return J.apply(this,arguments)};$.open=Q,$.send=z}function C1(){if(X1)return;X1=!0,c2(),l2()}function P1(){let $=z0.map((J)=>({...J})),j=0;for(let J=$.length-1;J>=0;J-=1){let Q=$[J],z=Q?.responseSnippet;if(!Q||typeof z!=="string"||z.length===0)continue;if(j+z.length>b2)Q.responseSnippet=`[response omitted — report size budget reached (${z.length.toLocaleString()} chars)]`;else j+=z.length}return $}var r2={title:"รายงานปัญหา",summaryLabel:"หัวข้อปัญหา",summaryRequired:"(ต้องกรอกก่อนแจ้งปัญหา)",summaryPlaceholder:"สรุปปัญหาสั้น ๆ เช่น กดบันทึกร่างแล้ว error",detailLabel:"อธิบายปัญหา (ไม่บังคับ)",detailPlaceholder:"เกิดอะไรขึ้น? กำลังทำอะไรอยู่ตอนที่พบปัญหา?",annotateTitle:"วาดบนรูป",annotateHint:"ทำเครื่องหมายจุดที่มีปัญหาก่อนแนบ — วงกรอบ ชี้ลูกศร ไฮไลต์ หรือพิมพ์ข้อความ",annotateApply:"ใช้รูปนี้",cancel:"ยกเลิก",toolRect:"กรอบ",toolArrow:"ลูกศร",toolHighlight:"ไฮไลต์",toolText:"ข้อความ",deleteSelected:"ลบที่เลือก",clearAll:"ล้างทั้งหมด",annotateHelp:"เลือกเครื่องมือแล้วลากบนรูป · ไม่ได้เลือกเครื่องมือ = ย้าย/ปรับขนาดสิ่งที่วาดไว้ · กดกากบาทมุมขวาบนของรูปทรงเพื่อลบ",capturing:"กำลังเก็บภาพหน้าจอ…",noScreenshot:"ไม่มีภาพหน้าจอ — ยังส่งรายงานได้",cancelled:"ยกเลิกการเก็บภาพหน้าจอแล้ว",close:"ปิด",submit:"แจ้งปัญหา",submitting:"กำลังส่ง…",submitted:"แจ้งปัญหาสำเร็จ",crashed:"เกิดข้อผิดพลาดในระบบ",crashAction:"แจ้งปัญหา",failed:"ส่งรายงานไม่สำเร็จ",captured:"เก็บข้อมูลแล้ว",reporter:"ผู้แจ้ง",page:"หน้า",handoffTitle:"กำลังพาไปที่ระบบแจ้งปัญหา",handoffBody:"ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",handoffGo:"ไปเลย",handoffPreparing:"กำลังเตรียม…",handoffFailed:"เปิดรายการที่แจ้งไว้ไม่สำเร็จ",handoffBlocked:"เบราว์เซอร์บล็อกการเปิดแท็บใหม่",handoffOpen:"เปิดในแท็บใหม่"},s2={title:"Report a problem",summaryLabel:"Summary",summaryRequired:"(required)",summaryPlaceholder:"One line, e.g. saving a draft returns an error",detailLabel:"Details (optional)",detailPlaceholder:"What happened? What were you doing at the time?",annotateTitle:"Draw on the image",annotateHint:"Mark what went wrong before attaching — box it, point at it, highlight it, or type on it",annotateApply:"Use this image",cancel:"Cancel",toolRect:"Box",toolArrow:"Arrow",toolHighlight:"Highlight",toolText:"Text",deleteSelected:"Delete selected",clearAll:"Clear all",annotateHelp:"Pick a tool and drag on the image · no tool selected = move/resize what you drew · press the ✕ on a shape to delete it",capturing:"Capturing the screen…",noScreenshot:"No screenshot — you can still send the report",cancelled:"Screen capture cancelled",close:"Close",submit:"Send report",submitting:"Sending…",submitted:"Report sent",crashed:"Something went wrong",crashAction:"Report it",failed:"Could not send the report",captured:"Captured",reporter:"Reporter",page:"Page",handoffTitle:"Opening the support portal",handoffBody:"You will be signed in automatically to see what you reported",handoffGo:"Go now",handoffPreparing:"Preparing…",handoffFailed:"Could not open your reports",handoffBlocked:"Your browser blocked the new tab",handoffOpen:"Open in a new tab"};function Z0($){return $==="en"?s2:r2}var I0=null;function n2(){if(typeof document>"u")return null;if(I0?.isConnected)return I0;let $=document.createElement("lw-debug-toasts");$.dataset.debugReporter="true";let j=$.attachShadow({mode:"open"}),J=document.createElement("style");J.textContent=`
|
|
1
|
+
(()=>{var c1={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},R=null;function T0($){R=$}function f(){if(!R)throw Error("[debug-capture] configureDebugCapture() has not been called");return R}function A0(){return R!==null}function A(){let $=f().app;return{name:$.name,version:$.version??"0.0.0",environment:$.environment??l1()}}function l1(){if(typeof window>"u")return"unknown";let $=window.location.hostname;if($==="localhost"||$==="127.0.0.1"||$.endsWith(".local"))return"development";return"production"}function L($){let j=R?.capture?.[$];return typeof j==="number"?j:c1[$]}function L0($){let j=R?.module;if(!j)return null;try{return j($)??null}catch{return null}}function e(){let $=R?.redact;return{headers:$?.headers??[],queryKeys:($?.queryKeys??[]).map((j)=>j.toLowerCase()),bodyKeys:($?.bodyKeys??[]).map((j)=>j.toLowerCase())}}function E0(){return R?.capture?.overlaySelectors??[]}function x0($){if(typeof window>"u")return!1;let j;try{j=new URL($,window.location.href)}catch{return!1}if(r1(j))return!1;if(j.origin===window.location.origin)return!0;return(R?.capture?.bodyOrigins??[]).some((J)=>{try{return new URL(J).origin===j.origin}catch{return!1}})}function r1($){if(!R?.host)return!1;try{if(new URL(R.host).origin!==$.origin)return!1}catch{return!1}return $.pathname.startsWith("/ingest/")}var v="‹redacted›",s1=/^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i,n1=new Set(["access_token","token","id_token","refresh_token","code","secret","client_secret","password","apikey","api_key","signature","x-amz-signature","x-amz-credential"]),a1=/(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i,t1=/[\w.+-]+@[\w-]+\.[\w.-]+/g,e1=/\d(?:[\d\s-]{7,})\d/g;function b($){return $.replace(t1,v).replace(e1,v)}function $2($){if(s1.test($))return!0;return e().headers.some((J)=>J.toLowerCase()===$.toLowerCase())}function u($){let j={};for(let[J,Q]of Object.entries($))j[J]=$2(J)?v:Q;return j}function i($){try{let j=/^https?:\/\//i.test($),J=new URL($,j?void 0:"http://local.invalid"),Q=!1;if(J.searchParams.forEach((z,W)=>{if(n1.has(W.toLowerCase())||e().queryKeys.includes(W.toLowerCase()))J.searchParams.set(W,v),Q=!0}),!Q)return $;return j?J.toString():`${J.pathname}${J.search}`}catch{return $}}function w0($,j){if(j>6||$===null||typeof $!=="object")return $;if(Array.isArray($))return $.map((Q)=>w0(Q,j+1));let J={};for(let[Q,z]of Object.entries($)){let W=a1.test(Q)||e().bodyKeys.some((V)=>Q.toLowerCase().includes(V));J[Q]=W?v:w0(z,j+1)}return J}function o($,j){if($==null)return null;let J=$,Q=$.trim();if(Q.startsWith("{")||Q.startsWith("["))try{let z=JSON.parse(Q);J=JSON.stringify(w0(z,0))}catch{}if(J.length>j)return`${J.slice(0,j)}… [truncated ${J.length-j} chars]`;return J}var X0=120,Y0=40,m=($,j)=>$.length>j?`${$.slice(0,j)}…`:$,F0=($)=>{try{return decodeURIComponent($)}catch{return $}},p=[],h0=0,p0=!1;function d($,j,J,Q){let z=m(j,X0),W=p[p.length-1];if($==="navigate"&&W?.kind==="click"){let X=z.replace(/^ไปที่\s*/,"");if(W.detail.includes(`→ ${X}`))return W.at=new Date().toISOString(),W;let F=X.split(/[?#]/)[0]??X,H=W.source?F0(W.source.replace(/^→\s*/,"")).split(/[?#]/)[0]:null;if(H&&(F===H||F.startsWith(H)))return W.detail=m(`${W.detail} → ${X}`,X0),W.source=void 0,W.at=new Date().toISOString(),W}if(W&&W.kind===$&&W.detail===z){if(W.at=new Date().toISOString(),$!=="navigate")W.count=(W.count??1)+1;return W}h0+=1;let V={id:`act_${h0}`,at:new Date().toISOString(),kind:$,detail:z,count:1,source:J,html:j0(Q)};p.push(V);while(p.length>L("maxActions"))J2(p.shift());return V}var j2=200000,c=0;function j0($){if(!$)return;if(c+$.length>j2)return;return c+=$.length,$}function J2($){if(!$)return;if(c-=($.html?.length??0)+($.afterHtml?.length??0),c<0)c=0}function $0($){return $ instanceof Element&&Boolean($.closest("[data-debug-reporter]"))}var Q2='button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea',z2={button:"ปุ่ม",a:"ลิงก์",input:"ช่อง",textarea:"ช่อง",select:"ตัวเลือก",summary:"ส่วนขยาย"},m0={button:"ปุ่ม",tab:"แท็บ",menuitem:"เมนู",option:"ตัวเลือก",switch:"สวิตช์",checkbox:"ช่องเลือก",radio:"ตัวเลือก",link:"ลิงก์"};function Z2($){let j=$.getAttribute("role");if(j&&m0[j])return m0[j];return z2[$.tagName.toLowerCase()]??"ปุ่ม"}function W2($,j){try{let J=$,Q=0;while(J&&Q<=j){let z=i0(J);if(z&&typeof z.memoizedProps?.onClick==="function")return J;J=J.parentElement,Q+=1}}catch{}return null}function K2($){let j=$.getAttribute("aria-label")?.trim();if(j)return j;let J=$.getAttribute("title")?.trim();if(J)return J;if($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement)return($.getAttribute("placeholder")||$.getAttribute("name")||"").trim();if($ instanceof HTMLImageElement)return($.getAttribute("alt")||"").trim();let Q=($.textContent??"").replace(/\s+/g," ").trim();if(Q)return Q;if($ instanceof HTMLAnchorElement){let z=$.getAttribute("href");if(z?.startsWith("/"))return F0(z)}return""}function V2($){if(!($ instanceof Element))return null;let j=$.closest(Q2)??W2($,4);if(!j)return null;let J=j.tagName.toLowerCase();if(J==="html"||J==="body")return null;return j}function G2($){let j=b(K2($));if(!j)return null;return`${Z2($)} “${m(j,Y0)}”`}var u0=6000,w2=4000,X2=/(?:^|\s)!?(?:fixed|absolute|sticky|inset-\S+|z-\S+|top-\S+|bottom-\S+|left-\S+|right-\S+|w-screen|h-screen|min-h-screen|max-h-screen|translate-\S+|scale-\S+)(?=\s|$)/g;function Y2($){$.querySelectorAll("script, style, link, iframe, object, embed, noscript, canvas, video, audio").forEach((z)=>z.remove());let j=[$,...Array.from($.querySelectorAll("*"))];for(let z of j){for(let V of Array.from(z.attributes)){let X=V.name.toLowerCase();if(X.startsWith("on")||X==="srcdoc"||X==="value"||X.startsWith("data-"))z.removeAttribute(V.name)}if(z instanceof HTMLAnchorElement)z.setAttribute("href","#");if(z instanceof HTMLImageElement)z.removeAttribute("src");let W=z.getAttribute("class");if(W){let V=W.replace(X2," ").replace(/\s+/g," ").trim();if(V)z.setAttribute("class",V);else z.removeAttribute("class")}}let J=document.createTreeWalker($,NodeFilter.SHOW_TEXT),Q=J.nextNode();while(Q){if(Q.nodeValue)Q.nodeValue=b(Q.nodeValue);Q=J.nextNode()}}function M0($,j,J){try{let Q=$.outerHTML;if(!Q||Q.length>j)return;let z=$.cloneNode(!0);Y2(z);let W=z.outerHTML;return W&&W.length<=J?W:void 0}catch{return}}var F2=($)=>M0($,u0,w2),M2=150000,H2=40000,g0=($)=>M0($,M2,H2);function I2($){if(!($ instanceof HTMLInputElement)&&!($ instanceof HTMLTextAreaElement)&&!($ instanceof HTMLSelectElement))return null;let j=$.name||$.id||$.getAttribute("aria-label")||$.getAttribute("placeholder")||$.tagName.toLowerCase();return`ช่อง “${b(j)}”`}var y0=80;function i0($){let j=Object.keys($).find((J)=>J.startsWith("__reactFiber$")||J.startsWith("__reactInternalInstance$"));return j?$[j]:null}function U2($){if(typeof $!=="function")return null;try{let j=Function.prototype.toString.call($);return(j.match(/\.(?:push|replace)\(\s*['"`]([^'"`]+)['"`]/)??j.match(/redirect\(\s*['"`]([^'"`]+)['"`]/))?.[1]??null}catch{return null}}function v0($){if(!$)return;return`→ ${$.length>y0?`${$.slice(0,y0)}…`:$}`}function C2($){try{let j=$.closest("a[href]")?.getAttribute("href");if(j&&j.startsWith("/"))return v0(j);let J=i0($),Q=0;while(J&&Q<30){if(typeof J.memoizedProps?.onClick==="function")return v0(U2(J.memoizedProps.onClick));J=J.return,Q+=1}return}catch{return}}var P2='[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';function N2(){let $=E0();return $.length?$.join(", "):P2}function B2($){let j=$.getAttribute("role");if(j==="status"||j==="alert")return"ข้อความแจ้งเตือน";if(j==="menu")return"เมนู";if(j==="listbox")return"รายการตัวเลือก";if(j==="alertdialog")return"กล่องยืนยัน";return"กล่องโต้ตอบ"}function q2($){let j=$.getAttribute("aria-label")?.trim();if(j)return j;let J=$.getAttribute("aria-labelledby");if(J){let W=J.split(/\s+/).map((V)=>document.getElementById(V)?.textContent?.trim()??"").filter(Boolean).join(" ");if(W)return W}let z=$.querySelector('[data-slot="dialog-title"], h1, h2, h3, [role="heading"]')?.textContent?.replace(/\s+/g," ").trim();if(z)return z;return($.textContent??"").replace(/\s+/g," ").trim()}function o0($){let j=b(q2($)),J=B2($);return j?`เปิด ${J} “${m(j,Y0)}”`:`เปิด ${J}`}var D2='[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin',f2=/กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;function S2($){if($.querySelector(D2))return!0;return f2.test($.textContent??"")}var k2=400,R2=250,O2=8000;function _2($,j){if(typeof MutationObserver>"u"){j.html=j0(g0($));return}let J=Date.now(),Q=!1,z=()=>{Q=!0,V.disconnect(),window.clearInterval(X),window.clearTimeout(F)},W=()=>{if(Q)return;if(z(),!$.isConnected)return;j.detail=m(o0($),X0),j.html=j0(g0($))},V=new MutationObserver(()=>{J=Date.now()});V.observe($,{childList:!0,subtree:!0,attributes:!0,characterData:!0});let X=window.setInterval(()=>{if(Q)return;if(!$.isConnected){z();return}if(Date.now()-J>=k2&&!S2($))W()},R2),F=window.setTimeout(W,O2)}function T2($){if($0($))return;let j=d("ui",o0($));if(j)_2($,j)}function A2(){if(typeof MutationObserver>"u")return;let $=new WeakSet;new MutationObserver((J)=>{for(let Q of J)for(let z of Array.from(Q.addedNodes)){if(!(z instanceof Element))continue;let W=N2(),V=z.matches(W)?[z]:Array.from(z.querySelectorAll(W));for(let X of V){if($.has(X))continue;$.add(X),T2(X)}}}).observe(document.body,{childList:!0,subtree:!0})}var L2=1600,E2=2500;function b0($){return{disabled:$.hasAttribute("disabled")||$.getAttribute("aria-disabled")==="true",busy:$.getAttribute("aria-busy")==="true",text:m(($.textContent??"").replace(/\s+/g," ").trim(),Y0)}}function x2($,j){if(!$.disabled&&j.disabled)return"ปุ่มถูกปิดใช้งานหลังคลิก";if(!$.busy&&j.busy)return"ปุ่มเข้าสู่สถานะกำลังโหลด";if($.text!==j.text&&j.text)return`ข้อความเปลี่ยนเป็น “${j.text}”`;return null}function h2($,j){if(typeof MutationObserver>"u")return;let J=b0($),Q=!1,z=(X,F)=>{if(Q)return;if(Q=!0,W.disconnect(),window.clearTimeout(V),j.afterNote=X,F)j.afterHtml=j0(M0($,u0,E2))},W=new MutationObserver(()=>{if(!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}let X=x2(J,b0($));if(X)z(X,!0)});W.observe($,{attributes:!0,attributeFilter:["disabled","aria-disabled","aria-busy","class"],childList:!0,subtree:!0,characterData:!0});let V=window.setTimeout(()=>{if(!Q&&!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}Q=!0,W.disconnect()},L2)}function d0(){if(p0||typeof window>"u")return;p0=!0,document.addEventListener("click",(Q)=>{if($0(Q.target))return;let z=V2(Q.target);if(!z)return;let W=G2(z);if(!W)return;let V=d("click",`คลิก ${W}`,C2(z),F2(z));if(V)h2(z,V)},{capture:!0,passive:!0}),document.addEventListener("change",(Q)=>{if($0(Q.target))return;let z=I2(Q.target);if(z)d("input",`แก้ไข ${z}`)},{capture:!0,passive:!0}),document.addEventListener("submit",(Q)=>{if($0(Q.target))return;d("submit","ส่งฟอร์ม")},{capture:!0,passive:!0});let $=()=>d("navigate",`ไปที่ ${F0(i(location.pathname+location.search))}`),j=history.pushState.bind(history),J=history.replaceState.bind(history);history.pushState=(...Q)=>{let z=j(...Q);return $(),z},history.replaceState=(...Q)=>{let z=J(...Q);return $(),z},window.addEventListener("popstate",$),A2()}function c0(){return p.map(($)=>({...$}))}var l0=2000,J0=[],r0=0,s0=!1;function H0($,j){r0+=1,J0.push({id:`log_${r0}`,at:new Date().toISOString(),level:$,message:j.length>l0?`${j.slice(0,l0)}…`:j});while(J0.length>L("maxConsoleEntries"))J0.shift()}function p2(){let $=new WeakSet;return(j,J)=>{if(typeof J==="object"&&J!==null){if($.has(J))return"[Circular]";$.add(J)}if(typeof J==="bigint")return J.toString();return J}}function n0($){if(typeof $==="string")return $;if($ instanceof Error)return`${$.name}: ${$.message}`;try{return JSON.stringify($,p2())??String($)}catch{return String($)}}function a0(){if(s0||typeof window>"u")return;s0=!0;let $=["log","info","warn","error","debug"];for(let j of $){let J=console[j].bind(console);console[j]=(...Q)=>{H0(j,Q.map(n0).join(" ")),J(...Q)}}window.addEventListener("error",(j)=>{let J=j.filename?` (${j.filename}:${j.lineno}:${j.colno})`:"";H0("exception",`${j.message}${J}`)}),window.addEventListener("unhandledrejection",(j)=>{let J=j.reason instanceof Error?`${j.reason.name}: ${j.reason.message}`:n0(j.reason);H0("unhandledrejection",J)})}function t0(){return J0.map(($)=>({...$}))}var e0=new Set,$1=new Set;function j1($,j){return $.add(j),()=>$.delete(j)}function J1($,j){for(let J of[...$])J(j)}function Q1($){return j1(e0,$)}function Q0($={type:"manual"}){J1(e0,$)}function z1($){return j1($1,$)}function Z1($){J1($1,$)}var m2=15000,g2=["ResizeObserver loop","Script error.","Non-Error promise rejection captured"],W1=!1,K1=0;function y2($){return g2.some((j)=>$.includes(j))}function V1($){let j=$.message??"";if(!j||y2(j))return;let J=Date.now();if(J-K1<m2)return;K1=J,Z1({...$,message:j})}function G1(){if(W1||typeof window>"u")return;W1=!0,window.addEventListener("error",($)=>{if(!$.message&&!$.error)return;let j=$.error instanceof Error?$.error:null;V1({type:"runtime-error",message:$.message||(j?j.message:"Unknown error"),stack:j?.stack})}),window.addEventListener("unhandledrejection",($)=>{let j=$.reason;V1({type:"unhandledrejection",message:j instanceof Error?j.message:String(j),stack:j instanceof Error?j.stack:void 0})})}var F1=4000,v2=1e6,b2=1e7,z0=[],w1=0,X1=!1;function M1($){z0.push($);while(z0.length>L("maxRequests"))z0.shift()}function H1(){return w1+=1,`req_${w1}`}function Y1($){let j={};if(!$)return j;if($ instanceof Headers)$.forEach((J,Q)=>{j[Q]=J});else if(Array.isArray($))for(let[J,Q]of $)j[J]=Q;else Object.assign(j,$);return j}function u2($){let j={};return $.forEach((J,Q)=>{j[Q]=J}),j}function i2($){if($==null)return null;if(typeof $==="string")return $;if($ instanceof URLSearchParams)return $.toString();if(typeof FormData<"u"&&$ instanceof FormData)return`[FormData: ${Array.from($.keys()).join(", ")}]`;if(typeof Blob<"u"&&$ instanceof Blob)return`[Blob ${$.size} bytes]`;if($ instanceof ArrayBuffer)return`[ArrayBuffer ${$.byteLength} bytes]`;return"[binary]"}function o2($,j){let J="",Q="GET",z={},W=null;if(typeof $==="string")J=$;else if($ instanceof URL)J=$.toString();else J=$.url,Q=$.method||Q,z=Y1($.headers);if(j){if(j.method)Q=j.method;if(j.headers)z={...z,...Y1(j.headers)};if(j.body!==void 0)W=i2(j.body)}return{method:Q.toUpperCase(),url:J,headers:z,body:W}}function I1($){return!x0($)}function d2($,j){if(I1(j.url)){j.responseSnippet="[body not captured for this origin]";return}let J=$.headers.get("content-type")??"",Q=Number($.headers.get("content-length")??"0"),z=Q?`, ~${Q} bytes`:"";if(!/json|text|xml|html|javascript|urlencoded/i.test(J)){j.responseSnippet=`[binary ${J||"unknown"}${z}]`;return}if(Q>v2){j.responseSnippet=`[response ${J||"text"}${z} — omitted]`;return}try{$.clone().text().then((W)=>{j.responseSnippet=o(W,L("maxBodyChars"))}).catch(()=>{})}catch{}}function U1($,j){if(/[?&]_rsc=/.test($))return!0;for(let J of Object.keys(j)){let Q=J.toLowerCase();if(Q==="rsc"||Q==="next-router-prefetch"||Q==="next-router-state-tree")return!0}return!1}function c2(){if(typeof window>"u"||typeof window.fetch!=="function")return;let $=window.fetch.bind(window);window.fetch=Object.assign(async(j,J)=>{let Q=o2(j,J);if(U1(Q.url,Q.headers))return $(j,J);let z={id:H1(),startedAt:new Date().toISOString(),method:Q.method,url:i(Q.url),requestHeaders:u(Q.headers),requestBody:o(Q.body,F1),status:null,statusText:null,durationMs:null,via:"fetch"};M1(z);let W=performance.now();try{let V=await $(j,J);return z.status=V.status,z.statusText=V.statusText,z.durationMs=Math.round(performance.now()-W),z.responseHeaders=u(u2(V.headers)),d2(V,z),V}catch(V){throw z.durationMs=Math.round(performance.now()-W),z.error=V instanceof Error?`${V.name}: ${V.message}`:String(V),V}},$)}function l2(){if(typeof window>"u"||typeof window.XMLHttpRequest!=="function")return;let $=XMLHttpRequest.prototype,j=$.open,J=$.send,Q=function(W,V){let X=typeof V==="string"?V:V.toString();return this.__cibEntry=U1(X,{})?void 0:{id:H1(),startedAt:"",method:(W||"GET").toUpperCase(),url:i(X),requestHeaders:{},requestBody:null,status:null,statusText:null,durationMs:null,via:"xhr"},j.apply(this,arguments)},z=function(W){let V=this.__cibEntry;if(V){V.startedAt=new Date().toISOString(),V.requestBody=typeof W==="string"?o(W,F1):W==null?null:"[non-string body]";let X=performance.now();M1(V),this.addEventListener("loadend",()=>{if(V.status=this.status||null,V.statusText=this.statusText||null,V.durationMs=Math.round(performance.now()-X),I1(V.url))V.responseSnippet="[body not captured for this origin]";else if(this.responseType===""||this.responseType==="text")try{V.responseSnippet=o(this.responseText||"",L("maxBodyChars"))}catch{}else{let F=this.getResponseHeader("content-type")??this.responseType;V.responseSnippet=`[binary ${F}]`}})}return J.apply(this,arguments)};$.open=Q,$.send=z}function C1(){if(X1)return;X1=!0,c2(),l2()}function P1(){let $=z0.map((J)=>({...J})),j=0;for(let J=$.length-1;J>=0;J-=1){let Q=$[J],z=Q?.responseSnippet;if(!Q||typeof z!=="string"||z.length===0)continue;if(j+z.length>b2)Q.responseSnippet=`[response omitted — report size budget reached (${z.length.toLocaleString()} chars)]`;else j+=z.length}return $}var r2={title:"รายงานปัญหา",summaryLabel:"หัวข้อปัญหา",summaryRequired:"(ต้องกรอกก่อนแจ้งปัญหา)",summaryPlaceholder:"สรุปปัญหาสั้น ๆ เช่น กดบันทึกร่างแล้ว error",detailLabel:"อธิบายปัญหา (ไม่บังคับ)",detailPlaceholder:"เกิดอะไรขึ้น? กำลังทำอะไรอยู่ตอนที่พบปัญหา?",annotateTitle:"วาดบนรูป",annotateHint:"ทำเครื่องหมายจุดที่มีปัญหาก่อนแนบ — วงกรอบ ชี้ลูกศร ไฮไลต์ หรือพิมพ์ข้อความ",annotateApply:"ใช้รูปนี้",cancel:"ยกเลิก",toolRect:"กรอบ",toolArrow:"ลูกศร",toolHighlight:"ไฮไลต์",toolText:"ข้อความ",deleteSelected:"ลบที่เลือก",clearAll:"ล้างทั้งหมด",annotateHelp:"เลือกเครื่องมือแล้วลากบนรูป · ไม่ได้เลือกเครื่องมือ = ย้าย/ปรับขนาดสิ่งที่วาดไว้ · กดกากบาทมุมขวาบนของรูปทรงเพื่อลบ",capturing:"กำลังเก็บภาพหน้าจอ…",noScreenshot:"ไม่มีภาพหน้าจอ — ยังส่งรายงานได้",cancelled:"ยกเลิกการเก็บภาพหน้าจอแล้ว",close:"ปิด",submit:"แจ้งปัญหา",submitting:"กำลังส่ง…",submitted:"แจ้งปัญหาสำเร็จ",crashed:"เกิดข้อผิดพลาดในระบบ",crashAction:"แจ้งปัญหา",failed:"ส่งรายงานไม่สำเร็จ",captured:"เก็บข้อมูลแล้ว",reporter:"ผู้แจ้ง",page:"หน้า",handoffTitle:"กำลังพาไปที่ระบบแจ้งปัญหา",handoffBody:"ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",handoffGo:"ไปเลย",handoffPreparing:"กำลังเตรียม…",handoffFailed:"เปิดรายการที่แจ้งไว้ไม่สำเร็จ",handoffBlocked:"เบราว์เซอร์บล็อกการเปิดแท็บใหม่",handoffOpen:"เปิดในแท็บใหม่"},s2={title:"Report a problem",summaryLabel:"Summary",summaryRequired:"(required)",summaryPlaceholder:"One line, e.g. saving a draft returns an error",detailLabel:"Details (optional)",detailPlaceholder:"What happened? What were you doing at the time?",annotateTitle:"Draw on the image",annotateHint:"Mark what went wrong before attaching — box it, point at it, highlight it, or type on it",annotateApply:"Use this image",cancel:"Cancel",toolRect:"Box",toolArrow:"Arrow",toolHighlight:"Highlight",toolText:"Text",deleteSelected:"Delete selected",clearAll:"Clear all",annotateHelp:"Pick a tool and drag on the image · no tool selected = move/resize what you drew · press the ✕ on a shape to delete it",capturing:"Capturing the screen…",noScreenshot:"No screenshot — you can still send the report",cancelled:"Screen capture cancelled",close:"Close",submit:"Send report",submitting:"Sending…",submitted:"Report sent",crashed:"Something went wrong",crashAction:"Report it",failed:"Could not send the report",captured:"Captured",reporter:"Reporter",page:"Page",handoffTitle:"Opening the support portal",handoffBody:"You will be signed in automatically to see what you reported",handoffGo:"Go now",handoffPreparing:"Preparing…",handoffFailed:"Could not open your reports",handoffBlocked:"Your browser blocked the new tab",handoffOpen:"Open in a new tab"};function Z0($){return $==="en"?s2:r2}var I0=null;function n2(){if(typeof document>"u")return null;if(I0?.isConnected)return I0;let $=document.createElement("lw-debug-toasts");$.dataset.debugReporter="true";let j=$.attachShadow({mode:"open"}),J=document.createElement("style");J.textContent=`
|
|
2
2
|
:host { all: initial; }
|
|
3
3
|
.stack {
|
|
4
4
|
position: fixed; top: 16px; right: 16px; z-index: 2147483001;
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
}
|
|
31
31
|
@keyframes in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
|
|
32
32
|
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
|
|
33
|
-
`;let Q=document.createElement("div");return Q.className="stack",Q.setAttribute("role","status"),Q.setAttribute("aria-live","polite"),j.append(J,Q),document.body.append($),I0=Q,Q}function l($,j="success",J){let Q=n2();if(!Q)return;let z=document.createElement("div");z.className="toast",z.dataset.tone=j;let W=document.createElement("span");W.className="dot";let V=document.createElement("span");V.textContent=$;let X=document.createElement("button");X.type="button",X.className="close",X.textContent="✕",X.setAttribute("aria-label","ปิด");let F=()=>{window.clearTimeout(H),z.remove()};X.addEventListener("click",F);let H=j==="error"||J?0:window.setTimeout(F,6000);if(z.append(W,V),J){let U=document.createElement("button");U.type="button",U.className="action",U.textContent=J.label,U.addEventListener("click",()=>{F(),J.onClick()}),z.append(U)}z.append(X),Q.append(z)}function N1($,j,J){let Q=$.filter((W)=>Boolean(W.error)||W.status!=null&&W.status>=400).slice(-20).map((W)=>({method:W.method,url:W.url,status:W.status,error:W.error,at:W.startedAt})),z=j.filter((W)=>W.level==="error"||W.level==="exception"||W.level==="unhandledrejection").slice(-20).map((W)=>W.message);return{failedRequests:Q,errors:z,erroredQueries:J.slice(0,20)}}function a2(){let $={memoryUsedMb:null,memoryLimitMb:null,domContentLoadedMs:null,loadEventMs:null};if(typeof performance>"u")return $;let j=performance.memory;if(j)$.memoryUsedMb=Math.round(j.usedJSHeapSize/1024/1024),$.memoryLimitMb=Math.round(j.jsHeapSizeLimit/1024/1024);let[J]=performance.getEntriesByType("navigation");if(J)$.domContentLoadedMs=Math.round(J.domContentLoadedEventEnd),$.loadEventMs=Math.round(J.loadEventEnd);return $}function U0($,j){if(!$)return j;try{return $()}catch{return j}}function B1(){let $=f(),{pathname:j,search:J,href:Q}=window.location;return{capturedAt:new Date().toISOString(),route:{href:Q,pathname:j,search:J},module:L0(j),user:U0($.user,{}),apiHeaders:u(U0($.headers,{})),app:{name:h().name,version:h().version,environment:h().environment},client:{userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,online:navigator.onLine,viewport:{width:window.innerWidth,height:window.innerHeight,dpr:window.devicePixelRatio},screen:{width:window.screen.width,height:window.screen.height}},performance:a2(),extra:U0($.extra,{})}}var t2=2;function q1($){let j=P1(),J=t0();return{context:B1(),reason:$.reason,note:$.note,cause:N1(j,J,$.erroredQueries),actionTrail:c0(),network:j,console:J,screenshotDataUrl:$.screenshotDataUrl,screenshotMethod:$.screenshotMethod,meta:{generatedBy:"lightwork-debug-capture",schemaVersion:t2}}}async function D1(){if(typeof navigator<"u"&&Boolean(navigator.mediaDevices?.getDisplayMedia)){let J=await e2();if(J.status==="ok")return{dataUrl:J.dataUrl,method:"display-media"};if(J.status==="cancelled")return{dataUrl:null,method:"cancelled"}}let j=await J4();if(j)return{dataUrl:j,method:"html-to-image"};return{dataUrl:null,method:"none"}}async function e2(){let $=null;try{let j={video:{frameRate:30},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude"};$=await navigator.mediaDevices.getDisplayMedia(j);let J=await $4($);return J?{status:"ok",dataUrl:J}:{status:"error"}}catch(j){if(j instanceof DOMException&&(j.name==="NotAllowedError"||j.name==="AbortError"))return{status:"cancelled"};return{status:"error"}}finally{$?.getTracks().forEach((j)=>j.stop())}}async function $4($){let j=document.createElement("video");j.srcObject=$,j.muted=!0,j.playsInline=!0,await new Promise((V)=>{let X=!1,F=()=>{if(X)return;X=!0,V()};j.onloadedmetadata=()=>{j.play().then(F).catch(F)},window.setTimeout(F,1500)}),await j4(j);let{videoWidth:J,videoHeight:Q}=j;if(!J||!Q)return null;let z=document.createElement("canvas");z.width=J,z.height=Q;let W=z.getContext("2d");if(!W)return null;W.drawImage(j,0,0,J,Q),j.pause(),j.srcObject=null;try{return z.toDataURL("image/png")}catch{return null}}function j4($){return new Promise((j)=>{let J=!1,Q=()=>{if(J)return;J=!0,j()},z=$;if(typeof z.requestVideoFrameCallback==="function")z.requestVideoFrameCallback(()=>Q()),window.setTimeout(Q,1000);else window.setTimeout(Q,250)})}async function J4(){let $=f().screenshotFallback;if(!$)return null;let j=await $().catch(()=>null);if(!j)return null;try{return await j(document.body,{cacheBust:!0,pixelRatio:Math.min(window.devicePixelRatio||1,2),filter:(J)=>!(J instanceof HTMLElement&&J.dataset?.debugReporter==="true")})}catch{return null}}var Q4=2000,z4=0.82,Z4=3000000;function W4($){return new Promise((j,J)=>{let Q=new Image;Q.onload=()=>j(Q),Q.onerror=()=>J(Error("could not read the screenshot")),Q.src=$})}async function f1($){try{let j=await W4($),J=Math.max(j.naturalWidth,j.naturalHeight),Q=Math.min(1,Q4/J),z=document.createElement("canvas");z.width=Math.max(1,Math.round(j.naturalWidth*Q)),z.height=Math.max(1,Math.round(j.naturalHeight*Q));let W=z.getContext("2d");if(!W)return $;W.fillStyle="#fff",W.fillRect(0,0,z.width,z.height),W.drawImage(j,0,0,z.width,z.height);let V=z4,X=z.toDataURL("image/jpeg",V);while(X.length>Z4&&V>0.4)V-=0.15,X=z.toDataURL("image/jpeg",V);return X}catch{return $}}var K4=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,V4=/^\d+$/,G4=/^[0-9a-f]{16,}$/i;function S1($){if($.reason.type==="manual")return null;let j=$.cause?.failedRequests?.[0];if(!j?.url)return null;let J;try{J=new URL(j.url,"http://x").pathname}catch{J=j.url}let Q=J.split("/").map((W)=>K4.test(W)||V4.test(W)||G4.test(W)?":id":W).join("/"),z=j.status??(j.error?"ERR":"?");return`${j.method??"REQ"} ${Q} ${z}`}var k1=2000000;function W0($){let{screenshotDataUrl:j,...J}=$;return JSON.stringify(J).length}function R1($,j=2000000){if(W0($)<=j)return $;let J=$.network.map((z)=>({...z})),Q={...$,network:J};for(let z of J){if(W0(Q)<=j)return Q;if(typeof z.responseSnippet==="string"&&z.responseSnippet.length>35)z.responseSnippet="[body dropped — report size budget]";if(typeof z.requestBody==="string"&&z.requestBody.length>35)z.requestBody="[body dropped — report size budget]"}while(Q.network.length>1&&W0(Q)>j)Q.network=Q.network.slice(1);while(Q.console.length>1&&W0(Q)>j)Q.console=Q.console.slice(1);return Q}var O1=32768;function w4($){let j="";for(let J=0;J<$.length;J+=O1)j+=String.fromCharCode(...$.subarray(J,J+O1));return btoa(j)}function X4($){return{dataUri:`data:application/json;base64,${w4(new TextEncoder().encode(JSON.stringify($)))}`,filename:"debug-bundle.json"}}async function Y4(){let $=f().identity;if(!$)return{};try{let j=await $();return j?{authorization:`Bearer ${j}`}:{}}catch{return{}}}async function _1($,j){let J=f(),Q=R1(j,k1),{context:z,note:W}=Q,V=[];if(Q.screenshotDataUrl){let U=await f1(Q.screenshotDataUrl);V.push({dataUri:U,filename:"screenshot.jpg"})}V.push(X4(Q));let X=S1(Q),F={title:$,description:W.trim()||void 0,category:z.module?.label||h().name,routeUrl:z.route.href,priority:"MEDIUM",requesterEmail:z.user.email??void 0,requesterName:z.user.fullName??void 0,customFields:{unit:z.user.unit??"",appVersion:z.app.version,environment:z.app.environment,reasonType:Q.reason.type,appName:h().name,module:z.module?.label??""},context:{...X?{signature:X}:{},capturedAt:z.capturedAt,reason:Q.reason,cause:Q.cause,actionTrail:Q.actionTrail,client:z.client,performance:z.performance,apiHeaders:z.apiHeaders,extra:z.extra,counts:{network:Q.network.length,console:Q.console.length,actions:Q.actionTrail.length},screenshotMethod:Q.screenshotMethod},attachments:V},H=await fetch(`${J.host.replace(/\/$/,"")}/ingest/tickets`,{method:"POST",headers:{"content-type":"application/json","x-realm-key":J.realmKey,...await Y4()},body:JSON.stringify(F)});if(!H.ok){let U=H.headers.get("retry-after"),P=await H.json().then((C)=>C.error).catch(()=>null);throw Error(H.status===429?`Too many reports — try again in ${U??"a moment"}s`:P??`Report failed (${H.status})`)}return await H.json()}var r=Math.PI/6;function T1($,j,J){let Q=j.x-$.x,z=j.y-$.y,W=Math.hypot(Q,z),V=Math.atan2(z,Q),X=[{x:j.x,y:j.y},{x:j.x-J*Math.cos(V-r),y:j.y-J*Math.sin(V-r)},{x:j.x-J*Math.cos(V+r),y:j.y-J*Math.sin(V+r)}],F=J*Math.cos(r)*0.92;if(W<=F)return{shaft:null,head:X};return{shaft:{from:$,to:{x:j.x-F*Math.cos(V),y:j.y-F*Math.sin(V)}},head:X}}var C0="#f44336",F4="rgba(250, 204, 21, 0.4)",P0=22,A1="#2563eb",L1=9,E1=11,x1=18,h1=4,K0=8,M4=[{id:"nw",fx:0,fy:0,cursor:"nwse-resize"},{id:"n",fx:0.5,fy:0,cursor:"ns-resize"},{id:"ne",fx:1,fy:0,cursor:"nesw-resize"},{id:"e",fx:1,fy:0.5,cursor:"ew-resize"},{id:"se",fx:1,fy:1,cursor:"nwse-resize"},{id:"s",fx:0.5,fy:1,cursor:"ns-resize"},{id:"sw",fx:0,fy:1,cursor:"nesw-resize"},{id:"w",fx:0,fy:0.5,cursor:"ew-resize"}];function p1($,j,J){let Q=[],z=null,W=-1,V=null,X=null,F=$.getContext("2d");function H(){let Z=$.getBoundingClientRect().width;return Z>0?$.width/Z:1}function U(Z){let K=$.getBoundingClientRect();return{x:(Z.clientX-K.left)/K.width*$.width,y:(Z.clientY-K.top)/K.height*$.height}}function P(Z){let K=Z.size??P0;if(!F)return(Z.text?.length??0)*K*0.6;F.save(),F.font=`600 ${K}px system-ui, sans-serif`;let w=F.measureText(Z.text??"").width;return F.restore(),w}function C(Z){if(Z.tool==="text"){let K=Z.size??P0;return{left:Z.x1,top:Z.y1,right:Z.x1+P(Z),bottom:Z.y1+K*1.25}}return{left:Math.min(Z.x1,Z.x2),top:Math.min(Z.y1,Z.y2),right:Math.max(Z.x1,Z.x2),bottom:Math.max(Z.y1,Z.y2)}}function S(Z){if(Z.tool==="arrow")return[{id:"tail",x:Z.x1,y:Z.y1,cursor:"move"},{id:"head",x:Z.x2,y:Z.y2,cursor:"move"}];let K=C(Z);if(Z.tool==="text")return[{id:"size",x:K.right,y:K.bottom,cursor:"nwse-resize"}];return M4.map((w)=>({id:w.id,x:K.left+(K.right-K.left)*w.fx,y:K.top+(K.bottom-K.top)*w.fy,cursor:w.cursor}))}function q(Z){let K=C(Z);return{x:K.right+x1*H(),y:K.top-x1*H()}}function D(Z,K,w){let{shaft:G,head:Y}=T1({x:K.x1,y:K.y1},{x:K.x2,y:K.y2},Math.max(10,16*w));if(G)Z.lineCap="butt",Z.beginPath(),Z.moveTo(G.from.x,G.from.y),Z.lineTo(G.to.x,G.to.y),Z.stroke();Z.beginPath(),Z.moveTo(Y[0].x,Y[0].y),Z.lineTo(Y[1].x,Y[1].y),Z.lineTo(Y[2].x,Y[2].y),Z.closePath(),Z.fill()}function O(Z,K,w){Z.save(),Z.lineWidth=Math.max(2,3*w),Z.strokeStyle=C0,Z.fillStyle=C0;let G=C(K);if(K.tool==="rect")Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(K.tool==="arrow")D(Z,K,w);else if(K.tool==="highlight")Z.fillStyle=F4,Z.fillRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(K.tool==="text"&&K.text){let Y=K.size??P0;Z.font=`600 ${Y}px system-ui, sans-serif`,Z.textBaseline="top";let M=Y*0.22;Z.fillStyle="rgba(255,255,255,0.92)",Z.fillRect(G.left-M,G.top-M,G.right-G.left+M*2,G.bottom-G.top+M*2),Z.fillStyle=C0,Z.fillText(K.text,G.left,G.top)}Z.restore()}function n(Z,K,w){let G=C(K);Z.save(),Z.strokeStyle=A1,Z.lineWidth=Math.max(1,1.5*w),Z.setLineDash([6*w,4*w]),Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top),Z.setLineDash([]);let Y=L1*w;for(let k of S(K))Z.fillStyle="#fff",Z.strokeStyle=A1,Z.lineWidth=Math.max(1,1.5*w),Z.beginPath(),Z.rect(k.x-Y/2,k.y-Y/2,Y,Y),Z.fill(),Z.stroke();let M=q(K),I=E1*w;Z.beginPath(),Z.arc(M.x,M.y,I,0,Math.PI*2),Z.fillStyle="#dc2626",Z.fill(),Z.strokeStyle="#fff",Z.lineWidth=Math.max(1.5,2*w),Z.beginPath(),Z.moveTo(M.x-I*0.4,M.y-I*0.4),Z.lineTo(M.x+I*0.4,M.y+I*0.4),Z.moveTo(M.x+I*0.4,M.y-I*0.4),Z.lineTo(M.x-I*0.4,M.y+I*0.4),Z.stroke(),Z.restore()}function N(){if(!F)return;let Z=H();if(F.clearRect(0,0,$.width,$.height),F.drawImage(j,0,0,$.width,$.height),Q.forEach((w,G)=>{if(G!==a)O(F,w,Z)}),V)O(F,V,Z);let K=Q[W];if(K&&!V)n(F,K,Z)}function B0(Z,K,w,G,Y){return Math.abs(Z-w)<=Y&&Math.abs(K-G)<=Y}function q0(Z,K){let w=Q[W];if(!w)return null;let G=L1*H()/2+3*H();for(let Y of S(w))if(B0(Z,K,Y.x,Y.y,G))return Y.id;return null}function D0(Z,K){let w=Q[W];if(!w)return!1;let G=q(w);return B0(Z,K,G.x,G.y,E1*H())}function V0(Z,K){let w=6*H();for(let G=Q.length-1;G>=0;G-=1){let Y=Q[G];if(Y.tool==="arrow"){let I=Y.x2-Y.x1,k=Y.y2-Y.y1,E=Math.hypot(I,k)||1,x=Math.max(0,Math.min(1,((Z-Y.x1)*I+(K-Y.y1)*k)/(E*E)));if(Math.hypot(Z-(Y.x1+x*I),K-(Y.y1+x*k))<=w+4*H())return G;continue}let M=C(Y);if(Z>=M.left-w&&Z<=M.right+w&&K>=M.top-w&&K<=M.bottom+w)return G}return-1}function b1(Z,K,w,G,Y){if(K==="tail"){Z.x1=w.x1+G,Z.y1=w.y1+Y;return}if(K==="head"){Z.x2=w.x2+G,Z.y2=w.y2+Y;return}if(K==="size"){let d1=(w.size??24)+Y;Z.size=Math.max(10,d1);return}let M=C(w),{left:I,top:k,right:E,bottom:x}=M;if(K.includes("w"))I=Math.min(E-K0,I+G);if(K.includes("e"))E=Math.max(I+K0,E+G);if(K.includes("n"))k=Math.min(x-K0,k+Y);if(K.includes("s"))x=Math.max(k+K0,x+Y);Z.x1=I,Z.y1=k,Z.x2=E,Z.y2=x}function u1(Z,K,w,G){Z.x1=K.x1+w,Z.y1=K.y1+G,Z.x2=K.x2+w,Z.y2=K.y2+G}let _=null,a=-1,T={x:0,y:0,size:24};function i1(){let Z=$.getBoundingClientRect().width;return Z>0?Z/$.width:1}function o1(Z,K){if(!F)return Z.length*K*0.6;F.save(),F.font=`600 ${K}px system-ui, sans-serif`;let w=F.measureText(Z||" ").width;return F.restore(),w}function f0(){if(!_)return;let Z=$.parentElement;if(!Z)return;let K=$.getBoundingClientRect(),w=Z.getBoundingClientRect(),G=i1(),Y=T.size*G;_.style.left=`${K.left-w.left+T.x*G}px`,_.style.top=`${K.top-w.top+T.y*G}px`,_.style.fontSize=`${Y}px`,_.style.width=`${Math.max(40,o1(_.value,Y)+Y)}px`}function y(Z){let K=_;if(!K)return;_=null;let w=K.value.trim(),G=a;if(a=-1,K.remove(),Z&&w){if(G>=0&&Q[G])Q[G].text=w,W=G;else Q.push({tool:"text",x1:T.x,y1:T.y,x2:T.x,y2:T.y,text:w,size:T.size}),W=Q.length-1;J()}else if(G>=0)W=G;$.focus(),N()}function S0(Z,K,w=-1){y(!0);let G=$.parentElement;if(!G)return;if(getComputedStyle(G).position==="static")G.style.position="relative";let Y=w>=0?Q[w]:void 0;a=w,T={x:Y?.x1??Z,y:Y?.y1??K,size:Y?.size??Math.round(24*H())};let M=document.createElement("input");M.type="text",M.className="text-edit",M.value=Y?.text??"",M.setAttribute("aria-label","ข้อความบนภาพ"),M.placeholder="ข้อความ",_=M,G.append(M),f0(),M.addEventListener("input",f0),M.addEventListener("keydown",(I)=>{if(I.stopPropagation(),I.key==="Enter")y(!0);else if(I.key==="Escape")y(!1)}),requestAnimationFrame(()=>{if(_!==M)return;M.focus(),M.select(),M.addEventListener("blur",()=>y(!0))}),N()}function k0(Z){let{x:K,y:w}=U(Z);if($.setPointerCapture(Z.pointerId),D0(K,w)){G0();return}let G=q0(K,w);if(G&&Q[W]){X={grip:G,x:K,y:w,start:{...Q[W]}};return}if(z==="text"){if(Z.preventDefault(),$.hasPointerCapture(Z.pointerId))$.releasePointerCapture(Z.pointerId);z=null,J(),S0(K,w);return}if(z){V={tool:z,x1:K,y1:w,x2:K,y2:w},W=-1;return}let Y=V0(K,w);W=Y,X=Y>=0?{grip:"body",x:K,y:w,start:{...Q[Y]}}:null,N()}function R0(Z){let{x:K,y:w}=U(Z);if(V){V.x2=K,V.y2=w,N();return}if(X){let Y=Q[W];if(!Y)return;let M=K-X.x,I=w-X.y;if(X.grip==="body")u1(Y,X.start,M,I);else b1(Y,X.grip,X.start,M,I);N();return}if(z){$.style.cursor="crosshair";return}if(D0(K,w)){$.style.cursor="pointer";return}let G=q0(K,w);if(G){let Y=Q[W]?S(Q[W]).find((M)=>M.id===G):null;$.style.cursor=Y?.cursor??"pointer";return}$.style.cursor=V0(K,w)>=0?"move":"default"}function t(){if(V){if(!(Math.abs(V.x2-V.x1)<h1&&Math.abs(V.y2-V.y1)<h1))Q.push(V),W=Q.length-1,z=null,J();V=null}if(X)X=null,J();N()}function O0(Z){let K=$.getBoundingClientRect(),w=(Z.clientX-K.left)/K.width*$.width,G=(Z.clientY-K.top)/K.height*$.height,Y=V0(w,G),M=Q[Y];if(!M||M.tool!=="text")return;Z.preventDefault(),S0(M.x1,M.y1,Y)}function _0(Z){if(W<0)return;if(Z.key==="Delete"||Z.key==="Backspace")Z.preventDefault(),G0();else if(Z.key==="Escape")W=-1,N()}function G0(){if(W<0)return;Q.splice(W,1),W=-1,J(),N()}return $.addEventListener("pointerdown",k0),$.addEventListener("pointermove",R0),$.addEventListener("pointerup",t),$.addEventListener("pointercancel",t),$.addEventListener("dblclick",O0),$.tabIndex=0,$.addEventListener("keydown",_0),N(),{setTool(Z){z=Z,W=-1,$.style.cursor=Z?"crosshair":"default",N()},deleteSelected:G0,clear(){Q.length=0,W=-1,J(),N()},hasShapes:()=>Q.length>0,hasSelection:()=>W>=0,toDataUrl(){let Z=document.createElement("canvas");Z.width=j.naturalWidth,Z.height=j.naturalHeight;let K=Z.getContext("2d");if(!K)return $.toDataURL("image/png");K.drawImage(j,0,0);let w=H();for(let G of Q)O(K,G,w);return Z.toDataURL("image/png")},destroy(){y(!1),$.removeEventListener("pointerdown",k0),$.removeEventListener("pointermove",R0),$.removeEventListener("pointerup",t),$.removeEventListener("pointercancel",t),$.removeEventListener("dblclick",O0),$.removeEventListener("keydown",_0)}}}var m1=`
|
|
33
|
+
`;let Q=document.createElement("div");return Q.className="stack",Q.setAttribute("role","status"),Q.setAttribute("aria-live","polite"),j.append(J,Q),document.body.append($),I0=Q,Q}function l($,j="success",J){let Q=n2();if(!Q)return;let z=document.createElement("div");z.className="toast",z.dataset.tone=j;let W=document.createElement("span");W.className="dot";let V=document.createElement("span");V.textContent=$;let X=document.createElement("button");X.type="button",X.className="close",X.textContent="✕",X.setAttribute("aria-label","ปิด");let F=()=>{window.clearTimeout(H),z.remove()};X.addEventListener("click",F);let H=j==="error"||J?0:window.setTimeout(F,6000);if(z.append(W,V),J){let U=document.createElement("button");U.type="button",U.className="action",U.textContent=J.label,U.addEventListener("click",()=>{F(),J.onClick()}),z.append(U)}z.append(X),Q.append(z)}function N1($,j,J){let Q=$.filter((W)=>Boolean(W.error)||W.status!=null&&W.status>=400).slice(-20).map((W)=>({method:W.method,url:W.url,status:W.status,error:W.error,at:W.startedAt})),z=j.filter((W)=>W.level==="error"||W.level==="exception"||W.level==="unhandledrejection").slice(-20).map((W)=>W.message);return{failedRequests:Q,errors:z,erroredQueries:J.slice(0,20)}}function a2(){let $={memoryUsedMb:null,memoryLimitMb:null,domContentLoadedMs:null,loadEventMs:null};if(typeof performance>"u")return $;let j=performance.memory;if(j)$.memoryUsedMb=Math.round(j.usedJSHeapSize/1024/1024),$.memoryLimitMb=Math.round(j.jsHeapSizeLimit/1024/1024);let[J]=performance.getEntriesByType("navigation");if(J)$.domContentLoadedMs=Math.round(J.domContentLoadedEventEnd),$.loadEventMs=Math.round(J.loadEventEnd);return $}function U0($,j){if(!$)return j;try{return $()}catch{return j}}function B1(){let $=f(),{pathname:j,search:J,href:Q}=window.location;return{capturedAt:new Date().toISOString(),route:{href:Q,pathname:j,search:J},module:L0(j),user:U0($.user,{}),apiHeaders:u(U0($.headers,{})),app:{name:A().name,version:A().version,environment:A().environment},client:{userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,online:navigator.onLine,viewport:{width:window.innerWidth,height:window.innerHeight,dpr:window.devicePixelRatio},screen:{width:window.screen.width,height:window.screen.height}},performance:a2(),extra:U0($.extra,{})}}var t2=2;function q1($){let j=P1(),J=t0();return{context:B1(),reason:$.reason,note:$.note,cause:N1(j,J,$.erroredQueries),actionTrail:c0(),network:j,console:J,screenshotDataUrl:$.screenshotDataUrl,screenshotMethod:$.screenshotMethod,meta:{generatedBy:"lightwork-debug-capture",schemaVersion:t2}}}async function D1(){if(typeof navigator<"u"&&Boolean(navigator.mediaDevices?.getDisplayMedia)){let J=await e2();if(J.status==="ok")return{dataUrl:J.dataUrl,method:"display-media"};if(J.status==="cancelled")return{dataUrl:null,method:"cancelled"}}let j=await J4();if(j)return{dataUrl:j,method:"html-to-image"};return{dataUrl:null,method:"none"}}async function e2(){let $=null;try{let j={video:{frameRate:30},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude"};$=await navigator.mediaDevices.getDisplayMedia(j);let J=await $4($);return J?{status:"ok",dataUrl:J}:{status:"error"}}catch(j){if(j instanceof DOMException&&(j.name==="NotAllowedError"||j.name==="AbortError"))return{status:"cancelled"};return{status:"error"}}finally{$?.getTracks().forEach((j)=>j.stop())}}async function $4($){let j=document.createElement("video");j.srcObject=$,j.muted=!0,j.playsInline=!0,await new Promise((V)=>{let X=!1,F=()=>{if(X)return;X=!0,V()};j.onloadedmetadata=()=>{j.play().then(F).catch(F)},window.setTimeout(F,1500)}),await j4(j);let{videoWidth:J,videoHeight:Q}=j;if(!J||!Q)return null;let z=document.createElement("canvas");z.width=J,z.height=Q;let W=z.getContext("2d");if(!W)return null;W.drawImage(j,0,0,J,Q),j.pause(),j.srcObject=null;try{return z.toDataURL("image/png")}catch{return null}}function j4($){return new Promise((j)=>{let J=!1,Q=()=>{if(J)return;J=!0,j()},z=$;if(typeof z.requestVideoFrameCallback==="function")z.requestVideoFrameCallback(()=>Q()),window.setTimeout(Q,1000);else window.setTimeout(Q,250)})}async function J4(){let $=f().screenshotFallback;if(!$)return null;let j=await $().catch(()=>null);if(!j)return null;try{return await j(document.body,{cacheBust:!0,pixelRatio:Math.min(window.devicePixelRatio||1,2),filter:(J)=>!(J instanceof HTMLElement&&J.dataset?.debugReporter==="true")})}catch{return null}}var Q4=2000,z4=0.82,Z4=3000000;function W4($){return new Promise((j,J)=>{let Q=new Image;Q.onload=()=>j(Q),Q.onerror=()=>J(Error("could not read the screenshot")),Q.src=$})}async function f1($){try{let j=await W4($),J=Math.max(j.naturalWidth,j.naturalHeight),Q=Math.min(1,Q4/J),z=document.createElement("canvas");z.width=Math.max(1,Math.round(j.naturalWidth*Q)),z.height=Math.max(1,Math.round(j.naturalHeight*Q));let W=z.getContext("2d");if(!W)return $;W.fillStyle="#fff",W.fillRect(0,0,z.width,z.height),W.drawImage(j,0,0,z.width,z.height);let V=z4,X=z.toDataURL("image/jpeg",V);while(X.length>Z4&&V>0.4)V-=0.15,X=z.toDataURL("image/jpeg",V);return X}catch{return $}}var K4=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,V4=/^\d+$/,G4=/^[0-9a-f]{16,}$/i;function S1($){if($.reason.type==="manual")return null;let j=$.cause?.failedRequests?.[0];if(!j?.url)return null;let J;try{J=new URL(j.url,"http://x").pathname}catch{J=j.url}let Q=J.split("/").map((W)=>K4.test(W)||V4.test(W)||G4.test(W)?":id":W).join("/"),z=j.status??(j.error?"ERR":"?");return`${j.method??"REQ"} ${Q} ${z}`}var k1=2000000;function W0($){let{screenshotDataUrl:j,...J}=$;return JSON.stringify(J).length}function R1($,j=2000000){if(W0($)<=j)return $;let J=$.network.map((z)=>({...z})),Q={...$,network:J};for(let z of J){if(W0(Q)<=j)return Q;if(typeof z.responseSnippet==="string"&&z.responseSnippet.length>35)z.responseSnippet="[body dropped — report size budget]";if(typeof z.requestBody==="string"&&z.requestBody.length>35)z.requestBody="[body dropped — report size budget]"}while(Q.network.length>1&&W0(Q)>j)Q.network=Q.network.slice(1);while(Q.console.length>1&&W0(Q)>j)Q.console=Q.console.slice(1);return Q}var O1=32768;function w4($){let j="";for(let J=0;J<$.length;J+=O1)j+=String.fromCharCode(...$.subarray(J,J+O1));return btoa(j)}function X4($){return{dataUri:`data:application/json;base64,${w4(new TextEncoder().encode(JSON.stringify($)))}`,filename:"debug-bundle.json"}}async function Y4(){let $=f().identity;if(!$)return{};try{let j=await $();return j?{authorization:`Bearer ${j}`}:{}}catch{return{}}}async function _1($,j){let J=f(),Q=R1(j,k1),{context:z,note:W}=Q,V=[];if(Q.screenshotDataUrl){let U=await f1(Q.screenshotDataUrl);V.push({dataUri:U,filename:"screenshot.jpg"})}V.push(X4(Q));let X=S1(Q),F={title:$,description:W.trim()||void 0,appName:A().name,category:z.module?.label||A().name,routeUrl:z.route.href,priority:"MEDIUM",requesterEmail:z.user.email??void 0,requesterName:z.user.fullName??void 0,customFields:{unit:z.user.unit??"",appVersion:z.app.version,environment:z.app.environment,reasonType:Q.reason.type,appName:A().name,module:z.module?.label??""},context:{...X?{signature:X}:{},capturedAt:z.capturedAt,reason:Q.reason,cause:Q.cause,actionTrail:Q.actionTrail,client:z.client,performance:z.performance,apiHeaders:z.apiHeaders,extra:z.extra,counts:{network:Q.network.length,console:Q.console.length,actions:Q.actionTrail.length},screenshotMethod:Q.screenshotMethod},attachments:V},H=await fetch(`${J.host.replace(/\/$/,"")}/ingest/tickets`,{method:"POST",headers:{"content-type":"application/json","x-realm-key":J.realmKey,...await Y4()},body:JSON.stringify(F)});if(!H.ok){let U=H.headers.get("retry-after"),P=await H.json().then((C)=>C.error).catch(()=>null);throw Error(H.status===429?`Too many reports — try again in ${U??"a moment"}s`:P??`Report failed (${H.status})`)}return await H.json()}var r=Math.PI/6;function T1($,j,J){let Q=j.x-$.x,z=j.y-$.y,W=Math.hypot(Q,z),V=Math.atan2(z,Q),X=[{x:j.x,y:j.y},{x:j.x-J*Math.cos(V-r),y:j.y-J*Math.sin(V-r)},{x:j.x-J*Math.cos(V+r),y:j.y-J*Math.sin(V+r)}],F=J*Math.cos(r)*0.92;if(W<=F)return{shaft:null,head:X};return{shaft:{from:$,to:{x:j.x-F*Math.cos(V),y:j.y-F*Math.sin(V)}},head:X}}var C0="#f44336",F4="rgba(250, 204, 21, 0.4)",P0=22,A1="#2563eb",L1=9,E1=11,x1=18,h1=4,K0=8,M4=[{id:"nw",fx:0,fy:0,cursor:"nwse-resize"},{id:"n",fx:0.5,fy:0,cursor:"ns-resize"},{id:"ne",fx:1,fy:0,cursor:"nesw-resize"},{id:"e",fx:1,fy:0.5,cursor:"ew-resize"},{id:"se",fx:1,fy:1,cursor:"nwse-resize"},{id:"s",fx:0.5,fy:1,cursor:"ns-resize"},{id:"sw",fx:0,fy:1,cursor:"nesw-resize"},{id:"w",fx:0,fy:0.5,cursor:"ew-resize"}];function p1($,j,J){let Q=[],z=null,W=-1,V=null,X=null,F=$.getContext("2d");function H(){let Z=$.getBoundingClientRect().width;return Z>0?$.width/Z:1}function U(Z){let K=$.getBoundingClientRect();return{x:(Z.clientX-K.left)/K.width*$.width,y:(Z.clientY-K.top)/K.height*$.height}}function P(Z){let K=Z.size??P0;if(!F)return(Z.text?.length??0)*K*0.6;F.save(),F.font=`600 ${K}px system-ui, sans-serif`;let w=F.measureText(Z.text??"").width;return F.restore(),w}function C(Z){if(Z.tool==="text"){let K=Z.size??P0;return{left:Z.x1,top:Z.y1,right:Z.x1+P(Z),bottom:Z.y1+K*1.25}}return{left:Math.min(Z.x1,Z.x2),top:Math.min(Z.y1,Z.y2),right:Math.max(Z.x1,Z.x2),bottom:Math.max(Z.y1,Z.y2)}}function S(Z){if(Z.tool==="arrow")return[{id:"tail",x:Z.x1,y:Z.y1,cursor:"move"},{id:"head",x:Z.x2,y:Z.y2,cursor:"move"}];let K=C(Z);if(Z.tool==="text")return[{id:"size",x:K.right,y:K.bottom,cursor:"nwse-resize"}];return M4.map((w)=>({id:w.id,x:K.left+(K.right-K.left)*w.fx,y:K.top+(K.bottom-K.top)*w.fy,cursor:w.cursor}))}function q(Z){let K=C(Z);return{x:K.right+x1*H(),y:K.top-x1*H()}}function D(Z,K,w){let{shaft:G,head:Y}=T1({x:K.x1,y:K.y1},{x:K.x2,y:K.y2},Math.max(10,16*w));if(G)Z.lineCap="butt",Z.beginPath(),Z.moveTo(G.from.x,G.from.y),Z.lineTo(G.to.x,G.to.y),Z.stroke();Z.beginPath(),Z.moveTo(Y[0].x,Y[0].y),Z.lineTo(Y[1].x,Y[1].y),Z.lineTo(Y[2].x,Y[2].y),Z.closePath(),Z.fill()}function O(Z,K,w){Z.save(),Z.lineWidth=Math.max(2,3*w),Z.strokeStyle=C0,Z.fillStyle=C0;let G=C(K);if(K.tool==="rect")Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(K.tool==="arrow")D(Z,K,w);else if(K.tool==="highlight")Z.fillStyle=F4,Z.fillRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(K.tool==="text"&&K.text){let Y=K.size??P0;Z.font=`600 ${Y}px system-ui, sans-serif`,Z.textBaseline="top";let M=Y*0.22;Z.fillStyle="rgba(255,255,255,0.92)",Z.fillRect(G.left-M,G.top-M,G.right-G.left+M*2,G.bottom-G.top+M*2),Z.fillStyle=C0,Z.fillText(K.text,G.left,G.top)}Z.restore()}function n(Z,K,w){let G=C(K);Z.save(),Z.strokeStyle=A1,Z.lineWidth=Math.max(1,1.5*w),Z.setLineDash([6*w,4*w]),Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top),Z.setLineDash([]);let Y=L1*w;for(let k of S(K))Z.fillStyle="#fff",Z.strokeStyle=A1,Z.lineWidth=Math.max(1,1.5*w),Z.beginPath(),Z.rect(k.x-Y/2,k.y-Y/2,Y,Y),Z.fill(),Z.stroke();let M=q(K),I=E1*w;Z.beginPath(),Z.arc(M.x,M.y,I,0,Math.PI*2),Z.fillStyle="#dc2626",Z.fill(),Z.strokeStyle="#fff",Z.lineWidth=Math.max(1.5,2*w),Z.beginPath(),Z.moveTo(M.x-I*0.4,M.y-I*0.4),Z.lineTo(M.x+I*0.4,M.y+I*0.4),Z.moveTo(M.x+I*0.4,M.y-I*0.4),Z.lineTo(M.x-I*0.4,M.y+I*0.4),Z.stroke(),Z.restore()}function N(){if(!F)return;let Z=H();if(F.clearRect(0,0,$.width,$.height),F.drawImage(j,0,0,$.width,$.height),Q.forEach((w,G)=>{if(G!==a)O(F,w,Z)}),V)O(F,V,Z);let K=Q[W];if(K&&!V)n(F,K,Z)}function B0(Z,K,w,G,Y){return Math.abs(Z-w)<=Y&&Math.abs(K-G)<=Y}function q0(Z,K){let w=Q[W];if(!w)return null;let G=L1*H()/2+3*H();for(let Y of S(w))if(B0(Z,K,Y.x,Y.y,G))return Y.id;return null}function D0(Z,K){let w=Q[W];if(!w)return!1;let G=q(w);return B0(Z,K,G.x,G.y,E1*H())}function V0(Z,K){let w=6*H();for(let G=Q.length-1;G>=0;G-=1){let Y=Q[G];if(Y.tool==="arrow"){let I=Y.x2-Y.x1,k=Y.y2-Y.y1,x=Math.hypot(I,k)||1,h=Math.max(0,Math.min(1,((Z-Y.x1)*I+(K-Y.y1)*k)/(x*x)));if(Math.hypot(Z-(Y.x1+h*I),K-(Y.y1+h*k))<=w+4*H())return G;continue}let M=C(Y);if(Z>=M.left-w&&Z<=M.right+w&&K>=M.top-w&&K<=M.bottom+w)return G}return-1}function b1(Z,K,w,G,Y){if(K==="tail"){Z.x1=w.x1+G,Z.y1=w.y1+Y;return}if(K==="head"){Z.x2=w.x2+G,Z.y2=w.y2+Y;return}if(K==="size"){let d1=(w.size??24)+Y;Z.size=Math.max(10,d1);return}let M=C(w),{left:I,top:k,right:x,bottom:h}=M;if(K.includes("w"))I=Math.min(x-K0,I+G);if(K.includes("e"))x=Math.max(I+K0,x+G);if(K.includes("n"))k=Math.min(h-K0,k+Y);if(K.includes("s"))h=Math.max(k+K0,h+Y);Z.x1=I,Z.y1=k,Z.x2=x,Z.y2=h}function u1(Z,K,w,G){Z.x1=K.x1+w,Z.y1=K.y1+G,Z.x2=K.x2+w,Z.y2=K.y2+G}let _=null,a=-1,T={x:0,y:0,size:24};function i1(){let Z=$.getBoundingClientRect().width;return Z>0?Z/$.width:1}function o1(Z,K){if(!F)return Z.length*K*0.6;F.save(),F.font=`600 ${K}px system-ui, sans-serif`;let w=F.measureText(Z||" ").width;return F.restore(),w}function f0(){if(!_)return;let Z=$.parentElement;if(!Z)return;let K=$.getBoundingClientRect(),w=Z.getBoundingClientRect(),G=i1(),Y=T.size*G;_.style.left=`${K.left-w.left+T.x*G}px`,_.style.top=`${K.top-w.top+T.y*G}px`,_.style.fontSize=`${Y}px`,_.style.width=`${Math.max(40,o1(_.value,Y)+Y)}px`}function y(Z){let K=_;if(!K)return;_=null;let w=K.value.trim(),G=a;if(a=-1,K.remove(),Z&&w){if(G>=0&&Q[G])Q[G].text=w,W=G;else Q.push({tool:"text",x1:T.x,y1:T.y,x2:T.x,y2:T.y,text:w,size:T.size}),W=Q.length-1;J()}else if(G>=0)W=G;$.focus(),N()}function S0(Z,K,w=-1){y(!0);let G=$.parentElement;if(!G)return;if(getComputedStyle(G).position==="static")G.style.position="relative";let Y=w>=0?Q[w]:void 0;a=w,T={x:Y?.x1??Z,y:Y?.y1??K,size:Y?.size??Math.round(24*H())};let M=document.createElement("input");M.type="text",M.className="text-edit",M.value=Y?.text??"",M.setAttribute("aria-label","ข้อความบนภาพ"),M.placeholder="ข้อความ",_=M,G.append(M),f0(),M.addEventListener("input",f0),M.addEventListener("keydown",(I)=>{if(I.stopPropagation(),I.key==="Enter")y(!0);else if(I.key==="Escape")y(!1)}),requestAnimationFrame(()=>{if(_!==M)return;M.focus(),M.select(),M.addEventListener("blur",()=>y(!0))}),N()}function k0(Z){let{x:K,y:w}=U(Z);if($.setPointerCapture(Z.pointerId),D0(K,w)){G0();return}let G=q0(K,w);if(G&&Q[W]){X={grip:G,x:K,y:w,start:{...Q[W]}};return}if(z==="text"){if(Z.preventDefault(),$.hasPointerCapture(Z.pointerId))$.releasePointerCapture(Z.pointerId);z=null,J(),S0(K,w);return}if(z){V={tool:z,x1:K,y1:w,x2:K,y2:w},W=-1;return}let Y=V0(K,w);W=Y,X=Y>=0?{grip:"body",x:K,y:w,start:{...Q[Y]}}:null,N()}function R0(Z){let{x:K,y:w}=U(Z);if(V){V.x2=K,V.y2=w,N();return}if(X){let Y=Q[W];if(!Y)return;let M=K-X.x,I=w-X.y;if(X.grip==="body")u1(Y,X.start,M,I);else b1(Y,X.grip,X.start,M,I);N();return}if(z){$.style.cursor="crosshair";return}if(D0(K,w)){$.style.cursor="pointer";return}let G=q0(K,w);if(G){let Y=Q[W]?S(Q[W]).find((M)=>M.id===G):null;$.style.cursor=Y?.cursor??"pointer";return}$.style.cursor=V0(K,w)>=0?"move":"default"}function t(){if(V){if(!(Math.abs(V.x2-V.x1)<h1&&Math.abs(V.y2-V.y1)<h1))Q.push(V),W=Q.length-1,z=null,J();V=null}if(X)X=null,J();N()}function O0(Z){let K=$.getBoundingClientRect(),w=(Z.clientX-K.left)/K.width*$.width,G=(Z.clientY-K.top)/K.height*$.height,Y=V0(w,G),M=Q[Y];if(!M||M.tool!=="text")return;Z.preventDefault(),S0(M.x1,M.y1,Y)}function _0(Z){if(W<0)return;if(Z.key==="Delete"||Z.key==="Backspace")Z.preventDefault(),G0();else if(Z.key==="Escape")W=-1,N()}function G0(){if(W<0)return;Q.splice(W,1),W=-1,J(),N()}return $.addEventListener("pointerdown",k0),$.addEventListener("pointermove",R0),$.addEventListener("pointerup",t),$.addEventListener("pointercancel",t),$.addEventListener("dblclick",O0),$.tabIndex=0,$.addEventListener("keydown",_0),N(),{setTool(Z){z=Z,W=-1,$.style.cursor=Z?"crosshair":"default",N()},deleteSelected:G0,clear(){Q.length=0,W=-1,J(),N()},hasShapes:()=>Q.length>0,hasSelection:()=>W>=0,toDataUrl(){let Z=document.createElement("canvas");Z.width=j.naturalWidth,Z.height=j.naturalHeight;let K=Z.getContext("2d");if(!K)return $.toDataURL("image/png");K.drawImage(j,0,0);let w=H();for(let G of Q)O(K,G,w);return Z.toDataURL("image/png")},destroy(){y(!1),$.removeEventListener("pointerdown",k0),$.removeEventListener("pointermove",R0),$.removeEventListener("pointerup",t),$.removeEventListener("pointercancel",t),$.removeEventListener("dblclick",O0),$.removeEventListener("keydown",_0)}}}var m1=`
|
|
34
34
|
:host { all: initial; }
|
|
35
35
|
* { box-sizing: border-box; }
|
|
36
36
|
|
|
@@ -113,4 +113,4 @@ canvas { width: 100%; height: auto; display: block; border: 1px solid #e2e8f0; b
|
|
|
113
113
|
border-radius: 0 0 16px 16px;
|
|
114
114
|
}
|
|
115
115
|
.foot .grow { flex: 1; }
|
|
116
|
-
`;var s="lw-debug-reporter",H4=()=>[];var I4=[{tool:"rect",key:"toolRect"},{tool:"arrow",key:"toolArrow"},{tool:"highlight",key:"toolHighlight"},{tool:"text",key:"toolText"}];function U4(){return class extends HTMLElement{root;stop=null;annotator=null;bundle=null;busy=!1;constructor(){super();this.root=this.attachShadow({mode:"open"})}connectedCallback(){this.dataset.debugReporter="true",this.stop=Q1((j)=>void this.open(j))}disconnectedCallback(){this.stop?.(),this.stop=null,this.close()}async open(j){if(this.busy)return;this.busy=!0;let J=Z0(f().locale),Q=await D1();if(Q.method==="cancelled"){this.close();return}this.bundle=q1({reason:j,note:"",screenshotDataUrl:Q.dataUrl,screenshotMethod:Q.method,erroredQueries:C4()}),this.renderForm(J)}close(){this.annotator?.destroy(),this.annotator=null,this.bundle=null,this.busy=!1,this.root.replaceChildren()}shell(j){let J=document.createElement("style");J.textContent=m1;let Q=document.createElement("div");Q.className="backdrop";let z=document.createElement("div");return z.className="panel",z.setAttribute("role","dialog"),z.setAttribute("aria-modal","true"),z.setAttribute("aria-label",j.title),Q.append(z),this.root.replaceChildren(J,Q),z}renderShell(j,J){let Q=this.shell(j),z=B("div","head");z.append(B("h2","",j.title)),Q.append(z,B("p","status",J))}renderForm(j){let J=this.bundle;if(!J)return;let Q=this.shell(j),z=B("div","head"),W=g("✕","icon");W.setAttribute("aria-label",j.close),W.addEventListener("click",()=>this.close()),z.append(B("h2","",j.title),W);let V=document.createElement("input");V.type="text",V.placeholder=j.summaryPlaceholder;let X=N0(j.summaryLabel,j.summaryRequired,!0),F=document.createElement("textarea");F.placeholder=j.detailPlaceholder;let H=B("div","meta");H.innerHTML="";let{context:U}=J;for(let[D,O]of[[j.reporter,`${U.user.fullName??"—"} (${U.user.email??"—"})`],[j.page,U.route.href],[j.captured,`${J.network.length} network · ${J.console.length} console · ${J.actionTrail.length} actions`]]){let n=document.createElement("div"),N=document.createElement("b");N.textContent=`${D}: `,n.append(N,document.createTextNode(O)),H.append(n)}let P=B("p","status",""),C=g(j.submit,"primary");if(C.disabled=!0,V.addEventListener("input",()=>{C.disabled=V.value.trim().length===0}),Q.append(z,X,V,N0(j.detailLabel),F,H),J.screenshotDataUrl)Q.append(...this.screenshotSection(j,J.screenshotDataUrl));else Q.append(B("p","status",j.noScreenshot));let S=B("div","foot"),q=g(j.close);q.addEventListener("click",()=>this.close()),S.append(q,P,B("span","grow"),C),Q.append(S),C.addEventListener("click",async()=>{C.disabled=!0,P.dataset.tone="",P.textContent=j.submitting;try{let D=await _1(V.value.trim(),{...J,note:F.value,screenshotDataUrl:this.annotator?.hasShapes()?this.annotator.toDataUrl():J.screenshotDataUrl}),O=this.dispatchEvent(new CustomEvent("lw-report-submitted",{detail:D,bubbles:!0,composed:!0,cancelable:!0}));if(this.close(),O)l(`${j.submitted} — #${D.number}`,"success")}catch(D){let O=D instanceof Error?D.message:j.failed;P.dataset.tone="error",P.textContent=O,l(`${j.failed} — ${O}`,"error"),C.disabled=!1}}),V.focus()}screenshotSection(j,J){let Q=N0(j.annotateHint),z=B("div","tools"),W=document.createElement("canvas"),V=B("div","shot");V.append(W);let X=[],F=(C)=>{for(let S of X)S.setAttribute("aria-pressed",String(S===C))};for(let{tool:C,key:S}of I4){let q=g(j[S]);q.setAttribute("aria-pressed","false"),q.addEventListener("click",()=>{let D=q.getAttribute("aria-pressed")==="true";F(D?null:q),this.annotator?.setTool(D?null:C)}),X.push(q),z.append(q)}z.append(B("span","sep"));let H=g(j.deleteSelected);H.addEventListener("click",()=>this.annotator?.deleteSelected());let U=g(j.clearAll);U.addEventListener("click",()=>{this.annotator?.clear(),F(null)}),z.append(H,U);let P=new Image;return P.onload=()=>{W.width=P.naturalWidth,W.height=P.naturalHeight,this.annotator=p1(W,P,()=>{F(null),H.disabled=!this.annotator?.hasSelection()})},P.src=J,[Q,z,B("p","status",j.annotateHelp),V]}}}function C4(){try{return H4()}catch{return[]}}function B($,j="",J=""){let Q=document.createElement($);if(j)Q.className=j;if(J)Q.textContent=J;return Q}function g($,j=""){let J=document.createElement("button");if(J.type="button",J.textContent=$,j)J.className=j;return J}function N0($,j="",J=!1){let Q=document.createElement("label");if(Q.append(document.createTextNode($)),J){let z=document.createElement("span");z.className="req",z.textContent=" *",Q.append(z)}if(j){let z=document.createElement("span");z.className="hint",z.textContent=` ${j}`,Q.append(z)}return Q}function g1(){if(typeof window>"u"||customElements.get(s))return;customElements.define(s,U4())}var y1=!1;function v1($={}){if(y1||typeof window>"u")return;if(!A0()){console.error("[debug-capture] configureDebugCapture() must be called before install");return}if(y1=!0,C1(),a0(),d0(),G1(),$.ui===!1)return;let j=Z0(f().locale);if(z1((J)=>{l(J.message??j.crashed,"error",{label:j.crashAction,onClick:()=>Q0(J)})}),g1(),!document.querySelector(s))document.body.append(document.createElement(s))}var P4=document.currentScript,
|
|
116
|
+
`;var s="lw-debug-reporter",H4=()=>[];var I4=[{tool:"rect",key:"toolRect"},{tool:"arrow",key:"toolArrow"},{tool:"highlight",key:"toolHighlight"},{tool:"text",key:"toolText"}];function U4(){return class extends HTMLElement{root;stop=null;annotator=null;bundle=null;busy=!1;constructor(){super();this.root=this.attachShadow({mode:"open"})}connectedCallback(){this.dataset.debugReporter="true",this.stop=Q1((j)=>void this.open(j))}disconnectedCallback(){this.stop?.(),this.stop=null,this.close()}async open(j){if(this.busy)return;this.busy=!0;let J=Z0(f().locale),Q=await D1();if(Q.method==="cancelled"){this.close();return}this.bundle=q1({reason:j,note:"",screenshotDataUrl:Q.dataUrl,screenshotMethod:Q.method,erroredQueries:C4()}),this.renderForm(J)}close(){this.annotator?.destroy(),this.annotator=null,this.bundle=null,this.busy=!1,this.root.replaceChildren()}shell(j){let J=document.createElement("style");J.textContent=m1;let Q=document.createElement("div");Q.className="backdrop";let z=document.createElement("div");return z.className="panel",z.setAttribute("role","dialog"),z.setAttribute("aria-modal","true"),z.setAttribute("aria-label",j.title),Q.append(z),this.root.replaceChildren(J,Q),z}renderShell(j,J){let Q=this.shell(j),z=B("div","head");z.append(B("h2","",j.title)),Q.append(z,B("p","status",J))}renderForm(j){let J=this.bundle;if(!J)return;let Q=this.shell(j),z=B("div","head"),W=g("✕","icon");W.setAttribute("aria-label",j.close),W.addEventListener("click",()=>this.close()),z.append(B("h2","",j.title),W);let V=document.createElement("input");V.type="text",V.placeholder=j.summaryPlaceholder;let X=N0(j.summaryLabel,j.summaryRequired,!0),F=document.createElement("textarea");F.placeholder=j.detailPlaceholder;let H=B("div","meta");H.innerHTML="";let{context:U}=J;for(let[D,O]of[[j.reporter,`${U.user.fullName??"—"} (${U.user.email??"—"})`],[j.page,U.route.href],[j.captured,`${J.network.length} network · ${J.console.length} console · ${J.actionTrail.length} actions`]]){let n=document.createElement("div"),N=document.createElement("b");N.textContent=`${D}: `,n.append(N,document.createTextNode(O)),H.append(n)}let P=B("p","status",""),C=g(j.submit,"primary");if(C.disabled=!0,V.addEventListener("input",()=>{C.disabled=V.value.trim().length===0}),Q.append(z,X,V,N0(j.detailLabel),F,H),J.screenshotDataUrl)Q.append(...this.screenshotSection(j,J.screenshotDataUrl));else Q.append(B("p","status",j.noScreenshot));let S=B("div","foot"),q=g(j.close);q.addEventListener("click",()=>this.close()),S.append(q,P,B("span","grow"),C),Q.append(S),C.addEventListener("click",async()=>{C.disabled=!0,P.dataset.tone="",P.textContent=j.submitting;try{let D=await _1(V.value.trim(),{...J,note:F.value,screenshotDataUrl:this.annotator?.hasShapes()?this.annotator.toDataUrl():J.screenshotDataUrl}),O=this.dispatchEvent(new CustomEvent("lw-report-submitted",{detail:D,bubbles:!0,composed:!0,cancelable:!0}));if(this.close(),O)l(`${j.submitted} — #${D.number}`,"success")}catch(D){let O=D instanceof Error?D.message:j.failed;P.dataset.tone="error",P.textContent=O,l(`${j.failed} — ${O}`,"error"),C.disabled=!1}}),V.focus()}screenshotSection(j,J){let Q=N0(j.annotateHint),z=B("div","tools"),W=document.createElement("canvas"),V=B("div","shot");V.append(W);let X=[],F=(C)=>{for(let S of X)S.setAttribute("aria-pressed",String(S===C))};for(let{tool:C,key:S}of I4){let q=g(j[S]);q.setAttribute("aria-pressed","false"),q.addEventListener("click",()=>{let D=q.getAttribute("aria-pressed")==="true";F(D?null:q),this.annotator?.setTool(D?null:C)}),X.push(q),z.append(q)}z.append(B("span","sep"));let H=g(j.deleteSelected);H.addEventListener("click",()=>this.annotator?.deleteSelected());let U=g(j.clearAll);U.addEventListener("click",()=>{this.annotator?.clear(),F(null)}),z.append(H,U);let P=new Image;return P.onload=()=>{W.width=P.naturalWidth,W.height=P.naturalHeight,this.annotator=p1(W,P,()=>{F(null),H.disabled=!this.annotator?.hasSelection()})},P.src=J,[Q,z,B("p","status",j.annotateHelp),V]}}}function C4(){try{return H4()}catch{return[]}}function B($,j="",J=""){let Q=document.createElement($);if(j)Q.className=j;if(J)Q.textContent=J;return Q}function g($,j=""){let J=document.createElement("button");if(J.type="button",J.textContent=$,j)J.className=j;return J}function N0($,j="",J=!1){let Q=document.createElement("label");if(Q.append(document.createTextNode($)),J){let z=document.createElement("span");z.className="req",z.textContent=" *",Q.append(z)}if(j){let z=document.createElement("span");z.className="hint",z.textContent=` ${j}`,Q.append(z)}return Q}function g1(){if(typeof window>"u"||customElements.get(s))return;customElements.define(s,U4())}var y1=!1;function v1($={}){if(y1||typeof window>"u")return;if(!A0()){console.error("[debug-capture] configureDebugCapture() must be called before install");return}if(y1=!0,C1(),a0(),d0(),G1(),$.ui===!1)return;let j=Z0(f().locale);if(z1((J)=>{l(J.message??j.crashed,"error",{label:j.crashAction,onClick:()=>Q0(J)})}),g1(),!document.querySelector(s))document.body.append(document.createElement(s))}var P4=document.currentScript,E=P4?.dataset??{};if(E.host&&E.realmKey)T0({host:E.host,realmKey:E.realmKey,app:{name:E.appName??document.title??"app",version:E.appVersion??"0.0.0",environment:E.environment??"production"},locale:E.locale==="en"?"en":"th"}),v1();window.lwReportProblem=Q0;})();
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var J2={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},T=null;function Q2($){T=$}function R(){if(!T)throw Error("[debug-capture] configureDebugCapture() has not been called");return T}function U0(){return T!==null}function x(){let $=R().app;return{name:$.name,version:$.version??"0.0.0",environment:$.environment??z2()}}function z2(){if(typeof window>"u")return"unknown";let $=window.location.hostname;if($==="localhost"||$==="127.0.0.1"||$.endsWith(".local"))return"development";return"production"}function h($){let j=T?.capture?.[$];return typeof j==="number"?j:J2[$]}function n0($){let j=T?.module;if(!j)return null;try{return j($)??null}catch{return null}}function Z0(){let $=T?.redact;return{headers:$?.headers??[],queryKeys:($?.queryKeys??[]).map((j)=>j.toLowerCase()),bodyKeys:($?.bodyKeys??[]).map((j)=>j.toLowerCase())}}function a0(){return T?.capture?.overlaySelectors??[]}function t0($){if(typeof window>"u")return!1;let j;try{j=new URL($,window.location.href)}catch{return!1}if(Z2(j))return!1;if(j.origin===window.location.origin)return!0;return(T?.capture?.bodyOrigins??[]).some((J)=>{try{return new URL(J).origin===j.origin}catch{return!1}})}function Z2($){if(!T?.host)return!1;try{if(new URL(T.host).origin!==$.origin)return!1}catch{return!1}return $.pathname.startsWith("/ingest/")}var d="‹redacted›",W2=/^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i,K2=new Set(["access_token","token","id_token","refresh_token","code","secret","client_secret","password","apikey","api_key","signature","x-amz-signature","x-amz-credential"]),V2=/(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i,X2=/[\w.+-]+@[\w-]+\.[\w.-]+/g,G2=/\d(?:[\d\s-]{7,})\d/g;function c($){return $.replace(X2,d).replace(G2,d)}function Y2($){if(W2.test($))return!0;return Z0().headers.some((J)=>J.toLowerCase()===$.toLowerCase())}function i($){let j={};for(let[J,Q]of Object.entries($))j[J]=Y2(J)?d:Q;return j}function o($){try{let j=/^https?:\/\//i.test($),J=new URL($,j?void 0:"http://local.invalid"),Q=!1;if(J.searchParams.forEach((z,W)=>{if(K2.has(W.toLowerCase())||Z0().queryKeys.includes(W.toLowerCase()))J.searchParams.set(W,d),Q=!0}),!Q)return $;return j?J.toString():`${J.pathname}${J.search}`}catch{return $}}function C0($,j){if(j>6||$===null||typeof $!=="object")return $;if(Array.isArray($))return $.map((Q)=>C0(Q,j+1));let J={};for(let[Q,z]of Object.entries($)){let W=V2.test(Q)||Z0().bodyKeys.some((K)=>Q.toLowerCase().includes(K));J[Q]=W?d:C0(z,j+1)}return J}function l($,j){if($==null)return null;let J=$,Q=$.trim();if(Q.startsWith("{")||Q.startsWith("["))try{let z=JSON.parse(Q);J=JSON.stringify(C0(z,0))}catch{}if(J.length>j)return`${J.slice(0,j)}… [truncated ${J.length-j} chars]`;return J}var P0=120,I0=40,s=($,j)=>$.length>j?`${$.slice(0,j)}…`:$,w0=($)=>{try{return decodeURIComponent($)}catch{return $}},r=[],e0=0,$1=!1;function j0($,j,J,Q){let z=s(j,P0),W=r[r.length-1];if($==="navigate"&&W?.kind==="click"){let G=z.replace(/^ไปที่\s*/,"");if(W.detail.includes(`→ ${G}`))return W.at=new Date().toISOString(),W;let H=G.split(/[?#]/)[0]??G,U=W.source?w0(W.source.replace(/^→\s*/,"")).split(/[?#]/)[0]:null;if(U&&(H===U||H.startsWith(U)))return W.detail=s(`${W.detail} → ${G}`,P0),W.source=void 0,W.at=new Date().toISOString(),W}if(W&&W.kind===$&&W.detail===z){if(W.at=new Date().toISOString(),$!=="navigate")W.count=(W.count??1)+1;return W}e0+=1;let K={id:`act_${e0}`,at:new Date().toISOString(),kind:$,detail:z,count:1,source:J,html:K0(Q)};r.push(K);while(r.length>h("maxActions"))H2(r.shift());return K}var F2=200000,J0=0;function K0($){if(!$)return;if(J0+$.length>F2)return;return J0+=$.length,$}function H2($){if(!$)return;if(J0-=($.html?.length??0)+($.afterHtml?.length??0),J0<0)J0=0}function D0($){return $&&$>1?` (×${$})`:""}function W0($){return $ instanceof Element&&Boolean($.closest("[data-debug-reporter]"))}var M2='button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea',U2={button:"ปุ่ม",a:"ลิงก์",input:"ช่อง",textarea:"ช่อง",select:"ตัวเลือก",summary:"ส่วนขยาย"},j1={button:"ปุ่ม",tab:"แท็บ",menuitem:"เมนู",option:"ตัวเลือก",switch:"สวิตช์",checkbox:"ช่องเลือก",radio:"ตัวเลือก",link:"ลิงก์"};function C2($){let j=$.getAttribute("role");if(j&&j1[j])return j1[j];return U2[$.tagName.toLowerCase()]??"ปุ่ม"}function P2($,j){try{let J=$,Q=0;while(J&&Q<=j){let z=K1(J);if(z&&typeof z.memoizedProps?.onClick==="function")return J;J=J.parentElement,Q+=1}}catch{}return null}function I2($){let j=$.getAttribute("aria-label")?.trim();if(j)return j;let J=$.getAttribute("title")?.trim();if(J)return J;if($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement)return($.getAttribute("placeholder")||$.getAttribute("name")||"").trim();if($ instanceof HTMLImageElement)return($.getAttribute("alt")||"").trim();let Q=($.textContent??"").replace(/\s+/g," ").trim();if(Q)return Q;if($ instanceof HTMLAnchorElement){let z=$.getAttribute("href");if(z?.startsWith("/"))return w0(z)}return""}function w2($){if(!($ instanceof Element))return null;let j=$.closest(M2)??P2($,4);if(!j)return null;let J=j.tagName.toLowerCase();if(J==="html"||J==="body")return null;return j}function D2($){let j=c(I2($));if(!j)return null;return`${C2($)} “${s(j,I0)}”`}var W1=6000,N2=4000,B2=/(?:^|\s)!?(?:fixed|absolute|sticky|inset-\S+|z-\S+|top-\S+|bottom-\S+|left-\S+|right-\S+|w-screen|h-screen|min-h-screen|max-h-screen|translate-\S+|scale-\S+)(?=\s|$)/g;function q2($){$.querySelectorAll("script, style, link, iframe, object, embed, noscript, canvas, video, audio").forEach((z)=>z.remove());let j=[$,...Array.from($.querySelectorAll("*"))];for(let z of j){for(let K of Array.from(z.attributes)){let G=K.name.toLowerCase();if(G.startsWith("on")||G==="srcdoc"||G==="value"||G.startsWith("data-"))z.removeAttribute(K.name)}if(z instanceof HTMLAnchorElement)z.setAttribute("href","#");if(z instanceof HTMLImageElement)z.removeAttribute("src");let W=z.getAttribute("class");if(W){let K=W.replace(B2," ").replace(/\s+/g," ").trim();if(K)z.setAttribute("class",K);else z.removeAttribute("class")}}let J=document.createTreeWalker($,NodeFilter.SHOW_TEXT),Q=J.nextNode();while(Q){if(Q.nodeValue)Q.nodeValue=c(Q.nodeValue);Q=J.nextNode()}}function N0($,j,J){try{let Q=$.outerHTML;if(!Q||Q.length>j)return;let z=$.cloneNode(!0);q2(z);let W=z.outerHTML;return W&&W.length<=J?W:void 0}catch{return}}var S2=($)=>N0($,W1,N2),R2=150000,O2=40000,J1=($)=>N0($,R2,O2);function _2($){if(!($ instanceof HTMLInputElement)&&!($ instanceof HTMLTextAreaElement)&&!($ instanceof HTMLSelectElement))return null;let j=$.name||$.id||$.getAttribute("aria-label")||$.getAttribute("placeholder")||$.tagName.toLowerCase();return`ช่อง “${c(j)}”`}var Q1=80;function K1($){let j=Object.keys($).find((J)=>J.startsWith("__reactFiber$")||J.startsWith("__reactInternalInstance$"));return j?$[j]:null}function L2($){if(typeof $!=="function")return null;try{let j=Function.prototype.toString.call($);return(j.match(/\.(?:push|replace)\(\s*['"`]([^'"`]+)['"`]/)??j.match(/redirect\(\s*['"`]([^'"`]+)['"`]/))?.[1]??null}catch{return null}}function z1($){if(!$)return;return`→ ${$.length>Q1?`${$.slice(0,Q1)}…`:$}`}function A2($){try{let j=$.closest("a[href]")?.getAttribute("href");if(j&&j.startsWith("/"))return z1(j);let J=K1($),Q=0;while(J&&Q<30){if(typeof J.memoizedProps?.onClick==="function")return z1(L2(J.memoizedProps.onClick));J=J.return,Q+=1}return}catch{return}}var f2='[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';function T2(){let $=a0();return $.length?$.join(", "):f2}function k2($){let j=$.getAttribute("role");if(j==="status"||j==="alert")return"ข้อความแจ้งเตือน";if(j==="menu")return"เมนู";if(j==="listbox")return"รายการตัวเลือก";if(j==="alertdialog")return"กล่องยืนยัน";return"กล่องโต้ตอบ"}function E2($){let j=$.getAttribute("aria-label")?.trim();if(j)return j;let J=$.getAttribute("aria-labelledby");if(J){let W=J.split(/\s+/).map((K)=>document.getElementById(K)?.textContent?.trim()??"").filter(Boolean).join(" ");if(W)return W}let z=$.querySelector('[data-slot="dialog-title"], h1, h2, h3, [role="heading"]')?.textContent?.replace(/\s+/g," ").trim();if(z)return z;return($.textContent??"").replace(/\s+/g," ").trim()}function V1($){let j=c(E2($)),J=k2($);return j?`เปิด ${J} “${s(j,I0)}”`:`เปิด ${J}`}var x2='[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin',h2=/กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;function g2($){if($.querySelector(x2))return!0;return h2.test($.textContent??"")}var p2=400,m2=250,v2=8000;function y2($,j){if(typeof MutationObserver>"u"){j.html=K0(J1($));return}let J=Date.now(),Q=!1,z=()=>{Q=!0,K.disconnect(),window.clearInterval(G),window.clearTimeout(H)},W=()=>{if(Q)return;if(z(),!$.isConnected)return;j.detail=s(V1($),P0),j.html=K0(J1($))},K=new MutationObserver(()=>{J=Date.now()});K.observe($,{childList:!0,subtree:!0,attributes:!0,characterData:!0});let G=window.setInterval(()=>{if(Q)return;if(!$.isConnected){z();return}if(Date.now()-J>=p2&&!g2($))W()},m2),H=window.setTimeout(W,v2)}function b2($){if(W0($))return;let j=j0("ui",V1($));if(j)y2($,j)}function u2(){if(typeof MutationObserver>"u")return;let $=new WeakSet;new MutationObserver((J)=>{for(let Q of J)for(let z of Array.from(Q.addedNodes)){if(!(z instanceof Element))continue;let W=T2(),K=z.matches(W)?[z]:Array.from(z.querySelectorAll(W));for(let G of K){if($.has(G))continue;$.add(G),b2(G)}}}).observe(document.body,{childList:!0,subtree:!0})}var d2=1600,c2=2500;function Z1($){return{disabled:$.hasAttribute("disabled")||$.getAttribute("aria-disabled")==="true",busy:$.getAttribute("aria-busy")==="true",text:s(($.textContent??"").replace(/\s+/g," ").trim(),I0)}}function i2($,j){if(!$.disabled&&j.disabled)return"ปุ่มถูกปิดใช้งานหลังคลิก";if(!$.busy&&j.busy)return"ปุ่มเข้าสู่สถานะกำลังโหลด";if($.text!==j.text&&j.text)return`ข้อความเปลี่ยนเป็น “${j.text}”`;return null}function o2($,j){if(typeof MutationObserver>"u")return;let J=Z1($),Q=!1,z=(G,H)=>{if(Q)return;if(Q=!0,W.disconnect(),window.clearTimeout(K),j.afterNote=G,H)j.afterHtml=K0(N0($,W1,c2))},W=new MutationObserver(()=>{if(!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}let G=i2(J,Z1($));if(G)z(G,!0)});W.observe($,{attributes:!0,attributeFilter:["disabled","aria-disabled","aria-busy","class"],childList:!0,subtree:!0,characterData:!0});let K=window.setTimeout(()=>{if(!Q&&!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}Q=!0,W.disconnect()},d2)}function X1(){if($1||typeof window>"u")return;$1=!0,document.addEventListener("click",(Q)=>{if(W0(Q.target))return;let z=w2(Q.target);if(!z)return;let W=D2(z);if(!W)return;let K=j0("click",`คลิก ${W}`,A2(z),S2(z));if(K)o2(z,K)},{capture:!0,passive:!0}),document.addEventListener("change",(Q)=>{if(W0(Q.target))return;let z=_2(Q.target);if(z)j0("input",`แก้ไข ${z}`)},{capture:!0,passive:!0}),document.addEventListener("submit",(Q)=>{if(W0(Q.target))return;j0("submit","ส่งฟอร์ม")},{capture:!0,passive:!0});let $=()=>j0("navigate",`ไปที่ ${w0(o(location.pathname+location.search))}`),j=history.pushState.bind(history),J=history.replaceState.bind(history);history.pushState=(...Q)=>{let z=j(...Q);return $(),z},history.replaceState=(...Q)=>{let z=J(...Q);return $(),z},window.addEventListener("popstate",$),u2()}function B0(){return r.map(($)=>({...$}))}var G1=2000,V0=[],Y1=0,F1=!1;function q0($,j){Y1+=1,V0.push({id:`log_${Y1}`,at:new Date().toISOString(),level:$,message:j.length>G1?`${j.slice(0,G1)}…`:j});while(V0.length>h("maxConsoleEntries"))V0.shift()}function l2(){let $=new WeakSet;return(j,J)=>{if(typeof J==="object"&&J!==null){if($.has(J))return"[Circular]";$.add(J)}if(typeof J==="bigint")return J.toString();return J}}function H1($){if(typeof $==="string")return $;if($ instanceof Error)return`${$.name}: ${$.message}`;try{return JSON.stringify($,l2())??String($)}catch{return String($)}}function M1(){if(F1||typeof window>"u")return;F1=!0;let $=["log","info","warn","error","debug"];for(let j of $){let J=console[j].bind(console);console[j]=(...Q)=>{q0(j,Q.map(H1).join(" ")),J(...Q)}}window.addEventListener("error",(j)=>{let J=j.filename?` (${j.filename}:${j.lineno}:${j.colno})`:"";q0("exception",`${j.message}${J}`)}),window.addEventListener("unhandledrejection",(j)=>{let J=j.reason instanceof Error?`${j.reason.name}: ${j.reason.message}`:H1(j.reason);q0("unhandledrejection",J)})}function S0(){return V0.map(($)=>({...$}))}var U1=new Set,C1=new Set;function P1($,j){return $.add(j),()=>$.delete(j)}function I1($,j){for(let J of[...$])J(j)}function R0($){return P1(U1,$)}function O0($={type:"manual"}){I1(U1,$)}function _0($){return P1(C1,$)}function L0($){I1(C1,$)}var r2=15000,s2=["ResizeObserver loop","Script error.","Non-Error promise rejection captured"],w1=!1,D1=0;function n2($){return s2.some((j)=>$.includes(j))}function N1($){let j=$.message??"";if(!j||n2(j))return;let J=Date.now();if(J-D1<r2)return;D1=J,L0({...$,message:j})}function B1(){if(w1||typeof window>"u")return;w1=!0,window.addEventListener("error",($)=>{if(!$.message&&!$.error)return;let j=$.error instanceof Error?$.error:null;N1({type:"runtime-error",message:$.message||(j?j.message:"Unknown error"),stack:j?.stack})}),window.addEventListener("unhandledrejection",($)=>{let j=$.reason;N1({type:"unhandledrejection",message:j instanceof Error?j.message:String(j),stack:j instanceof Error?j.stack:void 0})})}var O1=4000,a2=1e6,t2=1e7,X0=[],q1=0,S1=!1;function _1($){X0.push($);while(X0.length>h("maxRequests"))X0.shift()}function L1(){return q1+=1,`req_${q1}`}function R1($){let j={};if(!$)return j;if($ instanceof Headers)$.forEach((J,Q)=>{j[Q]=J});else if(Array.isArray($))for(let[J,Q]of $)j[J]=Q;else Object.assign(j,$);return j}function e2($){let j={};return $.forEach((J,Q)=>{j[Q]=J}),j}function $4($){if($==null)return null;if(typeof $==="string")return $;if($ instanceof URLSearchParams)return $.toString();if(typeof FormData<"u"&&$ instanceof FormData)return`[FormData: ${Array.from($.keys()).join(", ")}]`;if(typeof Blob<"u"&&$ instanceof Blob)return`[Blob ${$.size} bytes]`;if($ instanceof ArrayBuffer)return`[ArrayBuffer ${$.byteLength} bytes]`;return"[binary]"}function j4($,j){let J="",Q="GET",z={},W=null;if(typeof $==="string")J=$;else if($ instanceof URL)J=$.toString();else J=$.url,Q=$.method||Q,z=R1($.headers);if(j){if(j.method)Q=j.method;if(j.headers)z={...z,...R1(j.headers)};if(j.body!==void 0)W=$4(j.body)}return{method:Q.toUpperCase(),url:J,headers:z,body:W}}function A1($){return!t0($)}function J4($,j){if(A1(j.url)){j.responseSnippet="[body not captured for this origin]";return}let J=$.headers.get("content-type")??"",Q=Number($.headers.get("content-length")??"0"),z=Q?`, ~${Q} bytes`:"";if(!/json|text|xml|html|javascript|urlencoded/i.test(J)){j.responseSnippet=`[binary ${J||"unknown"}${z}]`;return}if(Q>a2){j.responseSnippet=`[response ${J||"text"}${z} — omitted]`;return}try{$.clone().text().then((W)=>{j.responseSnippet=l(W,h("maxBodyChars"))}).catch(()=>{})}catch{}}function f1($,j){if(/[?&]_rsc=/.test($))return!0;for(let J of Object.keys(j)){let Q=J.toLowerCase();if(Q==="rsc"||Q==="next-router-prefetch"||Q==="next-router-state-tree")return!0}return!1}function Q4(){if(typeof window>"u"||typeof window.fetch!=="function")return;let $=window.fetch.bind(window);window.fetch=Object.assign(async(j,J)=>{let Q=j4(j,J);if(f1(Q.url,Q.headers))return $(j,J);let z={id:L1(),startedAt:new Date().toISOString(),method:Q.method,url:o(Q.url),requestHeaders:i(Q.headers),requestBody:l(Q.body,O1),status:null,statusText:null,durationMs:null,via:"fetch"};_1(z);let W=performance.now();try{let K=await $(j,J);return z.status=K.status,z.statusText=K.statusText,z.durationMs=Math.round(performance.now()-W),z.responseHeaders=i(e2(K.headers)),J4(K,z),K}catch(K){throw z.durationMs=Math.round(performance.now()-W),z.error=K instanceof Error?`${K.name}: ${K.message}`:String(K),K}},$)}function z4(){if(typeof window>"u"||typeof window.XMLHttpRequest!=="function")return;let $=XMLHttpRequest.prototype,j=$.open,J=$.send,Q=function(W,K){let G=typeof K==="string"?K:K.toString();return this.__cibEntry=f1(G,{})?void 0:{id:L1(),startedAt:"",method:(W||"GET").toUpperCase(),url:o(G),requestHeaders:{},requestBody:null,status:null,statusText:null,durationMs:null,via:"xhr"},j.apply(this,arguments)},z=function(W){let K=this.__cibEntry;if(K){K.startedAt=new Date().toISOString(),K.requestBody=typeof W==="string"?l(W,O1):W==null?null:"[non-string body]";let G=performance.now();_1(K),this.addEventListener("loadend",()=>{if(K.status=this.status||null,K.statusText=this.statusText||null,K.durationMs=Math.round(performance.now()-G),A1(K.url))K.responseSnippet="[body not captured for this origin]";else if(this.responseType===""||this.responseType==="text")try{K.responseSnippet=l(this.responseText||"",h("maxBodyChars"))}catch{}else{let H=this.getResponseHeader("content-type")??this.responseType;K.responseSnippet=`[binary ${H}]`}})}return J.apply(this,arguments)};$.open=Q,$.send=z}function T1(){if(S1)return;S1=!0,Q4(),z4()}function A0(){let $=X0.map((J)=>({...J})),j=0;for(let J=$.length-1;J>=0;J-=1){let Q=$[J],z=Q?.responseSnippet;if(!Q||typeof z!=="string"||z.length===0)continue;if(j+z.length>t2)Q.responseSnippet=`[response omitted — report size budget reached (${z.length.toLocaleString()} chars)]`;else j+=z.length}return $}var Z4={title:"รายงานปัญหา",summaryLabel:"หัวข้อปัญหา",summaryRequired:"(ต้องกรอกก่อนแจ้งปัญหา)",summaryPlaceholder:"สรุปปัญหาสั้น ๆ เช่น กดบันทึกร่างแล้ว error",detailLabel:"อธิบายปัญหา (ไม่บังคับ)",detailPlaceholder:"เกิดอะไรขึ้น? กำลังทำอะไรอยู่ตอนที่พบปัญหา?",annotateTitle:"วาดบนรูป",annotateHint:"ทำเครื่องหมายจุดที่มีปัญหาก่อนแนบ — วงกรอบ ชี้ลูกศร ไฮไลต์ หรือพิมพ์ข้อความ",annotateApply:"ใช้รูปนี้",cancel:"ยกเลิก",toolRect:"กรอบ",toolArrow:"ลูกศร",toolHighlight:"ไฮไลต์",toolText:"ข้อความ",deleteSelected:"ลบที่เลือก",clearAll:"ล้างทั้งหมด",annotateHelp:"เลือกเครื่องมือแล้วลากบนรูป · ไม่ได้เลือกเครื่องมือ = ย้าย/ปรับขนาดสิ่งที่วาดไว้ · กดกากบาทมุมขวาบนของรูปทรงเพื่อลบ",capturing:"กำลังเก็บภาพหน้าจอ…",noScreenshot:"ไม่มีภาพหน้าจอ — ยังส่งรายงานได้",cancelled:"ยกเลิกการเก็บภาพหน้าจอแล้ว",close:"ปิด",submit:"แจ้งปัญหา",submitting:"กำลังส่ง…",submitted:"แจ้งปัญหาสำเร็จ",crashed:"เกิดข้อผิดพลาดในระบบ",crashAction:"แจ้งปัญหา",failed:"ส่งรายงานไม่สำเร็จ",captured:"เก็บข้อมูลแล้ว",reporter:"ผู้แจ้ง",page:"หน้า",handoffTitle:"กำลังพาไปที่ระบบแจ้งปัญหา",handoffBody:"ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",handoffGo:"ไปเลย",handoffPreparing:"กำลังเตรียม…",handoffFailed:"เปิดรายการที่แจ้งไว้ไม่สำเร็จ",handoffBlocked:"เบราว์เซอร์บล็อกการเปิดแท็บใหม่",handoffOpen:"เปิดในแท็บใหม่"},W4={title:"Report a problem",summaryLabel:"Summary",summaryRequired:"(required)",summaryPlaceholder:"One line, e.g. saving a draft returns an error",detailLabel:"Details (optional)",detailPlaceholder:"What happened? What were you doing at the time?",annotateTitle:"Draw on the image",annotateHint:"Mark what went wrong before attaching — box it, point at it, highlight it, or type on it",annotateApply:"Use this image",cancel:"Cancel",toolRect:"Box",toolArrow:"Arrow",toolHighlight:"Highlight",toolText:"Text",deleteSelected:"Delete selected",clearAll:"Clear all",annotateHelp:"Pick a tool and drag on the image · no tool selected = move/resize what you drew · press the ✕ on a shape to delete it",capturing:"Capturing the screen…",noScreenshot:"No screenshot — you can still send the report",cancelled:"Screen capture cancelled",close:"Close",submit:"Send report",submitting:"Sending…",submitted:"Report sent",crashed:"Something went wrong",crashAction:"Report it",failed:"Could not send the report",captured:"Captured",reporter:"Reporter",page:"Page",handoffTitle:"Opening the support portal",handoffBody:"You will be signed in automatically to see what you reported",handoffGo:"Go now",handoffPreparing:"Preparing…",handoffFailed:"Could not open your reports",handoffBlocked:"Your browser blocked the new tab",handoffOpen:"Open in a new tab"};function b($){return $==="en"?W4:Z4}var f0=null;function K4(){if(typeof document>"u")return null;if(f0?.isConnected)return f0;let $=document.createElement("lw-debug-toasts");$.dataset.debugReporter="true";let j=$.attachShadow({mode:"open"}),J=document.createElement("style");J.textContent=`
|
|
1
|
+
var J2={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},T=null;function Q2($){T=$}function R(){if(!T)throw Error("[debug-capture] configureDebugCapture() has not been called");return T}function U0(){return T!==null}function E(){let $=R().app;return{name:$.name,version:$.version??"0.0.0",environment:$.environment??z2()}}function z2(){if(typeof window>"u")return"unknown";let $=window.location.hostname;if($==="localhost"||$==="127.0.0.1"||$.endsWith(".local"))return"development";return"production"}function h($){let j=T?.capture?.[$];return typeof j==="number"?j:J2[$]}function n0($){let j=T?.module;if(!j)return null;try{return j($)??null}catch{return null}}function Z0(){let $=T?.redact;return{headers:$?.headers??[],queryKeys:($?.queryKeys??[]).map((j)=>j.toLowerCase()),bodyKeys:($?.bodyKeys??[]).map((j)=>j.toLowerCase())}}function a0(){return T?.capture?.overlaySelectors??[]}function t0($){if(typeof window>"u")return!1;let j;try{j=new URL($,window.location.href)}catch{return!1}if(Z2(j))return!1;if(j.origin===window.location.origin)return!0;return(T?.capture?.bodyOrigins??[]).some((J)=>{try{return new URL(J).origin===j.origin}catch{return!1}})}function Z2($){if(!T?.host)return!1;try{if(new URL(T.host).origin!==$.origin)return!1}catch{return!1}return $.pathname.startsWith("/ingest/")}var d="‹redacted›",W2=/^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i,K2=new Set(["access_token","token","id_token","refresh_token","code","secret","client_secret","password","apikey","api_key","signature","x-amz-signature","x-amz-credential"]),V2=/(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i,X2=/[\w.+-]+@[\w-]+\.[\w.-]+/g,G2=/\d(?:[\d\s-]{7,})\d/g;function c($){return $.replace(X2,d).replace(G2,d)}function Y2($){if(W2.test($))return!0;return Z0().headers.some((J)=>J.toLowerCase()===$.toLowerCase())}function i($){let j={};for(let[J,Q]of Object.entries($))j[J]=Y2(J)?d:Q;return j}function o($){try{let j=/^https?:\/\//i.test($),J=new URL($,j?void 0:"http://local.invalid"),Q=!1;if(J.searchParams.forEach((z,W)=>{if(K2.has(W.toLowerCase())||Z0().queryKeys.includes(W.toLowerCase()))J.searchParams.set(W,d),Q=!0}),!Q)return $;return j?J.toString():`${J.pathname}${J.search}`}catch{return $}}function C0($,j){if(j>6||$===null||typeof $!=="object")return $;if(Array.isArray($))return $.map((Q)=>C0(Q,j+1));let J={};for(let[Q,z]of Object.entries($)){let W=V2.test(Q)||Z0().bodyKeys.some((K)=>Q.toLowerCase().includes(K));J[Q]=W?d:C0(z,j+1)}return J}function l($,j){if($==null)return null;let J=$,Q=$.trim();if(Q.startsWith("{")||Q.startsWith("["))try{let z=JSON.parse(Q);J=JSON.stringify(C0(z,0))}catch{}if(J.length>j)return`${J.slice(0,j)}… [truncated ${J.length-j} chars]`;return J}var P0=120,I0=40,s=($,j)=>$.length>j?`${$.slice(0,j)}…`:$,w0=($)=>{try{return decodeURIComponent($)}catch{return $}},r=[],e0=0,$1=!1;function j0($,j,J,Q){let z=s(j,P0),W=r[r.length-1];if($==="navigate"&&W?.kind==="click"){let G=z.replace(/^ไปที่\s*/,"");if(W.detail.includes(`→ ${G}`))return W.at=new Date().toISOString(),W;let H=G.split(/[?#]/)[0]??G,U=W.source?w0(W.source.replace(/^→\s*/,"")).split(/[?#]/)[0]:null;if(U&&(H===U||H.startsWith(U)))return W.detail=s(`${W.detail} → ${G}`,P0),W.source=void 0,W.at=new Date().toISOString(),W}if(W&&W.kind===$&&W.detail===z){if(W.at=new Date().toISOString(),$!=="navigate")W.count=(W.count??1)+1;return W}e0+=1;let K={id:`act_${e0}`,at:new Date().toISOString(),kind:$,detail:z,count:1,source:J,html:K0(Q)};r.push(K);while(r.length>h("maxActions"))H2(r.shift());return K}var F2=200000,J0=0;function K0($){if(!$)return;if(J0+$.length>F2)return;return J0+=$.length,$}function H2($){if(!$)return;if(J0-=($.html?.length??0)+($.afterHtml?.length??0),J0<0)J0=0}function D0($){return $&&$>1?` (×${$})`:""}function W0($){return $ instanceof Element&&Boolean($.closest("[data-debug-reporter]"))}var M2='button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea',U2={button:"ปุ่ม",a:"ลิงก์",input:"ช่อง",textarea:"ช่อง",select:"ตัวเลือก",summary:"ส่วนขยาย"},j1={button:"ปุ่ม",tab:"แท็บ",menuitem:"เมนู",option:"ตัวเลือก",switch:"สวิตช์",checkbox:"ช่องเลือก",radio:"ตัวเลือก",link:"ลิงก์"};function C2($){let j=$.getAttribute("role");if(j&&j1[j])return j1[j];return U2[$.tagName.toLowerCase()]??"ปุ่ม"}function P2($,j){try{let J=$,Q=0;while(J&&Q<=j){let z=K1(J);if(z&&typeof z.memoizedProps?.onClick==="function")return J;J=J.parentElement,Q+=1}}catch{}return null}function I2($){let j=$.getAttribute("aria-label")?.trim();if(j)return j;let J=$.getAttribute("title")?.trim();if(J)return J;if($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement)return($.getAttribute("placeholder")||$.getAttribute("name")||"").trim();if($ instanceof HTMLImageElement)return($.getAttribute("alt")||"").trim();let Q=($.textContent??"").replace(/\s+/g," ").trim();if(Q)return Q;if($ instanceof HTMLAnchorElement){let z=$.getAttribute("href");if(z?.startsWith("/"))return w0(z)}return""}function w2($){if(!($ instanceof Element))return null;let j=$.closest(M2)??P2($,4);if(!j)return null;let J=j.tagName.toLowerCase();if(J==="html"||J==="body")return null;return j}function D2($){let j=c(I2($));if(!j)return null;return`${C2($)} “${s(j,I0)}”`}var W1=6000,N2=4000,B2=/(?:^|\s)!?(?:fixed|absolute|sticky|inset-\S+|z-\S+|top-\S+|bottom-\S+|left-\S+|right-\S+|w-screen|h-screen|min-h-screen|max-h-screen|translate-\S+|scale-\S+)(?=\s|$)/g;function q2($){$.querySelectorAll("script, style, link, iframe, object, embed, noscript, canvas, video, audio").forEach((z)=>z.remove());let j=[$,...Array.from($.querySelectorAll("*"))];for(let z of j){for(let K of Array.from(z.attributes)){let G=K.name.toLowerCase();if(G.startsWith("on")||G==="srcdoc"||G==="value"||G.startsWith("data-"))z.removeAttribute(K.name)}if(z instanceof HTMLAnchorElement)z.setAttribute("href","#");if(z instanceof HTMLImageElement)z.removeAttribute("src");let W=z.getAttribute("class");if(W){let K=W.replace(B2," ").replace(/\s+/g," ").trim();if(K)z.setAttribute("class",K);else z.removeAttribute("class")}}let J=document.createTreeWalker($,NodeFilter.SHOW_TEXT),Q=J.nextNode();while(Q){if(Q.nodeValue)Q.nodeValue=c(Q.nodeValue);Q=J.nextNode()}}function N0($,j,J){try{let Q=$.outerHTML;if(!Q||Q.length>j)return;let z=$.cloneNode(!0);q2(z);let W=z.outerHTML;return W&&W.length<=J?W:void 0}catch{return}}var S2=($)=>N0($,W1,N2),R2=150000,O2=40000,J1=($)=>N0($,R2,O2);function _2($){if(!($ instanceof HTMLInputElement)&&!($ instanceof HTMLTextAreaElement)&&!($ instanceof HTMLSelectElement))return null;let j=$.name||$.id||$.getAttribute("aria-label")||$.getAttribute("placeholder")||$.tagName.toLowerCase();return`ช่อง “${c(j)}”`}var Q1=80;function K1($){let j=Object.keys($).find((J)=>J.startsWith("__reactFiber$")||J.startsWith("__reactInternalInstance$"));return j?$[j]:null}function L2($){if(typeof $!=="function")return null;try{let j=Function.prototype.toString.call($);return(j.match(/\.(?:push|replace)\(\s*['"`]([^'"`]+)['"`]/)??j.match(/redirect\(\s*['"`]([^'"`]+)['"`]/))?.[1]??null}catch{return null}}function z1($){if(!$)return;return`→ ${$.length>Q1?`${$.slice(0,Q1)}…`:$}`}function A2($){try{let j=$.closest("a[href]")?.getAttribute("href");if(j&&j.startsWith("/"))return z1(j);let J=K1($),Q=0;while(J&&Q<30){if(typeof J.memoizedProps?.onClick==="function")return z1(L2(J.memoizedProps.onClick));J=J.return,Q+=1}return}catch{return}}var f2='[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';function T2(){let $=a0();return $.length?$.join(", "):f2}function k2($){let j=$.getAttribute("role");if(j==="status"||j==="alert")return"ข้อความแจ้งเตือน";if(j==="menu")return"เมนู";if(j==="listbox")return"รายการตัวเลือก";if(j==="alertdialog")return"กล่องยืนยัน";return"กล่องโต้ตอบ"}function E2($){let j=$.getAttribute("aria-label")?.trim();if(j)return j;let J=$.getAttribute("aria-labelledby");if(J){let W=J.split(/\s+/).map((K)=>document.getElementById(K)?.textContent?.trim()??"").filter(Boolean).join(" ");if(W)return W}let z=$.querySelector('[data-slot="dialog-title"], h1, h2, h3, [role="heading"]')?.textContent?.replace(/\s+/g," ").trim();if(z)return z;return($.textContent??"").replace(/\s+/g," ").trim()}function V1($){let j=c(E2($)),J=k2($);return j?`เปิด ${J} “${s(j,I0)}”`:`เปิด ${J}`}var x2='[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin',h2=/กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;function g2($){if($.querySelector(x2))return!0;return h2.test($.textContent??"")}var m2=400,p2=250,v2=8000;function y2($,j){if(typeof MutationObserver>"u"){j.html=K0(J1($));return}let J=Date.now(),Q=!1,z=()=>{Q=!0,K.disconnect(),window.clearInterval(G),window.clearTimeout(H)},W=()=>{if(Q)return;if(z(),!$.isConnected)return;j.detail=s(V1($),P0),j.html=K0(J1($))},K=new MutationObserver(()=>{J=Date.now()});K.observe($,{childList:!0,subtree:!0,attributes:!0,characterData:!0});let G=window.setInterval(()=>{if(Q)return;if(!$.isConnected){z();return}if(Date.now()-J>=m2&&!g2($))W()},p2),H=window.setTimeout(W,v2)}function b2($){if(W0($))return;let j=j0("ui",V1($));if(j)y2($,j)}function u2(){if(typeof MutationObserver>"u")return;let $=new WeakSet;new MutationObserver((J)=>{for(let Q of J)for(let z of Array.from(Q.addedNodes)){if(!(z instanceof Element))continue;let W=T2(),K=z.matches(W)?[z]:Array.from(z.querySelectorAll(W));for(let G of K){if($.has(G))continue;$.add(G),b2(G)}}}).observe(document.body,{childList:!0,subtree:!0})}var d2=1600,c2=2500;function Z1($){return{disabled:$.hasAttribute("disabled")||$.getAttribute("aria-disabled")==="true",busy:$.getAttribute("aria-busy")==="true",text:s(($.textContent??"").replace(/\s+/g," ").trim(),I0)}}function i2($,j){if(!$.disabled&&j.disabled)return"ปุ่มถูกปิดใช้งานหลังคลิก";if(!$.busy&&j.busy)return"ปุ่มเข้าสู่สถานะกำลังโหลด";if($.text!==j.text&&j.text)return`ข้อความเปลี่ยนเป็น “${j.text}”`;return null}function o2($,j){if(typeof MutationObserver>"u")return;let J=Z1($),Q=!1,z=(G,H)=>{if(Q)return;if(Q=!0,W.disconnect(),window.clearTimeout(K),j.afterNote=G,H)j.afterHtml=K0(N0($,W1,c2))},W=new MutationObserver(()=>{if(!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}let G=i2(J,Z1($));if(G)z(G,!0)});W.observe($,{attributes:!0,attributeFilter:["disabled","aria-disabled","aria-busy","class"],childList:!0,subtree:!0,characterData:!0});let K=window.setTimeout(()=>{if(!Q&&!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}Q=!0,W.disconnect()},d2)}function X1(){if($1||typeof window>"u")return;$1=!0,document.addEventListener("click",(Q)=>{if(W0(Q.target))return;let z=w2(Q.target);if(!z)return;let W=D2(z);if(!W)return;let K=j0("click",`คลิก ${W}`,A2(z),S2(z));if(K)o2(z,K)},{capture:!0,passive:!0}),document.addEventListener("change",(Q)=>{if(W0(Q.target))return;let z=_2(Q.target);if(z)j0("input",`แก้ไข ${z}`)},{capture:!0,passive:!0}),document.addEventListener("submit",(Q)=>{if(W0(Q.target))return;j0("submit","ส่งฟอร์ม")},{capture:!0,passive:!0});let $=()=>j0("navigate",`ไปที่ ${w0(o(location.pathname+location.search))}`),j=history.pushState.bind(history),J=history.replaceState.bind(history);history.pushState=(...Q)=>{let z=j(...Q);return $(),z},history.replaceState=(...Q)=>{let z=J(...Q);return $(),z},window.addEventListener("popstate",$),u2()}function B0(){return r.map(($)=>({...$}))}var G1=2000,V0=[],Y1=0,F1=!1;function q0($,j){Y1+=1,V0.push({id:`log_${Y1}`,at:new Date().toISOString(),level:$,message:j.length>G1?`${j.slice(0,G1)}…`:j});while(V0.length>h("maxConsoleEntries"))V0.shift()}function l2(){let $=new WeakSet;return(j,J)=>{if(typeof J==="object"&&J!==null){if($.has(J))return"[Circular]";$.add(J)}if(typeof J==="bigint")return J.toString();return J}}function H1($){if(typeof $==="string")return $;if($ instanceof Error)return`${$.name}: ${$.message}`;try{return JSON.stringify($,l2())??String($)}catch{return String($)}}function M1(){if(F1||typeof window>"u")return;F1=!0;let $=["log","info","warn","error","debug"];for(let j of $){let J=console[j].bind(console);console[j]=(...Q)=>{q0(j,Q.map(H1).join(" ")),J(...Q)}}window.addEventListener("error",(j)=>{let J=j.filename?` (${j.filename}:${j.lineno}:${j.colno})`:"";q0("exception",`${j.message}${J}`)}),window.addEventListener("unhandledrejection",(j)=>{let J=j.reason instanceof Error?`${j.reason.name}: ${j.reason.message}`:H1(j.reason);q0("unhandledrejection",J)})}function S0(){return V0.map(($)=>({...$}))}var U1=new Set,C1=new Set;function P1($,j){return $.add(j),()=>$.delete(j)}function I1($,j){for(let J of[...$])J(j)}function R0($){return P1(U1,$)}function O0($={type:"manual"}){I1(U1,$)}function _0($){return P1(C1,$)}function L0($){I1(C1,$)}var r2=15000,s2=["ResizeObserver loop","Script error.","Non-Error promise rejection captured"],w1=!1,D1=0;function n2($){return s2.some((j)=>$.includes(j))}function N1($){let j=$.message??"";if(!j||n2(j))return;let J=Date.now();if(J-D1<r2)return;D1=J,L0({...$,message:j})}function B1(){if(w1||typeof window>"u")return;w1=!0,window.addEventListener("error",($)=>{if(!$.message&&!$.error)return;let j=$.error instanceof Error?$.error:null;N1({type:"runtime-error",message:$.message||(j?j.message:"Unknown error"),stack:j?.stack})}),window.addEventListener("unhandledrejection",($)=>{let j=$.reason;N1({type:"unhandledrejection",message:j instanceof Error?j.message:String(j),stack:j instanceof Error?j.stack:void 0})})}var O1=4000,a2=1e6,t2=1e7,X0=[],q1=0,S1=!1;function _1($){X0.push($);while(X0.length>h("maxRequests"))X0.shift()}function L1(){return q1+=1,`req_${q1}`}function R1($){let j={};if(!$)return j;if($ instanceof Headers)$.forEach((J,Q)=>{j[Q]=J});else if(Array.isArray($))for(let[J,Q]of $)j[J]=Q;else Object.assign(j,$);return j}function e2($){let j={};return $.forEach((J,Q)=>{j[Q]=J}),j}function $4($){if($==null)return null;if(typeof $==="string")return $;if($ instanceof URLSearchParams)return $.toString();if(typeof FormData<"u"&&$ instanceof FormData)return`[FormData: ${Array.from($.keys()).join(", ")}]`;if(typeof Blob<"u"&&$ instanceof Blob)return`[Blob ${$.size} bytes]`;if($ instanceof ArrayBuffer)return`[ArrayBuffer ${$.byteLength} bytes]`;return"[binary]"}function j4($,j){let J="",Q="GET",z={},W=null;if(typeof $==="string")J=$;else if($ instanceof URL)J=$.toString();else J=$.url,Q=$.method||Q,z=R1($.headers);if(j){if(j.method)Q=j.method;if(j.headers)z={...z,...R1(j.headers)};if(j.body!==void 0)W=$4(j.body)}return{method:Q.toUpperCase(),url:J,headers:z,body:W}}function A1($){return!t0($)}function J4($,j){if(A1(j.url)){j.responseSnippet="[body not captured for this origin]";return}let J=$.headers.get("content-type")??"",Q=Number($.headers.get("content-length")??"0"),z=Q?`, ~${Q} bytes`:"";if(!/json|text|xml|html|javascript|urlencoded/i.test(J)){j.responseSnippet=`[binary ${J||"unknown"}${z}]`;return}if(Q>a2){j.responseSnippet=`[response ${J||"text"}${z} — omitted]`;return}try{$.clone().text().then((W)=>{j.responseSnippet=l(W,h("maxBodyChars"))}).catch(()=>{})}catch{}}function f1($,j){if(/[?&]_rsc=/.test($))return!0;for(let J of Object.keys(j)){let Q=J.toLowerCase();if(Q==="rsc"||Q==="next-router-prefetch"||Q==="next-router-state-tree")return!0}return!1}function Q4(){if(typeof window>"u"||typeof window.fetch!=="function")return;let $=window.fetch.bind(window);window.fetch=Object.assign(async(j,J)=>{let Q=j4(j,J);if(f1(Q.url,Q.headers))return $(j,J);let z={id:L1(),startedAt:new Date().toISOString(),method:Q.method,url:o(Q.url),requestHeaders:i(Q.headers),requestBody:l(Q.body,O1),status:null,statusText:null,durationMs:null,via:"fetch"};_1(z);let W=performance.now();try{let K=await $(j,J);return z.status=K.status,z.statusText=K.statusText,z.durationMs=Math.round(performance.now()-W),z.responseHeaders=i(e2(K.headers)),J4(K,z),K}catch(K){throw z.durationMs=Math.round(performance.now()-W),z.error=K instanceof Error?`${K.name}: ${K.message}`:String(K),K}},$)}function z4(){if(typeof window>"u"||typeof window.XMLHttpRequest!=="function")return;let $=XMLHttpRequest.prototype,j=$.open,J=$.send,Q=function(W,K){let G=typeof K==="string"?K:K.toString();return this.__cibEntry=f1(G,{})?void 0:{id:L1(),startedAt:"",method:(W||"GET").toUpperCase(),url:o(G),requestHeaders:{},requestBody:null,status:null,statusText:null,durationMs:null,via:"xhr"},j.apply(this,arguments)},z=function(W){let K=this.__cibEntry;if(K){K.startedAt=new Date().toISOString(),K.requestBody=typeof W==="string"?l(W,O1):W==null?null:"[non-string body]";let G=performance.now();_1(K),this.addEventListener("loadend",()=>{if(K.status=this.status||null,K.statusText=this.statusText||null,K.durationMs=Math.round(performance.now()-G),A1(K.url))K.responseSnippet="[body not captured for this origin]";else if(this.responseType===""||this.responseType==="text")try{K.responseSnippet=l(this.responseText||"",h("maxBodyChars"))}catch{}else{let H=this.getResponseHeader("content-type")??this.responseType;K.responseSnippet=`[binary ${H}]`}})}return J.apply(this,arguments)};$.open=Q,$.send=z}function T1(){if(S1)return;S1=!0,Q4(),z4()}function A0(){let $=X0.map((J)=>({...J})),j=0;for(let J=$.length-1;J>=0;J-=1){let Q=$[J],z=Q?.responseSnippet;if(!Q||typeof z!=="string"||z.length===0)continue;if(j+z.length>t2)Q.responseSnippet=`[response omitted — report size budget reached (${z.length.toLocaleString()} chars)]`;else j+=z.length}return $}var Z4={title:"รายงานปัญหา",summaryLabel:"หัวข้อปัญหา",summaryRequired:"(ต้องกรอกก่อนแจ้งปัญหา)",summaryPlaceholder:"สรุปปัญหาสั้น ๆ เช่น กดบันทึกร่างแล้ว error",detailLabel:"อธิบายปัญหา (ไม่บังคับ)",detailPlaceholder:"เกิดอะไรขึ้น? กำลังทำอะไรอยู่ตอนที่พบปัญหา?",annotateTitle:"วาดบนรูป",annotateHint:"ทำเครื่องหมายจุดที่มีปัญหาก่อนแนบ — วงกรอบ ชี้ลูกศร ไฮไลต์ หรือพิมพ์ข้อความ",annotateApply:"ใช้รูปนี้",cancel:"ยกเลิก",toolRect:"กรอบ",toolArrow:"ลูกศร",toolHighlight:"ไฮไลต์",toolText:"ข้อความ",deleteSelected:"ลบที่เลือก",clearAll:"ล้างทั้งหมด",annotateHelp:"เลือกเครื่องมือแล้วลากบนรูป · ไม่ได้เลือกเครื่องมือ = ย้าย/ปรับขนาดสิ่งที่วาดไว้ · กดกากบาทมุมขวาบนของรูปทรงเพื่อลบ",capturing:"กำลังเก็บภาพหน้าจอ…",noScreenshot:"ไม่มีภาพหน้าจอ — ยังส่งรายงานได้",cancelled:"ยกเลิกการเก็บภาพหน้าจอแล้ว",close:"ปิด",submit:"แจ้งปัญหา",submitting:"กำลังส่ง…",submitted:"แจ้งปัญหาสำเร็จ",crashed:"เกิดข้อผิดพลาดในระบบ",crashAction:"แจ้งปัญหา",failed:"ส่งรายงานไม่สำเร็จ",captured:"เก็บข้อมูลแล้ว",reporter:"ผู้แจ้ง",page:"หน้า",handoffTitle:"กำลังพาไปที่ระบบแจ้งปัญหา",handoffBody:"ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",handoffGo:"ไปเลย",handoffPreparing:"กำลังเตรียม…",handoffFailed:"เปิดรายการที่แจ้งไว้ไม่สำเร็จ",handoffBlocked:"เบราว์เซอร์บล็อกการเปิดแท็บใหม่",handoffOpen:"เปิดในแท็บใหม่"},W4={title:"Report a problem",summaryLabel:"Summary",summaryRequired:"(required)",summaryPlaceholder:"One line, e.g. saving a draft returns an error",detailLabel:"Details (optional)",detailPlaceholder:"What happened? What were you doing at the time?",annotateTitle:"Draw on the image",annotateHint:"Mark what went wrong before attaching — box it, point at it, highlight it, or type on it",annotateApply:"Use this image",cancel:"Cancel",toolRect:"Box",toolArrow:"Arrow",toolHighlight:"Highlight",toolText:"Text",deleteSelected:"Delete selected",clearAll:"Clear all",annotateHelp:"Pick a tool and drag on the image · no tool selected = move/resize what you drew · press the ✕ on a shape to delete it",capturing:"Capturing the screen…",noScreenshot:"No screenshot — you can still send the report",cancelled:"Screen capture cancelled",close:"Close",submit:"Send report",submitting:"Sending…",submitted:"Report sent",crashed:"Something went wrong",crashAction:"Report it",failed:"Could not send the report",captured:"Captured",reporter:"Reporter",page:"Page",handoffTitle:"Opening the support portal",handoffBody:"You will be signed in automatically to see what you reported",handoffGo:"Go now",handoffPreparing:"Preparing…",handoffFailed:"Could not open your reports",handoffBlocked:"Your browser blocked the new tab",handoffOpen:"Open in a new tab"};function b($){return $==="en"?W4:Z4}var f0=null;function K4(){if(typeof document>"u")return null;if(f0?.isConnected)return f0;let $=document.createElement("lw-debug-toasts");$.dataset.debugReporter="true";let j=$.attachShadow({mode:"open"}),J=document.createElement("style");J.textContent=`
|
|
2
2
|
:host { all: initial; }
|
|
3
3
|
.stack {
|
|
4
4
|
position: fixed; top: 16px; right: 16px; z-index: 2147483001;
|
|
@@ -30,7 +30,7 @@ var J2={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},T
|
|
|
30
30
|
}
|
|
31
31
|
@keyframes in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
|
|
32
32
|
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
|
|
33
|
-
`;let Q=document.createElement("div");return Q.className="stack",Q.setAttribute("role","status"),Q.setAttribute("aria-live","polite"),j.append(J,Q),document.body.append($),f0=Q,Q}function n($,j="success",J){let Q=K4();if(!Q)return;let z=document.createElement("div");z.className="toast",z.dataset.tone=j;let W=document.createElement("span");W.className="dot";let K=document.createElement("span");K.textContent=$;let G=document.createElement("button");G.type="button",G.className="close",G.textContent="✕",G.setAttribute("aria-label","ปิด");let H=()=>{window.clearTimeout(U),z.remove()};G.addEventListener("click",H);let U=j==="error"||J?0:window.setTimeout(H,6000);if(z.append(W,K),J){let C=document.createElement("button");C.type="button",C.className="action",C.textContent=J.label,C.addEventListener("click",()=>{H(),J.onClick()}),z.append(C)}z.append(G),Q.append(z)}function k1($,j,J){let Q=$.filter((W)=>Boolean(W.error)||W.status!=null&&W.status>=400).slice(-20).map((W)=>({method:W.method,url:W.url,status:W.status,error:W.error,at:W.startedAt})),z=j.filter((W)=>W.level==="error"||W.level==="exception"||W.level==="unhandledrejection").slice(-20).map((W)=>W.message);return{failedRequests:Q,errors:z,erroredQueries:J.slice(0,20)}}function E1($){return $.failedRequests.length+$.errors.length+$.erroredQueries.length}function V4(){let $={memoryUsedMb:null,memoryLimitMb:null,domContentLoadedMs:null,loadEventMs:null};if(typeof performance>"u")return $;let j=performance.memory;if(j)$.memoryUsedMb=Math.round(j.usedJSHeapSize/1024/1024),$.memoryLimitMb=Math.round(j.jsHeapSizeLimit/1024/1024);let[J]=performance.getEntriesByType("navigation");if(J)$.domContentLoadedMs=Math.round(J.domContentLoadedEventEnd),$.loadEventMs=Math.round(J.loadEventEnd);return $}function T0($,j){if(!$)return j;try{return $()}catch{return j}}function x1(){let $=R(),{pathname:j,search:J,href:Q}=window.location;return{capturedAt:new Date().toISOString(),route:{href:Q,pathname:j,search:J},module:n0(j),user:T0($.user,{}),apiHeaders:i(T0($.headers,{})),app:{name:
|
|
33
|
+
`;let Q=document.createElement("div");return Q.className="stack",Q.setAttribute("role","status"),Q.setAttribute("aria-live","polite"),j.append(J,Q),document.body.append($),f0=Q,Q}function n($,j="success",J){let Q=K4();if(!Q)return;let z=document.createElement("div");z.className="toast",z.dataset.tone=j;let W=document.createElement("span");W.className="dot";let K=document.createElement("span");K.textContent=$;let G=document.createElement("button");G.type="button",G.className="close",G.textContent="✕",G.setAttribute("aria-label","ปิด");let H=()=>{window.clearTimeout(U),z.remove()};G.addEventListener("click",H);let U=j==="error"||J?0:window.setTimeout(H,6000);if(z.append(W,K),J){let C=document.createElement("button");C.type="button",C.className="action",C.textContent=J.label,C.addEventListener("click",()=>{H(),J.onClick()}),z.append(C)}z.append(G),Q.append(z)}function k1($,j,J){let Q=$.filter((W)=>Boolean(W.error)||W.status!=null&&W.status>=400).slice(-20).map((W)=>({method:W.method,url:W.url,status:W.status,error:W.error,at:W.startedAt})),z=j.filter((W)=>W.level==="error"||W.level==="exception"||W.level==="unhandledrejection").slice(-20).map((W)=>W.message);return{failedRequests:Q,errors:z,erroredQueries:J.slice(0,20)}}function E1($){return $.failedRequests.length+$.errors.length+$.erroredQueries.length}function V4(){let $={memoryUsedMb:null,memoryLimitMb:null,domContentLoadedMs:null,loadEventMs:null};if(typeof performance>"u")return $;let j=performance.memory;if(j)$.memoryUsedMb=Math.round(j.usedJSHeapSize/1024/1024),$.memoryLimitMb=Math.round(j.jsHeapSizeLimit/1024/1024);let[J]=performance.getEntriesByType("navigation");if(J)$.domContentLoadedMs=Math.round(J.domContentLoadedEventEnd),$.loadEventMs=Math.round(J.loadEventEnd);return $}function T0($,j){if(!$)return j;try{return $()}catch{return j}}function x1(){let $=R(),{pathname:j,search:J,href:Q}=window.location;return{capturedAt:new Date().toISOString(),route:{href:Q,pathname:j,search:J},module:n0(j),user:T0($.user,{}),apiHeaders:i(T0($.headers,{})),app:{name:E().name,version:E().version,environment:E().environment},client:{userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform,online:navigator.onLine,viewport:{width:window.innerWidth,height:window.innerHeight,dpr:window.devicePixelRatio},screen:{width:window.screen.width,height:window.screen.height}},performance:V4(),extra:T0($.extra,{})}}var X4=2,G4={manual:"ผู้ใช้แจ้งเอง","runtime-error":"ข้อผิดพลาด runtime (auto)",unhandledrejection:"Promise rejection (auto)","framework-error":"หน้าจอค้าง/พัง (auto)"};function k0($){let j=A0(),J=S0();return{context:x1(),reason:$.reason,note:$.note,cause:k1(j,J,$.erroredQueries),actionTrail:B0(),network:j,console:J,screenshotDataUrl:$.screenshotDataUrl,screenshotMethod:$.screenshotMethod,meta:{generatedBy:"lightwork-debug-capture",schemaVersion:X4}}}function h1($){return $.replace(/'/g,"'\\''")}function g1($){let j=[`curl -X ${$.method} '${$.url}'`];for(let[J,Q]of Object.entries($.requestHeaders))j.push(` -H '${J}: ${h1(Q)}'`);if($.requestBody)j.push(` --data '${h1($.requestBody)}'`);return j.join(" \\\n")}function Y4($){if($.error)return`ERR ${$.error}`;return`${$.status??"—"} ${$.statusText??""}`.trim()}function F4($){if($.length===0)return"No network activity captured.";return $.map((j)=>{let J=j.durationMs!=null?`${j.durationMs}ms`:"—",Q=`# [${Y4(j)}] ${j.method} ${j.url} (${J}, ${j.startedAt})`,z=j.responseSnippet?`
|
|
34
34
|
# response: ${j.responseSnippet}`:"";return`${Q}
|
|
35
35
|
${g1(j)}${z}`}).join(`
|
|
36
36
|
|
|
@@ -38,7 +38,7 @@ ${g1(j)}${z}`}).join(`
|
|
|
38
38
|
`)}function M4($){if($.length===0)return"No user actions captured.";let j=0;return $.map((J)=>{let Q=J.source?` (${J.source})`:"",z=`${J.detail}${D0(J.count)}${Q}`;if(J.kind==="ui")return` ↳ [${J.at}] ${z}`;j+=1;let W=`${j}. [${J.at}] ${z}`;return J.afterNote?`${W}
|
|
39
39
|
↳ ${J.afterNote}`:W}).join(`
|
|
40
40
|
`)}function U4($){let j=[];for(let J of $.failedRequests)j.push(`✗ ${J.status??J.error??"ERR"} ${J.method} ${J.url}`);for(let J of $.errors)j.push(`⚠ ${J}`);for(let J of $.erroredQueries)j.push(`⚠ React Query error: ${J.key} — ${J.error}`);return j}function C4($){let{context:j}=$;return[`User : ${j.user.fullName??"—"} (${j.user.email??"—"})`,`Unit : ${j.user.unit??"—"}`,`Roles : ${j.user.roles?.join(", ")||"—"}`,`Route : ${j.route.href}`,`Module : ${j.module?`${j.module.label} (${j.module.key})`:"—"}`,`App : ${j.app.name} v${j.app.version} · ${j.app.environment}`,`Memory : ${j.performance.memoryUsedMb??"—"}/${j.performance.memoryLimitMb??"—"} MB`,`Client : ${j.client.userAgent}`,`Viewport : ${j.client.viewport.width}×${j.client.viewport.height} @${j.client.viewport.dpr}x`,`Reason : ${G4[$.reason.type]}${$.reason.message?` — ${$.reason.message}`:""}`,`Captured : ${$.network.length} requests · ${$.console.length} console · ${$.actionTrail.length} actions · screenshot=${$.screenshotMethod}`]}function P4($){let j=U4($.cause),J=[`## \uD83D\uDC1E ${$.context.app.name} — Debug Report`,`**Generated:** ${$.context.capturedAt}`,"",...C4($).map((Q)=>`- ${Q.replace(/\s{2,}:/,":")}`),"",`**หมายเหตุจากผู้แจ้ง:** ${$.note.trim()||"(ไม่มี)"}`];if(j.length>0)J.push("","### ⚠ สาเหตุที่น่าจะเป็น","```",...j,"```");return J.push("",`<details><summary>ขั้นตอน (${$.actionTrail.length})</summary>`,"","```",M4($.actionTrail),"```","</details>","",`<details><summary>Network (${$.network.length})</summary>`,"","```",F4($.network),"```","</details>","",`<details><summary>Console (${$.console.length})</summary>`,"","```",H4($.console),"```","</details>","","_ข้อมูลลับ (token, cookie) ถูกปกปิดอัตโนมัติ · ภาพหน้าจออยู่ในไฟล์ .zip_"),J.join(`
|
|
41
|
-
`)}function I4($){return $.replace(/[:.]/g,"-").replace("T","_").slice(0,19)}function w4($,j){return`debug-report_${I4($.context.capturedAt)}.${j}`}function D4($){return E1($.cause)>0}async function E0(){if(typeof navigator<"u"&&Boolean(navigator.mediaDevices?.getDisplayMedia)){let J=await N4();if(J.status==="ok")return{dataUrl:J.dataUrl,method:"display-media"};if(J.status==="cancelled")return{dataUrl:null,method:"cancelled"}}let j=await S4();if(j)return{dataUrl:j,method:"html-to-image"};return{dataUrl:null,method:"none"}}async function N4(){let $=null;try{let j={video:{frameRate:30},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude"};$=await navigator.mediaDevices.getDisplayMedia(j);let J=await B4($);return J?{status:"ok",dataUrl:J}:{status:"error"}}catch(j){if(j instanceof DOMException&&(j.name==="NotAllowedError"||j.name==="AbortError"))return{status:"cancelled"};return{status:"error"}}finally{$?.getTracks().forEach((j)=>j.stop())}}async function B4($){let j=document.createElement("video");j.srcObject=$,j.muted=!0,j.playsInline=!0,await new Promise((K)=>{let G=!1,H=()=>{if(G)return;G=!0,K()};j.onloadedmetadata=()=>{j.play().then(H).catch(H)},window.setTimeout(H,1500)}),await q4(j);let{videoWidth:J,videoHeight:Q}=j;if(!J||!Q)return null;let z=document.createElement("canvas");z.width=J,z.height=Q;let W=z.getContext("2d");if(!W)return null;W.drawImage(j,0,0,J,Q),j.pause(),j.srcObject=null;try{return z.toDataURL("image/png")}catch{return null}}function q4($){return new Promise((j)=>{let J=!1,Q=()=>{if(J)return;J=!0,j()},z=$;if(typeof z.requestVideoFrameCallback==="function")z.requestVideoFrameCallback(()=>Q()),window.setTimeout(Q,1000);else window.setTimeout(Q,250)})}async function S4(){let $=R().screenshotFallback;if(!$)return null;let j=await $().catch(()=>null);if(!j)return null;try{return await j(document.body,{cacheBust:!0,pixelRatio:Math.min(window.devicePixelRatio||1,2),filter:(J)=>!(J instanceof HTMLElement&&J.dataset?.debugReporter==="true")})}catch{return null}}var R4=2000,O4=0.82,_4=3000000;function L4($){return new Promise((j,J)=>{let Q=new Image;Q.onload=()=>j(Q),Q.onerror=()=>J(Error("could not read the screenshot")),Q.src=$})}async function p1($){try{let j=await L4($),J=Math.max(j.naturalWidth,j.naturalHeight),Q=Math.min(1,R4/J),z=document.createElement("canvas");z.width=Math.max(1,Math.round(j.naturalWidth*Q)),z.height=Math.max(1,Math.round(j.naturalHeight*Q));let W=z.getContext("2d");if(!W)return $;W.fillStyle="#fff",W.fillRect(0,0,z.width,z.height),W.drawImage(j,0,0,z.width,z.height);let K=O4,G=z.toDataURL("image/jpeg",K);while(G.length>_4&&K>0.4)K-=0.15,G=z.toDataURL("image/jpeg",K);return G}catch{return $}}var A4=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,f4=/^\d+$/,T4=/^[0-9a-f]{16,}$/i;function x0($){if($.reason.type==="manual")return null;let j=$.cause?.failedRequests?.[0];if(!j?.url)return null;let J;try{J=new URL(j.url,"http://x").pathname}catch{J=j.url}let Q=J.split("/").map((W)=>A4.test(W)||f4.test(W)||T4.test(W)?":id":W).join("/"),z=j.status??(j.error?"ERR":"?");return`${j.method??"REQ"} ${Q} ${z}`}var h0=2000000;function G0($){let{screenshotDataUrl:j,...J}=$;return JSON.stringify(J).length}function g0($,j=2000000){if(G0($)<=j)return $;let J=$.network.map((z)=>({...z})),Q={...$,network:J};for(let z of J){if(G0(Q)<=j)return Q;if(typeof z.responseSnippet==="string"&&z.responseSnippet.length>35)z.responseSnippet="[body dropped — report size budget]";if(typeof z.requestBody==="string"&&z.requestBody.length>35)z.requestBody="[body dropped — report size budget]"}while(Q.network.length>1&&G0(Q)>j)Q.network=Q.network.slice(1);while(Q.console.length>1&&G0(Q)>j)Q.console=Q.console.slice(1);return Q}var m1=32768;function k4($){let j="";for(let J=0;J<$.length;J+=m1)j+=String.fromCharCode(...$.subarray(J,J+m1));return btoa(j)}function E4($){return{dataUri:`data:application/json;base64,${k4(new TextEncoder().encode(JSON.stringify($)))}`,filename:"debug-bundle.json"}}async function x4(){let $=R().identity;if(!$)return{};try{let j=await $();return j?{authorization:`Bearer ${j}`}:{}}catch{return{}}}async function p0($,j){let J=R(),Q=g0(j,h0),{context:z,note:W}=Q,K=[];if(Q.screenshotDataUrl){let C=await p1(Q.screenshotDataUrl);K.push({dataUri:C,filename:"screenshot.jpg"})}K.push(E4(Q));let G=x0(Q),H={title:$,description:W.trim()||void 0,category:z.module?.label||x().name,routeUrl:z.route.href,priority:"MEDIUM",requesterEmail:z.user.email??void 0,requesterName:z.user.fullName??void 0,customFields:{unit:z.user.unit??"",appVersion:z.app.version,environment:z.app.environment,reasonType:Q.reason.type,appName:x().name,module:z.module?.label??""},context:{...G?{signature:G}:{},capturedAt:z.capturedAt,reason:Q.reason,cause:Q.cause,actionTrail:Q.actionTrail,client:z.client,performance:z.performance,apiHeaders:z.apiHeaders,extra:z.extra,counts:{network:Q.network.length,console:Q.console.length,actions:Q.actionTrail.length},screenshotMethod:Q.screenshotMethod},attachments:K},U=await fetch(`${J.host.replace(/\/$/,"")}/ingest/tickets`,{method:"POST",headers:{"content-type":"application/json","x-realm-key":J.realmKey,...await x4()},body:JSON.stringify(H)});if(!U.ok){let C=U.headers.get("retry-after"),w=await U.json().then((P)=>P.error).catch(()=>null);throw Error(U.status===429?`Too many reports — try again in ${C??"a moment"}s`:w??`Report failed (${U.status})`)}return await U.json()}var Q0=Math.PI/6;function v1($,j,J){let Q=j.x-$.x,z=j.y-$.y,W=Math.hypot(Q,z),K=Math.atan2(z,Q),G=[{x:j.x,y:j.y},{x:j.x-J*Math.cos(K-Q0),y:j.y-J*Math.sin(K-Q0)},{x:j.x-J*Math.cos(K+Q0),y:j.y-J*Math.sin(K+Q0)}],H=J*Math.cos(Q0)*0.92;if(W<=H)return{shaft:null,head:G};return{shaft:{from:$,to:{x:j.x-H*Math.cos(K),y:j.y-H*Math.sin(K)}},head:G}}var m0="#f44336",h4="rgba(250, 204, 21, 0.4)",v0=22,y1="#2563eb",b1=9,u1=11,d1=18,c1=4,Y0=8,g4=[{id:"nw",fx:0,fy:0,cursor:"nwse-resize"},{id:"n",fx:0.5,fy:0,cursor:"ns-resize"},{id:"ne",fx:1,fy:0,cursor:"nesw-resize"},{id:"e",fx:1,fy:0.5,cursor:"ew-resize"},{id:"se",fx:1,fy:1,cursor:"nwse-resize"},{id:"s",fx:0.5,fy:1,cursor:"ns-resize"},{id:"sw",fx:0,fy:1,cursor:"nesw-resize"},{id:"w",fx:0,fy:0.5,cursor:"ew-resize"}];function y0($,j,J){let Q=[],z=null,W=-1,K=null,G=null,H=$.getContext("2d");function U(){let Z=$.getBoundingClientRect().width;return Z>0?$.width/Z:1}function C(Z){let V=$.getBoundingClientRect();return{x:(Z.clientX-V.left)/V.width*$.width,y:(Z.clientY-V.top)/V.height*$.height}}function w(Z){let V=Z.size??v0;if(!H)return(Z.text?.length??0)*V*0.6;H.save(),H.font=`600 ${V}px system-ui, sans-serif`;let Y=H.measureText(Z.text??"").width;return H.restore(),Y}function P(Z){if(Z.tool==="text"){let V=Z.size??v0;return{left:Z.x1,top:Z.y1,right:Z.x1+w(Z),bottom:Z.y1+V*1.25}}return{left:Math.min(Z.x1,Z.x2),top:Math.min(Z.y1,Z.y2),right:Math.max(Z.x1,Z.x2),bottom:Math.max(Z.y1,Z.y2)}}function O(Z){if(Z.tool==="arrow")return[{id:"tail",x:Z.x1,y:Z.y1,cursor:"move"},{id:"head",x:Z.x2,y:Z.y2,cursor:"move"}];let V=P(Z);if(Z.tool==="text")return[{id:"size",x:V.right,y:V.bottom,cursor:"nwse-resize"}];return g4.map((Y)=>({id:Y.id,x:V.left+(V.right-V.left)*Y.fx,y:V.top+(V.bottom-V.top)*Y.fy,cursor:Y.cursor}))}function N(Z){let V=P(Z);return{x:V.right+d1*U(),y:V.top-d1*U()}}function S(Z,V,Y){let{shaft:X,head:F}=v1({x:V.x1,y:V.y1},{x:V.x2,y:V.y2},Math.max(10,16*Y));if(X)Z.lineCap="butt",Z.beginPath(),Z.moveTo(X.from.x,X.from.y),Z.lineTo(X.to.x,X.to.y),Z.stroke();Z.beginPath(),Z.moveTo(F[0].x,F[0].y),Z.lineTo(F[1].x,F[1].y),Z.lineTo(F[2].x,F[2].y),Z.closePath(),Z.fill()}function _(Z,V,Y){Z.save(),Z.lineWidth=Math.max(2,3*Y),Z.strokeStyle=m0,Z.fillStyle=m0;let X=P(V);if(V.tool==="rect")Z.strokeRect(X.left,X.top,X.right-X.left,X.bottom-X.top);else if(V.tool==="arrow")S(Z,V,Y);else if(V.tool==="highlight")Z.fillStyle=h4,Z.fillRect(X.left,X.top,X.right-X.left,X.bottom-X.top);else if(V.tool==="text"&&V.text){let F=V.size??v0;Z.font=`600 ${F}px system-ui, sans-serif`,Z.textBaseline="top";let M=F*0.22;Z.fillStyle="rgba(255,255,255,0.92)",Z.fillRect(X.left-M,X.top-M,X.right-X.left+M*2,X.bottom-X.top+M*2),Z.fillStyle=m0,Z.fillText(V.text,X.left,X.top)}Z.restore()}function D(Z,V,Y){let X=P(V);Z.save(),Z.strokeStyle=y1,Z.lineWidth=Math.max(1,1.5*Y),Z.setLineDash([6*Y,4*Y]),Z.strokeRect(X.left,X.top,X.right-X.left,X.bottom-X.top),Z.setLineDash([]);let F=b1*Y;for(let f of O(V))Z.fillStyle="#fff",Z.strokeStyle=y1,Z.lineWidth=Math.max(1,1.5*Y),Z.beginPath(),Z.rect(f.x-F/2,f.y-F/2,F,F),Z.fill(),Z.stroke();let M=N(V),I=u1*Y;Z.beginPath(),Z.arc(M.x,M.y,I,0,Math.PI*2),Z.fillStyle="#dc2626",Z.fill(),Z.strokeStyle="#fff",Z.lineWidth=Math.max(1.5,2*Y),Z.beginPath(),Z.moveTo(M.x-I*0.4,M.y-I*0.4),Z.lineTo(M.x+I*0.4,M.y+I*0.4),Z.moveTo(M.x+I*0.4,M.y-I*0.4),Z.lineTo(M.x-I*0.4,M.y+I*0.4),Z.stroke(),Z.restore()}function q(){if(!H)return;let Z=U();if(H.clearRect(0,0,$.width,$.height),H.drawImage(j,0,0,$.width,$.height),Q.forEach((Y,X)=>{if(X!==m)_(H,Y,Z)}),K)_(H,K,Z);let V=Q[W];if(V&&!K)D(H,V,Z)}function g(Z,V,Y,X,F){return Math.abs(Z-Y)<=F&&Math.abs(V-X)<=F}function e(Z,V){let Y=Q[W];if(!Y)return null;let X=b1*U()/2+3*U();for(let F of O(Y))if(g(Z,V,F.x,F.y,X))return F.id;return null}function u(Z,V){let Y=Q[W];if(!Y)return!1;let X=N(Y);return g(Z,V,X.x,X.y,u1*U())}function E(Z,V){let Y=6*U();for(let X=Q.length-1;X>=0;X-=1){let F=Q[X];if(F.tool==="arrow"){let I=F.x2-F.x1,f=F.y2-F.y1,v=Math.hypot(I,f)||1,y=Math.max(0,Math.min(1,((Z-F.x1)*I+(V-F.y1)*f)/(v*v)));if(Math.hypot(Z-(F.x1+y*I),V-(F.y1+y*f))<=Y+4*U())return X;continue}let M=P(F);if(Z>=M.left-Y&&Z<=M.right+Y&&V>=M.top-Y&&V<=M.bottom+Y)return X}return-1}function p(Z,V,Y,X,F){if(V==="tail"){Z.x1=Y.x1+X,Z.y1=Y.y1+F;return}if(V==="head"){Z.x2=Y.x2+X,Z.y2=Y.y2+F;return}if(V==="size"){let j2=(Y.size??24)+F;Z.size=Math.max(10,j2);return}let M=P(Y),{left:I,top:f,right:v,bottom:y}=M;if(V.includes("w"))I=Math.min(v-Y0,I+X);if(V.includes("e"))v=Math.max(I+Y0,v+X);if(V.includes("n"))f=Math.min(y-Y0,f+F);if(V.includes("s"))y=Math.max(f+Y0,y+F);Z.x1=I,Z.y1=f,Z.x2=v,Z.y2=y}function H0(Z,V,Y,X){Z.x1=V.x1+Y,Z.y1=V.y1+X,Z.x2=V.x2+Y,Z.y2=V.y2+X}let L=null,m=-1,B={x:0,y:0,size:24};function k(){let Z=$.getBoundingClientRect().width;return Z>0?Z/$.width:1}function $2(Z,V){if(!H)return Z.length*V*0.6;H.save(),H.font=`600 ${V}px system-ui, sans-serif`;let Y=H.measureText(Z||" ").width;return H.restore(),Y}function c0(){if(!L)return;let Z=$.parentElement;if(!Z)return;let V=$.getBoundingClientRect(),Y=Z.getBoundingClientRect(),X=k(),F=B.size*X;L.style.left=`${V.left-Y.left+B.x*X}px`,L.style.top=`${V.top-Y.top+B.y*X}px`,L.style.fontSize=`${F}px`,L.style.width=`${Math.max(40,$2(L.value,F)+F)}px`}function $0(Z){let V=L;if(!V)return;L=null;let Y=V.value.trim(),X=m;if(m=-1,V.remove(),Z&&Y){if(X>=0&&Q[X])Q[X].text=Y,W=X;else Q.push({tool:"text",x1:B.x,y1:B.y,x2:B.x,y2:B.y,text:Y,size:B.size}),W=Q.length-1;J()}else if(X>=0)W=X;$.focus(),q()}function i0(Z,V,Y=-1){$0(!0);let X=$.parentElement;if(!X)return;if(getComputedStyle(X).position==="static")X.style.position="relative";let F=Y>=0?Q[Y]:void 0;m=Y,B={x:F?.x1??Z,y:F?.y1??V,size:F?.size??Math.round(24*U())};let M=document.createElement("input");M.type="text",M.className="text-edit",M.value=F?.text??"",M.setAttribute("aria-label","ข้อความบนภาพ"),M.placeholder="ข้อความ",L=M,X.append(M),c0(),M.addEventListener("input",c0),M.addEventListener("keydown",(I)=>{if(I.stopPropagation(),I.key==="Enter")$0(!0);else if(I.key==="Escape")$0(!1)}),requestAnimationFrame(()=>{if(L!==M)return;M.focus(),M.select(),M.addEventListener("blur",()=>$0(!0))}),q()}function o0(Z){let{x:V,y:Y}=C(Z);if($.setPointerCapture(Z.pointerId),u(V,Y)){M0();return}let X=e(V,Y);if(X&&Q[W]){G={grip:X,x:V,y:Y,start:{...Q[W]}};return}if(z==="text"){if(Z.preventDefault(),$.hasPointerCapture(Z.pointerId))$.releasePointerCapture(Z.pointerId);z=null,J(),i0(V,Y);return}if(z){K={tool:z,x1:V,y1:Y,x2:V,y2:Y},W=-1;return}let F=E(V,Y);W=F,G=F>=0?{grip:"body",x:V,y:Y,start:{...Q[F]}}:null,q()}function l0(Z){let{x:V,y:Y}=C(Z);if(K){K.x2=V,K.y2=Y,q();return}if(G){let F=Q[W];if(!F)return;let M=V-G.x,I=Y-G.y;if(G.grip==="body")H0(F,G.start,M,I);else p(F,G.grip,G.start,M,I);q();return}if(z){$.style.cursor="crosshair";return}if(u(V,Y)){$.style.cursor="pointer";return}let X=e(V,Y);if(X){let F=Q[W]?O(Q[W]).find((M)=>M.id===X):null;$.style.cursor=F?.cursor??"pointer";return}$.style.cursor=E(V,Y)>=0?"move":"default"}function z0(){if(K){if(!(Math.abs(K.x2-K.x1)<c1&&Math.abs(K.y2-K.y1)<c1))Q.push(K),W=Q.length-1,z=null,J();K=null}if(G)G=null,J();q()}function r0(Z){let V=$.getBoundingClientRect(),Y=(Z.clientX-V.left)/V.width*$.width,X=(Z.clientY-V.top)/V.height*$.height,F=E(Y,X),M=Q[F];if(!M||M.tool!=="text")return;Z.preventDefault(),i0(M.x1,M.y1,F)}function s0(Z){if(W<0)return;if(Z.key==="Delete"||Z.key==="Backspace")Z.preventDefault(),M0();else if(Z.key==="Escape")W=-1,q()}function M0(){if(W<0)return;Q.splice(W,1),W=-1,J(),q()}return $.addEventListener("pointerdown",o0),$.addEventListener("pointermove",l0),$.addEventListener("pointerup",z0),$.addEventListener("pointercancel",z0),$.addEventListener("dblclick",r0),$.tabIndex=0,$.addEventListener("keydown",s0),q(),{setTool(Z){z=Z,W=-1,$.style.cursor=Z?"crosshair":"default",q()},deleteSelected:M0,clear(){Q.length=0,W=-1,J(),q()},hasShapes:()=>Q.length>0,hasSelection:()=>W>=0,toDataUrl(){let Z=document.createElement("canvas");Z.width=j.naturalWidth,Z.height=j.naturalHeight;let V=Z.getContext("2d");if(!V)return $.toDataURL("image/png");V.drawImage(j,0,0);let Y=U();for(let X of Q)_(V,X,Y);return Z.toDataURL("image/png")},destroy(){$0(!1),$.removeEventListener("pointerdown",o0),$.removeEventListener("pointermove",l0),$.removeEventListener("pointerup",z0),$.removeEventListener("pointercancel",z0),$.removeEventListener("dblclick",r0),$.removeEventListener("keydown",s0)}}}var i1=`
|
|
41
|
+
`)}function I4($){return $.replace(/[:.]/g,"-").replace("T","_").slice(0,19)}function w4($,j){return`debug-report_${I4($.context.capturedAt)}.${j}`}function D4($){return E1($.cause)>0}async function E0(){if(typeof navigator<"u"&&Boolean(navigator.mediaDevices?.getDisplayMedia)){let J=await N4();if(J.status==="ok")return{dataUrl:J.dataUrl,method:"display-media"};if(J.status==="cancelled")return{dataUrl:null,method:"cancelled"}}let j=await S4();if(j)return{dataUrl:j,method:"html-to-image"};return{dataUrl:null,method:"none"}}async function N4(){let $=null;try{let j={video:{frameRate:30},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude"};$=await navigator.mediaDevices.getDisplayMedia(j);let J=await B4($);return J?{status:"ok",dataUrl:J}:{status:"error"}}catch(j){if(j instanceof DOMException&&(j.name==="NotAllowedError"||j.name==="AbortError"))return{status:"cancelled"};return{status:"error"}}finally{$?.getTracks().forEach((j)=>j.stop())}}async function B4($){let j=document.createElement("video");j.srcObject=$,j.muted=!0,j.playsInline=!0,await new Promise((K)=>{let G=!1,H=()=>{if(G)return;G=!0,K()};j.onloadedmetadata=()=>{j.play().then(H).catch(H)},window.setTimeout(H,1500)}),await q4(j);let{videoWidth:J,videoHeight:Q}=j;if(!J||!Q)return null;let z=document.createElement("canvas");z.width=J,z.height=Q;let W=z.getContext("2d");if(!W)return null;W.drawImage(j,0,0,J,Q),j.pause(),j.srcObject=null;try{return z.toDataURL("image/png")}catch{return null}}function q4($){return new Promise((j)=>{let J=!1,Q=()=>{if(J)return;J=!0,j()},z=$;if(typeof z.requestVideoFrameCallback==="function")z.requestVideoFrameCallback(()=>Q()),window.setTimeout(Q,1000);else window.setTimeout(Q,250)})}async function S4(){let $=R().screenshotFallback;if(!$)return null;let j=await $().catch(()=>null);if(!j)return null;try{return await j(document.body,{cacheBust:!0,pixelRatio:Math.min(window.devicePixelRatio||1,2),filter:(J)=>!(J instanceof HTMLElement&&J.dataset?.debugReporter==="true")})}catch{return null}}var R4=2000,O4=0.82,_4=3000000;function L4($){return new Promise((j,J)=>{let Q=new Image;Q.onload=()=>j(Q),Q.onerror=()=>J(Error("could not read the screenshot")),Q.src=$})}async function m1($){try{let j=await L4($),J=Math.max(j.naturalWidth,j.naturalHeight),Q=Math.min(1,R4/J),z=document.createElement("canvas");z.width=Math.max(1,Math.round(j.naturalWidth*Q)),z.height=Math.max(1,Math.round(j.naturalHeight*Q));let W=z.getContext("2d");if(!W)return $;W.fillStyle="#fff",W.fillRect(0,0,z.width,z.height),W.drawImage(j,0,0,z.width,z.height);let K=O4,G=z.toDataURL("image/jpeg",K);while(G.length>_4&&K>0.4)K-=0.15,G=z.toDataURL("image/jpeg",K);return G}catch{return $}}var A4=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,f4=/^\d+$/,T4=/^[0-9a-f]{16,}$/i;function x0($){if($.reason.type==="manual")return null;let j=$.cause?.failedRequests?.[0];if(!j?.url)return null;let J;try{J=new URL(j.url,"http://x").pathname}catch{J=j.url}let Q=J.split("/").map((W)=>A4.test(W)||f4.test(W)||T4.test(W)?":id":W).join("/"),z=j.status??(j.error?"ERR":"?");return`${j.method??"REQ"} ${Q} ${z}`}var h0=2000000;function G0($){let{screenshotDataUrl:j,...J}=$;return JSON.stringify(J).length}function g0($,j=2000000){if(G0($)<=j)return $;let J=$.network.map((z)=>({...z})),Q={...$,network:J};for(let z of J){if(G0(Q)<=j)return Q;if(typeof z.responseSnippet==="string"&&z.responseSnippet.length>35)z.responseSnippet="[body dropped — report size budget]";if(typeof z.requestBody==="string"&&z.requestBody.length>35)z.requestBody="[body dropped — report size budget]"}while(Q.network.length>1&&G0(Q)>j)Q.network=Q.network.slice(1);while(Q.console.length>1&&G0(Q)>j)Q.console=Q.console.slice(1);return Q}var p1=32768;function k4($){let j="";for(let J=0;J<$.length;J+=p1)j+=String.fromCharCode(...$.subarray(J,J+p1));return btoa(j)}function E4($){return{dataUri:`data:application/json;base64,${k4(new TextEncoder().encode(JSON.stringify($)))}`,filename:"debug-bundle.json"}}async function x4(){let $=R().identity;if(!$)return{};try{let j=await $();return j?{authorization:`Bearer ${j}`}:{}}catch{return{}}}async function m0($,j){let J=R(),Q=g0(j,h0),{context:z,note:W}=Q,K=[];if(Q.screenshotDataUrl){let C=await m1(Q.screenshotDataUrl);K.push({dataUri:C,filename:"screenshot.jpg"})}K.push(E4(Q));let G=x0(Q),H={title:$,description:W.trim()||void 0,appName:E().name,category:z.module?.label||E().name,routeUrl:z.route.href,priority:"MEDIUM",requesterEmail:z.user.email??void 0,requesterName:z.user.fullName??void 0,customFields:{unit:z.user.unit??"",appVersion:z.app.version,environment:z.app.environment,reasonType:Q.reason.type,appName:E().name,module:z.module?.label??""},context:{...G?{signature:G}:{},capturedAt:z.capturedAt,reason:Q.reason,cause:Q.cause,actionTrail:Q.actionTrail,client:z.client,performance:z.performance,apiHeaders:z.apiHeaders,extra:z.extra,counts:{network:Q.network.length,console:Q.console.length,actions:Q.actionTrail.length},screenshotMethod:Q.screenshotMethod},attachments:K},U=await fetch(`${J.host.replace(/\/$/,"")}/ingest/tickets`,{method:"POST",headers:{"content-type":"application/json","x-realm-key":J.realmKey,...await x4()},body:JSON.stringify(H)});if(!U.ok){let C=U.headers.get("retry-after"),w=await U.json().then((P)=>P.error).catch(()=>null);throw Error(U.status===429?`Too many reports — try again in ${C??"a moment"}s`:w??`Report failed (${U.status})`)}return await U.json()}var Q0=Math.PI/6;function v1($,j,J){let Q=j.x-$.x,z=j.y-$.y,W=Math.hypot(Q,z),K=Math.atan2(z,Q),G=[{x:j.x,y:j.y},{x:j.x-J*Math.cos(K-Q0),y:j.y-J*Math.sin(K-Q0)},{x:j.x-J*Math.cos(K+Q0),y:j.y-J*Math.sin(K+Q0)}],H=J*Math.cos(Q0)*0.92;if(W<=H)return{shaft:null,head:G};return{shaft:{from:$,to:{x:j.x-H*Math.cos(K),y:j.y-H*Math.sin(K)}},head:G}}var p0="#f44336",h4="rgba(250, 204, 21, 0.4)",v0=22,y1="#2563eb",b1=9,u1=11,d1=18,c1=4,Y0=8,g4=[{id:"nw",fx:0,fy:0,cursor:"nwse-resize"},{id:"n",fx:0.5,fy:0,cursor:"ns-resize"},{id:"ne",fx:1,fy:0,cursor:"nesw-resize"},{id:"e",fx:1,fy:0.5,cursor:"ew-resize"},{id:"se",fx:1,fy:1,cursor:"nwse-resize"},{id:"s",fx:0.5,fy:1,cursor:"ns-resize"},{id:"sw",fx:0,fy:1,cursor:"nesw-resize"},{id:"w",fx:0,fy:0.5,cursor:"ew-resize"}];function y0($,j,J){let Q=[],z=null,W=-1,K=null,G=null,H=$.getContext("2d");function U(){let Z=$.getBoundingClientRect().width;return Z>0?$.width/Z:1}function C(Z){let V=$.getBoundingClientRect();return{x:(Z.clientX-V.left)/V.width*$.width,y:(Z.clientY-V.top)/V.height*$.height}}function w(Z){let V=Z.size??v0;if(!H)return(Z.text?.length??0)*V*0.6;H.save(),H.font=`600 ${V}px system-ui, sans-serif`;let Y=H.measureText(Z.text??"").width;return H.restore(),Y}function P(Z){if(Z.tool==="text"){let V=Z.size??v0;return{left:Z.x1,top:Z.y1,right:Z.x1+w(Z),bottom:Z.y1+V*1.25}}return{left:Math.min(Z.x1,Z.x2),top:Math.min(Z.y1,Z.y2),right:Math.max(Z.x1,Z.x2),bottom:Math.max(Z.y1,Z.y2)}}function O(Z){if(Z.tool==="arrow")return[{id:"tail",x:Z.x1,y:Z.y1,cursor:"move"},{id:"head",x:Z.x2,y:Z.y2,cursor:"move"}];let V=P(Z);if(Z.tool==="text")return[{id:"size",x:V.right,y:V.bottom,cursor:"nwse-resize"}];return g4.map((Y)=>({id:Y.id,x:V.left+(V.right-V.left)*Y.fx,y:V.top+(V.bottom-V.top)*Y.fy,cursor:Y.cursor}))}function N(Z){let V=P(Z);return{x:V.right+d1*U(),y:V.top-d1*U()}}function S(Z,V,Y){let{shaft:X,head:F}=v1({x:V.x1,y:V.y1},{x:V.x2,y:V.y2},Math.max(10,16*Y));if(X)Z.lineCap="butt",Z.beginPath(),Z.moveTo(X.from.x,X.from.y),Z.lineTo(X.to.x,X.to.y),Z.stroke();Z.beginPath(),Z.moveTo(F[0].x,F[0].y),Z.lineTo(F[1].x,F[1].y),Z.lineTo(F[2].x,F[2].y),Z.closePath(),Z.fill()}function _(Z,V,Y){Z.save(),Z.lineWidth=Math.max(2,3*Y),Z.strokeStyle=p0,Z.fillStyle=p0;let X=P(V);if(V.tool==="rect")Z.strokeRect(X.left,X.top,X.right-X.left,X.bottom-X.top);else if(V.tool==="arrow")S(Z,V,Y);else if(V.tool==="highlight")Z.fillStyle=h4,Z.fillRect(X.left,X.top,X.right-X.left,X.bottom-X.top);else if(V.tool==="text"&&V.text){let F=V.size??v0;Z.font=`600 ${F}px system-ui, sans-serif`,Z.textBaseline="top";let M=F*0.22;Z.fillStyle="rgba(255,255,255,0.92)",Z.fillRect(X.left-M,X.top-M,X.right-X.left+M*2,X.bottom-X.top+M*2),Z.fillStyle=p0,Z.fillText(V.text,X.left,X.top)}Z.restore()}function D(Z,V,Y){let X=P(V);Z.save(),Z.strokeStyle=y1,Z.lineWidth=Math.max(1,1.5*Y),Z.setLineDash([6*Y,4*Y]),Z.strokeRect(X.left,X.top,X.right-X.left,X.bottom-X.top),Z.setLineDash([]);let F=b1*Y;for(let f of O(V))Z.fillStyle="#fff",Z.strokeStyle=y1,Z.lineWidth=Math.max(1,1.5*Y),Z.beginPath(),Z.rect(f.x-F/2,f.y-F/2,F,F),Z.fill(),Z.stroke();let M=N(V),I=u1*Y;Z.beginPath(),Z.arc(M.x,M.y,I,0,Math.PI*2),Z.fillStyle="#dc2626",Z.fill(),Z.strokeStyle="#fff",Z.lineWidth=Math.max(1.5,2*Y),Z.beginPath(),Z.moveTo(M.x-I*0.4,M.y-I*0.4),Z.lineTo(M.x+I*0.4,M.y+I*0.4),Z.moveTo(M.x+I*0.4,M.y-I*0.4),Z.lineTo(M.x-I*0.4,M.y+I*0.4),Z.stroke(),Z.restore()}function q(){if(!H)return;let Z=U();if(H.clearRect(0,0,$.width,$.height),H.drawImage(j,0,0,$.width,$.height),Q.forEach((Y,X)=>{if(X!==p)_(H,Y,Z)}),K)_(H,K,Z);let V=Q[W];if(V&&!K)D(H,V,Z)}function g(Z,V,Y,X,F){return Math.abs(Z-Y)<=F&&Math.abs(V-X)<=F}function e(Z,V){let Y=Q[W];if(!Y)return null;let X=b1*U()/2+3*U();for(let F of O(Y))if(g(Z,V,F.x,F.y,X))return F.id;return null}function u(Z,V){let Y=Q[W];if(!Y)return!1;let X=N(Y);return g(Z,V,X.x,X.y,u1*U())}function x(Z,V){let Y=6*U();for(let X=Q.length-1;X>=0;X-=1){let F=Q[X];if(F.tool==="arrow"){let I=F.x2-F.x1,f=F.y2-F.y1,v=Math.hypot(I,f)||1,y=Math.max(0,Math.min(1,((Z-F.x1)*I+(V-F.y1)*f)/(v*v)));if(Math.hypot(Z-(F.x1+y*I),V-(F.y1+y*f))<=Y+4*U())return X;continue}let M=P(F);if(Z>=M.left-Y&&Z<=M.right+Y&&V>=M.top-Y&&V<=M.bottom+Y)return X}return-1}function m(Z,V,Y,X,F){if(V==="tail"){Z.x1=Y.x1+X,Z.y1=Y.y1+F;return}if(V==="head"){Z.x2=Y.x2+X,Z.y2=Y.y2+F;return}if(V==="size"){let j2=(Y.size??24)+F;Z.size=Math.max(10,j2);return}let M=P(Y),{left:I,top:f,right:v,bottom:y}=M;if(V.includes("w"))I=Math.min(v-Y0,I+X);if(V.includes("e"))v=Math.max(I+Y0,v+X);if(V.includes("n"))f=Math.min(y-Y0,f+F);if(V.includes("s"))y=Math.max(f+Y0,y+F);Z.x1=I,Z.y1=f,Z.x2=v,Z.y2=y}function H0(Z,V,Y,X){Z.x1=V.x1+Y,Z.y1=V.y1+X,Z.x2=V.x2+Y,Z.y2=V.y2+X}let L=null,p=-1,B={x:0,y:0,size:24};function k(){let Z=$.getBoundingClientRect().width;return Z>0?Z/$.width:1}function $2(Z,V){if(!H)return Z.length*V*0.6;H.save(),H.font=`600 ${V}px system-ui, sans-serif`;let Y=H.measureText(Z||" ").width;return H.restore(),Y}function c0(){if(!L)return;let Z=$.parentElement;if(!Z)return;let V=$.getBoundingClientRect(),Y=Z.getBoundingClientRect(),X=k(),F=B.size*X;L.style.left=`${V.left-Y.left+B.x*X}px`,L.style.top=`${V.top-Y.top+B.y*X}px`,L.style.fontSize=`${F}px`,L.style.width=`${Math.max(40,$2(L.value,F)+F)}px`}function $0(Z){let V=L;if(!V)return;L=null;let Y=V.value.trim(),X=p;if(p=-1,V.remove(),Z&&Y){if(X>=0&&Q[X])Q[X].text=Y,W=X;else Q.push({tool:"text",x1:B.x,y1:B.y,x2:B.x,y2:B.y,text:Y,size:B.size}),W=Q.length-1;J()}else if(X>=0)W=X;$.focus(),q()}function i0(Z,V,Y=-1){$0(!0);let X=$.parentElement;if(!X)return;if(getComputedStyle(X).position==="static")X.style.position="relative";let F=Y>=0?Q[Y]:void 0;p=Y,B={x:F?.x1??Z,y:F?.y1??V,size:F?.size??Math.round(24*U())};let M=document.createElement("input");M.type="text",M.className="text-edit",M.value=F?.text??"",M.setAttribute("aria-label","ข้อความบนภาพ"),M.placeholder="ข้อความ",L=M,X.append(M),c0(),M.addEventListener("input",c0),M.addEventListener("keydown",(I)=>{if(I.stopPropagation(),I.key==="Enter")$0(!0);else if(I.key==="Escape")$0(!1)}),requestAnimationFrame(()=>{if(L!==M)return;M.focus(),M.select(),M.addEventListener("blur",()=>$0(!0))}),q()}function o0(Z){let{x:V,y:Y}=C(Z);if($.setPointerCapture(Z.pointerId),u(V,Y)){M0();return}let X=e(V,Y);if(X&&Q[W]){G={grip:X,x:V,y:Y,start:{...Q[W]}};return}if(z==="text"){if(Z.preventDefault(),$.hasPointerCapture(Z.pointerId))$.releasePointerCapture(Z.pointerId);z=null,J(),i0(V,Y);return}if(z){K={tool:z,x1:V,y1:Y,x2:V,y2:Y},W=-1;return}let F=x(V,Y);W=F,G=F>=0?{grip:"body",x:V,y:Y,start:{...Q[F]}}:null,q()}function l0(Z){let{x:V,y:Y}=C(Z);if(K){K.x2=V,K.y2=Y,q();return}if(G){let F=Q[W];if(!F)return;let M=V-G.x,I=Y-G.y;if(G.grip==="body")H0(F,G.start,M,I);else m(F,G.grip,G.start,M,I);q();return}if(z){$.style.cursor="crosshair";return}if(u(V,Y)){$.style.cursor="pointer";return}let X=e(V,Y);if(X){let F=Q[W]?O(Q[W]).find((M)=>M.id===X):null;$.style.cursor=F?.cursor??"pointer";return}$.style.cursor=x(V,Y)>=0?"move":"default"}function z0(){if(K){if(!(Math.abs(K.x2-K.x1)<c1&&Math.abs(K.y2-K.y1)<c1))Q.push(K),W=Q.length-1,z=null,J();K=null}if(G)G=null,J();q()}function r0(Z){let V=$.getBoundingClientRect(),Y=(Z.clientX-V.left)/V.width*$.width,X=(Z.clientY-V.top)/V.height*$.height,F=x(Y,X),M=Q[F];if(!M||M.tool!=="text")return;Z.preventDefault(),i0(M.x1,M.y1,F)}function s0(Z){if(W<0)return;if(Z.key==="Delete"||Z.key==="Backspace")Z.preventDefault(),M0();else if(Z.key==="Escape")W=-1,q()}function M0(){if(W<0)return;Q.splice(W,1),W=-1,J(),q()}return $.addEventListener("pointerdown",o0),$.addEventListener("pointermove",l0),$.addEventListener("pointerup",z0),$.addEventListener("pointercancel",z0),$.addEventListener("dblclick",r0),$.tabIndex=0,$.addEventListener("keydown",s0),q(),{setTool(Z){z=Z,W=-1,$.style.cursor=Z?"crosshair":"default",q()},deleteSelected:M0,clear(){Q.length=0,W=-1,J(),q()},hasShapes:()=>Q.length>0,hasSelection:()=>W>=0,toDataUrl(){let Z=document.createElement("canvas");Z.width=j.naturalWidth,Z.height=j.naturalHeight;let V=Z.getContext("2d");if(!V)return $.toDataURL("image/png");V.drawImage(j,0,0);let Y=U();for(let X of Q)_(V,X,Y);return Z.toDataURL("image/png")},destroy(){$0(!1),$.removeEventListener("pointerdown",o0),$.removeEventListener("pointermove",l0),$.removeEventListener("pointerup",z0),$.removeEventListener("pointercancel",z0),$.removeEventListener("dblclick",r0),$.removeEventListener("keydown",s0)}}}var i1=`
|
|
42
42
|
:host { all: initial; }
|
|
43
43
|
* { box-sizing: border-box; }
|
|
44
44
|
|
|
@@ -121,7 +121,7 @@ canvas { width: 100%; height: auto; display: block; border: 1px solid #e2e8f0; b
|
|
|
121
121
|
border-radius: 0 0 16px 16px;
|
|
122
122
|
}
|
|
123
123
|
.foot .grow { flex: 1; }
|
|
124
|
-
`;var t="lw-debug-reporter",o1=()=>[];function
|
|
124
|
+
`;var t="lw-debug-reporter",o1=()=>[];function m4($){o1=$}var p4=[{tool:"rect",key:"toolRect"},{tool:"arrow",key:"toolArrow"},{tool:"highlight",key:"toolHighlight"},{tool:"text",key:"toolText"}];function v4(){return class extends HTMLElement{root;stop=null;annotator=null;bundle=null;busy=!1;constructor(){super();this.root=this.attachShadow({mode:"open"})}connectedCallback(){this.dataset.debugReporter="true",this.stop=R0((j)=>void this.open(j))}disconnectedCallback(){this.stop?.(),this.stop=null,this.close()}async open(j){if(this.busy)return;this.busy=!0;let J=b(R().locale),Q=await E0();if(Q.method==="cancelled"){this.close();return}this.bundle=k0({reason:j,note:"",screenshotDataUrl:Q.dataUrl,screenshotMethod:Q.method,erroredQueries:y4()}),this.renderForm(J)}close(){this.annotator?.destroy(),this.annotator=null,this.bundle=null,this.busy=!1,this.root.replaceChildren()}shell(j){let J=document.createElement("style");J.textContent=i1;let Q=document.createElement("div");Q.className="backdrop";let z=document.createElement("div");return z.className="panel",z.setAttribute("role","dialog"),z.setAttribute("aria-modal","true"),z.setAttribute("aria-label",j.title),Q.append(z),this.root.replaceChildren(J,Q),z}renderShell(j,J){let Q=this.shell(j),z=A("div","head");z.append(A("h2","",j.title)),Q.append(z,A("p","status",J))}renderForm(j){let J=this.bundle;if(!J)return;let Q=this.shell(j),z=A("div","head"),W=a("✕","icon");W.setAttribute("aria-label",j.close),W.addEventListener("click",()=>this.close()),z.append(A("h2","",j.title),W);let K=document.createElement("input");K.type="text",K.placeholder=j.summaryPlaceholder;let G=b0(j.summaryLabel,j.summaryRequired,!0),H=document.createElement("textarea");H.placeholder=j.detailPlaceholder;let U=A("div","meta");U.innerHTML="";let{context:C}=J;for(let[S,_]of[[j.reporter,`${C.user.fullName??"—"} (${C.user.email??"—"})`],[j.page,C.route.href],[j.captured,`${J.network.length} network · ${J.console.length} console · ${J.actionTrail.length} actions`]]){let D=document.createElement("div"),q=document.createElement("b");q.textContent=`${S}: `,D.append(q,document.createTextNode(_)),U.append(D)}let w=A("p","status",""),P=a(j.submit,"primary");if(P.disabled=!0,K.addEventListener("input",()=>{P.disabled=K.value.trim().length===0}),Q.append(z,G,K,b0(j.detailLabel),H,U),J.screenshotDataUrl)Q.append(...this.screenshotSection(j,J.screenshotDataUrl));else Q.append(A("p","status",j.noScreenshot));let O=A("div","foot"),N=a(j.close);N.addEventListener("click",()=>this.close()),O.append(N,w,A("span","grow"),P),Q.append(O),P.addEventListener("click",async()=>{P.disabled=!0,w.dataset.tone="",w.textContent=j.submitting;try{let S=await m0(K.value.trim(),{...J,note:H.value,screenshotDataUrl:this.annotator?.hasShapes()?this.annotator.toDataUrl():J.screenshotDataUrl}),_=this.dispatchEvent(new CustomEvent("lw-report-submitted",{detail:S,bubbles:!0,composed:!0,cancelable:!0}));if(this.close(),_)n(`${j.submitted} — #${S.number}`,"success")}catch(S){let _=S instanceof Error?S.message:j.failed;w.dataset.tone="error",w.textContent=_,n(`${j.failed} — ${_}`,"error"),P.disabled=!1}}),K.focus()}screenshotSection(j,J){let Q=b0(j.annotateHint),z=A("div","tools"),W=document.createElement("canvas"),K=A("div","shot");K.append(W);let G=[],H=(P)=>{for(let O of G)O.setAttribute("aria-pressed",String(O===P))};for(let{tool:P,key:O}of p4){let N=a(j[O]);N.setAttribute("aria-pressed","false"),N.addEventListener("click",()=>{let S=N.getAttribute("aria-pressed")==="true";H(S?null:N),this.annotator?.setTool(S?null:P)}),G.push(N),z.append(N)}z.append(A("span","sep"));let U=a(j.deleteSelected);U.addEventListener("click",()=>this.annotator?.deleteSelected());let C=a(j.clearAll);C.addEventListener("click",()=>{this.annotator?.clear(),H(null)}),z.append(U,C);let w=new Image;return w.onload=()=>{W.width=w.naturalWidth,W.height=w.naturalHeight,this.annotator=y0(W,w,()=>{H(null),U.disabled=!this.annotator?.hasSelection()})},w.src=J,[Q,z,A("p","status",j.annotateHelp),K]}}}function y4(){try{return o1()}catch{return[]}}function A($,j="",J=""){let Q=document.createElement($);if(j)Q.className=j;if(J)Q.textContent=J;return Q}function a($,j=""){let J=document.createElement("button");if(J.type="button",J.textContent=$,j)J.className=j;return J}function b0($,j="",J=!1){let Q=document.createElement("label");if(Q.append(document.createTextNode($)),J){let z=document.createElement("span");z.className="req",z.textContent=" *",Q.append(z)}if(j){let z=document.createElement("span");z.className="hint",z.textContent=` ${j}`,Q.append(z)}return Q}function u0(){if(typeof window>"u"||customElements.get(t))return;customElements.define(t,v4())}var l1=!1;function b4($={}){if(l1||typeof window>"u")return;if(!U0()){console.error("[debug-capture] configureDebugCapture() must be called before install");return}if(l1=!0,T1(),M1(),X1(),B1(),$.ui===!1)return;let j=b(R().locale);if(_0((J)=>{n(J.message??j.crashed,"error",{label:j.crashAction,onClick:()=>O0(J)})}),u0(),!document.querySelector(t))document.body.append(document.createElement(t))}var u4=new Set(["error","exception","unhandledrejection"]);function r1($){if($.error)return!0;return $.status!==null&&$.status>=400}function d0($){if(!$)return null;let j=Date.parse($);return Number.isNaN(j)?null:j}function d4($){try{let{pathname:j}=new URL($,"http://x");try{return decodeURIComponent(j)}catch{return j}}catch{return $.split(/[?#]/)[0]??$}}function c4($,j,J){let Q=(K)=>({elapsedMs:K,requests:[],failedRequests:[],consoleErrors:[],slowestMs:null});if($.length===0)return[];let z=$.map((K)=>d0(K.at)),W=(K)=>{for(let G=K+1;G<z.length;G+=1){let H=z[G];if(H!=null)return H}return Number.POSITIVE_INFINITY};return $.map((K,G)=>{let H=z[G]??null,U=(G>0?z[G-1]:null)??null,C=H!==null&&U!==null?Math.max(0,H-U):null;if(H===null)return Q(C);let w=H,P=Math.max(w,W(G)),O=(D)=>D!==null&&D>=w&&(D<P||P===Number.POSITIVE_INFINITY),N=j.filter((D)=>O(d0(D.startedAt))),S=J.filter((D)=>u4.has(D.level)&&O(d0(D.at))),_=N.map((D)=>D.durationMs).filter((D)=>typeof D==="number");return{elapsedMs:C,requests:N,failedRequests:N.filter(r1),consoleErrors:S,slowestMs:_.length>0?Math.max(..._):null}})}function i4($,j){return $.requests.length===0&&$.consoleErrors.length===0&&($.elapsedMs===null||$.elapsedMs<j)}function o4($){if($<1000)return`${Math.round($)} มิลลิวินาที`;let j=$/1000;if(j<10)return`${j.toFixed(1)} วิ`;if(j<60)return`${Math.round(j)} วิ`;let J=Math.floor(j/60),Q=Math.round(j%60);return Q===0?`${J} นาที`:`${J} นาที ${Q} วิ`}var l4="lw-portal-handoff",s1=138.23,r4=`
|
|
125
125
|
:host { all: initial; }
|
|
126
126
|
.backdrop {
|
|
127
127
|
position: fixed; inset: 0; z-index: 2147483002;
|
|
@@ -214,4 +214,4 @@ p { margin: 0; font-size: 13px; line-height: 1.6; color: #475569; }
|
|
|
214
214
|
<button type="button" class="cancel"></button>
|
|
215
215
|
<button type="button" class="go"></button>
|
|
216
216
|
</div>
|
|
217
|
-
</div>`,z.append(K);let G=(D)=>K.querySelector(D),H=G(".card"),U=G(".bar"),C=G(".count"),w=G("h2"),P=G(".body"),O=G(".host"),N=G(".go"),S=G(".cancel");w.textContent=j.handoffTitle,P.textContent=j.handoffBody;try{O.textContent=new URL(R().host).host}catch{O.textContent=""}N.textContent=j.handoffGo,S.textContent=j.cancel,H.style.setProperty("--secs",`${J}s`),C.textContent=String(J),document.body.append(Q),requestAnimationFrame(()=>K.setAttribute("data-open","1"));let _=document.activeElement;return N.focus({preventScroll:!0}),new Promise((D)=>{let q=!1,g=null,e=!1,u=Date.now()+J*1000,
|
|
217
|
+
</div>`,z.append(K);let G=(D)=>K.querySelector(D),H=G(".card"),U=G(".bar"),C=G(".count"),w=G("h2"),P=G(".body"),O=G(".host"),N=G(".go"),S=G(".cancel");w.textContent=j.handoffTitle,P.textContent=j.handoffBody;try{O.textContent=new URL(R().host).host}catch{O.textContent=""}N.textContent=j.handoffGo,S.textContent=j.cancel,H.style.setProperty("--secs",`${J}s`),C.textContent=String(J),document.body.append(Q),requestAnimationFrame(()=>K.setAttribute("data-open","1"));let _=document.activeElement;return N.focus({preventScroll:!0}),new Promise((D)=>{let q=!1,g=null,e=!1,u=Date.now()+J*1000,x=window.setInterval(()=>{let B=Math.ceil((u-Date.now())/1000);if(C.textContent=String(Math.max(0,B)),Date.now()>=u)L()},100);function m(B){if(q)return;if(q=!0,window.clearInterval(x),document.removeEventListener("keydown",p,!0),K.removeAttribute("data-open"),window.setTimeout(()=>Q.remove(),200),!B)_?.focus?.({preventScroll:!0});D()}function H0(B){window.clearInterval(x),U.classList.remove("spinner"),U.style.animation="none",C.textContent="",w.textContent=j.handoffBlocked,P.textContent=j.handoffBody;let k=document.createElement("a");k.className="go",k.href=B,k.target="_blank",k.rel="noopener noreferrer",k.textContent=j.handoffOpen,k.addEventListener("click",()=>m(!0)),N.replaceWith(k),k.focus({preventScroll:!0})}function L(){if(q||e)return;if(g)return $.go(g)?m(!0):H0(g);window.clearInterval(x),C.textContent="",U.classList.add("spinner"),w.textContent=j.handoffPreparing}function p(B){if(B.key==="Escape")B.stopPropagation(),m(!1)}document.addEventListener("keydown",p,!0),N.addEventListener("click",L),S.addEventListener("click",()=>m(!1)),K.addEventListener("click",(B)=>{if(B.target===K)m(!1)}),$.prepare().then((B)=>{if(g=B,!q&&Date.now()>=u)L()},()=>{e=!0,window.clearInterval(x),H.classList.add("error"),U.classList.remove("spinner"),U.style.animation="none",C.textContent="",w.textContent=j.handoffFailed,P.textContent=j.handoffBody,N.remove(),S.textContent=j.close})})}var s4="/sso";function e1($,j,J){let Q=new URL(s4,$.endsWith("/")?$:`${$}/`);return Q.searchParams.set("realm",j),Q.searchParams.set("token",J),Q.toString()}class F0 extends Error{constructor($="No identity provider is configured, or nobody is signed in"){super($);this.name="NoIdentityError"}}async function a1(){let $=R();if(!$.identity)throw new F0;let j=await $.identity();if(!j)throw new F0;return e1($.host,$.realmKey,j)}function t1($,j){if(j==="_self")return window.location.assign($),!0;let J=window.open($,"_blank");if(!J)return!1;try{J.opener=null}catch{}return!0}async function n4($={}){if($.announce===!1){t1(await a1(),$.target);return}await n1({seconds:$.seconds,prepare:a1,go:(j)=>t1(j,$.target)})}export{g0 as trimToBudget,g1 as toCurl,e1 as supportPortalUrl,m0 as submitBundle,n as showToast,m4 as setErroredQueriesSource,d4 as requestPath,b as reporterStrings,o as redactUrl,c as redactLabel,i as redactHeaders,l as redactBody,n4 as openSupportPortal,R0 as onLaunch,_0 as onCrash,O0 as launch,i4 as isQuietStep,r1 as isFailedRequest,U0 as isConfigured,b4 as installDebugCapture,D4 as hasCause,A0 as getNetworkLog,S0 as getConsoleLog,R as getConfig,B0 as getActionTrail,o4 as formatDuration,x0 as errorSignature,L0 as emitCrash,u0 as defineReporterElement,y0 as createAnnotator,c4 as correlateActionTrail,Q2 as configureDebugCapture,E0 as captureScreen,P4 as bundleToMarkdown,w4 as bundleFileName,k0 as buildBundle,E as appInfo,D0 as actionCountSuffix,t as REPORTER_TAG,d as REDACTED,F0 as NoIdentityError,h0 as BUNDLE_BUDGET_BYTES};
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Whoever the host has authenticated. Email is the account key. */
|
|
2
|
+
export interface SupportUser {
|
|
3
|
+
/** The host's own id for this person, recorded so a changed email still matches. */
|
|
4
|
+
id?: string | null;
|
|
5
|
+
email: string;
|
|
6
|
+
name?: string | null;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Two minutes.
|
|
10
|
+
*
|
|
11
|
+
* The token is fetched when the button is pressed and spent on arrival, so it
|
|
12
|
+
* only has to survive one redirect — and it travels in a URL, which means
|
|
13
|
+
* browser history and every access log along the way. The support host refuses
|
|
14
|
+
* anything older than this regardless of what `exp` claims, so a longer TTL
|
|
15
|
+
* buys nothing.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_TTL_SECONDS = 120;
|
|
18
|
+
/**
|
|
19
|
+
* Sign a reporter token for a user the host has ALREADY authenticated.
|
|
20
|
+
*
|
|
21
|
+
* Deliberately not a general "sign anything" helper: it asserts the person
|
|
22
|
+
* handed to it and nothing else. There is no path here to mint a token for
|
|
23
|
+
* somebody who is not signed in.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createSupportToken(options: {
|
|
26
|
+
/** The realm's reporter secret. Server-side only — never send it to a browser. */
|
|
27
|
+
secret: string;
|
|
28
|
+
user: SupportUser;
|
|
29
|
+
ttlSeconds?: number;
|
|
30
|
+
}): {
|
|
31
|
+
token: string;
|
|
32
|
+
expiresIn: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* A ready-made route handler, for the common case.
|
|
36
|
+
*
|
|
37
|
+
* Returns a standard `Response`, so it works anywhere the Fetch API does —
|
|
38
|
+
* Next's app router, Bun, Deno, Hono. The one thing it cannot do for you is
|
|
39
|
+
* work out who is signed in; that is your session, and only you can read it.
|
|
40
|
+
*
|
|
41
|
+
* // app/api/support-token/route.ts
|
|
42
|
+
* import { supportTokenHandler } from "@lightworkai.official/debug-capture/server";
|
|
43
|
+
* export const dynamic = "force-dynamic";
|
|
44
|
+
* export const GET = supportTokenHandler({
|
|
45
|
+
* user: async () => {
|
|
46
|
+
* const session = await getServerSession(authOptions);
|
|
47
|
+
* return session?.user ? { id: session.user.id, email: session.user.email } : null;
|
|
48
|
+
* },
|
|
49
|
+
* });
|
|
50
|
+
*/
|
|
51
|
+
export declare function supportTokenHandler(options: {
|
|
52
|
+
/** Defaults to `process.env.SUPPORT_REPORTER_SECRET`. */
|
|
53
|
+
secret?: string;
|
|
54
|
+
/** Null when nobody is signed in — answered 401, which the button reports. */
|
|
55
|
+
user: () => SupportUser | null | Promise<SupportUser | null>;
|
|
56
|
+
ttlSeconds?: number;
|
|
57
|
+
}): () => Promise<Response>;
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import { createHmac, randomUUID } from "node:crypto";
|
|
3
|
+
var DEFAULT_TTL_SECONDS = 120;
|
|
4
|
+
var b64 = (value) => Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
|
|
5
|
+
function createSupportToken(options) {
|
|
6
|
+
const email = options.user.email?.trim().toLowerCase();
|
|
7
|
+
if (!email || !email.includes("@"))
|
|
8
|
+
throw new Error("createSupportToken: a real email is required");
|
|
9
|
+
if (!options.secret || options.secret.length < 16) {
|
|
10
|
+
throw new Error("createSupportToken: the realm's reporter secret is missing or too short");
|
|
11
|
+
}
|
|
12
|
+
const now = Math.floor(Date.now() / 1000);
|
|
13
|
+
const expiresIn = Math.min(Math.max(Math.floor(options.ttlSeconds ?? DEFAULT_TTL_SECONDS), 30), 12 * 60 * 60);
|
|
14
|
+
const body = `${b64({ alg: "HS256", typ: "JWT" })}.${b64({
|
|
15
|
+
sub: options.user.id?.trim() || email,
|
|
16
|
+
email,
|
|
17
|
+
name: options.user.name?.trim() || null,
|
|
18
|
+
jti: randomUUID(),
|
|
19
|
+
iat: now,
|
|
20
|
+
exp: now + expiresIn
|
|
21
|
+
})}`;
|
|
22
|
+
return { token: `${body}.${createHmac("sha256", options.secret).update(body).digest("base64url")}`, expiresIn };
|
|
23
|
+
}
|
|
24
|
+
function supportTokenHandler(options) {
|
|
25
|
+
return async () => {
|
|
26
|
+
const secret = options.secret ?? process.env.SUPPORT_REPORTER_SECRET;
|
|
27
|
+
if (!secret) {
|
|
28
|
+
return json({ error: "Support identity is not configured" }, 503);
|
|
29
|
+
}
|
|
30
|
+
const user = await options.user();
|
|
31
|
+
if (!user?.email)
|
|
32
|
+
return json({ error: "Unauthorized" }, 401);
|
|
33
|
+
try {
|
|
34
|
+
const { token, expiresIn } = createSupportToken({ secret, user, ttlSeconds: options.ttlSeconds });
|
|
35
|
+
return json({ token, expiresIn }, 200);
|
|
36
|
+
} catch {
|
|
37
|
+
return json({ error: "Support identity is not configured" }, 503);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function json(body, status) {
|
|
42
|
+
return new Response(JSON.stringify(body), {
|
|
43
|
+
status,
|
|
44
|
+
headers: {
|
|
45
|
+
"content-type": "application/json",
|
|
46
|
+
"cache-control": "no-store, private"
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
supportTokenHandler,
|
|
52
|
+
createSupportToken,
|
|
53
|
+
DEFAULT_TTL_SECONDS
|
|
54
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightworkai.official/debug-capture",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Report-a-problem widget: rolling network/console/action capture, annotated screenshot, and submission to a Lightwork Support host",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -12,7 +12,12 @@
|
|
|
12
12
|
"default": "./dist/index.mjs"
|
|
13
13
|
},
|
|
14
14
|
"./embed": "./dist/debug-capture.js",
|
|
15
|
-
"./style.css": "./src/styles.css"
|
|
15
|
+
"./style.css": "./src/styles.css",
|
|
16
|
+
"./server": {
|
|
17
|
+
"types": "./dist/server.d.ts",
|
|
18
|
+
"import": "./dist/server.mjs",
|
|
19
|
+
"default": "./dist/server.mjs"
|
|
20
|
+
}
|
|
16
21
|
},
|
|
17
22
|
"files": [
|
|
18
23
|
"dist",
|
|
@@ -22,7 +27,7 @@
|
|
|
22
27
|
],
|
|
23
28
|
"scripts": {
|
|
24
29
|
"build": "rm -rf dist && bun run build:esm && bun run build:iife && bun run build:types",
|
|
25
|
-
"build:esm": "bun build src/index.ts --outfile dist/index.mjs --format esm --minify",
|
|
30
|
+
"build:esm": "bun build src/index.ts --outfile dist/index.mjs --format esm --minify && bun build src/server.ts --outfile dist/server.mjs --format esm --target node --external node:crypto",
|
|
26
31
|
"build:iife": "bun build src/embed.ts --outfile dist/debug-capture.js --format iife --minify",
|
|
27
32
|
"build:types": "tsc -p tsconfig.build.json --emitDeclarationOnly --outDir dist",
|
|
28
33
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The half that runs on the HOST'S SERVER.
|
|
3
|
+
*
|
|
4
|
+
* Reading someone's tickets needs proof of who is asking, and only the host can
|
|
5
|
+
* give it: the realm key ships in client source, so it can authorise filing a
|
|
6
|
+
* report and never reading one back. The host signs a short statement of who is
|
|
7
|
+
* in front of it, with a secret only its server holds.
|
|
8
|
+
*
|
|
9
|
+
* That much is unavoidable. What was avoidable is every adopter hand-rolling
|
|
10
|
+
* HMAC and guessing the claim names — the ERP's version of this file was
|
|
11
|
+
* eighty-five lines, and getting `alg`, `jti` or `iat` wrong fails in ways that
|
|
12
|
+
* are hard to read from the outside.
|
|
13
|
+
*
|
|
14
|
+
* Imported from "@lightworkai.official/debug-capture/server", NOT from the
|
|
15
|
+
* package root: this uses node:crypto and must never be reachable from a
|
|
16
|
+
* browser bundle. It is the one part of this library that touches the secret.
|
|
17
|
+
*/
|
|
18
|
+
import { createHmac, randomUUID } from "node:crypto";
|
|
19
|
+
|
|
20
|
+
/** Whoever the host has authenticated. Email is the account key. */
|
|
21
|
+
export interface SupportUser {
|
|
22
|
+
/** The host's own id for this person, recorded so a changed email still matches. */
|
|
23
|
+
id?: string | null;
|
|
24
|
+
email: string;
|
|
25
|
+
name?: string | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Two minutes.
|
|
30
|
+
*
|
|
31
|
+
* The token is fetched when the button is pressed and spent on arrival, so it
|
|
32
|
+
* only has to survive one redirect — and it travels in a URL, which means
|
|
33
|
+
* browser history and every access log along the way. The support host refuses
|
|
34
|
+
* anything older than this regardless of what `exp` claims, so a longer TTL
|
|
35
|
+
* buys nothing.
|
|
36
|
+
*/
|
|
37
|
+
export const DEFAULT_TTL_SECONDS = 120;
|
|
38
|
+
|
|
39
|
+
const b64 = (value: object): string => Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Sign a reporter token for a user the host has ALREADY authenticated.
|
|
43
|
+
*
|
|
44
|
+
* Deliberately not a general "sign anything" helper: it asserts the person
|
|
45
|
+
* handed to it and nothing else. There is no path here to mint a token for
|
|
46
|
+
* somebody who is not signed in.
|
|
47
|
+
*/
|
|
48
|
+
export function createSupportToken(options: {
|
|
49
|
+
/** The realm's reporter secret. Server-side only — never send it to a browser. */
|
|
50
|
+
secret: string;
|
|
51
|
+
user: SupportUser;
|
|
52
|
+
ttlSeconds?: number;
|
|
53
|
+
}): { token: string; expiresIn: number } {
|
|
54
|
+
const email = options.user.email?.trim().toLowerCase();
|
|
55
|
+
if (!email || !email.includes("@")) throw new Error("createSupportToken: a real email is required");
|
|
56
|
+
if (!options.secret || options.secret.length < 16) {
|
|
57
|
+
throw new Error("createSupportToken: the realm's reporter secret is missing or too short");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const now = Math.floor(Date.now() / 1000);
|
|
61
|
+
const expiresIn = Math.min(Math.max(Math.floor(options.ttlSeconds ?? DEFAULT_TTL_SECONDS), 30), 12 * 60 * 60);
|
|
62
|
+
const body = `${b64({ alg: "HS256", typ: "JWT" })}.${b64({
|
|
63
|
+
// The host's own id when it has one, so the same person is recognised even
|
|
64
|
+
// if their email later changes. The email stands in when it does not.
|
|
65
|
+
sub: options.user.id?.trim() || email,
|
|
66
|
+
email,
|
|
67
|
+
name: options.user.name?.trim() || null,
|
|
68
|
+
// Spent once on arrival; without it the freshness window is a replay window.
|
|
69
|
+
jti: randomUUID(),
|
|
70
|
+
iat: now,
|
|
71
|
+
exp: now + expiresIn,
|
|
72
|
+
})}`;
|
|
73
|
+
|
|
74
|
+
return { token: `${body}.${createHmac("sha256", options.secret).update(body).digest("base64url")}`, expiresIn };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A ready-made route handler, for the common case.
|
|
79
|
+
*
|
|
80
|
+
* Returns a standard `Response`, so it works anywhere the Fetch API does —
|
|
81
|
+
* Next's app router, Bun, Deno, Hono. The one thing it cannot do for you is
|
|
82
|
+
* work out who is signed in; that is your session, and only you can read it.
|
|
83
|
+
*
|
|
84
|
+
* // app/api/support-token/route.ts
|
|
85
|
+
* import { supportTokenHandler } from "@lightworkai.official/debug-capture/server";
|
|
86
|
+
* export const dynamic = "force-dynamic";
|
|
87
|
+
* export const GET = supportTokenHandler({
|
|
88
|
+
* user: async () => {
|
|
89
|
+
* const session = await getServerSession(authOptions);
|
|
90
|
+
* return session?.user ? { id: session.user.id, email: session.user.email } : null;
|
|
91
|
+
* },
|
|
92
|
+
* });
|
|
93
|
+
*/
|
|
94
|
+
export function supportTokenHandler(options: {
|
|
95
|
+
/** Defaults to `process.env.SUPPORT_REPORTER_SECRET`. */
|
|
96
|
+
secret?: string;
|
|
97
|
+
/** Null when nobody is signed in — answered 401, which the button reports. */
|
|
98
|
+
user: () => SupportUser | null | Promise<SupportUser | null>;
|
|
99
|
+
ttlSeconds?: number;
|
|
100
|
+
}): () => Promise<Response> {
|
|
101
|
+
return async () => {
|
|
102
|
+
const secret = options.secret ?? process.env.SUPPORT_REPORTER_SECRET;
|
|
103
|
+
if (!secret) {
|
|
104
|
+
// Not something the user did: this deployment was never given a secret.
|
|
105
|
+
return json({ error: "Support identity is not configured" }, 503);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const user = await options.user();
|
|
109
|
+
if (!user?.email) return json({ error: "Unauthorized" }, 401);
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const { token, expiresIn } = createSupportToken({ secret, user, ttlSeconds: options.ttlSeconds });
|
|
113
|
+
return json({ token, expiresIn }, 200);
|
|
114
|
+
} catch {
|
|
115
|
+
// A bad secret or a malformed user is a misconfiguration, not a 401 —
|
|
116
|
+
// saying "unauthorized" would send someone to check their login.
|
|
117
|
+
return json({ error: "Support identity is not configured" }, 503);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function json(body: unknown, status: number): Response {
|
|
123
|
+
return new Response(JSON.stringify(body), {
|
|
124
|
+
status,
|
|
125
|
+
headers: {
|
|
126
|
+
"content-type": "application/json",
|
|
127
|
+
// A bearer credential must not sit in a shared cache, or the next user of
|
|
128
|
+
// this browser (or a CDN) is handed the last one.
|
|
129
|
+
"cache-control": "no-store, private",
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
}
|
package/src/submit.ts
CHANGED
|
@@ -98,6 +98,13 @@ export async function submitBundle(title: string, bundle: DebugBundle): Promise<
|
|
|
98
98
|
// complaint nowhere in it. The original sends the note or omits the field,
|
|
99
99
|
// and everything technical belongs in the structured data below.
|
|
100
100
|
description: note.trim() || undefined,
|
|
101
|
+
/*
|
|
102
|
+
* How this application names itself. It becomes the ticket's PREFIX —
|
|
103
|
+
* `app: { name: "ACME" }` files ACME-100 — so it is the same name on the
|
|
104
|
+
* reporter's list and on the desk's board, whichever realm either of them
|
|
105
|
+
* happens to be looking from.
|
|
106
|
+
*/
|
|
107
|
+
appName: appInfo().name,
|
|
101
108
|
// Which module broke, if the app says; otherwise which app. Both are
|
|
102
109
|
// things the app states about itself — neither is inferred from a URL.
|
|
103
110
|
category: context.module?.label || appInfo().name,
|