@lightworkai.official/debug-capture 0.12.0 → 0.12.2
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 +14 -5
- package/dist/capture/replay.d.ts +25 -1
- package/dist/config.d.ts +9 -1
- package/dist/debug-capture.js +3 -9
- package/dist/index.mjs +10 -16
- package/dist/types.d.ts +3 -5
- package/dist/ui/strings.d.ts +2 -3
- package/dist/ui/styles.d.ts +1 -1
- package/package.json +1 -1
- package/src/bundle.ts +1 -3
- package/src/capture/replay.ts +7 -3
- package/src/config.ts +11 -1
- package/src/submit.ts +7 -10
- package/src/types.ts +3 -5
- package/src/ui/element.ts +9 -25
- package/src/ui/strings.ts +4 -7
- package/src/ui/styles.ts +0 -6
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ the problem.
|
|
|
83
83
|
configureDebugCapture({
|
|
84
84
|
…,
|
|
85
85
|
replay: true, // the last 60 s, inputs masked
|
|
86
|
-
// replay: { seconds: 90,
|
|
86
|
+
// replay: { seconds: 90, blockSelector: "[data-lw-private], iframe, img", maskTextSelector: "td.person" },
|
|
87
87
|
});
|
|
88
88
|
```
|
|
89
89
|
|
|
@@ -99,20 +99,29 @@ hide everything they can:
|
|
|
99
99
|
|
|
100
100
|
- every value typed into any field is masked before it is recorded
|
|
101
101
|
(`maskAllInputs`); passwords never leave the field.
|
|
102
|
+
- what is typed where there is no field — a `contenteditable` editor — is
|
|
103
|
+
masked too (`maskTextSelector`, default editable `[contenteditable]` and
|
|
104
|
+
`[data-lw-mask]`): the layout stays, each character becomes `*`. Put
|
|
105
|
+
`data-lw-mask` on any region whose words matter but whose shape is enough.
|
|
102
106
|
- anything under `blockSelector` — default `data-lw-private` — is recorded as
|
|
103
107
|
a grey box of the same size, contents and changes dropped. Mark document
|
|
104
|
-
viewers, a citizen's record, a chart of somebody's salary
|
|
108
|
+
viewers, a citizen's record, a chart of somebody's salary — or name the
|
|
109
|
+
element type: `blockSelector: "[data-lw-private], iframe, img"` covers every
|
|
110
|
+
document viewer and picture an app has, and the next one.
|
|
105
111
|
- `maskText: true` masks every piece of text as well, for a screen where the
|
|
106
112
|
words themselves are the secret.
|
|
107
113
|
- URLs in links and images go through the same redaction as the network log
|
|
108
114
|
(`token`, `signature`, `code`, …).
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
|
|
116
|
+
It is taken the way the network and console logs are — part of the capture,
|
|
117
|
+
listed in the dialog's "เก็บข้อมูลแล้ว" row, not a question put to the reporter.
|
|
118
|
+
Whether an app records at all is the host's decision, made once in config.
|
|
111
119
|
|
|
112
120
|
On the way out it is gzipped in the browser (about ten to one) and attached
|
|
113
121
|
as `session-replay.json.gz`, its own file beside the screenshot and the
|
|
114
122
|
bundle, capped at `maxBytes` (4 MB): a report always files, with or without
|
|
115
|
-
its replay, and the ticket says which.
|
|
123
|
+
its replay, and the ticket says which (`context.replay` — the length, or
|
|
124
|
+
`omitted: "too-large" | "empty"`). The support host keeps replays for
|
|
116
125
|
`REPLAY_RETENTION_DAYS` (30) and shows them to the desk only — never on the
|
|
117
126
|
reporter's own ticket page, never through the MCP tools.
|
|
118
127
|
|
package/dist/capture/replay.d.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The last minute of the page, kept in memory for the moment someone reports.
|
|
3
|
+
*
|
|
4
|
+
* rrweb records the DOM: one full snapshot, then every mutation, scroll,
|
|
5
|
+
* click and (masked) keystroke after it. A replay can only start at a
|
|
6
|
+
* snapshot, so the recorder is asked for a fresh one every half-window and
|
|
7
|
+
* the events are kept in WINDOWS, each beginning with its snapshot. A report
|
|
8
|
+
* takes whole windows from the newest back until the configured length is
|
|
9
|
+
* covered — which is why it always plays from the start and why it may run
|
|
10
|
+
* up to half as long again as asked.
|
|
11
|
+
*
|
|
12
|
+
* Three windows are retained, no more: the ones a report can use, and the one
|
|
13
|
+
* being filled. A page that mutates without pause would otherwise grow the
|
|
14
|
+
* buffer for as long as the tab stayed open. `checkoutEveryNth` is the second
|
|
15
|
+
* guard — a mutation storm cuts a new window early, and the old one ages out
|
|
16
|
+
* instead of ballooning.
|
|
17
|
+
*
|
|
18
|
+
* The recorder is loaded on demand and after the page has settled. It is a
|
|
19
|
+
* quarter of this package's weight again, and a host that did not ask for a
|
|
20
|
+
* replay never downloads it.
|
|
21
|
+
*/
|
|
22
|
+
import { replayOptions } from "../config";
|
|
1
23
|
import type { ReplayCapture, ReplayEvent } from "../types";
|
|
2
24
|
type Recorder = (options: Record<string, unknown>) => (() => void) | undefined;
|
|
3
25
|
export interface RecorderModule {
|
|
@@ -12,6 +34,7 @@ export declare function setRecorderLoader(load: () => Promise<RecorderModule>):
|
|
|
12
34
|
* widget gets blamed for a slow first paint.
|
|
13
35
|
*/
|
|
14
36
|
export declare function installReplay(): void;
|
|
37
|
+
declare function start(options: NonNullable<ReturnType<typeof replayOptions>>): Promise<void>;
|
|
15
38
|
declare function push(event: ReplayEvent): void;
|
|
16
39
|
/**
|
|
17
40
|
* The events a report should carry: whole windows, newest first, until the
|
|
@@ -20,9 +43,10 @@ declare function push(event: ReplayEvent): void;
|
|
|
20
43
|
export declare function takeReplay(now?: number): ReplayCapture | null;
|
|
21
44
|
export declare function isReplayRecording(): boolean;
|
|
22
45
|
export declare function stopReplay(): void;
|
|
23
|
-
/** Test seam: feed events as the recorder would. */
|
|
46
|
+
/** Test seam: feed events as the recorder would, or start against a fake recorder. */
|
|
24
47
|
export declare const _replayInternals: {
|
|
25
48
|
push: typeof push;
|
|
26
49
|
reset: () => undefined;
|
|
50
|
+
start: typeof start;
|
|
27
51
|
};
|
|
28
52
|
export {};
|
package/dist/config.d.ts
CHANGED
|
@@ -201,7 +201,15 @@ export interface ReplayOptions {
|
|
|
201
201
|
* dialog and toasts are always excluded.
|
|
202
202
|
*/
|
|
203
203
|
blockSelector?: string;
|
|
204
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Elements whose TEXT is masked (each character a `*`) while their layout
|
|
206
|
+
* is kept. Default: editable `[contenteditable]` and `[data-lw-mask]`. A rich-text editor
|
|
207
|
+
* is where typing happens without an `<input>`, so what is written there is
|
|
208
|
+
* masked the way a field's value is; `data-lw-mask` marks any other region
|
|
209
|
+
* whose words matter but whose shape is enough — a table of names.
|
|
210
|
+
*/
|
|
211
|
+
maskTextSelector?: string;
|
|
212
|
+
/** Mask every piece of text, not only what is typed. Default false. */
|
|
205
213
|
maskText?: boolean;
|
|
206
214
|
/**
|
|
207
215
|
* The most a replay may weigh once compressed. A report still files when its
|
package/dist/debug-capture.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{var V2=(($)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy($,{get:(J,Q)=>(typeof require<"u"?require:J)[Q]}):$)(function($){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+$+'" is not supported')});var G2={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},S=null;function p0($){let J=[];if(!$.host?.trim())J.push("host");if(!$.realmKey?.trim())J.push("realmKey");if(!$.app?.name?.trim())J.push("app.name");if(typeof $.module!=="function")J.push("module");if(J.length)throw Error(`[debug-capture] configureDebugCapture is missing: ${J.join(", ")}. `+"See the README — `module` maps a pathname to the part of your app it belongs to.");S=$}function w(){if(!S)throw Error("[debug-capture] configureDebugCapture() has not been called");return S}function j0(){return S!==null}function p(){let $=w().app;return{name:$.name,version:$.version??"0.0.0",environment:$.environment??X2()}}function X2(){if(typeof window>"u")return"unknown";let $=window.location.hostname;if($==="localhost"||$==="127.0.0.1"||$.endsWith(".local"))return"development";return"production"}function x($){let J=S?.capture?.[$];return typeof J==="number"?J:G2[$]}function y0($){let J=S?.module;if(!J)return null;try{return J($)??null}catch{return null}}function z0(){let $=S?.redact;return{headers:$?.headers??[],queryKeys:($?.queryKeys??[]).map((J)=>J.toLowerCase()),bodyKeys:($?.bodyKeys??[]).map((J)=>J.toLowerCase())}}function b0(){return S?.capture?.overlaySelectors??[]}var M0={seconds:60,blockSelector:"[data-lw-private]",maskText:!1,maxBytes:4000000};function i(){let $=S?.replay;if(!$)return null;let J=$===!0?{}:$,Q=typeof J.seconds==="number"&&J.seconds>0?J.seconds:M0.seconds,j=typeof J.maxBytes==="number"&&J.maxBytes>0?J.maxBytes:M0.maxBytes;return{seconds:Q,blockSelector:J.blockSelector?.trim()||M0.blockSelector,maskText:J.maskText===!0,maxBytes:j}}function v0($){if(typeof window>"u")return!1;let J;try{J=new URL($,window.location.href)}catch{return!1}if(Y2(J))return!1;if(J.origin===window.location.origin)return!0;return(S?.capture?.bodyOrigins??[]).some((Q)=>{try{return new URL(Q).origin===J.origin}catch{return!1}})}function Y2($){if(!S?.host)return!1;try{if(new URL(S.host).origin!==$.origin)return!1}catch{return!1}return $.pathname.startsWith("/ingest/")}function u0($){let J=Object.entries($).map(([Q,j])=>[Q.replace(/\/+$/,"")||"/",j]).sort((Q,j)=>j[0].length-Q[0].length);return(Q)=>{let j=(Q||"/").replace(/\/+$/,"")||"/";for(let[z,K]of J)if(j===z||j.startsWith(`${z}/`))return{key:z,label:K};return null}}var c="‹redacted›",F2=/^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i,H2=new Set(["access_token","token","id_token","refresh_token","code","secret","client_secret","password","apikey","api_key","signature","x-amz-signature","x-amz-credential"]),U2=/(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i,I2=/[\w.+-]+@[\w-]+\.[\w.-]+/g,M2=/\d(?:[\d\s-]{7,})\d/g;function o($){return $.replace(I2,c).replace(M2,c)}function P2($){if(F2.test($))return!0;return z0().headers.some((Q)=>Q.toLowerCase()===$.toLowerCase())}function l($){let J={};for(let[Q,j]of Object.entries($))J[Q]=P2(Q)?c:j;return J}function E($){try{let J=/^https?:\/\//i.test($),Q=new URL($,J?void 0:"http://local.invalid"),j=!1;if(Q.searchParams.forEach((z,K)=>{if(H2.has(K.toLowerCase())||z0().queryKeys.includes(K.toLowerCase()))Q.searchParams.set(K,c),j=!0}),!j)return $;return J?Q.toString():`${Q.pathname}${Q.search}`}catch{return $}}function P0($,J){if(J>6||$===null||typeof $!=="object")return $;if(Array.isArray($))return $.map((j)=>P0(j,J+1));let Q={};for(let[j,z]of Object.entries($)){let K=U2.test(j)||z0().bodyKeys.some((W)=>j.toLowerCase().includes(W));Q[j]=K?c:P0(z,J+1)}return Q}function r($,J){if($==null)return null;let Q=$,j=$.trim();if(j.startsWith("{")||j.startsWith("["))try{let z=JSON.parse(j);Q=JSON.stringify(P0(z,0))}catch{}if(Q.length>J)return`${Q.slice(0,J)}… [truncated ${Q.length-J} chars]`;return Q}var C0=120,q0=40,b=($,J)=>$.length>J?`${$.slice(0,J)}…`:$,B0=($)=>{try{return decodeURIComponent($)}catch{return $}},y=[],d0=0,i0=!1;function s($,J,Q,j){let z=b(J,C0),K=y[y.length-1];if($==="navigate"&&K?.kind==="click"){let Y=z.replace(/^ไปที่\s*/,"");if(K.detail.includes(`→ ${Y}`))return K.at=new Date().toISOString(),K;let H=Y.split(/[?#]/)[0]??Y,I=K.source?B0(K.source.replace(/^→\s*/,"")).split(/[?#]/)[0]:null;if(I&&(H===I||H.startsWith(I)))return K.detail=b(`${K.detail} → ${Y}`,C0),K.source=void 0,K.at=new Date().toISOString(),K}if(K&&K.kind===$&&K.detail===z){if(K.at=new Date().toISOString(),$!=="navigate")K.count=(K.count??1)+1;return K}d0+=1;let W={id:`act_${d0}`,at:new Date().toISOString(),kind:$,detail:z,count:1,source:Q,html:K0(j)};y.push(W);while(y.length>x("maxActions"))q2(y.shift());return W}var C2=200000,n=0;function K0($){if(!$)return;if(n+$.length>C2)return;return n+=$.length,$}function q2($){if(!$)return;if(n-=($.html?.length??0)+($.afterHtml?.length??0),n<0)n=0}function Z0($){return $ instanceof Element&&Boolean($.closest("[data-debug-reporter]"))}var B2='button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea',N2={button:"ปุ่ม",a:"ลิงก์",input:"ช่อง",textarea:"ช่อง",select:"ตัวเลือก",summary:"ส่วนขยาย"},c0={button:"ปุ่ม",tab:"แท็บ",menuitem:"เมนู",option:"ตัวเลือก",switch:"สวิตช์",checkbox:"ช่องเลือก",radio:"ตัวเลือก",link:"ลิงก์"};function D2($){let J=$.getAttribute("role");if(J&&c0[J])return c0[J];return N2[$.tagName.toLowerCase()]??"ปุ่ม"}function w2($,J){try{let Q=$,j=0;while(Q&&j<=J){let z=a0(Q);if(z&&typeof z.memoizedProps?.onClick==="function")return Q;Q=Q.parentElement,j+=1}}catch{}return null}function k2($){let J=$.getAttribute("aria-label")?.trim();if(J)return J;let Q=$.getAttribute("title")?.trim();if(Q)return Q;if($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement)return($.getAttribute("placeholder")||$.getAttribute("name")||"").trim();if($ instanceof HTMLImageElement)return($.getAttribute("alt")||"").trim();let j=($.textContent??"").replace(/\s+/g," ").trim();if(j)return j;if($ instanceof HTMLAnchorElement){let z=$.getAttribute("href");if(z?.startsWith("/"))return B0(z)}return""}function S2($){if(!($ instanceof Element))return null;let J=$.closest(B2)??w2($,4);if(!J)return null;let Q=J.tagName.toLowerCase();if(Q==="html"||Q==="body")return null;return J}function O2($){let J=o(k2($));if(!J)return null;return`${D2($)} “${b(J,q0)}”`}var n0=6000,R2=4000,_2=/(?:^|\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 T2($){$.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 W of Array.from(z.attributes)){let Y=W.name.toLowerCase();if(Y.startsWith("on")||Y==="srcdoc"||Y==="value"||Y.startsWith("data-"))z.removeAttribute(W.name)}if(z instanceof HTMLAnchorElement)z.setAttribute("href","#");if(z instanceof HTMLImageElement)z.removeAttribute("src");let K=z.getAttribute("class");if(K){let W=K.replace(_2," ").replace(/\s+/g," ").trim();if(W)z.setAttribute("class",W);else z.removeAttribute("class")}}let Q=document.createTreeWalker($,NodeFilter.SHOW_TEXT),j=Q.nextNode();while(j){if(j.nodeValue)j.nodeValue=o(j.nodeValue);j=Q.nextNode()}}function N0($,J,Q){try{let j=$.outerHTML;if(!j||j.length>J)return;let z=$.cloneNode(!0);T2(z);let K=z.outerHTML;return K&&K.length<=Q?K:void 0}catch{return}}var L2=($)=>N0($,n0,R2),f2=150000,A2=40000,o0=($)=>N0($,f2,A2);function x2($){if(!($ instanceof HTMLInputElement)&&!($ instanceof HTMLTextAreaElement)&&!($ instanceof HTMLSelectElement))return null;let J=$.name||$.id||$.getAttribute("aria-label")||$.getAttribute("placeholder")||$.tagName.toLowerCase();return`ช่อง “${o(J)}”`}var l0=80;function a0($){let J=Object.keys($).find((Q)=>Q.startsWith("__reactFiber$")||Q.startsWith("__reactInternalInstance$"));return J?$[J]:null}function E2($){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 r0($){if(!$)return;return`→ ${$.length>l0?`${$.slice(0,l0)}…`:$}`}function h2($){try{let J=$.closest("a[href]")?.getAttribute("href");if(J&&J.startsWith("/"))return r0(J);let Q=a0($),j=0;while(Q&&j<30){if(typeof Q.memoizedProps?.onClick==="function")return r0(E2(Q.memoizedProps.onClick));Q=Q.return,j+=1}return}catch{return}}var m2='[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';function g2(){let $=b0();return $.length?$.join(", "):m2}function p2($){let J=$.getAttribute("role");if(J==="status"||J==="alert")return"ข้อความแจ้งเตือน";if(J==="menu")return"เมนู";if(J==="listbox")return"รายการตัวเลือก";if(J==="alertdialog")return"กล่องยืนยัน";return"กล่องโต้ตอบ"}function y2($){let J=$.getAttribute("aria-label")?.trim();if(J)return J;let Q=$.getAttribute("aria-labelledby");if(Q){let K=Q.split(/\s+/).map((W)=>document.getElementById(W)?.textContent?.trim()??"").filter(Boolean).join(" ");if(K)return K}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 t0($){let J=o(y2($)),Q=p2($);return J?`เปิด ${Q} “${b(J,q0)}”`:`เปิด ${Q}`}var b2='[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin',v2=/กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;function u2($){if($.querySelector(b2))return!0;return v2.test($.textContent??"")}var d2=400,i2=250,c2=8000;function o2($,J){if(typeof MutationObserver>"u"){J.html=K0(o0($));return}let Q=Date.now(),j=!1,z=()=>{j=!0,W.disconnect(),window.clearInterval(Y),window.clearTimeout(H)},K=()=>{if(j)return;if(z(),!$.isConnected)return;J.detail=b(t0($),C0),J.html=K0(o0($))},W=new MutationObserver(()=>{Q=Date.now()});W.observe($,{childList:!0,subtree:!0,attributes:!0,characterData:!0});let Y=window.setInterval(()=>{if(j)return;if(!$.isConnected){z();return}if(Date.now()-Q>=d2&&!u2($))K()},i2),H=window.setTimeout(K,c2)}function l2($){if(Z0($))return;let J=s("ui",t0($));if(J)o2($,J)}function r2(){if(typeof MutationObserver>"u")return;let $=new WeakSet;new MutationObserver((Q)=>{for(let j of Q)for(let z of Array.from(j.addedNodes)){if(!(z instanceof Element))continue;let K=g2(),W=z.matches(K)?[z]:Array.from(z.querySelectorAll(K));for(let Y of W){if($.has(Y))continue;$.add(Y),l2(Y)}}}).observe(document.body,{childList:!0,subtree:!0})}var s2=1600,n2=2500;function s0($){return{disabled:$.hasAttribute("disabled")||$.getAttribute("aria-disabled")==="true",busy:$.getAttribute("aria-busy")==="true",text:b(($.textContent??"").replace(/\s+/g," ").trim(),q0)}}function a2($,J){if(!$.disabled&&J.disabled)return"ปุ่มถูกปิดใช้งานหลังคลิก";if(!$.busy&&J.busy)return"ปุ่มเข้าสู่สถานะกำลังโหลด";if($.text!==J.text&&J.text)return`ข้อความเปลี่ยนเป็น “${J.text}”`;return null}function t2($,J){if(typeof MutationObserver>"u")return;let Q=s0($),j=!1,z=(Y,H)=>{if(j)return;if(j=!0,K.disconnect(),window.clearTimeout(W),J.afterNote=Y,H)J.afterHtml=K0(N0($,n0,n2))},K=new MutationObserver(()=>{if(!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}let Y=a2(Q,s0($));if(Y)z(Y,!0)});K.observe($,{attributes:!0,attributeFilter:["disabled","aria-disabled","aria-busy","class"],childList:!0,subtree:!0,characterData:!0});let W=window.setTimeout(()=>{if(!j&&!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}j=!0,K.disconnect()},s2)}function e0(){if(i0||typeof window>"u")return;i0=!0,document.addEventListener("click",(j)=>{if(Z0(j.target))return;let z=S2(j.target);if(!z)return;let K=O2(z);if(!K)return;let W=s("click",`คลิก ${K}`,h2(z),L2(z));if(W)t2(z,W)},{capture:!0,passive:!0}),document.addEventListener("change",(j)=>{if(Z0(j.target))return;let z=x2(j.target);if(z)s("input",`แก้ไข ${z}`)},{capture:!0,passive:!0}),document.addEventListener("submit",(j)=>{if(Z0(j.target))return;s("submit","ส่งฟอร์ม")},{capture:!0,passive:!0});let $=()=>s("navigate",`ไปที่ ${B0(E(location.pathname+location.search))}`),J=history.pushState.bind(history),Q=history.replaceState.bind(history);history.pushState=(...j)=>{let z=J(...j);return $(),z},history.replaceState=(...j)=>{let z=Q(...j);return $(),z},window.addEventListener("popstate",$),r2()}function $1(){return y.map(($)=>({...$}))}var J1=2000,W0=[],Q1=0,j1=!1;function D0($,J){Q1+=1,W0.push({id:`log_${Q1}`,at:new Date().toISOString(),level:$,message:J.length>J1?`${J.slice(0,J1)}…`:J});while(W0.length>x("maxConsoleEntries"))W0.shift()}function e2(){let $=new WeakSet;return(J,Q)=>{if(typeof Q==="object"&&Q!==null){if($.has(Q))return"[Circular]";$.add(Q)}if(typeof Q==="bigint")return Q.toString();return Q}}function z1($){if(typeof $==="string")return $;if($ instanceof Error)return`${$.name}: ${$.message}`;try{let J=JSON.stringify($,e2());if(J!==void 0)return J}catch{}try{return String($)}catch{}try{return Object.prototype.toString.call($)}catch{return`[${typeof $}]`}}function Z1(){if(j1||typeof window>"u")return;j1=!0;let $=["log","info","warn","error","debug"];for(let J of $){let Q=console[J].bind(console);console[J]=(...j)=>{D0(J,j.map(z1).join(" ")),Q(...j)}}window.addEventListener("error",(J)=>{let Q=J.filename?` (${J.filename}:${J.lineno}:${J.colno})`:"";D0("exception",`${J.message}${Q}`)}),window.addEventListener("unhandledrejection",(J)=>{let Q=J.reason instanceof Error?`${J.reason.name}: ${J.reason.message}`:z1(J.reason);D0("unhandledrejection",Q)})}function K1(){return W0.map(($)=>({...$}))}var W1=new Set,V1=new Set;function G1($,J){return $.add(J),()=>$.delete(J)}function X1($,J){for(let Q of[...$])Q(J)}function Y1($){return G1(W1,$)}function V0($={type:"manual"}){X1(W1,$)}function F1($){return G1(V1,$)}function H1($){X1(V1,$)}var $4=15000,J4=["ResizeObserver loop","Script error.","Non-Error promise rejection captured"],U1=!1,I1=0;function Q4($){return J4.some((J)=>$.includes(J))}function M1($){let J=$.message??"";if(!J||Q4(J))return;let Q=Date.now();if(Q-I1<$4)return;I1=Q,H1({...$,message:J})}function P1(){if(U1||typeof window>"u")return;U1=!0,window.addEventListener("error",($)=>{if(!$.message&&!$.error)return;let J=$.error instanceof Error?$.error:null;M1({type:"runtime-error",message:$.message||(J?J.message:"Unknown error"),stack:J?.stack})}),window.addEventListener("unhandledrejection",($)=>{let J=$.reason;M1({type:"unhandledrejection",message:J instanceof Error?J.message:String(J),stack:J instanceof Error?J.stack:void 0})})}var N1=4000,j4=1e6,z4=1e7,G0=[],C1=0,q1=!1;function D1($){G0.push($);while(G0.length>x("maxRequests"))G0.shift()}function w1(){return C1+=1,`req_${C1}`}function B1($){let J={};if(!$)return J;if($ instanceof Headers)$.forEach((Q,j)=>{J[j]=Q});else if(Array.isArray($))for(let[Q,j]of $)J[Q]=j;else Object.assign(J,$);return J}function Z4($){let J={};return $.forEach((Q,j)=>{J[j]=Q}),J}function K4($){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 W4($,J){let Q="",j="GET",z={},K=null;if(typeof $==="string")Q=$;else if($ instanceof URL)Q=$.toString();else Q=$.url,j=$.method||j,z=B1($.headers);if(J){if(J.method)j=J.method;if(J.headers)z={...z,...B1(J.headers)};if(J.body!==void 0)K=K4(J.body)}return{method:j.toUpperCase(),url:Q,headers:z,body:K}}function k1($){return!v0($)}function V4($,J){if(k1(J.url)){J.responseSnippet="[body not captured for this origin]";return}let Q=$.headers.get("content-type")??"",j=Number($.headers.get("content-length")??"0"),z=j?`, ~${j} bytes`:"";if(!/json|text|xml|html|javascript|urlencoded/i.test(Q)){J.responseSnippet=`[binary ${Q||"unknown"}${z}]`;return}if(j>j4){J.responseSnippet=`[response ${Q||"text"}${z} — omitted]`;return}try{$.clone().text().then((K)=>{J.responseSnippet=r(K,x("maxBodyChars"))}).catch(()=>{})}catch{}}function S1($,J){if(/[?&]_rsc=/.test($))return!0;for(let Q of Object.keys(J)){let j=Q.toLowerCase();if(j==="rsc"||j==="next-router-prefetch"||j==="next-router-state-tree")return!0}return!1}function G4(){if(typeof window>"u"||typeof window.fetch!=="function")return;let $=window.fetch.bind(window);window.fetch=Object.assign(async(J,Q)=>{let j=W4(J,Q);if(S1(j.url,j.headers))return $(J,Q);let z={id:w1(),startedAt:new Date().toISOString(),method:j.method,url:E(j.url),requestHeaders:l(j.headers),requestBody:r(j.body,N1),status:null,statusText:null,durationMs:null,via:"fetch"};D1(z);let K=performance.now();try{let W=await $(J,Q);return z.status=W.status,z.statusText=W.statusText,z.durationMs=Math.round(performance.now()-K),z.responseHeaders=l(Z4(W.headers)),V4(W,z),W}catch(W){throw z.durationMs=Math.round(performance.now()-K),z.error=W instanceof Error?`${W.name}: ${W.message}`:String(W),W}},$)}function X4(){if(typeof window>"u"||typeof window.XMLHttpRequest!=="function")return;let $=XMLHttpRequest.prototype,J=$.open,Q=$.send,j=function(K,W){let Y=typeof W==="string"?W:W.toString();return this.__lwEntry=S1(Y,{})?void 0:{id:w1(),startedAt:"",method:(K||"GET").toUpperCase(),url:E(Y),requestHeaders:{},requestBody:null,status:null,statusText:null,durationMs:null,via:"xhr"},J.apply(this,arguments)},z=function(K){let W=this.__lwEntry;if(W){W.startedAt=new Date().toISOString(),W.requestBody=typeof K==="string"?r(K,N1):K==null?null:"[non-string body]";let Y=performance.now();D1(W),this.addEventListener("loadend",()=>{if(W.status=this.status||null,W.statusText=this.statusText||null,W.durationMs=Math.round(performance.now()-Y),k1(W.url))W.responseSnippet="[body not captured for this origin]";else if(this.responseType===""||this.responseType==="text")try{W.responseSnippet=r(this.responseText||"",x("maxBodyChars"))}catch{}else{let H=this.getResponseHeader("content-type")??this.responseType;W.responseSnippet=`[binary ${H}]`}})}return Q.apply(this,arguments)};$.open=j,$.send=z}function O1(){if(q1)return;q1=!0,G4(),X4()}function R1(){let $=G0.map((Q)=>({...Q})),J=0;for(let Q=$.length-1;Q>=0;Q-=1){let j=$[Q],z=j?.responseSnippet;if(!j||typeof z!=="string"||z.length===0)continue;if(J+z.length>z4)j.responseSnippet=`[response omitted — report size budget reached (${z.length.toLocaleString()} chars)]`;else J+=z.length}return $}var Y4=4,_1=3,F4=4000,H4="[data-debug-reporter]",T1=()=>import("@rrweb/record");function L1($){T1=$}var _=[],w0=null,X0=!1;function f1(){if(typeof window>"u"||w0||X0)return;let $=i();if(!$)return;X0=!0;let J=()=>void U4($);if("requestIdleCallback"in window)window.requestIdleCallback(J,{timeout:3000});else setTimeout(J,1000)}async function U4($){let J;try{J=(await T1()).record}catch(Q){X0=!1,console.warn("[debug-capture] session replay could not start:",Q);return}if(w0)return;try{w0=J({emit:(Q)=>I4(Q),checkoutEveryNms:Math.max(1000,$.seconds*1000/2),checkoutEveryNth:F4,maskAllInputs:!0,...$.maskText?{maskTextSelector:"*"}:{},blockSelector:`${$.blockSelector}, ${H4}`,slimDOMOptions:"all",inlineStylesheet:!0,sampling:{mousemove:50,scroll:150,media:800,input:"last"},recordCanvas:!1,errorHandler:()=>!0})??null}catch(Q){console.warn("[debug-capture] session replay could not start:",Q)}finally{X0=!1}}function I4($){if($.type===Y4||_.length===0){if(_.push([]),_.length>_1)_=_.slice(-_1)}_[_.length-1].push($)}function A1($=Date.now()){let J=i();if(!J||!_.length)return null;let Q=$-J.seconds*1000,j=_.length-1;while(j>0&&(_[j][0]?.timestamp??$)>Q)j-=1;let z=_.slice(j).flat(),K=z[0]?.timestamp,W=z[z.length-1]?.timestamp;if(K===void 0||W===void 0)return null;return{events:z,startedAt:new Date(K).toISOString(),endedAt:new Date(W).toISOString(),durationMs:Math.max(0,W-K)}}var M4={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:"หน้า",replayAttach:"แนบการบันทึกหน้าจอ {seconds} วินาทีก่อนแจ้ง",replayWhat:"บันทึกเฉพาะโครงสร้างหน้าจอและการคลิก — ข้อความที่พิมพ์ในช่องกรอกถูกปิดบังไว้",handoffTitle:"กำลังพาไปที่ระบบแจ้งปัญหา",handoffBody:"ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",handoffGo:"ไปเลย",handoffPreparing:"กำลังเตรียม…",handoffFailed:"เปิดรายการที่แจ้งไว้ไม่สำเร็จ",handoffBlocked:"เบราว์เซอร์บล็อกการเปิดแท็บใหม่",handoffOpen:"เปิดในแท็บใหม่"},P4={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",replayAttach:"Attach a replay of the last {seconds} seconds",replayWhat:"The page and your clicks are recorded, not a video — anything typed into a field is masked",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 Y0($){return $==="en"?P4:M4}var C4="lw-debug-toasts",q4=6000,B4=`
|
|
1
|
+
(()=>{var V2=(($)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy($,{get:(J,Q)=>(typeof require<"u"?require:J)[Q]}):$)(function($){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+$+'" is not supported')});var G2={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},O=null;function y0($){let J=[];if(!$.host?.trim())J.push("host");if(!$.realmKey?.trim())J.push("realmKey");if(!$.app?.name?.trim())J.push("app.name");if(typeof $.module!=="function")J.push("module");if(J.length)throw Error(`[debug-capture] configureDebugCapture is missing: ${J.join(", ")}. `+"See the README — `module` maps a pathname to the part of your app it belongs to.");O=$}function N(){if(!O)throw Error("[debug-capture] configureDebugCapture() has not been called");return O}function j0(){return O!==null}function g(){let $=N().app;return{name:$.name,version:$.version??"0.0.0",environment:$.environment??X2()}}function X2(){if(typeof window>"u")return"unknown";let $=window.location.hostname;if($==="localhost"||$==="127.0.0.1"||$.endsWith(".local"))return"development";return"production"}function x($){let J=O?.capture?.[$];return typeof J==="number"?J:G2[$]}function p0($){let J=O?.module;if(!J)return null;try{return J($)??null}catch{return null}}function z0(){let $=O?.redact;return{headers:$?.headers??[],queryKeys:($?.queryKeys??[]).map((J)=>J.toLowerCase()),bodyKeys:($?.bodyKeys??[]).map((J)=>J.toLowerCase())}}function b0(){return O?.capture?.overlaySelectors??[]}var Q0={seconds:60,blockSelector:"[data-lw-private]",maskTextSelector:'[contenteditable]:not([contenteditable="false"]), [data-lw-mask]',maskText:!1,maxBytes:4000000};function u(){let $=O?.replay;if(!$)return null;let J=$===!0?{}:$,Q=typeof J.seconds==="number"&&J.seconds>0?J.seconds:Q0.seconds,j=typeof J.maxBytes==="number"&&J.maxBytes>0?J.maxBytes:Q0.maxBytes;return{seconds:Q,blockSelector:J.blockSelector?.trim()||Q0.blockSelector,maskTextSelector:J.maskTextSelector?.trim()||Q0.maskTextSelector,maskText:J.maskText===!0,maxBytes:j}}function v0($){if(typeof window>"u")return!1;let J;try{J=new URL($,window.location.href)}catch{return!1}if(Y2(J))return!1;if(J.origin===window.location.origin)return!0;return(O?.capture?.bodyOrigins??[]).some((Q)=>{try{return new URL(Q).origin===J.origin}catch{return!1}})}function Y2($){if(!O?.host)return!1;try{if(new URL(O.host).origin!==$.origin)return!1}catch{return!1}return $.pathname.startsWith("/ingest/")}function u0($){let J=Object.entries($).map(([Q,j])=>[Q.replace(/\/+$/,"")||"/",j]).sort((Q,j)=>j[0].length-Q[0].length);return(Q)=>{let j=(Q||"/").replace(/\/+$/,"")||"/";for(let[z,K]of J)if(j===z||j.startsWith(`${z}/`))return{key:z,label:K};return null}}var d="‹redacted›",F2=/^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i,H2=new Set(["access_token","token","id_token","refresh_token","code","secret","client_secret","password","apikey","api_key","signature","x-amz-signature","x-amz-credential"]),U2=/(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i,I2=/[\w.+-]+@[\w-]+\.[\w.-]+/g,M2=/\d(?:[\d\s-]{7,})\d/g;function i($){return $.replace(I2,d).replace(M2,d)}function C2($){if(F2.test($))return!0;return z0().headers.some((Q)=>Q.toLowerCase()===$.toLowerCase())}function c($){let J={};for(let[Q,j]of Object.entries($))J[Q]=C2(Q)?d:j;return J}function E($){try{let J=/^https?:\/\//i.test($),Q=new URL($,J?void 0:"http://local.invalid"),j=!1;if(Q.searchParams.forEach((z,K)=>{if(H2.has(K.toLowerCase())||z0().queryKeys.includes(K.toLowerCase()))Q.searchParams.set(K,d),j=!0}),!j)return $;return J?Q.toString():`${Q.pathname}${Q.search}`}catch{return $}}function M0($,J){if(J>6||$===null||typeof $!=="object")return $;if(Array.isArray($))return $.map((j)=>M0(j,J+1));let Q={};for(let[j,z]of Object.entries($)){let K=U2.test(j)||z0().bodyKeys.some((W)=>j.toLowerCase().includes(W));Q[j]=K?d:M0(z,J+1)}return Q}function o($,J){if($==null)return null;let Q=$,j=$.trim();if(j.startsWith("{")||j.startsWith("["))try{let z=JSON.parse(j);Q=JSON.stringify(M0(z,0))}catch{}if(Q.length>J)return`${Q.slice(0,J)}… [truncated ${Q.length-J} chars]`;return Q}var C0=120,P0=40,p=($,J)=>$.length>J?`${$.slice(0,J)}…`:$,q0=($)=>{try{return decodeURIComponent($)}catch{return $}},y=[],d0=0,i0=!1;function l($,J,Q,j){let z=p(J,C0),K=y[y.length-1];if($==="navigate"&&K?.kind==="click"){let Y=z.replace(/^ไปที่\s*/,"");if(K.detail.includes(`→ ${Y}`))return K.at=new Date().toISOString(),K;let H=Y.split(/[?#]/)[0]??Y,I=K.source?q0(K.source.replace(/^→\s*/,"")).split(/[?#]/)[0]:null;if(I&&(H===I||H.startsWith(I)))return K.detail=p(`${K.detail} → ${Y}`,C0),K.source=void 0,K.at=new Date().toISOString(),K}if(K&&K.kind===$&&K.detail===z){if(K.at=new Date().toISOString(),$!=="navigate")K.count=(K.count??1)+1;return K}d0+=1;let W={id:`act_${d0}`,at:new Date().toISOString(),kind:$,detail:z,count:1,source:Q,html:K0(j)};y.push(W);while(y.length>x("maxActions"))q2(y.shift());return W}var P2=200000,r=0;function K0($){if(!$)return;if(r+$.length>P2)return;return r+=$.length,$}function q2($){if(!$)return;if(r-=($.html?.length??0)+($.afterHtml?.length??0),r<0)r=0}function Z0($){return $ instanceof Element&&Boolean($.closest("[data-debug-reporter]"))}var B2='button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea',N2={button:"ปุ่ม",a:"ลิงก์",input:"ช่อง",textarea:"ช่อง",select:"ตัวเลือก",summary:"ส่วนขยาย"},c0={button:"ปุ่ม",tab:"แท็บ",menuitem:"เมนู",option:"ตัวเลือก",switch:"สวิตช์",checkbox:"ช่องเลือก",radio:"ตัวเลือก",link:"ลิงก์"};function D2($){let J=$.getAttribute("role");if(J&&c0[J])return c0[J];return N2[$.tagName.toLowerCase()]??"ปุ่ม"}function w2($,J){try{let Q=$,j=0;while(Q&&j<=J){let z=a0(Q);if(z&&typeof z.memoizedProps?.onClick==="function")return Q;Q=Q.parentElement,j+=1}}catch{}return null}function k2($){let J=$.getAttribute("aria-label")?.trim();if(J)return J;let Q=$.getAttribute("title")?.trim();if(Q)return Q;if($ instanceof HTMLInputElement||$ instanceof HTMLTextAreaElement||$ instanceof HTMLSelectElement)return($.getAttribute("placeholder")||$.getAttribute("name")||"").trim();if($ instanceof HTMLImageElement)return($.getAttribute("alt")||"").trim();let j=($.textContent??"").replace(/\s+/g," ").trim();if(j)return j;if($ instanceof HTMLAnchorElement){let z=$.getAttribute("href");if(z?.startsWith("/"))return q0(z)}return""}function S2($){if(!($ instanceof Element))return null;let J=$.closest(B2)??w2($,4);if(!J)return null;let Q=J.tagName.toLowerCase();if(Q==="html"||Q==="body")return null;return J}function O2($){let J=i(k2($));if(!J)return null;return`${D2($)} “${p(J,P0)}”`}var n0=6000,R2=4000,_2=/(?:^|\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 T2($){$.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 W of Array.from(z.attributes)){let Y=W.name.toLowerCase();if(Y.startsWith("on")||Y==="srcdoc"||Y==="value"||Y.startsWith("data-"))z.removeAttribute(W.name)}if(z instanceof HTMLAnchorElement)z.setAttribute("href","#");if(z instanceof HTMLImageElement)z.removeAttribute("src");let K=z.getAttribute("class");if(K){let W=K.replace(_2," ").replace(/\s+/g," ").trim();if(W)z.setAttribute("class",W);else z.removeAttribute("class")}}let Q=document.createTreeWalker($,NodeFilter.SHOW_TEXT),j=Q.nextNode();while(j){if(j.nodeValue)j.nodeValue=i(j.nodeValue);j=Q.nextNode()}}function B0($,J,Q){try{let j=$.outerHTML;if(!j||j.length>J)return;let z=$.cloneNode(!0);T2(z);let K=z.outerHTML;return K&&K.length<=Q?K:void 0}catch{return}}var L2=($)=>B0($,n0,R2),A2=150000,f2=40000,o0=($)=>B0($,A2,f2);function x2($){if(!($ instanceof HTMLInputElement)&&!($ instanceof HTMLTextAreaElement)&&!($ instanceof HTMLSelectElement))return null;let J=$.name||$.id||$.getAttribute("aria-label")||$.getAttribute("placeholder")||$.tagName.toLowerCase();return`ช่อง “${i(J)}”`}var l0=80;function a0($){let J=Object.keys($).find((Q)=>Q.startsWith("__reactFiber$")||Q.startsWith("__reactInternalInstance$"));return J?$[J]:null}function E2($){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 r0($){if(!$)return;return`→ ${$.length>l0?`${$.slice(0,l0)}…`:$}`}function h2($){try{let J=$.closest("a[href]")?.getAttribute("href");if(J&&J.startsWith("/"))return r0(J);let Q=a0($),j=0;while(Q&&j<30){if(typeof Q.memoizedProps?.onClick==="function")return r0(E2(Q.memoizedProps.onClick));Q=Q.return,j+=1}return}catch{return}}var m2='[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';function g2(){let $=b0();return $.length?$.join(", "):m2}function y2($){let J=$.getAttribute("role");if(J==="status"||J==="alert")return"ข้อความแจ้งเตือน";if(J==="menu")return"เมนู";if(J==="listbox")return"รายการตัวเลือก";if(J==="alertdialog")return"กล่องยืนยัน";return"กล่องโต้ตอบ"}function p2($){let J=$.getAttribute("aria-label")?.trim();if(J)return J;let Q=$.getAttribute("aria-labelledby");if(Q){let K=Q.split(/\s+/).map((W)=>document.getElementById(W)?.textContent?.trim()??"").filter(Boolean).join(" ");if(K)return K}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 t0($){let J=i(p2($)),Q=y2($);return J?`เปิด ${Q} “${p(J,P0)}”`:`เปิด ${Q}`}var b2='[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin',v2=/กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;function u2($){if($.querySelector(b2))return!0;return v2.test($.textContent??"")}var d2=400,i2=250,c2=8000;function o2($,J){if(typeof MutationObserver>"u"){J.html=K0(o0($));return}let Q=Date.now(),j=!1,z=()=>{j=!0,W.disconnect(),window.clearInterval(Y),window.clearTimeout(H)},K=()=>{if(j)return;if(z(),!$.isConnected)return;J.detail=p(t0($),C0),J.html=K0(o0($))},W=new MutationObserver(()=>{Q=Date.now()});W.observe($,{childList:!0,subtree:!0,attributes:!0,characterData:!0});let Y=window.setInterval(()=>{if(j)return;if(!$.isConnected){z();return}if(Date.now()-Q>=d2&&!u2($))K()},i2),H=window.setTimeout(K,c2)}function l2($){if(Z0($))return;let J=l("ui",t0($));if(J)o2($,J)}function r2(){if(typeof MutationObserver>"u")return;let $=new WeakSet;new MutationObserver((Q)=>{for(let j of Q)for(let z of Array.from(j.addedNodes)){if(!(z instanceof Element))continue;let K=g2(),W=z.matches(K)?[z]:Array.from(z.querySelectorAll(K));for(let Y of W){if($.has(Y))continue;$.add(Y),l2(Y)}}}).observe(document.body,{childList:!0,subtree:!0})}var s2=1600,n2=2500;function s0($){return{disabled:$.hasAttribute("disabled")||$.getAttribute("aria-disabled")==="true",busy:$.getAttribute("aria-busy")==="true",text:p(($.textContent??"").replace(/\s+/g," ").trim(),P0)}}function a2($,J){if(!$.disabled&&J.disabled)return"ปุ่มถูกปิดใช้งานหลังคลิก";if(!$.busy&&J.busy)return"ปุ่มเข้าสู่สถานะกำลังโหลด";if($.text!==J.text&&J.text)return`ข้อความเปลี่ยนเป็น “${J.text}”`;return null}function t2($,J){if(typeof MutationObserver>"u")return;let Q=s0($),j=!1,z=(Y,H)=>{if(j)return;if(j=!0,K.disconnect(),window.clearTimeout(W),J.afterNote=Y,H)J.afterHtml=K0(B0($,n0,n2))},K=new MutationObserver(()=>{if(!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}let Y=a2(Q,s0($));if(Y)z(Y,!0)});K.observe($,{attributes:!0,attributeFilter:["disabled","aria-disabled","aria-busy","class"],childList:!0,subtree:!0,characterData:!0});let W=window.setTimeout(()=>{if(!j&&!$.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}j=!0,K.disconnect()},s2)}function e0(){if(i0||typeof window>"u")return;i0=!0,document.addEventListener("click",(j)=>{if(Z0(j.target))return;let z=S2(j.target);if(!z)return;let K=O2(z);if(!K)return;let W=l("click",`คลิก ${K}`,h2(z),L2(z));if(W)t2(z,W)},{capture:!0,passive:!0}),document.addEventListener("change",(j)=>{if(Z0(j.target))return;let z=x2(j.target);if(z)l("input",`แก้ไข ${z}`)},{capture:!0,passive:!0}),document.addEventListener("submit",(j)=>{if(Z0(j.target))return;l("submit","ส่งฟอร์ม")},{capture:!0,passive:!0});let $=()=>l("navigate",`ไปที่ ${q0(E(location.pathname+location.search))}`),J=history.pushState.bind(history),Q=history.replaceState.bind(history);history.pushState=(...j)=>{let z=J(...j);return $(),z},history.replaceState=(...j)=>{let z=Q(...j);return $(),z},window.addEventListener("popstate",$),r2()}function $1(){return y.map(($)=>({...$}))}var J1=2000,W0=[],Q1=0,j1=!1;function N0($,J){Q1+=1,W0.push({id:`log_${Q1}`,at:new Date().toISOString(),level:$,message:J.length>J1?`${J.slice(0,J1)}…`:J});while(W0.length>x("maxConsoleEntries"))W0.shift()}function e2(){let $=new WeakSet;return(J,Q)=>{if(typeof Q==="object"&&Q!==null){if($.has(Q))return"[Circular]";$.add(Q)}if(typeof Q==="bigint")return Q.toString();return Q}}function z1($){if(typeof $==="string")return $;if($ instanceof Error)return`${$.name}: ${$.message}`;try{let J=JSON.stringify($,e2());if(J!==void 0)return J}catch{}try{return String($)}catch{}try{return Object.prototype.toString.call($)}catch{return`[${typeof $}]`}}function Z1(){if(j1||typeof window>"u")return;j1=!0;let $=["log","info","warn","error","debug"];for(let J of $){let Q=console[J].bind(console);console[J]=(...j)=>{N0(J,j.map(z1).join(" ")),Q(...j)}}window.addEventListener("error",(J)=>{let Q=J.filename?` (${J.filename}:${J.lineno}:${J.colno})`:"";N0("exception",`${J.message}${Q}`)}),window.addEventListener("unhandledrejection",(J)=>{let Q=J.reason instanceof Error?`${J.reason.name}: ${J.reason.message}`:z1(J.reason);N0("unhandledrejection",Q)})}function K1(){return W0.map(($)=>({...$}))}var W1=new Set,V1=new Set;function G1($,J){return $.add(J),()=>$.delete(J)}function X1($,J){for(let Q of[...$])Q(J)}function Y1($){return G1(W1,$)}function V0($={type:"manual"}){X1(W1,$)}function F1($){return G1(V1,$)}function H1($){X1(V1,$)}var $4=15000,J4=["ResizeObserver loop","Script error.","Non-Error promise rejection captured"],U1=!1,I1=0;function Q4($){return J4.some((J)=>$.includes(J))}function M1($){let J=$.message??"";if(!J||Q4(J))return;let Q=Date.now();if(Q-I1<$4)return;I1=Q,H1({...$,message:J})}function C1(){if(U1||typeof window>"u")return;U1=!0,window.addEventListener("error",($)=>{if(!$.message&&!$.error)return;let J=$.error instanceof Error?$.error:null;M1({type:"runtime-error",message:$.message||(J?J.message:"Unknown error"),stack:J?.stack})}),window.addEventListener("unhandledrejection",($)=>{let J=$.reason;M1({type:"unhandledrejection",message:J instanceof Error?J.message:String(J),stack:J instanceof Error?J.stack:void 0})})}var N1=4000,j4=1e6,z4=1e7,G0=[],P1=0,q1=!1;function D1($){G0.push($);while(G0.length>x("maxRequests"))G0.shift()}function w1(){return P1+=1,`req_${P1}`}function B1($){let J={};if(!$)return J;if($ instanceof Headers)$.forEach((Q,j)=>{J[j]=Q});else if(Array.isArray($))for(let[Q,j]of $)J[Q]=j;else Object.assign(J,$);return J}function Z4($){let J={};return $.forEach((Q,j)=>{J[j]=Q}),J}function K4($){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 W4($,J){let Q="",j="GET",z={},K=null;if(typeof $==="string")Q=$;else if($ instanceof URL)Q=$.toString();else Q=$.url,j=$.method||j,z=B1($.headers);if(J){if(J.method)j=J.method;if(J.headers)z={...z,...B1(J.headers)};if(J.body!==void 0)K=K4(J.body)}return{method:j.toUpperCase(),url:Q,headers:z,body:K}}function k1($){return!v0($)}function V4($,J){if(k1(J.url)){J.responseSnippet="[body not captured for this origin]";return}let Q=$.headers.get("content-type")??"",j=Number($.headers.get("content-length")??"0"),z=j?`, ~${j} bytes`:"";if(!/json|text|xml|html|javascript|urlencoded/i.test(Q)){J.responseSnippet=`[binary ${Q||"unknown"}${z}]`;return}if(j>j4){J.responseSnippet=`[response ${Q||"text"}${z} — omitted]`;return}try{$.clone().text().then((K)=>{J.responseSnippet=o(K,x("maxBodyChars"))}).catch(()=>{})}catch{}}function S1($,J){if(/[?&]_rsc=/.test($))return!0;for(let Q of Object.keys(J)){let j=Q.toLowerCase();if(j==="rsc"||j==="next-router-prefetch"||j==="next-router-state-tree")return!0}return!1}function G4(){if(typeof window>"u"||typeof window.fetch!=="function")return;let $=window.fetch.bind(window);window.fetch=Object.assign(async(J,Q)=>{let j=W4(J,Q);if(S1(j.url,j.headers))return $(J,Q);let z={id:w1(),startedAt:new Date().toISOString(),method:j.method,url:E(j.url),requestHeaders:c(j.headers),requestBody:o(j.body,N1),status:null,statusText:null,durationMs:null,via:"fetch"};D1(z);let K=performance.now();try{let W=await $(J,Q);return z.status=W.status,z.statusText=W.statusText,z.durationMs=Math.round(performance.now()-K),z.responseHeaders=c(Z4(W.headers)),V4(W,z),W}catch(W){throw z.durationMs=Math.round(performance.now()-K),z.error=W instanceof Error?`${W.name}: ${W.message}`:String(W),W}},$)}function X4(){if(typeof window>"u"||typeof window.XMLHttpRequest!=="function")return;let $=XMLHttpRequest.prototype,J=$.open,Q=$.send,j=function(K,W){let Y=typeof W==="string"?W:W.toString();return this.__lwEntry=S1(Y,{})?void 0:{id:w1(),startedAt:"",method:(K||"GET").toUpperCase(),url:E(Y),requestHeaders:{},requestBody:null,status:null,statusText:null,durationMs:null,via:"xhr"},J.apply(this,arguments)},z=function(K){let W=this.__lwEntry;if(W){W.startedAt=new Date().toISOString(),W.requestBody=typeof K==="string"?o(K,N1):K==null?null:"[non-string body]";let Y=performance.now();D1(W),this.addEventListener("loadend",()=>{if(W.status=this.status||null,W.statusText=this.statusText||null,W.durationMs=Math.round(performance.now()-Y),k1(W.url))W.responseSnippet="[body not captured for this origin]";else if(this.responseType===""||this.responseType==="text")try{W.responseSnippet=o(this.responseText||"",x("maxBodyChars"))}catch{}else{let H=this.getResponseHeader("content-type")??this.responseType;W.responseSnippet=`[binary ${H}]`}})}return Q.apply(this,arguments)};$.open=j,$.send=z}function O1(){if(q1)return;q1=!0,G4(),X4()}function R1(){let $=G0.map((Q)=>({...Q})),J=0;for(let Q=$.length-1;Q>=0;Q-=1){let j=$[Q],z=j?.responseSnippet;if(!j||typeof z!=="string"||z.length===0)continue;if(J+z.length>z4)j.responseSnippet=`[response omitted — report size budget reached (${z.length.toLocaleString()} chars)]`;else J+=z.length}return $}var Y4=4,_1=3,F4=4000,H4="[data-debug-reporter]",T1=()=>import("@rrweb/record");function L1($){T1=$}var _=[],D0=null,X0=!1;function A1(){if(typeof window>"u"||D0||X0)return;let $=u();if(!$)return;X0=!0;let J=()=>void U4($);if("requestIdleCallback"in window)window.requestIdleCallback(J,{timeout:3000});else setTimeout(J,1000)}async function U4($){let J;try{J=(await T1()).record}catch(Q){X0=!1,console.warn("[debug-capture] session replay could not start:",Q);return}if(D0)return;try{D0=J({emit:(Q)=>I4(Q),checkoutEveryNms:Math.max(1000,$.seconds*1000/2),checkoutEveryNth:F4,maskAllInputs:!0,maskTextSelector:$.maskText?"*":$.maskTextSelector,blockSelector:`${$.blockSelector}, ${H4}`,slimDOMOptions:"all",inlineStylesheet:!0,sampling:{mousemove:50,scroll:150,media:800,input:"last"},recordCanvas:!1,errorHandler:()=>!0})??null}catch(Q){console.warn("[debug-capture] session replay could not start:",Q)}finally{X0=!1}}function I4($){if($.type===Y4||_.length===0){if(_.push([]),_.length>_1)_=_.slice(-_1)}_[_.length-1].push($)}function f1($=Date.now()){let J=u();if(!J||!_.length)return null;let Q=$-J.seconds*1000,j=_.length-1;while(j>0&&(_[j][0]?.timestamp??$)>Q)j-=1;let z=_.slice(j).flat(),K=z[0]?.timestamp,W=z[z.length-1]?.timestamp;if(K===void 0||W===void 0)return null;return{events:z,startedAt:new Date(K).toISOString(),endedAt:new Date(W).toISOString(),durationMs:Math.max(0,W-K)}}var M4={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:"หน้า",replay:"บันทึกหน้าจอ",handoffTitle:"กำลังพาไปที่ระบบแจ้งปัญหา",handoffBody:"ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",handoffGo:"ไปเลย",handoffPreparing:"กำลังเตรียม…",handoffFailed:"เปิดรายการที่แจ้งไว้ไม่สำเร็จ",handoffBlocked:"เบราว์เซอร์บล็อกการเปิดแท็บใหม่",handoffOpen:"เปิดในแท็บใหม่"},C4={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",replay:"replay",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 Y0($){return $==="en"?C4:M4}var P4="lw-debug-toasts",q4=6000,B4=`
|
|
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
|
-
`,k0=null;function N4(){if(typeof document>"u")return null;if(k0?.isConnected)return k0;let $=document.createElement(C4);$.dataset.debugReporter="true";let J=$.attachShadow({mode:"open"}),Q=document.createElement("style");Q.textContent=B4;let j=document.createElement("div");return j.className="stack",j.setAttribute("role","status"),j.setAttribute("aria-live","polite"),J.append(Q,j),document.body.append($),k0=j,j}function a($,J="success",Q){let j=j0()?w().toast:void 0;if(j){j({message:$,tone:J,...Q?{action:Q}:{}});return}let z=N4();if(!z)return;let K=document.createElement("div");K.className="toast",K.dataset.tone=J;let W=document.createElement("span");W.className="dot";let Y=document.createElement("span");Y.textContent=$;let H=document.createElement("button");H.type="button",H.className="close",H.textContent="✕",H.setAttribute("aria-label","ปิด");let I=()=>{window.clearTimeout(k),K.remove()};H.addEventListener("click",I);let k=J==="error"||Q?0:window.setTimeout(I,q4);if(K.append(W,Y),Q){let M=document.createElement("button");M.type="button",M.className="action",M.textContent=Q.label,M.addEventListener("click",()=>{I(),Q.onClick()}),K.append(M)}K.append(H),z.append(K)}function x1($,J,Q){let j=$.filter((K)=>Boolean(K.error)||K.status!=null&&K.status>=400).slice(-20).map((K)=>({method:K.method,url:K.url,status:K.status,error:K.error,at:K.startedAt})),z=J.filter((K)=>K.level==="error"||K.level==="exception"||K.level==="unhandledrejection").slice(-20).map((K)=>K.message);return{failedRequests:j,errors:z,erroredQueries:Q.slice(0,20)}}function D4(){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[Q]=performance.getEntriesByType("navigation");if(Q)$.domContentLoadedMs=Math.round(Q.domContentLoadedEventEnd),$.loadEventMs=Math.round(Q.loadEventEnd);return $}function S0($,J){if(!$)return J;try{return $()}catch{return J}}function E1(){let $=w(),{pathname:J,search:Q,href:j}=window.location;return{capturedAt:new Date().toISOString(),route:{href:j,pathname:J,search:Q},module:y0(J),user:S0($.user,{}),apiHeaders:l(S0($.headers,{})),app:{name:p().name,version:p().version,environment:p().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:D4(),extra:S0($.extra,{})}}var w4=2;function h1($){let J=R1(),Q=K1();return{context:E1(),reason:$.reason,note:$.note,cause:x1(J,Q,$.erroredQueries),actionTrail:$1(),network:J,console:Q,screenshotDataUrl:$.screenshotDataUrl,screenshotMethod:$.screenshotMethod,replay:A1()??void 0,meta:{generatedBy:"lightwork-debug-capture",schemaVersion:w4}}}async function m1(){if(typeof navigator<"u"&&Boolean(navigator.mediaDevices?.getDisplayMedia)){let Q=await k4();if(Q.status==="ok")return{dataUrl:Q.dataUrl,method:"display-media"};if(Q.status==="cancelled")return{dataUrl:null,method:"cancelled"}}let J=await R4();if(J)return{dataUrl:J,method:"html-to-image"};return{dataUrl:null,method:"none"}}async function k4(){let $=null;try{let J={video:{frameRate:30},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude"};$=await navigator.mediaDevices.getDisplayMedia(J);let Q=await S4($);return Q?{status:"ok",dataUrl:Q}:{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 S4($){let J=document.createElement("video");J.srcObject=$,J.muted=!0,J.playsInline=!0,await new Promise((W)=>{let Y=!1,H=()=>{if(Y)return;Y=!0,W()};J.onloadedmetadata=()=>{J.play().then(H).catch(H)},window.setTimeout(H,1500)}),await O4(J);let{videoWidth:Q,videoHeight:j}=J;if(!Q||!j)return null;let z=document.createElement("canvas");z.width=Q,z.height=j;let K=z.getContext("2d");if(!K)return null;K.drawImage(J,0,0,Q,j),J.pause(),J.srcObject=null;try{return z.toDataURL("image/png")}catch{return null}}function O4($){return new Promise((J)=>{let Q=!1,j=()=>{if(Q)return;Q=!0,J()},z=$;if(typeof z.requestVideoFrameCallback==="function")z.requestVideoFrameCallback(()=>j()),window.setTimeout(j,1000);else window.setTimeout(j,250)})}async function R4(){let $=w().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:(Q)=>!(Q instanceof HTMLElement&&Q.dataset?.debugReporter==="true")})}catch{return null}}var _4=2000,T4=0.82,L4=3000000;function f4($){return new Promise((J,Q)=>{let j=new Image;j.onload=()=>J(j),j.onerror=()=>Q(Error("could not read the screenshot")),j.src=$})}async function g1($){try{let J=await f4($),Q=Math.max(J.naturalWidth,J.naturalHeight),j=Math.min(1,_4/Q),z=document.createElement("canvas");z.width=Math.max(1,Math.round(J.naturalWidth*j)),z.height=Math.max(1,Math.round(J.naturalHeight*j));let K=z.getContext("2d");if(!K)return $;K.fillStyle="#fff",K.fillRect(0,0,z.width,z.height),K.drawImage(J,0,0,z.width,z.height);let W=T4,Y=z.toDataURL("image/jpeg",W);while(Y.length>L4&&W>0.4)W-=0.15,Y=z.toDataURL("image/jpeg",W);return Y}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,x4=/^\d+$/,E4=/^[0-9a-f]{16,}$/i;function p1($){if($.reason.type==="manual")return null;let J=$.cause?.failedRequests?.[0];if(!J?.url)return null;let Q;try{Q=new URL(J.url,"http://x").pathname}catch{Q=J.url}let j=Q.split("/").map((K)=>A4.test(K)||x4.test(K)||E4.test(K)?":id":K).join("/"),z=J.status??(J.error?"ERR":"?");return`${J.method??"REQ"} ${j} ${z}`}var y1=2000000;function F0($){let{screenshotDataUrl:J,replay:Q,...j}=$;return JSON.stringify(j).length}function b1($,J=2000000){if(F0($)<=J)return $;let Q=$.network.map((z)=>({...z})),j={...$,network:Q};for(let z of Q){if(F0(j)<=J)return j;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(j.network.length>1&&F0(j)>J)j.network=j.network.slice(1);while(j.console.length>1&&F0(j)>J)j.console=j.console.slice(1);return j}function t($){let J="";for(let Q=0;Q<$.length;Q+=32768)J+=String.fromCharCode(...$.subarray(Q,Q+32768));return btoa(J)}var h4=4,m4=2,g4=3,p4=0,y4=new Set(["href","src","action","formaction","xlink:href","data","poster","srcset"]);function v1($){if(!$)return;for(let J of Object.keys($)){let Q=$[J];if(typeof Q!=="string"||!y4.has(J)||!Q.includes("?"))continue;$[J]=E(Q)}}function O0($){if(!$)return;v1($.attributes);for(let J of $.childNodes??[])O0(J)}function u1($){let J=JSON.parse(JSON.stringify($));for(let Q of J){let j=Q.data;if(!j||typeof j!=="object")continue;if(Q.type===h4&&typeof j.href==="string")j.href=E(j.href);else if(Q.type===m4)O0(j.node);else if(Q.type===g4&&j.source===p4){for(let z of j.adds??[])O0(z.node);for(let z of j.attributes??[])v1(z.attributes)}}return J}var b4="session-replay.json.gz",v4="session-replay.json";function u4($){return Boolean($&&$.events.length>0)}async function d4($){if(typeof CompressionStream>"u")return null;try{let J=new Blob([$]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(J).arrayBuffer())}catch{return null}}async function d1($,J){if(!u4($))return{summary:{omitted:"empty"}};let j={seconds:Math.round($.durationMs/1000),events:$.events.length,startedAt:$.startedAt,endedAt:$.endedAt},z=new TextEncoder().encode(JSON.stringify({events:u1($.events)})),K=await d4(z),W=K??z;if(W.byteLength>J)return{summary:{...j,bytes:W.byteLength,omitted:"too-large"}};let Y=K!==null;return{dataUri:`data:${Y?"application/gzip":"application/json"};base64,${t(W)}`,filename:Y?b4:v4,summary:{...j,bytes:W.byteLength,compressed:Y}}}function i4($){let{screenshotDataUrl:J,replay:Q,...j}=$;return{dataUri:`data:application/json;base64,${t(new TextEncoder().encode(JSON.stringify(j)))}`,filename:"debug-bundle.json"}}async function c4(){let $=w().identity;if(!$)return{};try{let J=await $();return J?{authorization:`Bearer ${J}`}:{}}catch{return{}}}async function i1($,J){let Q=w(),j=b1(J,y1),{context:z,note:K}=j,W=[];if(j.screenshotDataUrl){let P=await g1(j.screenshotDataUrl);W.push({dataUri:P,filename:"screenshot.jpg"})}W.push(i4(j));let Y,H=i();if(H)if(j.replay===null)Y={omitted:"declined"};else{let P=await d1(j.replay,H.maxBytes);if(Y=P.summary,"dataUri"in P)W.push({dataUri:P.dataUri,filename:P.filename})}let I=p1(j),k={title:$,description:K.trim()||void 0,appName:p().name,category:z.module?.label,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:j.reason.type,appName:p().name,module:z.module?.label??""},context:{...I?{signature:I}:{},capturedAt:z.capturedAt,reason:j.reason,cause:j.cause,actionTrail:j.actionTrail,client:z.client,performance:z.performance,apiHeaders:z.apiHeaders,extra:z.extra,counts:{network:j.network.length,console:j.console.length,actions:j.actionTrail.length},screenshotMethod:j.screenshotMethod,...Y?{replay:Y}:{}},attachments:W},M=await fetch(`${Q.host.replace(/\/$/,"")}/ingest/tickets`,{method:"POST",headers:{"content-type":"application/json","x-realm-key":Q.realmKey,...await c4()},body:JSON.stringify(k)});if(!M.ok){let P=M.headers.get("retry-after"),B=await M.json().then((N)=>N.error).catch(()=>null);throw Error(M.status===429?`Too many reports — try again in ${P??"a moment"}s`:B??`Report failed (${M.status})`)}return await M.json()}var e=Math.PI/6;function c1($,J,Q){let j=J.x-$.x,z=J.y-$.y,K=Math.hypot(j,z),W=Math.atan2(z,j),Y=[{x:J.x,y:J.y},{x:J.x-Q*Math.cos(W-e),y:J.y-Q*Math.sin(W-e)},{x:J.x-Q*Math.cos(W+e),y:J.y-Q*Math.sin(W+e)}],H=Q*Math.cos(e)*0.92;if(K<=H)return{shaft:null,head:Y};return{shaft:{from:$,to:{x:J.x-H*Math.cos(W),y:J.y-H*Math.sin(W)}},head:Y}}var R0="#f44336",o4="rgba(250, 204, 21, 0.4)",_0=22,o1="#2563eb",l1=9,r1=11,s1=18,n1=4,H0=8,l4=[{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 a1($,J,Q){let j=[],z=null,K=-1,W=null,Y=null,H=$.getContext("2d");function I(){let Z=$.getBoundingClientRect().width;return Z>0?$.width/Z:1}function k(Z){let V=$.getBoundingClientRect();return{x:(Z.clientX-V.left)/V.width*$.width,y:(Z.clientY-V.top)/V.height*$.height}}function M(Z){let V=Z.size??_0;if(!H)return(Z.text?.length??0)*V*0.6;H.save(),H.font=`600 ${V}px system-ui, sans-serif`;let X=H.measureText(Z.text??"").width;return H.restore(),X}function P(Z){if(Z.tool==="text"){let V=Z.size??_0;return{left:Z.x1,top:Z.y1,right:Z.x1+M(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 B(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 l4.map((X)=>({id:X.id,x:V.left+(V.right-V.left)*X.fx,y:V.top+(V.bottom-V.top)*X.fy,cursor:X.cursor}))}function N(Z){let V=P(Z);return{x:V.right+s1*I(),y:V.top-s1*I()}}function h(Z,V,X){let{shaft:G,head:F}=c1({x:V.x1,y:V.y1},{x:V.x2,y:V.y2},Math.max(10,16*X));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(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 O(Z,V,X){Z.save(),Z.lineWidth=Math.max(2,3*X),Z.strokeStyle=R0,Z.fillStyle=R0;let G=P(V);if(V.tool==="rect")Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(V.tool==="arrow")h(Z,V,X);else if(V.tool==="highlight")Z.fillStyle=o4,Z.fillRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(V.tool==="text"&&V.text){let F=V.size??_0;Z.font=`600 ${F}px system-ui, sans-serif`,Z.textBaseline="top";let U=F*0.22;Z.fillStyle="rgba(255,255,255,0.92)",Z.fillRect(G.left-U,G.top-U,G.right-G.left+U*2,G.bottom-G.top+U*2),Z.fillStyle=R0,Z.fillText(V.text,G.left,G.top)}Z.restore()}function A(Z,V,X){let G=P(V);Z.save(),Z.strokeStyle=o1,Z.lineWidth=Math.max(1,1.5*X),Z.setLineDash([6*X,4*X]),Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top),Z.setLineDash([]);let F=l1*X;for(let R of B(V))Z.fillStyle="#fff",Z.strokeStyle=o1,Z.lineWidth=Math.max(1,1.5*X),Z.beginPath(),Z.rect(R.x-F/2,R.y-F/2,F,F),Z.fill(),Z.stroke();let U=N(V),C=r1*X;Z.beginPath(),Z.arc(U.x,U.y,C,0,Math.PI*2),Z.fillStyle="#dc2626",Z.fill(),Z.strokeStyle="#fff",Z.lineWidth=Math.max(1.5,2*X),Z.beginPath(),Z.moveTo(U.x-C*0.4,U.y-C*0.4),Z.lineTo(U.x+C*0.4,U.y+C*0.4),Z.moveTo(U.x+C*0.4,U.y-C*0.4),Z.lineTo(U.x-C*0.4,U.y+C*0.4),Z.stroke(),Z.restore()}function D(){if(!H)return;let Z=I();if(H.clearRect(0,0,$.width,$.height),H.drawImage(J,0,0,$.width,$.height),j.forEach((X,G)=>{if(G!==J0)O(H,X,Z)}),W)O(H,W,Z);let V=j[K];if(V&&!W)A(H,V,Z)}function u(Z,V,X,G,F){return Math.abs(Z-X)<=F&&Math.abs(V-G)<=F}function L0(Z,V){let X=j[K];if(!X)return null;let G=l1*I()/2+3*I();for(let F of B(X))if(u(Z,V,F.x,F.y,G))return F.id;return null}function f0(Z,V){let X=j[K];if(!X)return!1;let G=N(X);return u(Z,V,G.x,G.y,r1*I())}function U0(Z,V){let X=6*I();for(let G=j.length-1;G>=0;G-=1){let F=j[G];if(F.tool==="arrow"){let C=F.x2-F.x1,R=F.y2-F.y1,m=Math.hypot(C,R)||1,g=Math.max(0,Math.min(1,((Z-F.x1)*C+(V-F.y1)*R)/(m*m)));if(Math.hypot(Z-(F.x1+g*C),V-(F.y1+g*R))<=X+4*I())return G;continue}let U=P(F);if(Z>=U.left-X&&Z<=U.right+X&&V>=U.top-X&&V<=U.bottom+X)return G}return-1}function j2(Z,V,X,G,F){if(V==="tail"){Z.x1=X.x1+G,Z.y1=X.y1+F;return}if(V==="head"){Z.x2=X.x2+G,Z.y2=X.y2+F;return}if(V==="size"){let W2=(X.size??24)+F;Z.size=Math.max(10,W2);return}let U=P(X),{left:C,top:R,right:m,bottom:g}=U;if(V.includes("w"))C=Math.min(m-H0,C+G);if(V.includes("e"))m=Math.max(C+H0,m+G);if(V.includes("n"))R=Math.min(g-H0,R+F);if(V.includes("s"))g=Math.max(R+H0,g+F);Z.x1=C,Z.y1=R,Z.x2=m,Z.y2=g}function z2(Z,V,X,G){Z.x1=V.x1+X,Z.y1=V.y1+G,Z.x2=V.x2+X,Z.y2=V.y2+G}let L=null,J0=-1,f={x:0,y:0,size:24};function Z2(){let Z=$.getBoundingClientRect().width;return Z>0?Z/$.width:1}function K2(Z,V){if(!H)return Z.length*V*0.6;H.save(),H.font=`600 ${V}px system-ui, sans-serif`;let X=H.measureText(Z||" ").width;return H.restore(),X}function A0(){if(!L)return;let Z=$.parentElement;if(!Z)return;let V=$.getBoundingClientRect(),X=Z.getBoundingClientRect(),G=Z2(),F=f.size*G;L.style.left=`${V.left-X.left+f.x*G}px`,L.style.top=`${V.top-X.top+f.y*G}px`,L.style.fontSize=`${F}px`,L.style.width=`${Math.max(40,K2(L.value,F)+F)}px`}function d(Z){let V=L;if(!V)return;L=null;let X=V.value.trim(),G=J0;if(J0=-1,V.remove(),Z&&X){if(G>=0&&j[G])j[G].text=X,K=G;else j.push({tool:"text",x1:f.x,y1:f.y,x2:f.x,y2:f.y,text:X,size:f.size}),K=j.length-1;Q()}else if(G>=0)K=G;$.focus(),D()}function x0(Z,V,X=-1){d(!0);let G=$.parentElement;if(!G)return;if(getComputedStyle(G).position==="static")G.style.position="relative";let F=X>=0?j[X]:void 0;J0=X,f={x:F?.x1??Z,y:F?.y1??V,size:F?.size??Math.round(24*I())};let U=document.createElement("input");U.type="text",U.className="text-edit",U.value=F?.text??"",U.setAttribute("aria-label","ข้อความบนภาพ"),U.placeholder="ข้อความ",L=U,G.append(U),A0(),U.addEventListener("input",A0),U.addEventListener("keydown",(C)=>{if(C.stopPropagation(),C.key==="Enter")d(!0);else if(C.key==="Escape")d(!1)}),requestAnimationFrame(()=>{if(L!==U)return;U.focus(),U.select(),U.addEventListener("blur",()=>d(!0))}),D()}function E0(Z){let{x:V,y:X}=k(Z);if($.setPointerCapture(Z.pointerId),f0(V,X)){I0();return}let G=L0(V,X);if(G&&j[K]){Y={grip:G,x:V,y:X,start:{...j[K]}};return}if(z==="text"){if(Z.preventDefault(),$.hasPointerCapture(Z.pointerId))$.releasePointerCapture(Z.pointerId);z=null,Q(),x0(V,X);return}if(z){W={tool:z,x1:V,y1:X,x2:V,y2:X},K=-1;return}let F=U0(V,X);K=F,Y=F>=0?{grip:"body",x:V,y:X,start:{...j[F]}}:null,D()}function h0(Z){let{x:V,y:X}=k(Z);if(W){W.x2=V,W.y2=X,D();return}if(Y){let F=j[K];if(!F)return;let U=V-Y.x,C=X-Y.y;if(Y.grip==="body")z2(F,Y.start,U,C);else j2(F,Y.grip,Y.start,U,C);D();return}if(z){$.style.cursor="crosshair";return}if(f0(V,X)){$.style.cursor="pointer";return}let G=L0(V,X);if(G){let F=j[K]?B(j[K]).find((U)=>U.id===G):null;$.style.cursor=F?.cursor??"pointer";return}$.style.cursor=U0(V,X)>=0?"move":"default"}function Q0(){if(W){if(!(Math.abs(W.x2-W.x1)<n1&&Math.abs(W.y2-W.y1)<n1))j.push(W),K=j.length-1,z=null,Q();W=null}if(Y)Y=null,Q();D()}function m0(Z){let V=$.getBoundingClientRect(),X=(Z.clientX-V.left)/V.width*$.width,G=(Z.clientY-V.top)/V.height*$.height,F=U0(X,G),U=j[F];if(!U||U.tool!=="text")return;Z.preventDefault(),x0(U.x1,U.y1,F)}function g0(Z){if(K<0)return;if(Z.key==="Delete"||Z.key==="Backspace")Z.preventDefault(),I0();else if(Z.key==="Escape")K=-1,D()}function I0(){if(K<0)return;j.splice(K,1),K=-1,Q(),D()}return $.addEventListener("pointerdown",E0),$.addEventListener("pointermove",h0),$.addEventListener("pointerup",Q0),$.addEventListener("pointercancel",Q0),$.addEventListener("dblclick",m0),$.tabIndex=0,$.addEventListener("keydown",g0),D(),{setTool(Z){z=Z,K=-1,$.style.cursor=Z?"crosshair":"default",D()},deleteSelected:I0,clear(){j.length=0,K=-1,Q(),D()},hasShapes:()=>j.length>0,hasSelection:()=>K>=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 X=I();for(let G of j)O(V,G,X);return Z.toDataURL("image/png")},destroy(){d(!1),$.removeEventListener("pointerdown",E0),$.removeEventListener("pointermove",h0),$.removeEventListener("pointerup",Q0),$.removeEventListener("pointercancel",Q0),$.removeEventListener("dblclick",m0),$.removeEventListener("keydown",g0)}}}var t1=`
|
|
33
|
+
`,w0=null;function N4(){if(typeof document>"u")return null;if(w0?.isConnected)return w0;let $=document.createElement(P4);$.dataset.debugReporter="true";let J=$.attachShadow({mode:"open"}),Q=document.createElement("style");Q.textContent=B4;let j=document.createElement("div");return j.className="stack",j.setAttribute("role","status"),j.setAttribute("aria-live","polite"),J.append(Q,j),document.body.append($),w0=j,j}function s($,J="success",Q){let j=j0()?N().toast:void 0;if(j){j({message:$,tone:J,...Q?{action:Q}:{}});return}let z=N4();if(!z)return;let K=document.createElement("div");K.className="toast",K.dataset.tone=J;let W=document.createElement("span");W.className="dot";let Y=document.createElement("span");Y.textContent=$;let H=document.createElement("button");H.type="button",H.className="close",H.textContent="✕",H.setAttribute("aria-label","ปิด");let I=()=>{window.clearTimeout(w),K.remove()};H.addEventListener("click",I);let w=J==="error"||Q?0:window.setTimeout(I,q4);if(K.append(W,Y),Q){let M=document.createElement("button");M.type="button",M.className="action",M.textContent=Q.label,M.addEventListener("click",()=>{I(),Q.onClick()}),K.append(M)}K.append(H),z.append(K)}function x1($,J,Q){let j=$.filter((K)=>Boolean(K.error)||K.status!=null&&K.status>=400).slice(-20).map((K)=>({method:K.method,url:K.url,status:K.status,error:K.error,at:K.startedAt})),z=J.filter((K)=>K.level==="error"||K.level==="exception"||K.level==="unhandledrejection").slice(-20).map((K)=>K.message);return{failedRequests:j,errors:z,erroredQueries:Q.slice(0,20)}}function D4(){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[Q]=performance.getEntriesByType("navigation");if(Q)$.domContentLoadedMs=Math.round(Q.domContentLoadedEventEnd),$.loadEventMs=Math.round(Q.loadEventEnd);return $}function k0($,J){if(!$)return J;try{return $()}catch{return J}}function E1(){let $=N(),{pathname:J,search:Q,href:j}=window.location;return{capturedAt:new Date().toISOString(),route:{href:j,pathname:J,search:Q},module:p0(J),user:k0($.user,{}),apiHeaders:c(k0($.headers,{})),app:{name:g().name,version:g().version,environment:g().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:D4(),extra:k0($.extra,{})}}var w4=2;function h1($){let J=R1(),Q=K1();return{context:E1(),reason:$.reason,note:$.note,cause:x1(J,Q,$.erroredQueries),actionTrail:$1(),network:J,console:Q,screenshotDataUrl:$.screenshotDataUrl,screenshotMethod:$.screenshotMethod,replay:f1()??void 0,meta:{generatedBy:"lightwork-debug-capture",schemaVersion:w4}}}async function m1(){if(typeof navigator<"u"&&Boolean(navigator.mediaDevices?.getDisplayMedia)){let Q=await k4();if(Q.status==="ok")return{dataUrl:Q.dataUrl,method:"display-media"};if(Q.status==="cancelled")return{dataUrl:null,method:"cancelled"}}let J=await R4();if(J)return{dataUrl:J,method:"html-to-image"};return{dataUrl:null,method:"none"}}async function k4(){let $=null;try{let J={video:{frameRate:30},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude"};$=await navigator.mediaDevices.getDisplayMedia(J);let Q=await S4($);return Q?{status:"ok",dataUrl:Q}:{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 S4($){let J=document.createElement("video");J.srcObject=$,J.muted=!0,J.playsInline=!0,await new Promise((W)=>{let Y=!1,H=()=>{if(Y)return;Y=!0,W()};J.onloadedmetadata=()=>{J.play().then(H).catch(H)},window.setTimeout(H,1500)}),await O4(J);let{videoWidth:Q,videoHeight:j}=J;if(!Q||!j)return null;let z=document.createElement("canvas");z.width=Q,z.height=j;let K=z.getContext("2d");if(!K)return null;K.drawImage(J,0,0,Q,j),J.pause(),J.srcObject=null;try{return z.toDataURL("image/png")}catch{return null}}function O4($){return new Promise((J)=>{let Q=!1,j=()=>{if(Q)return;Q=!0,J()},z=$;if(typeof z.requestVideoFrameCallback==="function")z.requestVideoFrameCallback(()=>j()),window.setTimeout(j,1000);else window.setTimeout(j,250)})}async function R4(){let $=N().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:(Q)=>!(Q instanceof HTMLElement&&Q.dataset?.debugReporter==="true")})}catch{return null}}var _4=2000,T4=0.82,L4=3000000;function A4($){return new Promise((J,Q)=>{let j=new Image;j.onload=()=>J(j),j.onerror=()=>Q(Error("could not read the screenshot")),j.src=$})}async function g1($){try{let J=await A4($),Q=Math.max(J.naturalWidth,J.naturalHeight),j=Math.min(1,_4/Q),z=document.createElement("canvas");z.width=Math.max(1,Math.round(J.naturalWidth*j)),z.height=Math.max(1,Math.round(J.naturalHeight*j));let K=z.getContext("2d");if(!K)return $;K.fillStyle="#fff",K.fillRect(0,0,z.width,z.height),K.drawImage(J,0,0,z.width,z.height);let W=T4,Y=z.toDataURL("image/jpeg",W);while(Y.length>L4&&W>0.4)W-=0.15,Y=z.toDataURL("image/jpeg",W);return Y}catch{return $}}var f4=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,x4=/^\d+$/,E4=/^[0-9a-f]{16,}$/i;function y1($){if($.reason.type==="manual")return null;let J=$.cause?.failedRequests?.[0];if(!J?.url)return null;let Q;try{Q=new URL(J.url,"http://x").pathname}catch{Q=J.url}let j=Q.split("/").map((K)=>f4.test(K)||x4.test(K)||E4.test(K)?":id":K).join("/"),z=J.status??(J.error?"ERR":"?");return`${J.method??"REQ"} ${j} ${z}`}var p1=2000000;function F0($){let{screenshotDataUrl:J,replay:Q,...j}=$;return JSON.stringify(j).length}function b1($,J=2000000){if(F0($)<=J)return $;let Q=$.network.map((z)=>({...z})),j={...$,network:Q};for(let z of Q){if(F0(j)<=J)return j;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(j.network.length>1&&F0(j)>J)j.network=j.network.slice(1);while(j.console.length>1&&F0(j)>J)j.console=j.console.slice(1);return j}function n($){let J="";for(let Q=0;Q<$.length;Q+=32768)J+=String.fromCharCode(...$.subarray(Q,Q+32768));return btoa(J)}var h4=4,m4=2,g4=3,y4=0,p4=new Set(["href","src","action","formaction","xlink:href","data","poster","srcset"]);function v1($){if(!$)return;for(let J of Object.keys($)){let Q=$[J];if(typeof Q!=="string"||!p4.has(J)||!Q.includes("?"))continue;$[J]=E(Q)}}function S0($){if(!$)return;v1($.attributes);for(let J of $.childNodes??[])S0(J)}function u1($){let J=JSON.parse(JSON.stringify($));for(let Q of J){let j=Q.data;if(!j||typeof j!=="object")continue;if(Q.type===h4&&typeof j.href==="string")j.href=E(j.href);else if(Q.type===m4)S0(j.node);else if(Q.type===g4&&j.source===y4){for(let z of j.adds??[])S0(z.node);for(let z of j.attributes??[])v1(z.attributes)}}return J}var b4="session-replay.json.gz",v4="session-replay.json";function u4($){return Boolean($&&$.events.length>0)}async function d4($){if(typeof CompressionStream>"u")return null;try{let J=new Blob([$]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(J).arrayBuffer())}catch{return null}}async function d1($,J){if(!u4($))return{summary:{omitted:"empty"}};let j={seconds:Math.round($.durationMs/1000),events:$.events.length,startedAt:$.startedAt,endedAt:$.endedAt},z=new TextEncoder().encode(JSON.stringify({events:u1($.events)})),K=await d4(z),W=K??z;if(W.byteLength>J)return{summary:{...j,bytes:W.byteLength,omitted:"too-large"}};let Y=K!==null;return{dataUri:`data:${Y?"application/gzip":"application/json"};base64,${n(W)}`,filename:Y?b4:v4,summary:{...j,bytes:W.byteLength,compressed:Y}}}function i4($){let{screenshotDataUrl:J,replay:Q,...j}=$;return{dataUri:`data:application/json;base64,${n(new TextEncoder().encode(JSON.stringify(j)))}`,filename:"debug-bundle.json"}}async function c4(){let $=N().identity;if(!$)return{};try{let J=await $();return J?{authorization:`Bearer ${J}`}:{}}catch{return{}}}async function i1($,J){let Q=N(),j=b1(J,p1),{context:z,note:K}=j,W=[];if(j.screenshotDataUrl){let C=await g1(j.screenshotDataUrl);W.push({dataUri:C,filename:"screenshot.jpg"})}W.push(i4(j));let Y,H=u();if(H){let C=await d1(j.replay,H.maxBytes);if(Y=C.summary,"dataUri"in C)W.push({dataUri:C.dataUri,filename:C.filename})}let I=y1(j),w={title:$,description:K.trim()||void 0,appName:g().name,category:z.module?.label,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:j.reason.type,appName:g().name,module:z.module?.label??""},context:{...I?{signature:I}:{},capturedAt:z.capturedAt,reason:j.reason,cause:j.cause,actionTrail:j.actionTrail,client:z.client,performance:z.performance,apiHeaders:z.apiHeaders,extra:z.extra,counts:{network:j.network.length,console:j.console.length,actions:j.actionTrail.length},screenshotMethod:j.screenshotMethod,...Y?{replay:Y}:{}},attachments:W},M=await fetch(`${Q.host.replace(/\/$/,"")}/ingest/tickets`,{method:"POST",headers:{"content-type":"application/json","x-realm-key":Q.realmKey,...await c4()},body:JSON.stringify(w)});if(!M.ok){let C=M.headers.get("retry-after"),k=await M.json().then((q)=>q.error).catch(()=>null);throw Error(M.status===429?`Too many reports — try again in ${C??"a moment"}s`:k??`Report failed (${M.status})`)}return await M.json()}var a=Math.PI/6;function c1($,J,Q){let j=J.x-$.x,z=J.y-$.y,K=Math.hypot(j,z),W=Math.atan2(z,j),Y=[{x:J.x,y:J.y},{x:J.x-Q*Math.cos(W-a),y:J.y-Q*Math.sin(W-a)},{x:J.x-Q*Math.cos(W+a),y:J.y-Q*Math.sin(W+a)}],H=Q*Math.cos(a)*0.92;if(K<=H)return{shaft:null,head:Y};return{shaft:{from:$,to:{x:J.x-H*Math.cos(W),y:J.y-H*Math.sin(W)}},head:Y}}var O0="#f44336",o4="rgba(250, 204, 21, 0.4)",R0=22,o1="#2563eb",l1=9,r1=11,s1=18,n1=4,H0=8,l4=[{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 a1($,J,Q){let j=[],z=null,K=-1,W=null,Y=null,H=$.getContext("2d");function I(){let Z=$.getBoundingClientRect().width;return Z>0?$.width/Z:1}function w(Z){let V=$.getBoundingClientRect();return{x:(Z.clientX-V.left)/V.width*$.width,y:(Z.clientY-V.top)/V.height*$.height}}function M(Z){let V=Z.size??R0;if(!H)return(Z.text?.length??0)*V*0.6;H.save(),H.font=`600 ${V}px system-ui, sans-serif`;let X=H.measureText(Z.text??"").width;return H.restore(),X}function C(Z){if(Z.tool==="text"){let V=Z.size??R0;return{left:Z.x1,top:Z.y1,right:Z.x1+M(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 k(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=C(Z);if(Z.tool==="text")return[{id:"size",x:V.right,y:V.bottom,cursor:"nwse-resize"}];return l4.map((X)=>({id:X.id,x:V.left+(V.right-V.left)*X.fx,y:V.top+(V.bottom-V.top)*X.fy,cursor:X.cursor}))}function q(Z){let V=C(Z);return{x:V.right+s1*I(),y:V.top-s1*I()}}function S(Z,V,X){let{shaft:G,head:F}=c1({x:V.x1,y:V.y1},{x:V.x2,y:V.y2},Math.max(10,16*X));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(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 L(Z,V,X){Z.save(),Z.lineWidth=Math.max(2,3*X),Z.strokeStyle=O0,Z.fillStyle=O0;let G=C(V);if(V.tool==="rect")Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(V.tool==="arrow")S(Z,V,X);else if(V.tool==="highlight")Z.fillStyle=o4,Z.fillRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(V.tool==="text"&&V.text){let F=V.size??R0;Z.font=`600 ${F}px system-ui, sans-serif`,Z.textBaseline="top";let U=F*0.22;Z.fillStyle="rgba(255,255,255,0.92)",Z.fillRect(G.left-U,G.top-U,G.right-G.left+U*2,G.bottom-G.top+U*2),Z.fillStyle=O0,Z.fillText(V.text,G.left,G.top)}Z.restore()}function e(Z,V,X){let G=C(V);Z.save(),Z.strokeStyle=o1,Z.lineWidth=Math.max(1,1.5*X),Z.setLineDash([6*X,4*X]),Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top),Z.setLineDash([]);let F=l1*X;for(let R of k(V))Z.fillStyle="#fff",Z.strokeStyle=o1,Z.lineWidth=Math.max(1,1.5*X),Z.beginPath(),Z.rect(R.x-F/2,R.y-F/2,F,F),Z.fill(),Z.stroke();let U=q(V),P=r1*X;Z.beginPath(),Z.arc(U.x,U.y,P,0,Math.PI*2),Z.fillStyle="#dc2626",Z.fill(),Z.strokeStyle="#fff",Z.lineWidth=Math.max(1.5,2*X),Z.beginPath(),Z.moveTo(U.x-P*0.4,U.y-P*0.4),Z.lineTo(U.x+P*0.4,U.y+P*0.4),Z.moveTo(U.x+P*0.4,U.y-P*0.4),Z.lineTo(U.x-P*0.4,U.y+P*0.4),Z.stroke(),Z.restore()}function B(){if(!H)return;let Z=I();if(H.clearRect(0,0,$.width,$.height),H.drawImage(J,0,0,$.width,$.height),j.forEach((X,G)=>{if(G!==$0)L(H,X,Z)}),W)L(H,W,Z);let V=j[K];if(V&&!W)e(H,V,Z)}function T0(Z,V,X,G,F){return Math.abs(Z-X)<=F&&Math.abs(V-G)<=F}function L0(Z,V){let X=j[K];if(!X)return null;let G=l1*I()/2+3*I();for(let F of k(X))if(T0(Z,V,F.x,F.y,G))return F.id;return null}function A0(Z,V){let X=j[K];if(!X)return!1;let G=q(X);return T0(Z,V,G.x,G.y,r1*I())}function U0(Z,V){let X=6*I();for(let G=j.length-1;G>=0;G-=1){let F=j[G];if(F.tool==="arrow"){let P=F.x2-F.x1,R=F.y2-F.y1,h=Math.hypot(P,R)||1,m=Math.max(0,Math.min(1,((Z-F.x1)*P+(V-F.y1)*R)/(h*h)));if(Math.hypot(Z-(F.x1+m*P),V-(F.y1+m*R))<=X+4*I())return G;continue}let U=C(F);if(Z>=U.left-X&&Z<=U.right+X&&V>=U.top-X&&V<=U.bottom+X)return G}return-1}function j2(Z,V,X,G,F){if(V==="tail"){Z.x1=X.x1+G,Z.y1=X.y1+F;return}if(V==="head"){Z.x2=X.x2+G,Z.y2=X.y2+F;return}if(V==="size"){let W2=(X.size??24)+F;Z.size=Math.max(10,W2);return}let U=C(X),{left:P,top:R,right:h,bottom:m}=U;if(V.includes("w"))P=Math.min(h-H0,P+G);if(V.includes("e"))h=Math.max(P+H0,h+G);if(V.includes("n"))R=Math.min(m-H0,R+F);if(V.includes("s"))m=Math.max(R+H0,m+F);Z.x1=P,Z.y1=R,Z.x2=h,Z.y2=m}function z2(Z,V,X,G){Z.x1=V.x1+X,Z.y1=V.y1+G,Z.x2=V.x2+X,Z.y2=V.y2+G}let A=null,$0=-1,f={x:0,y:0,size:24};function Z2(){let Z=$.getBoundingClientRect().width;return Z>0?Z/$.width:1}function K2(Z,V){if(!H)return Z.length*V*0.6;H.save(),H.font=`600 ${V}px system-ui, sans-serif`;let X=H.measureText(Z||" ").width;return H.restore(),X}function f0(){if(!A)return;let Z=$.parentElement;if(!Z)return;let V=$.getBoundingClientRect(),X=Z.getBoundingClientRect(),G=Z2(),F=f.size*G;A.style.left=`${V.left-X.left+f.x*G}px`,A.style.top=`${V.top-X.top+f.y*G}px`,A.style.fontSize=`${F}px`,A.style.width=`${Math.max(40,K2(A.value,F)+F)}px`}function v(Z){let V=A;if(!V)return;A=null;let X=V.value.trim(),G=$0;if($0=-1,V.remove(),Z&&X){if(G>=0&&j[G])j[G].text=X,K=G;else j.push({tool:"text",x1:f.x,y1:f.y,x2:f.x,y2:f.y,text:X,size:f.size}),K=j.length-1;Q()}else if(G>=0)K=G;$.focus(),B()}function x0(Z,V,X=-1){v(!0);let G=$.parentElement;if(!G)return;if(getComputedStyle(G).position==="static")G.style.position="relative";let F=X>=0?j[X]:void 0;$0=X,f={x:F?.x1??Z,y:F?.y1??V,size:F?.size??Math.round(24*I())};let U=document.createElement("input");U.type="text",U.className="text-edit",U.value=F?.text??"",U.setAttribute("aria-label","ข้อความบนภาพ"),U.placeholder="ข้อความ",A=U,G.append(U),f0(),U.addEventListener("input",f0),U.addEventListener("keydown",(P)=>{if(P.stopPropagation(),P.key==="Enter")v(!0);else if(P.key==="Escape")v(!1)}),requestAnimationFrame(()=>{if(A!==U)return;U.focus(),U.select(),U.addEventListener("blur",()=>v(!0))}),B()}function E0(Z){let{x:V,y:X}=w(Z);if($.setPointerCapture(Z.pointerId),A0(V,X)){I0();return}let G=L0(V,X);if(G&&j[K]){Y={grip:G,x:V,y:X,start:{...j[K]}};return}if(z==="text"){if(Z.preventDefault(),$.hasPointerCapture(Z.pointerId))$.releasePointerCapture(Z.pointerId);z=null,Q(),x0(V,X);return}if(z){W={tool:z,x1:V,y1:X,x2:V,y2:X},K=-1;return}let F=U0(V,X);K=F,Y=F>=0?{grip:"body",x:V,y:X,start:{...j[F]}}:null,B()}function h0(Z){let{x:V,y:X}=w(Z);if(W){W.x2=V,W.y2=X,B();return}if(Y){let F=j[K];if(!F)return;let U=V-Y.x,P=X-Y.y;if(Y.grip==="body")z2(F,Y.start,U,P);else j2(F,Y.grip,Y.start,U,P);B();return}if(z){$.style.cursor="crosshair";return}if(A0(V,X)){$.style.cursor="pointer";return}let G=L0(V,X);if(G){let F=j[K]?k(j[K]).find((U)=>U.id===G):null;$.style.cursor=F?.cursor??"pointer";return}$.style.cursor=U0(V,X)>=0?"move":"default"}function J0(){if(W){if(!(Math.abs(W.x2-W.x1)<n1&&Math.abs(W.y2-W.y1)<n1))j.push(W),K=j.length-1,z=null,Q();W=null}if(Y)Y=null,Q();B()}function m0(Z){let V=$.getBoundingClientRect(),X=(Z.clientX-V.left)/V.width*$.width,G=(Z.clientY-V.top)/V.height*$.height,F=U0(X,G),U=j[F];if(!U||U.tool!=="text")return;Z.preventDefault(),x0(U.x1,U.y1,F)}function g0(Z){if(K<0)return;if(Z.key==="Delete"||Z.key==="Backspace")Z.preventDefault(),I0();else if(Z.key==="Escape")K=-1,B()}function I0(){if(K<0)return;j.splice(K,1),K=-1,Q(),B()}return $.addEventListener("pointerdown",E0),$.addEventListener("pointermove",h0),$.addEventListener("pointerup",J0),$.addEventListener("pointercancel",J0),$.addEventListener("dblclick",m0),$.tabIndex=0,$.addEventListener("keydown",g0),B(),{setTool(Z){z=Z,K=-1,$.style.cursor=Z?"crosshair":"default",B()},deleteSelected:I0,clear(){j.length=0,K=-1,Q(),B()},hasShapes:()=>j.length>0,hasSelection:()=>K>=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 X=I();for(let G of j)L(V,G,X);return Z.toDataURL("image/png")},destroy(){v(!1),$.removeEventListener("pointerdown",E0),$.removeEventListener("pointermove",h0),$.removeEventListener("pointerup",J0),$.removeEventListener("pointercancel",J0),$.removeEventListener("dblclick",m0),$.removeEventListener("keydown",g0)}}}var t1=`
|
|
34
34
|
:host { all: initial; }
|
|
35
35
|
* { box-sizing: border-box; }
|
|
36
36
|
|
|
@@ -68,12 +68,6 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
68
68
|
font-size: 13px; line-height: 1.7; color: #475569; word-break: break-all;
|
|
69
69
|
}
|
|
70
70
|
.meta b { color: #0f172a; font-weight: 600; }
|
|
71
|
-
.meta .check {
|
|
72
|
-
display: flex; align-items: flex-start; gap: 8px; margin: 8px 0 0; padding-top: 8px;
|
|
73
|
-
border-top: 1px solid #e2e8f0; font-weight: 500; color: #0f172a; word-break: normal; cursor: pointer;
|
|
74
|
-
}
|
|
75
|
-
.meta .check input { margin: 5px 0 0; flex: none; accent-color: #2563eb; }
|
|
76
|
-
.meta .check .hint { display: block; font-size: 12px; line-height: 1.5; margin-top: 2px; }
|
|
77
71
|
|
|
78
72
|
.tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
79
73
|
.sep { width: 1px; align-self: stretch; background: #e2e8f0; margin: 0 4px; }
|
|
@@ -119,4 +113,4 @@ canvas { width: 100%; height: auto; display: block; border: 1px solid #e2e8f0; b
|
|
|
119
113
|
border-radius: 0 0 16px 16px;
|
|
120
114
|
}
|
|
121
115
|
.foot .grow { flex: 1; }
|
|
122
|
-
`;var
|
|
116
|
+
`;var t="lw-debug-reporter",r4=()=>[];var s4=[{tool:"rect",key:"toolRect"},{tool:"arrow",key:"toolArrow"},{tool:"highlight",key:"toolHighlight"},{tool:"text",key:"toolText"}];function n4(){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=Y1((J)=>void this.open(J))}disconnectedCallback(){this.stop?.(),this.stop=null,this.close()}async open(J){if(this.busy)return;this.busy=!0;let Q=Y0(N().locale),j=await m1();if(j.method==="cancelled"){this.close();return}this.bundle=h1({reason:J,note:"",screenshotDataUrl:j.dataUrl,screenshotMethod:j.method,erroredQueries:a4()}),this.renderForm(Q)}close(){this.annotator?.destroy(),this.annotator=null,this.bundle=null,this.busy=!1,this.root.replaceChildren()}shell(J){let Q=document.createElement("style");Q.textContent=t1;let j=document.createElement("div");j.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),j.append(z),this.root.replaceChildren(Q,j),z}renderShell(J,Q){let j=this.shell(J),z=D("div","head");z.append(D("h2","",J.title)),j.append(z,D("p","status",Q))}renderForm(J){let Q=this.bundle;if(!Q)return;let j=this.shell(J),z=D("div","head"),K=b("✕","icon");K.setAttribute("aria-label",J.close),K.addEventListener("click",()=>this.close()),z.append(D("h2","",J.title),K);let W=document.createElement("input");W.type="text",W.placeholder=J.summaryPlaceholder;let Y=_0(J.summaryLabel,J.summaryRequired,!0),H=document.createElement("textarea");H.placeholder=J.detailPlaceholder;let I=D("div","meta");I.innerHTML="";let{context:w}=Q;for(let[S,L]of[[J.reporter,`${w.user.fullName??"—"} (${w.user.email??"—"})`],[J.page,w.route.href],[J.captured,`${Q.network.length} network · ${Q.console.length} console · ${Q.actionTrail.length} actions${Q.replay?` · ${J.replay} ${Math.round(Q.replay.durationMs/1000)}s`:""}`]]){let e=document.createElement("div"),B=document.createElement("b");B.textContent=`${S}: `,e.append(B,document.createTextNode(L)),I.append(e)}let M=D("p","status",""),C=b(J.submit,"primary");if(C.disabled=!0,W.addEventListener("input",()=>{C.disabled=W.value.trim().length===0}),j.append(z,Y,W,_0(J.detailLabel),H,I),Q.screenshotDataUrl)j.append(...this.screenshotSection(J,Q.screenshotDataUrl));else j.append(D("p","status",J.noScreenshot));let k=D("div","foot"),q=b(J.close);q.addEventListener("click",()=>this.close()),k.append(q,M,D("span","grow"),C),j.append(k),C.addEventListener("click",async()=>{C.disabled=!0,M.dataset.tone="",M.textContent=J.submitting;try{let S=await i1(W.value.trim(),{...Q,note:H.value,screenshotDataUrl:this.annotator?.hasShapes()?this.annotator.toDataUrl():Q.screenshotDataUrl}),L=this.dispatchEvent(new CustomEvent("lw-report-submitted",{detail:S,bubbles:!0,composed:!0,cancelable:!0}));if(this.close(),L)s(`${J.submitted} — #${S.number}`,"success")}catch(S){let L=S instanceof Error?S.message:J.failed;M.dataset.tone="error",M.textContent=L,s(`${J.failed} — ${L}`,"error"),C.disabled=!1}}),W.focus()}screenshotSection(J,Q){let j=_0(J.annotateHint),z=D("div","tools"),K=document.createElement("canvas"),W=D("div","shot");W.append(K);let Y=[],H=(C)=>{for(let k of Y)k.setAttribute("aria-pressed",String(k===C))};for(let{tool:C,key:k}of s4){let q=b(J[k]);q.setAttribute("aria-pressed","false"),q.addEventListener("click",()=>{let S=q.getAttribute("aria-pressed")==="true";H(S?null:q),this.annotator?.setTool(S?null:C)}),Y.push(q),z.append(q)}z.append(D("span","sep"));let I=b(J.deleteSelected);I.addEventListener("click",()=>this.annotator?.deleteSelected());let w=b(J.clearAll);w.addEventListener("click",()=>{this.annotator?.clear(),H(null)}),z.append(I,w);let M=new Image;return M.onload=()=>{K.width=M.naturalWidth,K.height=M.naturalHeight,this.annotator=a1(K,M,()=>{H(null),I.disabled=!this.annotator?.hasSelection()})},M.src=Q,[j,z,D("p","status",J.annotateHelp),W]}}}function a4(){try{return r4()}catch{return[]}}function D($,J="",Q=""){let j=document.createElement($);if(J)j.className=J;if(Q)j.textContent=Q;return j}function b($,J=""){let Q=document.createElement("button");if(Q.type="button",Q.textContent=$,J)Q.className=J;return Q}function _0($,J="",Q=!1){let j=document.createElement("label");if(j.append(document.createTextNode($)),Q){let z=document.createElement("span");z.className="req",z.textContent=" *",j.append(z)}if(J){let z=document.createElement("span");z.className="hint",z.textContent=` ${J}`,j.append(z)}return j}function e1(){if(typeof window>"u"||customElements.get(t))return;customElements.define(t,n4())}var $2=!1;function J2($={}){if($2||typeof window>"u")return;if(!j0()){console.error("[debug-capture] configureDebugCapture() must be called before install");return}if($2=!0,O1(),Z1(),e0(),C1(),A1(),$.ui===!1)return;let J=Y0(N().locale);if(F1((Q)=>{s(Q.message??J.crashed,"error",{label:J.crashAction,onClick:()=>V0(Q)})}),e1(),!document.querySelector(t))document.body.append(document.createElement(t))}var Q2=document.currentScript,T=Q2?.dataset??{},t4="rrweb-record.mjs";L1(()=>import(new URL(t4,Q2?.src??location.href).href));function e4($){if(!$)return{};try{let J=JSON.parse($);if(!J||typeof J!=="object"||Array.isArray(J))return{};return Object.fromEntries(Object.entries(J).filter(([,Q])=>typeof Q==="string"&&Q.trim()))}catch{return{}}}if(T.host&&T.realmKey)y0({host:T.host,realmKey:T.realmKey,app:{name:T.appName??document.title??"app",version:T.appVersion??"0.0.0",environment:T.environment??"production"},module:u0(e4(T.modules)),locale:T.locale==="en"?"en":"th",...T.replay!==void 0?{replay:{seconds:Number(T.replay)||void 0}}:{}}),J2();window.lwReportProblem=V0;})();
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var M2=((J)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(J,{get:($,Q)=>(typeof require<"u"?require:$)[Q]}):J)(function(J){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+J+'" is not supported')});var C2={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},T=null;function I2(J){let $=[];if(!J.host?.trim())$.push("host");if(!J.realmKey?.trim())$.push("realmKey");if(!J.app?.name?.trim())$.push("app.name");if(typeof J.module!=="function")$.push("module");if($.length)throw Error(`[debug-capture] configureDebugCapture is missing: ${$.join(", ")}. `+"See the README — `module` maps a pathname to the part of your app it belongs to.");T=J}function O(){if(!T)throw Error("[debug-capture] configureDebugCapture() has not been called");return T}function z0(){return T!==null}function g(){let J=O().app;return{name:J.name,version:J.version??"0.0.0",environment:J.environment??P2()}}function P2(){if(typeof window>"u")return"unknown";let J=window.location.hostname;if(J==="localhost"||J==="127.0.0.1"||J.endsWith(".local"))return"development";return"production"}function v(J){let $=T?.capture?.[J];return typeof $==="number"?$:C2[J]}function Z1(J){let $=T?.module;if(!$)return null;try{return $(J)??null}catch{return null}}function G0(){let J=T?.redact;return{headers:J?.headers??[],queryKeys:(J?.queryKeys??[]).map(($)=>$.toLowerCase()),bodyKeys:(J?.bodyKeys??[]).map(($)=>$.toLowerCase())}}function K1(){return T?.capture?.overlaySelectors??[]}var q0={seconds:60,blockSelector:"[data-lw-private]",maskText:!1,maxBytes:4000000};function j0(){let J=T?.replay;if(!J)return null;let $=J===!0?{}:J,Q=typeof $.seconds==="number"&&$.seconds>0?$.seconds:q0.seconds,z=typeof $.maxBytes==="number"&&$.maxBytes>0?$.maxBytes:q0.maxBytes;return{seconds:Q,blockSelector:$.blockSelector?.trim()||q0.blockSelector,maskText:$.maskText===!0,maxBytes:z}}function W1(J){if(typeof window>"u")return!1;let $;try{$=new URL(J,window.location.href)}catch{return!1}if(D2($))return!1;if($.origin===window.location.origin)return!0;return(T?.capture?.bodyOrigins??[]).some((Q)=>{try{return new URL(Q).origin===$.origin}catch{return!1}})}function D2(J){if(!T?.host)return!1;try{if(new URL(T.host).origin!==J.origin)return!1}catch{return!1}return J.pathname.startsWith("/ingest/")}function N2(J){let $=Object.entries(J).map(([Q,z])=>[Q.replace(/\/+$/,"")||"/",z]).sort((Q,z)=>z[0].length-Q[0].length);return(Q)=>{let z=(Q||"/").replace(/\/+$/,"")||"/";for(let[j,K]of $)if(z===j||z.startsWith(`${j}/`))return{key:j,label:K};return null}}var i="‹redacted›",q2=/^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i,B2=new Set(["access_token","token","id_token","refresh_token","code","secret","client_secret","password","apikey","api_key","signature","x-amz-signature","x-amz-credential"]),S2=/(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i,O2=/[\w.+-]+@[\w-]+\.[\w.-]+/g,R2=/\d(?:[\d\s-]{7,})\d/g;function l(J){return J.replace(O2,i).replace(R2,i)}function _2(J){if(q2.test(J))return!0;return G0().headers.some((Q)=>Q.toLowerCase()===J.toLowerCase())}function o(J){let $={};for(let[Q,z]of Object.entries(J))$[Q]=_2(Q)?i:z;return $}function h(J){try{let $=/^https?:\/\//i.test(J),Q=new URL(J,$?void 0:"http://local.invalid"),z=!1;if(Q.searchParams.forEach((j,K)=>{if(B2.has(K.toLowerCase())||G0().queryKeys.includes(K.toLowerCase()))Q.searchParams.set(K,i),z=!0}),!z)return J;return $?Q.toString():`${Q.pathname}${Q.search}`}catch{return J}}function B0(J,$){if($>6||J===null||typeof J!=="object")return J;if(Array.isArray(J))return J.map((z)=>B0(z,$+1));let Q={};for(let[z,j]of Object.entries(J)){let K=S2.test(z)||G0().bodyKeys.some((W)=>z.toLowerCase().includes(W));Q[z]=K?i:B0(j,$+1)}return Q}function r(J,$){if(J==null)return null;let Q=J,z=J.trim();if(z.startsWith("{")||z.startsWith("["))try{let j=JSON.parse(z);Q=JSON.stringify(B0(j,0))}catch{}if(Q.length>$)return`${Q.slice(0,$)}… [truncated ${Q.length-$} chars]`;return Q}var S0=120,O0=40,n=(J,$)=>J.length>$?`${J.slice(0,$)}…`:J,R0=(J)=>{try{return decodeURIComponent(J)}catch{return J}},s=[],V1=0,X1=!1;function Z0(J,$,Q,z){let j=n($,S0),K=s[s.length-1];if(J==="navigate"&&K?.kind==="click"){let X=j.replace(/^ไปที่\s*/,"");if(K.detail.includes(`→ ${X}`))return K.at=new Date().toISOString(),K;let F=X.split(/[?#]/)[0]??X,M=K.source?R0(K.source.replace(/^→\s*/,"")).split(/[?#]/)[0]:null;if(M&&(F===M||F.startsWith(M)))return K.detail=n(`${K.detail} → ${X}`,S0),K.source=void 0,K.at=new Date().toISOString(),K}if(K&&K.kind===J&&K.detail===j){if(K.at=new Date().toISOString(),J!=="navigate")K.count=(K.count??1)+1;return K}V1+=1;let W={id:`act_${V1}`,at:new Date().toISOString(),kind:J,detail:j,count:1,source:Q,html:F0(z)};s.push(W);while(s.length>v("maxActions"))L2(s.shift());return W}var w2=200000,K0=0;function F0(J){if(!J)return;if(K0+J.length>w2)return;return K0+=J.length,J}function L2(J){if(!J)return;if(K0-=(J.html?.length??0)+(J.afterHtml?.length??0),K0<0)K0=0}function _0(J){return J&&J>1?` (×${J})`:""}function Y0(J){return J instanceof Element&&Boolean(J.closest("[data-debug-reporter]"))}var k2='button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea',T2={button:"ปุ่ม",a:"ลิงก์",input:"ช่อง",textarea:"ช่อง",select:"ตัวเลือก",summary:"ส่วนขยาย"},G1={button:"ปุ่ม",tab:"แท็บ",menuitem:"เมนู",option:"ตัวเลือก",switch:"สวิตช์",checkbox:"ช่องเลือก",radio:"ตัวเลือก",link:"ลิงก์"};function A2(J){let $=J.getAttribute("role");if($&&G1[$])return G1[$];return T2[J.tagName.toLowerCase()]??"ปุ่ม"}function x2(J,$){try{let Q=J,z=0;while(Q&&z<=$){let j=C1(Q);if(j&&typeof j.memoizedProps?.onClick==="function")return Q;Q=Q.parentElement,z+=1}}catch{}return null}function f2(J){let $=J.getAttribute("aria-label")?.trim();if($)return $;let Q=J.getAttribute("title")?.trim();if(Q)return Q;if(J instanceof HTMLInputElement||J instanceof HTMLTextAreaElement||J instanceof HTMLSelectElement)return(J.getAttribute("placeholder")||J.getAttribute("name")||"").trim();if(J instanceof HTMLImageElement)return(J.getAttribute("alt")||"").trim();let z=(J.textContent??"").replace(/\s+/g," ").trim();if(z)return z;if(J instanceof HTMLAnchorElement){let j=J.getAttribute("href");if(j?.startsWith("/"))return R0(j)}return""}function E2(J){if(!(J instanceof Element))return null;let $=J.closest(k2)??x2(J,4);if(!$)return null;let Q=$.tagName.toLowerCase();if(Q==="html"||Q==="body")return null;return $}function h2(J){let $=l(f2(J));if(!$)return null;return`${A2(J)} “${n($,O0)}”`}var M1=6000,m2=4000,g2=/(?:^|\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 v2(J){J.querySelectorAll("script, style, link, iframe, object, embed, noscript, canvas, video, audio").forEach((j)=>j.remove());let $=[J,...Array.from(J.querySelectorAll("*"))];for(let j of $){for(let W of Array.from(j.attributes)){let X=W.name.toLowerCase();if(X.startsWith("on")||X==="srcdoc"||X==="value"||X.startsWith("data-"))j.removeAttribute(W.name)}if(j instanceof HTMLAnchorElement)j.setAttribute("href","#");if(j instanceof HTMLImageElement)j.removeAttribute("src");let K=j.getAttribute("class");if(K){let W=K.replace(g2," ").replace(/\s+/g," ").trim();if(W)j.setAttribute("class",W);else j.removeAttribute("class")}}let Q=document.createTreeWalker(J,NodeFilter.SHOW_TEXT),z=Q.nextNode();while(z){if(z.nodeValue)z.nodeValue=l(z.nodeValue);z=Q.nextNode()}}function w0(J,$,Q){try{let z=J.outerHTML;if(!z||z.length>$)return;let j=J.cloneNode(!0);v2(j);let K=j.outerHTML;return K&&K.length<=Q?K:void 0}catch{return}}var y2=(J)=>w0(J,M1,m2),b2=150000,p2=40000,Y1=(J)=>w0(J,b2,p2);function u2(J){if(!(J instanceof HTMLInputElement)&&!(J instanceof HTMLTextAreaElement)&&!(J instanceof HTMLSelectElement))return null;let $=J.name||J.id||J.getAttribute("aria-label")||J.getAttribute("placeholder")||J.tagName.toLowerCase();return`ช่อง “${l($)}”`}var F1=80;function C1(J){let $=Object.keys(J).find((Q)=>Q.startsWith("__reactFiber$")||Q.startsWith("__reactInternalInstance$"));return $?J[$]:null}function d2(J){if(typeof J!=="function")return null;try{let $=Function.prototype.toString.call(J);return($.match(/\.(?:push|replace)\(\s*['"`]([^'"`]+)['"`]/)??$.match(/redirect\(\s*['"`]([^'"`]+)['"`]/))?.[1]??null}catch{return null}}function H1(J){if(!J)return;return`→ ${J.length>F1?`${J.slice(0,F1)}…`:J}`}function c2(J){try{let $=J.closest("a[href]")?.getAttribute("href");if($&&$.startsWith("/"))return H1($);let Q=C1(J),z=0;while(Q&&z<30){if(typeof Q.memoizedProps?.onClick==="function")return H1(d2(Q.memoizedProps.onClick));Q=Q.return,z+=1}return}catch{return}}var i2='[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';function l2(){let J=K1();return J.length?J.join(", "):i2}function o2(J){let $=J.getAttribute("role");if($==="status"||$==="alert")return"ข้อความแจ้งเตือน";if($==="menu")return"เมนู";if($==="listbox")return"รายการตัวเลือก";if($==="alertdialog")return"กล่องยืนยัน";return"กล่องโต้ตอบ"}function r2(J){let $=J.getAttribute("aria-label")?.trim();if($)return $;let Q=J.getAttribute("aria-labelledby");if(Q){let K=Q.split(/\s+/).map((W)=>document.getElementById(W)?.textContent?.trim()??"").filter(Boolean).join(" ");if(K)return K}let j=J.querySelector('[data-slot="dialog-title"], h1, h2, h3, [role="heading"]')?.textContent?.replace(/\s+/g," ").trim();if(j)return j;return(J.textContent??"").replace(/\s+/g," ").trim()}function I1(J){let $=l(r2(J)),Q=o2(J);return $?`เปิด ${Q} “${n($,O0)}”`:`เปิด ${Q}`}var s2='[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin',n2=/กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;function a2(J){if(J.querySelector(s2))return!0;return n2.test(J.textContent??"")}var t2=400,e2=250,J4=8000;function $4(J,$){if(typeof MutationObserver>"u"){$.html=F0(Y1(J));return}let Q=Date.now(),z=!1,j=()=>{z=!0,W.disconnect(),window.clearInterval(X),window.clearTimeout(F)},K=()=>{if(z)return;if(j(),!J.isConnected)return;$.detail=n(I1(J),S0),$.html=F0(Y1(J))},W=new MutationObserver(()=>{Q=Date.now()});W.observe(J,{childList:!0,subtree:!0,attributes:!0,characterData:!0});let X=window.setInterval(()=>{if(z)return;if(!J.isConnected){j();return}if(Date.now()-Q>=t2&&!a2(J))K()},e2),F=window.setTimeout(K,J4)}function Q4(J){if(Y0(J))return;let $=Z0("ui",I1(J));if($)$4(J,$)}function z4(){if(typeof MutationObserver>"u")return;let J=new WeakSet;new MutationObserver((Q)=>{for(let z of Q)for(let j of Array.from(z.addedNodes)){if(!(j instanceof Element))continue;let K=l2(),W=j.matches(K)?[j]:Array.from(j.querySelectorAll(K));for(let X of W){if(J.has(X))continue;J.add(X),Q4(X)}}}).observe(document.body,{childList:!0,subtree:!0})}var j4=1600,Z4=2500;function U1(J){return{disabled:J.hasAttribute("disabled")||J.getAttribute("aria-disabled")==="true",busy:J.getAttribute("aria-busy")==="true",text:n((J.textContent??"").replace(/\s+/g," ").trim(),O0)}}function K4(J,$){if(!J.disabled&&$.disabled)return"ปุ่มถูกปิดใช้งานหลังคลิก";if(!J.busy&&$.busy)return"ปุ่มเข้าสู่สถานะกำลังโหลด";if(J.text!==$.text&&$.text)return`ข้อความเปลี่ยนเป็น “${$.text}”`;return null}function W4(J,$){if(typeof MutationObserver>"u")return;let Q=U1(J),z=!1,j=(X,F)=>{if(z)return;if(z=!0,K.disconnect(),window.clearTimeout(W),$.afterNote=X,F)$.afterHtml=F0(w0(J,M1,Z4))},K=new MutationObserver(()=>{if(!J.isConnected){j("องค์ประกอบหายไปจากหน้าจอ",!1);return}let X=K4(Q,U1(J));if(X)j(X,!0)});K.observe(J,{attributes:!0,attributeFilter:["disabled","aria-disabled","aria-busy","class"],childList:!0,subtree:!0,characterData:!0});let W=window.setTimeout(()=>{if(!z&&!J.isConnected){j("องค์ประกอบหายไปจากหน้าจอ",!1);return}z=!0,K.disconnect()},j4)}function P1(){if(X1||typeof window>"u")return;X1=!0,document.addEventListener("click",(z)=>{if(Y0(z.target))return;let j=E2(z.target);if(!j)return;let K=h2(j);if(!K)return;let W=Z0("click",`คลิก ${K}`,c2(j),y2(j));if(W)W4(j,W)},{capture:!0,passive:!0}),document.addEventListener("change",(z)=>{if(Y0(z.target))return;let j=u2(z.target);if(j)Z0("input",`แก้ไข ${j}`)},{capture:!0,passive:!0}),document.addEventListener("submit",(z)=>{if(Y0(z.target))return;Z0("submit","ส่งฟอร์ม")},{capture:!0,passive:!0});let J=()=>Z0("navigate",`ไปที่ ${R0(h(location.pathname+location.search))}`),$=history.pushState.bind(history),Q=history.replaceState.bind(history);history.pushState=(...z)=>{let j=$(...z);return J(),j},history.replaceState=(...z)=>{let j=Q(...z);return J(),j},window.addEventListener("popstate",J),z4()}function L0(){return s.map((J)=>({...J}))}var D1=2000,H0=[],N1=0,q1=!1;function k0(J,$){N1+=1,H0.push({id:`log_${N1}`,at:new Date().toISOString(),level:J,message:$.length>D1?`${$.slice(0,D1)}…`:$});while(H0.length>v("maxConsoleEntries"))H0.shift()}function V4(){let J=new WeakSet;return($,Q)=>{if(typeof Q==="object"&&Q!==null){if(J.has(Q))return"[Circular]";J.add(Q)}if(typeof Q==="bigint")return Q.toString();return Q}}function B1(J){if(typeof J==="string")return J;if(J instanceof Error)return`${J.name}: ${J.message}`;try{let $=JSON.stringify(J,V4());if($!==void 0)return $}catch{}try{return String(J)}catch{}try{return Object.prototype.toString.call(J)}catch{return`[${typeof J}]`}}function S1(){if(q1||typeof window>"u")return;q1=!0;let J=["log","info","warn","error","debug"];for(let $ of J){let Q=console[$].bind(console);console[$]=(...z)=>{k0($,z.map(B1).join(" ")),Q(...z)}}window.addEventListener("error",($)=>{let Q=$.filename?` (${$.filename}:${$.lineno}:${$.colno})`:"";k0("exception",`${$.message}${Q}`)}),window.addEventListener("unhandledrejection",($)=>{let Q=$.reason instanceof Error?`${$.reason.name}: ${$.reason.message}`:B1($.reason);k0("unhandledrejection",Q)})}function T0(){return H0.map((J)=>({...J}))}var O1=new Set,R1=new Set;function _1(J,$){return J.add($),()=>J.delete($)}function w1(J,$){for(let Q of[...J])Q($)}function A0(J){return _1(O1,J)}function x0(J={type:"manual"}){w1(O1,J)}function f0(J){return _1(R1,J)}function E0(J){w1(R1,J)}var X4=15000,G4=["ResizeObserver loop","Script error.","Non-Error promise rejection captured"],L1=!1,k1=0;function Y4(J){return G4.some(($)=>J.includes($))}function T1(J){let $=J.message??"";if(!$||Y4($))return;let Q=Date.now();if(Q-k1<X4)return;k1=Q,E0({...J,message:$})}function A1(){if(L1||typeof window>"u")return;L1=!0,window.addEventListener("error",(J)=>{if(!J.message&&!J.error)return;let $=J.error instanceof Error?J.error:null;T1({type:"runtime-error",message:J.message||($?$.message:"Unknown error"),stack:$?.stack})}),window.addEventListener("unhandledrejection",(J)=>{let $=J.reason;T1({type:"unhandledrejection",message:$ instanceof Error?$.message:String($),stack:$ instanceof Error?$.stack:void 0})})}var h1=4000,F4=1e6,H4=1e7,U0=[],x1=0,f1=!1;function m1(J){U0.push(J);while(U0.length>v("maxRequests"))U0.shift()}function g1(){return x1+=1,`req_${x1}`}function E1(J){let $={};if(!J)return $;if(J instanceof Headers)J.forEach((Q,z)=>{$[z]=Q});else if(Array.isArray(J))for(let[Q,z]of J)$[Q]=z;else Object.assign($,J);return $}function U4(J){let $={};return J.forEach((Q,z)=>{$[z]=Q}),$}function M4(J){if(J==null)return null;if(typeof J==="string")return J;if(J instanceof URLSearchParams)return J.toString();if(typeof FormData<"u"&&J instanceof FormData)return`[FormData: ${Array.from(J.keys()).join(", ")}]`;if(typeof Blob<"u"&&J instanceof Blob)return`[Blob ${J.size} bytes]`;if(J instanceof ArrayBuffer)return`[ArrayBuffer ${J.byteLength} bytes]`;return"[binary]"}function C4(J,$){let Q="",z="GET",j={},K=null;if(typeof J==="string")Q=J;else if(J instanceof URL)Q=J.toString();else Q=J.url,z=J.method||z,j=E1(J.headers);if($){if($.method)z=$.method;if($.headers)j={...j,...E1($.headers)};if($.body!==void 0)K=M4($.body)}return{method:z.toUpperCase(),url:Q,headers:j,body:K}}function v1(J){return!W1(J)}function I4(J,$){if(v1($.url)){$.responseSnippet="[body not captured for this origin]";return}let Q=J.headers.get("content-type")??"",z=Number(J.headers.get("content-length")??"0"),j=z?`, ~${z} bytes`:"";if(!/json|text|xml|html|javascript|urlencoded/i.test(Q)){$.responseSnippet=`[binary ${Q||"unknown"}${j}]`;return}if(z>F4){$.responseSnippet=`[response ${Q||"text"}${j} — omitted]`;return}try{J.clone().text().then((K)=>{$.responseSnippet=r(K,v("maxBodyChars"))}).catch(()=>{})}catch{}}function y1(J,$){if(/[?&]_rsc=/.test(J))return!0;for(let Q of Object.keys($)){let z=Q.toLowerCase();if(z==="rsc"||z==="next-router-prefetch"||z==="next-router-state-tree")return!0}return!1}function P4(){if(typeof window>"u"||typeof window.fetch!=="function")return;let J=window.fetch.bind(window);window.fetch=Object.assign(async($,Q)=>{let z=C4($,Q);if(y1(z.url,z.headers))return J($,Q);let j={id:g1(),startedAt:new Date().toISOString(),method:z.method,url:h(z.url),requestHeaders:o(z.headers),requestBody:r(z.body,h1),status:null,statusText:null,durationMs:null,via:"fetch"};m1(j);let K=performance.now();try{let W=await J($,Q);return j.status=W.status,j.statusText=W.statusText,j.durationMs=Math.round(performance.now()-K),j.responseHeaders=o(U4(W.headers)),I4(W,j),W}catch(W){throw j.durationMs=Math.round(performance.now()-K),j.error=W instanceof Error?`${W.name}: ${W.message}`:String(W),W}},J)}function D4(){if(typeof window>"u"||typeof window.XMLHttpRequest!=="function")return;let J=XMLHttpRequest.prototype,$=J.open,Q=J.send,z=function(K,W){let X=typeof W==="string"?W:W.toString();return this.__lwEntry=y1(X,{})?void 0:{id:g1(),startedAt:"",method:(K||"GET").toUpperCase(),url:h(X),requestHeaders:{},requestBody:null,status:null,statusText:null,durationMs:null,via:"xhr"},$.apply(this,arguments)},j=function(K){let W=this.__lwEntry;if(W){W.startedAt=new Date().toISOString(),W.requestBody=typeof K==="string"?r(K,h1):K==null?null:"[non-string body]";let X=performance.now();m1(W),this.addEventListener("loadend",()=>{if(W.status=this.status||null,W.statusText=this.statusText||null,W.durationMs=Math.round(performance.now()-X),v1(W.url))W.responseSnippet="[body not captured for this origin]";else if(this.responseType===""||this.responseType==="text")try{W.responseSnippet=r(this.responseText||"",v("maxBodyChars"))}catch{}else{let F=this.getResponseHeader("content-type")??this.responseType;W.responseSnippet=`[binary ${F}]`}})}return Q.apply(this,arguments)};J.open=z,J.send=j}function b1(){if(f1)return;f1=!0,P4(),D4()}function h0(){let J=U0.map((Q)=>({...Q})),$=0;for(let Q=J.length-1;Q>=0;Q-=1){let z=J[Q],j=z?.responseSnippet;if(!z||typeof j!=="string"||j.length===0)continue;if($+j.length>H4)z.responseSnippet=`[response omitted — report size budget reached (${j.length.toLocaleString()} chars)]`;else $+=j.length}return J}var N4=4,p1=3,q4=4000,B4="[data-debug-reporter]",S4=()=>import("@rrweb/record");var A=[],a=null,M0=!1;function u1(){if(typeof window>"u"||a||M0)return;let J=j0();if(!J)return;M0=!0;let $=()=>void O4(J);if("requestIdleCallback"in window)window.requestIdleCallback($,{timeout:3000});else setTimeout($,1000)}async function O4(J){let $;try{$=(await S4()).record}catch(Q){M0=!1,console.warn("[debug-capture] session replay could not start:",Q);return}if(a)return;try{a=$({emit:(Q)=>R4(Q),checkoutEveryNms:Math.max(1000,J.seconds*1000/2),checkoutEveryNth:q4,maskAllInputs:!0,...J.maskText?{maskTextSelector:"*"}:{},blockSelector:`${J.blockSelector}, ${B4}`,slimDOMOptions:"all",inlineStylesheet:!0,sampling:{mousemove:50,scroll:150,media:800,input:"last"},recordCanvas:!1,errorHandler:()=>!0})??null}catch(Q){console.warn("[debug-capture] session replay could not start:",Q)}finally{M0=!1}}function R4(J){if(J.type===N4||A.length===0){if(A.push([]),A.length>p1)A=A.slice(-p1)}A[A.length-1].push(J)}function m0(J=Date.now()){let $=j0();if(!$||!A.length)return null;let Q=J-$.seconds*1000,z=A.length-1;while(z>0&&(A[z][0]?.timestamp??J)>Q)z-=1;let j=A.slice(z).flat(),K=j[0]?.timestamp,W=j[j.length-1]?.timestamp;if(K===void 0||W===void 0)return null;return{events:j,startedAt:new Date(K).toISOString(),endedAt:new Date(W).toISOString(),durationMs:Math.max(0,W-K)}}function _4(){return a!==null}function w4(){a?.(),a=null,A=[]}var L4={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:"หน้า",replayAttach:"แนบการบันทึกหน้าจอ {seconds} วินาทีก่อนแจ้ง",replayWhat:"บันทึกเฉพาะโครงสร้างหน้าจอและการคลิก — ข้อความที่พิมพ์ในช่องกรอกถูกปิดบังไว้",handoffTitle:"กำลังพาไปที่ระบบแจ้งปัญหา",handoffBody:"ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",handoffGo:"ไปเลย",handoffPreparing:"กำลังเตรียม…",handoffFailed:"เปิดรายการที่แจ้งไว้ไม่สำเร็จ",handoffBlocked:"เบราว์เซอร์บล็อกการเปิดแท็บใหม่",handoffOpen:"เปิดในแท็บใหม่"},k4={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",replayAttach:"Attach a replay of the last {seconds} seconds",replayWhat:"The page and your clicks are recorded, not a video — anything typed into a field is masked",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 d(J){return J==="en"?k4:L4}var T4="lw-debug-toasts",A4=6000,x4=`
|
|
1
|
+
var M2=((J)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(J,{get:($,Q)=>(typeof require<"u"?require:$)[Q]}):J)(function(J){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+J+'" is not supported')});var C2={maxRequests:60,maxConsoleEntries:120,maxActions:80,maxBodyChars:20000},k=null;function I2(J){let $=[];if(!J.host?.trim())$.push("host");if(!J.realmKey?.trim())$.push("realmKey");if(!J.app?.name?.trim())$.push("app.name");if(typeof J.module!=="function")$.push("module");if($.length)throw Error(`[debug-capture] configureDebugCapture is missing: ${$.join(", ")}. `+"See the README — `module` maps a pathname to the part of your app it belongs to.");k=J}function S(){if(!k)throw Error("[debug-capture] configureDebugCapture() has not been called");return k}function j0(){return k!==null}function m(){let J=S().app;return{name:J.name,version:J.version??"0.0.0",environment:J.environment??P2()}}function P2(){if(typeof window>"u")return"unknown";let J=window.location.hostname;if(J==="localhost"||J==="127.0.0.1"||J.endsWith(".local"))return"development";return"production"}function g(J){let $=k?.capture?.[J];return typeof $==="number"?$:C2[J]}function Z1(J){let $=k?.module;if(!$)return null;try{return $(J)??null}catch{return null}}function Y0(){let J=k?.redact;return{headers:J?.headers??[],queryKeys:(J?.queryKeys??[]).map(($)=>$.toLowerCase()),bodyKeys:(J?.bodyKeys??[]).map(($)=>$.toLowerCase())}}function K1(){return k?.capture?.overlaySelectors??[]}var G0={seconds:60,blockSelector:"[data-lw-private]",maskTextSelector:'[contenteditable]:not([contenteditable="false"]), [data-lw-mask]',maskText:!1,maxBytes:4000000};function z0(){let J=k?.replay;if(!J)return null;let $=J===!0?{}:J,Q=typeof $.seconds==="number"&&$.seconds>0?$.seconds:G0.seconds,j=typeof $.maxBytes==="number"&&$.maxBytes>0?$.maxBytes:G0.maxBytes;return{seconds:Q,blockSelector:$.blockSelector?.trim()||G0.blockSelector,maskTextSelector:$.maskTextSelector?.trim()||G0.maskTextSelector,maskText:$.maskText===!0,maxBytes:j}}function W1(J){if(typeof window>"u")return!1;let $;try{$=new URL(J,window.location.href)}catch{return!1}if(D2($))return!1;if($.origin===window.location.origin)return!0;return(k?.capture?.bodyOrigins??[]).some((Q)=>{try{return new URL(Q).origin===$.origin}catch{return!1}})}function D2(J){if(!k?.host)return!1;try{if(new URL(k.host).origin!==J.origin)return!1}catch{return!1}return J.pathname.startsWith("/ingest/")}function N2(J){let $=Object.entries(J).map(([Q,j])=>[Q.replace(/\/+$/,"")||"/",j]).sort((Q,j)=>j[0].length-Q[0].length);return(Q)=>{let j=(Q||"/").replace(/\/+$/,"")||"/";for(let[z,K]of $)if(j===z||j.startsWith(`${z}/`))return{key:z,label:K};return null}}var i="‹redacted›",q2=/^(authorization|proxy-authorization|cookie|set-cookie|x-[a-z-]*token|x-csrf[a-z-]*|x-xsrf[a-z-]*)$/i,B2=new Set(["access_token","token","id_token","refresh_token","code","secret","client_secret","password","apikey","api_key","signature","x-amz-signature","x-amz-credential"]),S2=/(password|passwd|token|secret|authorization|refresh|client_secret|otp|pin)/i,O2=/[\w.+-]+@[\w-]+\.[\w.-]+/g,w2=/\d(?:[\d\s-]{7,})\d/g;function l(J){return J.replace(O2,i).replace(w2,i)}function R2(J){if(q2.test(J))return!0;return Y0().headers.some((Q)=>Q.toLowerCase()===J.toLowerCase())}function o(J){let $={};for(let[Q,j]of Object.entries(J))$[Q]=R2(Q)?i:j;return $}function f(J){try{let $=/^https?:\/\//i.test(J),Q=new URL(J,$?void 0:"http://local.invalid"),j=!1;if(Q.searchParams.forEach((z,K)=>{if(B2.has(K.toLowerCase())||Y0().queryKeys.includes(K.toLowerCase()))Q.searchParams.set(K,i),j=!0}),!j)return J;return $?Q.toString():`${Q.pathname}${Q.search}`}catch{return J}}function B0(J,$){if($>6||J===null||typeof J!=="object")return J;if(Array.isArray(J))return J.map((j)=>B0(j,$+1));let Q={};for(let[j,z]of Object.entries(J)){let K=S2.test(j)||Y0().bodyKeys.some((W)=>j.toLowerCase().includes(W));Q[j]=K?i:B0(z,$+1)}return Q}function r(J,$){if(J==null)return null;let Q=J,j=J.trim();if(j.startsWith("{")||j.startsWith("["))try{let z=JSON.parse(j);Q=JSON.stringify(B0(z,0))}catch{}if(Q.length>$)return`${Q.slice(0,$)}… [truncated ${Q.length-$} chars]`;return Q}var S0=120,O0=40,n=(J,$)=>J.length>$?`${J.slice(0,$)}…`:J,w0=(J)=>{try{return decodeURIComponent(J)}catch{return J}},s=[],V1=0,X1=!1;function Z0(J,$,Q,j){let z=n($,S0),K=s[s.length-1];if(J==="navigate"&&K?.kind==="click"){let G=z.replace(/^ไปที่\s*/,"");if(K.detail.includes(`→ ${G}`))return K.at=new Date().toISOString(),K;let F=G.split(/[?#]/)[0]??G,M=K.source?w0(K.source.replace(/^→\s*/,"")).split(/[?#]/)[0]:null;if(M&&(F===M||F.startsWith(M)))return K.detail=n(`${K.detail} → ${G}`,S0),K.source=void 0,K.at=new Date().toISOString(),K}if(K&&K.kind===J&&K.detail===z){if(K.at=new Date().toISOString(),J!=="navigate")K.count=(K.count??1)+1;return K}V1+=1;let W={id:`act_${V1}`,at:new Date().toISOString(),kind:J,detail:z,count:1,source:Q,html:H0(j)};s.push(W);while(s.length>g("maxActions"))L2(s.shift());return W}var _2=200000,K0=0;function H0(J){if(!J)return;if(K0+J.length>_2)return;return K0+=J.length,J}function L2(J){if(!J)return;if(K0-=(J.html?.length??0)+(J.afterHtml?.length??0),K0<0)K0=0}function R0(J){return J&&J>1?` (×${J})`:""}function F0(J){return J instanceof Element&&Boolean(J.closest("[data-debug-reporter]"))}var T2='button, a[href], [role="button"], [role="tab"], [role="menuitem"], [role="option"], [role="switch"], [role="checkbox"], [role="radio"], [role="link"], summary, input, select, textarea',k2={button:"ปุ่ม",a:"ลิงก์",input:"ช่อง",textarea:"ช่อง",select:"ตัวเลือก",summary:"ส่วนขยาย"},G1={button:"ปุ่ม",tab:"แท็บ",menuitem:"เมนู",option:"ตัวเลือก",switch:"สวิตช์",checkbox:"ช่องเลือก",radio:"ตัวเลือก",link:"ลิงก์"};function A2(J){let $=J.getAttribute("role");if($&&G1[$])return G1[$];return k2[J.tagName.toLowerCase()]??"ปุ่ม"}function x2(J,$){try{let Q=J,j=0;while(Q&&j<=$){let z=C1(Q);if(z&&typeof z.memoizedProps?.onClick==="function")return Q;Q=Q.parentElement,j+=1}}catch{}return null}function E2(J){let $=J.getAttribute("aria-label")?.trim();if($)return $;let Q=J.getAttribute("title")?.trim();if(Q)return Q;if(J instanceof HTMLInputElement||J instanceof HTMLTextAreaElement||J instanceof HTMLSelectElement)return(J.getAttribute("placeholder")||J.getAttribute("name")||"").trim();if(J instanceof HTMLImageElement)return(J.getAttribute("alt")||"").trim();let j=(J.textContent??"").replace(/\s+/g," ").trim();if(j)return j;if(J instanceof HTMLAnchorElement){let z=J.getAttribute("href");if(z?.startsWith("/"))return w0(z)}return""}function f2(J){if(!(J instanceof Element))return null;let $=J.closest(T2)??x2(J,4);if(!$)return null;let Q=$.tagName.toLowerCase();if(Q==="html"||Q==="body")return null;return $}function h2(J){let $=l(E2(J));if(!$)return null;return`${A2(J)} “${n($,O0)}”`}var M1=6000,m2=4000,g2=/(?:^|\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 v2(J){J.querySelectorAll("script, style, link, iframe, object, embed, noscript, canvas, video, audio").forEach((z)=>z.remove());let $=[J,...Array.from(J.querySelectorAll("*"))];for(let z of $){for(let W of Array.from(z.attributes)){let G=W.name.toLowerCase();if(G.startsWith("on")||G==="srcdoc"||G==="value"||G.startsWith("data-"))z.removeAttribute(W.name)}if(z instanceof HTMLAnchorElement)z.setAttribute("href","#");if(z instanceof HTMLImageElement)z.removeAttribute("src");let K=z.getAttribute("class");if(K){let W=K.replace(g2," ").replace(/\s+/g," ").trim();if(W)z.setAttribute("class",W);else z.removeAttribute("class")}}let Q=document.createTreeWalker(J,NodeFilter.SHOW_TEXT),j=Q.nextNode();while(j){if(j.nodeValue)j.nodeValue=l(j.nodeValue);j=Q.nextNode()}}function _0(J,$,Q){try{let j=J.outerHTML;if(!j||j.length>$)return;let z=J.cloneNode(!0);v2(z);let K=z.outerHTML;return K&&K.length<=Q?K:void 0}catch{return}}var y2=(J)=>_0(J,M1,m2),b2=150000,p2=40000,Y1=(J)=>_0(J,b2,p2);function u2(J){if(!(J instanceof HTMLInputElement)&&!(J instanceof HTMLTextAreaElement)&&!(J instanceof HTMLSelectElement))return null;let $=J.name||J.id||J.getAttribute("aria-label")||J.getAttribute("placeholder")||J.tagName.toLowerCase();return`ช่อง “${l($)}”`}var F1=80;function C1(J){let $=Object.keys(J).find((Q)=>Q.startsWith("__reactFiber$")||Q.startsWith("__reactInternalInstance$"));return $?J[$]:null}function d2(J){if(typeof J!=="function")return null;try{let $=Function.prototype.toString.call(J);return($.match(/\.(?:push|replace)\(\s*['"`]([^'"`]+)['"`]/)??$.match(/redirect\(\s*['"`]([^'"`]+)['"`]/))?.[1]??null}catch{return null}}function H1(J){if(!J)return;return`→ ${J.length>F1?`${J.slice(0,F1)}…`:J}`}function c2(J){try{let $=J.closest("a[href]")?.getAttribute("href");if($&&$.startsWith("/"))return H1($);let Q=C1(J),j=0;while(Q&&j<30){if(typeof Q.memoizedProps?.onClick==="function")return H1(d2(Q.memoizedProps.onClick));Q=Q.return,j+=1}return}catch{return}}var i2='[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [role="status"], [role="alert"]';function l2(){let J=K1();return J.length?J.join(", "):i2}function o2(J){let $=J.getAttribute("role");if($==="status"||$==="alert")return"ข้อความแจ้งเตือน";if($==="menu")return"เมนู";if($==="listbox")return"รายการตัวเลือก";if($==="alertdialog")return"กล่องยืนยัน";return"กล่องโต้ตอบ"}function r2(J){let $=J.getAttribute("aria-label")?.trim();if($)return $;let Q=J.getAttribute("aria-labelledby");if(Q){let K=Q.split(/\s+/).map((W)=>document.getElementById(W)?.textContent?.trim()??"").filter(Boolean).join(" ");if(K)return K}let z=J.querySelector('[data-slot="dialog-title"], h1, h2, h3, [role="heading"]')?.textContent?.replace(/\s+/g," ").trim();if(z)return z;return(J.textContent??"").replace(/\s+/g," ").trim()}function I1(J){let $=l(r2(J)),Q=o2(J);return $?`เปิด ${Q} “${n($,O0)}”`:`เปิด ${Q}`}var s2='[aria-busy="true"], [role="progressbar"], [data-loading="true"], .animate-pulse, .animate-spin',n2=/กำลังโหลด|กำลังค้นหา|กำลังดำเนินการ|\bloading\b/i;function a2(J){if(J.querySelector(s2))return!0;return n2.test(J.textContent??"")}var t2=400,e2=250,J4=8000;function $4(J,$){if(typeof MutationObserver>"u"){$.html=H0(Y1(J));return}let Q=Date.now(),j=!1,z=()=>{j=!0,W.disconnect(),window.clearInterval(G),window.clearTimeout(F)},K=()=>{if(j)return;if(z(),!J.isConnected)return;$.detail=n(I1(J),S0),$.html=H0(Y1(J))},W=new MutationObserver(()=>{Q=Date.now()});W.observe(J,{childList:!0,subtree:!0,attributes:!0,characterData:!0});let G=window.setInterval(()=>{if(j)return;if(!J.isConnected){z();return}if(Date.now()-Q>=t2&&!a2(J))K()},e2),F=window.setTimeout(K,J4)}function Q4(J){if(F0(J))return;let $=Z0("ui",I1(J));if($)$4(J,$)}function j4(){if(typeof MutationObserver>"u")return;let J=new WeakSet;new MutationObserver((Q)=>{for(let j of Q)for(let z of Array.from(j.addedNodes)){if(!(z instanceof Element))continue;let K=l2(),W=z.matches(K)?[z]:Array.from(z.querySelectorAll(K));for(let G of W){if(J.has(G))continue;J.add(G),Q4(G)}}}).observe(document.body,{childList:!0,subtree:!0})}var z4=1600,Z4=2500;function U1(J){return{disabled:J.hasAttribute("disabled")||J.getAttribute("aria-disabled")==="true",busy:J.getAttribute("aria-busy")==="true",text:n((J.textContent??"").replace(/\s+/g," ").trim(),O0)}}function K4(J,$){if(!J.disabled&&$.disabled)return"ปุ่มถูกปิดใช้งานหลังคลิก";if(!J.busy&&$.busy)return"ปุ่มเข้าสู่สถานะกำลังโหลด";if(J.text!==$.text&&$.text)return`ข้อความเปลี่ยนเป็น “${$.text}”`;return null}function W4(J,$){if(typeof MutationObserver>"u")return;let Q=U1(J),j=!1,z=(G,F)=>{if(j)return;if(j=!0,K.disconnect(),window.clearTimeout(W),$.afterNote=G,F)$.afterHtml=H0(_0(J,M1,Z4))},K=new MutationObserver(()=>{if(!J.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}let G=K4(Q,U1(J));if(G)z(G,!0)});K.observe(J,{attributes:!0,attributeFilter:["disabled","aria-disabled","aria-busy","class"],childList:!0,subtree:!0,characterData:!0});let W=window.setTimeout(()=>{if(!j&&!J.isConnected){z("องค์ประกอบหายไปจากหน้าจอ",!1);return}j=!0,K.disconnect()},z4)}function P1(){if(X1||typeof window>"u")return;X1=!0,document.addEventListener("click",(j)=>{if(F0(j.target))return;let z=f2(j.target);if(!z)return;let K=h2(z);if(!K)return;let W=Z0("click",`คลิก ${K}`,c2(z),y2(z));if(W)W4(z,W)},{capture:!0,passive:!0}),document.addEventListener("change",(j)=>{if(F0(j.target))return;let z=u2(j.target);if(z)Z0("input",`แก้ไข ${z}`)},{capture:!0,passive:!0}),document.addEventListener("submit",(j)=>{if(F0(j.target))return;Z0("submit","ส่งฟอร์ม")},{capture:!0,passive:!0});let J=()=>Z0("navigate",`ไปที่ ${w0(f(location.pathname+location.search))}`),$=history.pushState.bind(history),Q=history.replaceState.bind(history);history.pushState=(...j)=>{let z=$(...j);return J(),z},history.replaceState=(...j)=>{let z=Q(...j);return J(),z},window.addEventListener("popstate",J),j4()}function L0(){return s.map((J)=>({...J}))}var D1=2000,U0=[],N1=0,q1=!1;function T0(J,$){N1+=1,U0.push({id:`log_${N1}`,at:new Date().toISOString(),level:J,message:$.length>D1?`${$.slice(0,D1)}…`:$});while(U0.length>g("maxConsoleEntries"))U0.shift()}function V4(){let J=new WeakSet;return($,Q)=>{if(typeof Q==="object"&&Q!==null){if(J.has(Q))return"[Circular]";J.add(Q)}if(typeof Q==="bigint")return Q.toString();return Q}}function B1(J){if(typeof J==="string")return J;if(J instanceof Error)return`${J.name}: ${J.message}`;try{let $=JSON.stringify(J,V4());if($!==void 0)return $}catch{}try{return String(J)}catch{}try{return Object.prototype.toString.call(J)}catch{return`[${typeof J}]`}}function S1(){if(q1||typeof window>"u")return;q1=!0;let J=["log","info","warn","error","debug"];for(let $ of J){let Q=console[$].bind(console);console[$]=(...j)=>{T0($,j.map(B1).join(" ")),Q(...j)}}window.addEventListener("error",($)=>{let Q=$.filename?` (${$.filename}:${$.lineno}:${$.colno})`:"";T0("exception",`${$.message}${Q}`)}),window.addEventListener("unhandledrejection",($)=>{let Q=$.reason instanceof Error?`${$.reason.name}: ${$.reason.message}`:B1($.reason);T0("unhandledrejection",Q)})}function k0(){return U0.map((J)=>({...J}))}var O1=new Set,w1=new Set;function R1(J,$){return J.add($),()=>J.delete($)}function _1(J,$){for(let Q of[...J])Q($)}function A0(J){return R1(O1,J)}function x0(J={type:"manual"}){_1(O1,J)}function E0(J){return R1(w1,J)}function f0(J){_1(w1,J)}var X4=15000,G4=["ResizeObserver loop","Script error.","Non-Error promise rejection captured"],L1=!1,T1=0;function Y4(J){return G4.some(($)=>J.includes($))}function k1(J){let $=J.message??"";if(!$||Y4($))return;let Q=Date.now();if(Q-T1<X4)return;T1=Q,f0({...J,message:$})}function A1(){if(L1||typeof window>"u")return;L1=!0,window.addEventListener("error",(J)=>{if(!J.message&&!J.error)return;let $=J.error instanceof Error?J.error:null;k1({type:"runtime-error",message:J.message||($?$.message:"Unknown error"),stack:$?.stack})}),window.addEventListener("unhandledrejection",(J)=>{let $=J.reason;k1({type:"unhandledrejection",message:$ instanceof Error?$.message:String($),stack:$ instanceof Error?$.stack:void 0})})}var h1=4000,F4=1e6,H4=1e7,M0=[],x1=0,E1=!1;function m1(J){M0.push(J);while(M0.length>g("maxRequests"))M0.shift()}function g1(){return x1+=1,`req_${x1}`}function f1(J){let $={};if(!J)return $;if(J instanceof Headers)J.forEach((Q,j)=>{$[j]=Q});else if(Array.isArray(J))for(let[Q,j]of J)$[Q]=j;else Object.assign($,J);return $}function U4(J){let $={};return J.forEach((Q,j)=>{$[j]=Q}),$}function M4(J){if(J==null)return null;if(typeof J==="string")return J;if(J instanceof URLSearchParams)return J.toString();if(typeof FormData<"u"&&J instanceof FormData)return`[FormData: ${Array.from(J.keys()).join(", ")}]`;if(typeof Blob<"u"&&J instanceof Blob)return`[Blob ${J.size} bytes]`;if(J instanceof ArrayBuffer)return`[ArrayBuffer ${J.byteLength} bytes]`;return"[binary]"}function C4(J,$){let Q="",j="GET",z={},K=null;if(typeof J==="string")Q=J;else if(J instanceof URL)Q=J.toString();else Q=J.url,j=J.method||j,z=f1(J.headers);if($){if($.method)j=$.method;if($.headers)z={...z,...f1($.headers)};if($.body!==void 0)K=M4($.body)}return{method:j.toUpperCase(),url:Q,headers:z,body:K}}function v1(J){return!W1(J)}function I4(J,$){if(v1($.url)){$.responseSnippet="[body not captured for this origin]";return}let Q=J.headers.get("content-type")??"",j=Number(J.headers.get("content-length")??"0"),z=j?`, ~${j} bytes`:"";if(!/json|text|xml|html|javascript|urlencoded/i.test(Q)){$.responseSnippet=`[binary ${Q||"unknown"}${z}]`;return}if(j>F4){$.responseSnippet=`[response ${Q||"text"}${z} — omitted]`;return}try{J.clone().text().then((K)=>{$.responseSnippet=r(K,g("maxBodyChars"))}).catch(()=>{})}catch{}}function y1(J,$){if(/[?&]_rsc=/.test(J))return!0;for(let Q of Object.keys($)){let j=Q.toLowerCase();if(j==="rsc"||j==="next-router-prefetch"||j==="next-router-state-tree")return!0}return!1}function P4(){if(typeof window>"u"||typeof window.fetch!=="function")return;let J=window.fetch.bind(window);window.fetch=Object.assign(async($,Q)=>{let j=C4($,Q);if(y1(j.url,j.headers))return J($,Q);let z={id:g1(),startedAt:new Date().toISOString(),method:j.method,url:f(j.url),requestHeaders:o(j.headers),requestBody:r(j.body,h1),status:null,statusText:null,durationMs:null,via:"fetch"};m1(z);let K=performance.now();try{let W=await J($,Q);return z.status=W.status,z.statusText=W.statusText,z.durationMs=Math.round(performance.now()-K),z.responseHeaders=o(U4(W.headers)),I4(W,z),W}catch(W){throw z.durationMs=Math.round(performance.now()-K),z.error=W instanceof Error?`${W.name}: ${W.message}`:String(W),W}},J)}function D4(){if(typeof window>"u"||typeof window.XMLHttpRequest!=="function")return;let J=XMLHttpRequest.prototype,$=J.open,Q=J.send,j=function(K,W){let G=typeof W==="string"?W:W.toString();return this.__lwEntry=y1(G,{})?void 0:{id:g1(),startedAt:"",method:(K||"GET").toUpperCase(),url:f(G),requestHeaders:{},requestBody:null,status:null,statusText:null,durationMs:null,via:"xhr"},$.apply(this,arguments)},z=function(K){let W=this.__lwEntry;if(W){W.startedAt=new Date().toISOString(),W.requestBody=typeof K==="string"?r(K,h1):K==null?null:"[non-string body]";let G=performance.now();m1(W),this.addEventListener("loadend",()=>{if(W.status=this.status||null,W.statusText=this.statusText||null,W.durationMs=Math.round(performance.now()-G),v1(W.url))W.responseSnippet="[body not captured for this origin]";else if(this.responseType===""||this.responseType==="text")try{W.responseSnippet=r(this.responseText||"",g("maxBodyChars"))}catch{}else{let F=this.getResponseHeader("content-type")??this.responseType;W.responseSnippet=`[binary ${F}]`}})}return Q.apply(this,arguments)};J.open=j,J.send=z}function b1(){if(E1)return;E1=!0,P4(),D4()}function h0(){let J=M0.map((Q)=>({...Q})),$=0;for(let Q=J.length-1;Q>=0;Q-=1){let j=J[Q],z=j?.responseSnippet;if(!j||typeof z!=="string"||z.length===0)continue;if($+z.length>H4)j.responseSnippet=`[response omitted — report size budget reached (${z.length.toLocaleString()} chars)]`;else $+=z.length}return J}var N4=4,p1=3,q4=4000,B4="[data-debug-reporter]",S4=()=>import("@rrweb/record");var A=[],a=null,C0=!1;function u1(){if(typeof window>"u"||a||C0)return;let J=z0();if(!J)return;C0=!0;let $=()=>void O4(J);if("requestIdleCallback"in window)window.requestIdleCallback($,{timeout:3000});else setTimeout($,1000)}async function O4(J){let $;try{$=(await S4()).record}catch(Q){C0=!1,console.warn("[debug-capture] session replay could not start:",Q);return}if(a)return;try{a=$({emit:(Q)=>w4(Q),checkoutEveryNms:Math.max(1000,J.seconds*1000/2),checkoutEveryNth:q4,maskAllInputs:!0,maskTextSelector:J.maskText?"*":J.maskTextSelector,blockSelector:`${J.blockSelector}, ${B4}`,slimDOMOptions:"all",inlineStylesheet:!0,sampling:{mousemove:50,scroll:150,media:800,input:"last"},recordCanvas:!1,errorHandler:()=>!0})??null}catch(Q){console.warn("[debug-capture] session replay could not start:",Q)}finally{C0=!1}}function w4(J){if(J.type===N4||A.length===0){if(A.push([]),A.length>p1)A=A.slice(-p1)}A[A.length-1].push(J)}function m0(J=Date.now()){let $=z0();if(!$||!A.length)return null;let Q=J-$.seconds*1000,j=A.length-1;while(j>0&&(A[j][0]?.timestamp??J)>Q)j-=1;let z=A.slice(j).flat(),K=z[0]?.timestamp,W=z[z.length-1]?.timestamp;if(K===void 0||W===void 0)return null;return{events:z,startedAt:new Date(K).toISOString(),endedAt:new Date(W).toISOString(),durationMs:Math.max(0,W-K)}}function R4(){return a!==null}function _4(){a?.(),a=null,A=[]}var L4={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:"หน้า",replay:"บันทึกหน้าจอ",handoffTitle:"กำลังพาไปที่ระบบแจ้งปัญหา",handoffBody:"ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",handoffGo:"ไปเลย",handoffPreparing:"กำลังเตรียม…",handoffFailed:"เปิดรายการที่แจ้งไว้ไม่สำเร็จ",handoffBlocked:"เบราว์เซอร์บล็อกการเปิดแท็บใหม่",handoffOpen:"เปิดในแท็บใหม่"},T4={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",replay:"replay",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 d(J){return J==="en"?T4:L4}var k4="lw-debug-toasts",A4=6000,x4=`
|
|
2
2
|
:host { all: initial; }
|
|
3
3
|
.stack {
|
|
4
4
|
position: fixed; top: 16px; right: 16px; z-index: 2147483001;
|
|
@@ -30,15 +30,15 @@ var M2=((J)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(J,{get:($,Q)=
|
|
|
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
|
-
`,g0=null;function
|
|
34
|
-
# response: ${$.responseSnippet}`:"";return`${
|
|
35
|
-
${o1($)}${
|
|
33
|
+
`,g0=null;function E4(){if(typeof document>"u")return null;if(g0?.isConnected)return g0;let J=document.createElement(k4);J.dataset.debugReporter="true";let $=J.attachShadow({mode:"open"}),Q=document.createElement("style");Q.textContent=x4;let j=document.createElement("div");return j.className="stack",j.setAttribute("role","status"),j.setAttribute("aria-live","polite"),$.append(Q,j),document.body.append(J),g0=j,j}function t(J,$="success",Q){let j=j0()?S().toast:void 0;if(j){j({message:J,tone:$,...Q?{action:Q}:{}});return}let z=E4();if(!z)return;let K=document.createElement("div");K.className="toast",K.dataset.tone=$;let W=document.createElement("span");W.className="dot";let G=document.createElement("span");G.textContent=J;let F=document.createElement("button");F.type="button",F.className="close",F.textContent="✕",F.setAttribute("aria-label","ปิด");let M=()=>{window.clearTimeout(q),K.remove()};F.addEventListener("click",M);let q=$==="error"||Q?0:window.setTimeout(M,A4);if(K.append(W,G),Q){let C=document.createElement("button");C.type="button",C.className="action",C.textContent=Q.label,C.addEventListener("click",()=>{M(),Q.onClick()}),K.append(C)}K.append(F),z.append(K)}function d1(J,$,Q){let j=J.filter((K)=>Boolean(K.error)||K.status!=null&&K.status>=400).slice(-20).map((K)=>({method:K.method,url:K.url,status:K.status,error:K.error,at:K.startedAt})),z=$.filter((K)=>K.level==="error"||K.level==="exception"||K.level==="unhandledrejection").slice(-20).map((K)=>K.message);return{failedRequests:j,errors:z,erroredQueries:Q.slice(0,20)}}function c1(J){return J.failedRequests.length+J.errors.length+J.erroredQueries.length}function f4(){let J={memoryUsedMb:null,memoryLimitMb:null,domContentLoadedMs:null,loadEventMs:null};if(typeof performance>"u")return J;let $=performance.memory;if($)J.memoryUsedMb=Math.round($.usedJSHeapSize/1024/1024),J.memoryLimitMb=Math.round($.jsHeapSizeLimit/1024/1024);let[Q]=performance.getEntriesByType("navigation");if(Q)J.domContentLoadedMs=Math.round(Q.domContentLoadedEventEnd),J.loadEventMs=Math.round(Q.loadEventEnd);return J}function v0(J,$){if(!J)return $;try{return J()}catch{return $}}function i1(){let J=S(),{pathname:$,search:Q,href:j}=window.location;return{capturedAt:new Date().toISOString(),route:{href:j,pathname:$,search:Q},module:Z1($),user:v0(J.user,{}),apiHeaders:o(v0(J.headers,{})),app:{name:m().name,version:m().version,environment:m().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:f4(),extra:v0(J.extra,{})}}var h4=2,m4={manual:"ผู้ใช้แจ้งเอง","runtime-error":"ข้อผิดพลาด runtime (auto)",unhandledrejection:"Promise rejection (auto)","framework-error":"หน้าจอค้าง/พัง (auto)"};function y0(J){let $=h0(),Q=k0();return{context:i1(),reason:J.reason,note:J.note,cause:d1($,Q,J.erroredQueries),actionTrail:L0(),network:$,console:Q,screenshotDataUrl:J.screenshotDataUrl,screenshotMethod:J.screenshotMethod,replay:m0()??void 0,meta:{generatedBy:"lightwork-debug-capture",schemaVersion:h4}}}function l1(J){return J.replace(/'/g,"'\\''")}function o1(J){let $=[`curl -X ${J.method} '${J.url}'`];for(let[Q,j]of Object.entries(J.requestHeaders))$.push(` -H '${Q}: ${l1(j)}'`);if(J.requestBody)$.push(` --data '${l1(J.requestBody)}'`);return $.join(" \\\n")}function g4(J){if(J.error)return`ERR ${J.error}`;return`${J.status??"—"} ${J.statusText??""}`.trim()}function v4(J){if(J.length===0)return"No network activity captured.";return J.map(($)=>{let Q=$.durationMs!=null?`${$.durationMs}ms`:"—",j=`# [${g4($)}] ${$.method} ${$.url} (${Q}, ${$.startedAt})`,z=$.responseSnippet?`
|
|
34
|
+
# response: ${$.responseSnippet}`:"";return`${j}
|
|
35
|
+
${o1($)}${z}`}).join(`
|
|
36
36
|
|
|
37
37
|
`)}function y4(J){if(J.length===0)return"No console output captured.";return J.map(($)=>`[${$.at}] ${$.level.toUpperCase()}: ${$.message}`).join(`
|
|
38
|
-
`)}function b4(J){if(J.length===0)return"No user actions captured.";let $=0;return J.map((Q)=>{let
|
|
38
|
+
`)}function b4(J){if(J.length===0)return"No user actions captured.";let $=0;return J.map((Q)=>{let j=Q.source?` (${Q.source})`:"",z=`${Q.detail}${R0(Q.count)}${j}`;if(Q.kind==="ui")return` ↳ [${Q.at}] ${z}`;$+=1;let K=`${$}. [${Q.at}] ${z}`;return Q.afterNote?`${K}
|
|
39
39
|
↳ ${Q.afterNote}`:K}).join(`
|
|
40
|
-
`)}function p4(J){let $=[];for(let Q of J.failedRequests)$.push(`✗ ${Q.status??Q.error??"ERR"} ${Q.method} ${Q.url}`);for(let Q of J.errors)$.push(`⚠ ${Q}`);for(let Q of J.erroredQueries)$.push(`⚠ React Query error: ${Q.key} — ${Q.error}`);return $}function u4(J){let{context:$}=J;return[`User : ${$.user.fullName??"—"} (${$.user.email??"—"})`,`Unit : ${$.user.unit??"—"}`,`Roles : ${$.user.roles?.join(", ")||"—"}`,`Route : ${$.route.href}`,`Module : ${$.module?`${$.module.label} (${$.module.key})`:"—"}`,`App : ${$.app.name} v${$.app.version} · ${$.app.environment}`,`Memory : ${$.performance.memoryUsedMb??"—"}/${$.performance.memoryLimitMb??"—"} MB`,`Client : ${$.client.userAgent}`,`Viewport : ${$.client.viewport.width}×${$.client.viewport.height} @${$.client.viewport.dpr}x`,`Reason : ${m4[J.reason.type]}${J.reason.message?` — ${J.reason.message}`:""}`,`Captured : ${J.network.length} requests · ${J.console.length} console · ${J.actionTrail.length} actions · screenshot=${J.screenshotMethod}${J.replay?` · replay=${Math.round(J.replay.durationMs/1000)}s`:""}`]}function d4(J){let $=p4(J.cause),Q=[`## \uD83D\uDC1E ${J.context.app.name} — Debug Report`,`**Generated:** ${J.context.capturedAt}`,"",...u4(J).map((
|
|
41
|
-
`)}function c4(J){return J.replace(/[:.]/g,"-").replace("T","_").slice(0,19)}function i4(J,$){return`debug-report_${c4(J.context.capturedAt)}.${$}`}function l4(J){return c1(J.cause)>0}async function b0(){if(typeof navigator<"u"&&Boolean(navigator.mediaDevices?.getDisplayMedia)){let Q=await o4();if(Q.status==="ok")return{dataUrl:Q.dataUrl,method:"display-media"};if(Q.status==="cancelled")return{dataUrl:null,method:"cancelled"}}let $=await n4();if($)return{dataUrl:$,method:"html-to-image"};return{dataUrl:null,method:"none"}}async function o4(){let J=null;try{let $={video:{frameRate:30},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude"};J=await navigator.mediaDevices.getDisplayMedia($);let Q=await r4(J);return Q?{status:"ok",dataUrl:Q}:{status:"error"}}catch($){if($ instanceof DOMException&&($.name==="NotAllowedError"||$.name==="AbortError"))return{status:"cancelled"};return{status:"error"}}finally{J?.getTracks().forEach(($)=>$.stop())}}async function r4(J){let $=document.createElement("video");$.srcObject=J,$.muted=!0,$.playsInline=!0,await new Promise((W)=>{let X=!1,F=()=>{if(X)return;X=!0,W()};$.onloadedmetadata=()=>{$.play().then(F).catch(F)},window.setTimeout(F,1500)}),await s4($);let{videoWidth:Q,videoHeight:z}=$;if(!Q||!z)return null;let j=document.createElement("canvas");j.width=Q,j.height=z;let K=j.getContext("2d");if(!K)return null;K.drawImage($,0,0,Q,z),$.pause(),$.srcObject=null;try{return j.toDataURL("image/png")}catch{return null}}function s4(J){return new Promise(($)=>{let Q=!1,z=()=>{if(Q)return;Q=!0,$()},j=J;if(typeof j.requestVideoFrameCallback==="function")j.requestVideoFrameCallback(()=>z()),window.setTimeout(z,1000);else window.setTimeout(z,250)})}async function n4(){let J=O().screenshotFallback;if(!J)return null;let $=await J().catch(()=>null);if(!$)return null;try{return await $(document.body,{cacheBust:!0,pixelRatio:Math.min(window.devicePixelRatio||1,2),filter:(Q)=>!(Q instanceof HTMLElement&&Q.dataset?.debugReporter==="true")})}catch{return null}}var a4=2000,t4=0.82,e4=3000000;function J6(J){return new Promise(($,Q)=>{let z=new Image;z.onload=()=>$(z),z.onerror=()=>Q(Error("could not read the screenshot")),z.src=J})}async function r1(J){try{let $=await J6(J),Q=Math.max($.naturalWidth,$.naturalHeight),z=Math.min(1,a4/Q),j=document.createElement("canvas");j.width=Math.max(1,Math.round($.naturalWidth*z)),j.height=Math.max(1,Math.round($.naturalHeight*z));let K=j.getContext("2d");if(!K)return J;K.fillStyle="#fff",K.fillRect(0,0,j.width,j.height),K.drawImage($,0,0,j.width,j.height);let W=t4,X=j.toDataURL("image/jpeg",W);while(X.length>e4&&W>0.4)W-=0.15,X=j.toDataURL("image/jpeg",W);return X}catch{return J}}var $6=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Q6=/^\d+$/,z6=/^[0-9a-f]{16,}$/i;function p0(J){if(J.reason.type==="manual")return null;let $=J.cause?.failedRequests?.[0];if(!$?.url)return null;let Q;try{Q=new URL($.url,"http://x").pathname}catch{Q=$.url}let z=Q.split("/").map((K)=>$6.test(K)||Q6.test(K)||z6.test(K)?":id":K).join("/"),j=$.status??($.error?"ERR":"?");return`${$.method??"REQ"} ${z} ${j}`}var u0=2000000;function C0(J){let{screenshotDataUrl:$,replay:Q,...z}=J;return JSON.stringify(z).length}function d0(J,$=2000000){if(C0(J)<=$)return J;let Q=J.network.map((j)=>({...j})),z={...J,network:Q};for(let j of Q){if(C0(z)<=$)return z;if(typeof j.responseSnippet==="string"&&j.responseSnippet.length>35)j.responseSnippet="[body dropped — report size budget]";if(typeof j.requestBody==="string"&&j.requestBody.length>35)j.requestBody="[body dropped — report size budget]"}while(z.network.length>1&&C0(z)>$)z.network=z.network.slice(1);while(z.console.length>1&&C0(z)>$)z.console=z.console.slice(1);return z}function W0(J){let $="";for(let Q=0;Q<J.length;Q+=32768)$+=String.fromCharCode(...J.subarray(Q,Q+32768));return btoa($)}var j6=4,Z6=2,K6=3,W6=0,V6=new Set(["href","src","action","formaction","xlink:href","data","poster","srcset"]);function s1(J){if(!J)return;for(let $ of Object.keys(J)){let Q=J[$];if(typeof Q!=="string"||!V6.has($)||!Q.includes("?"))continue;J[$]=h(Q)}}function c0(J){if(!J)return;s1(J.attributes);for(let $ of J.childNodes??[])c0($)}function n1(J){let $=JSON.parse(JSON.stringify(J));for(let Q of $){let z=Q.data;if(!z||typeof z!=="object")continue;if(Q.type===j6&&typeof z.href==="string")z.href=h(z.href);else if(Q.type===Z6)c0(z.node);else if(Q.type===K6&&z.source===W6){for(let j of z.adds??[])c0(j.node);for(let j of z.attributes??[])s1(j.attributes)}}return $}var a1="session-replay.json.gz",X6="session-replay.json";function G6(J){return Boolean(J&&J.events.length>0)}async function Y6(J){if(typeof CompressionStream>"u")return null;try{let $=new Blob([J]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response($).arrayBuffer())}catch{return null}}async function i0(J,$){if(!G6(J))return{summary:{omitted:"empty"}};let z={seconds:Math.round(J.durationMs/1000),events:J.events.length,startedAt:J.startedAt,endedAt:J.endedAt},j=new TextEncoder().encode(JSON.stringify({events:n1(J.events)})),K=await Y6(j),W=K??j;if(W.byteLength>$)return{summary:{...z,bytes:W.byteLength,omitted:"too-large"}};let X=K!==null;return{dataUri:`data:${X?"application/gzip":"application/json"};base64,${W0(W)}`,filename:X?a1:X6,summary:{...z,bytes:W.byteLength,compressed:X}}}function F6(J){let{screenshotDataUrl:$,replay:Q,...z}=J;return{dataUri:`data:application/json;base64,${W0(new TextEncoder().encode(JSON.stringify(z)))}`,filename:"debug-bundle.json"}}async function H6(){let J=O().identity;if(!J)return{};try{let $=await J();return $?{authorization:`Bearer ${$}`}:{}}catch{return{}}}async function l0(J,$){let Q=O(),z=d0($,u0),{context:j,note:K}=z,W=[];if(z.screenshotDataUrl){let I=await r1(z.screenshotDataUrl);W.push({dataUri:I,filename:"screenshot.jpg"})}W.push(F6(z));let X,F=j0();if(F)if(z.replay===null)X={omitted:"declined"};else{let I=await i0(z.replay,F.maxBytes);if(X=I.summary,"dataUri"in I)W.push({dataUri:I.dataUri,filename:I.filename})}let M=p0(z),B={title:J,description:K.trim()||void 0,appName:g().name,category:j.module?.label,routeUrl:j.route.href,priority:"MEDIUM",requesterEmail:j.user.email??void 0,requesterName:j.user.fullName??void 0,customFields:{unit:j.user.unit??"",appVersion:j.app.version,environment:j.app.environment,reasonType:z.reason.type,appName:g().name,module:j.module?.label??""},context:{...M?{signature:M}:{},capturedAt:j.capturedAt,reason:z.reason,cause:z.cause,actionTrail:z.actionTrail,client:j.client,performance:j.performance,apiHeaders:j.apiHeaders,extra:j.extra,counts:{network:z.network.length,console:z.console.length,actions:z.actionTrail.length},screenshotMethod:z.screenshotMethod,...X?{replay:X}:{}},attachments:W},C=await fetch(`${Q.host.replace(/\/$/,"")}/ingest/tickets`,{method:"POST",headers:{"content-type":"application/json","x-realm-key":Q.realmKey,...await H6()},body:JSON.stringify(B)});if(!C.ok){let I=C.headers.get("retry-after"),q=await C.json().then((N)=>N.error).catch(()=>null);throw Error(C.status===429?`Too many reports — try again in ${I??"a moment"}s`:q??`Report failed (${C.status})`)}return await C.json()}var V0=Math.PI/6;function t1(J,$,Q){let z=$.x-J.x,j=$.y-J.y,K=Math.hypot(z,j),W=Math.atan2(j,z),X=[{x:$.x,y:$.y},{x:$.x-Q*Math.cos(W-V0),y:$.y-Q*Math.sin(W-V0)},{x:$.x-Q*Math.cos(W+V0),y:$.y-Q*Math.sin(W+V0)}],F=Q*Math.cos(V0)*0.92;if(K<=F)return{shaft:null,head:X};return{shaft:{from:J,to:{x:$.x-F*Math.cos(W),y:$.y-F*Math.sin(W)}},head:X}}var o0="#f44336",U6="rgba(250, 204, 21, 0.4)",r0=22,e1="#2563eb",J2=9,$2=11,Q2=18,z2=4,I0=8,M6=[{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 s0(J,$,Q){let z=[],j=null,K=-1,W=null,X=null,F=J.getContext("2d");function M(){let Z=J.getBoundingClientRect().width;return Z>0?J.width/Z:1}function B(Z){let V=J.getBoundingClientRect();return{x:(Z.clientX-V.left)/V.width*J.width,y:(Z.clientY-V.top)/V.height*J.height}}function C(Z){let V=Z.size??r0;if(!F)return(Z.text?.length??0)*V*0.6;F.save(),F.font=`600 ${V}px system-ui, sans-serif`;let Y=F.measureText(Z.text??"").width;return F.restore(),Y}function I(Z){if(Z.tool==="text"){let V=Z.size??r0;return{left:Z.x1,top:Z.y1,right:Z.x1+C(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 q(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=I(Z);if(Z.tool==="text")return[{id:"size",x:V.right,y:V.bottom,cursor:"nwse-resize"}];return M6.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=I(Z);return{x:V.right+Q2*M(),y:V.top-Q2*M()}}function k(Z,V,Y){let{shaft:G,head:H}=t1({x:V.x1,y:V.y1},{x:V.x2,y:V.y2},Math.max(10,16*Y));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(H[0].x,H[0].y),Z.lineTo(H[1].x,H[1].y),Z.lineTo(H[2].x,H[2].y),Z.closePath(),Z.fill()}function w(Z,V,Y){Z.save(),Z.lineWidth=Math.max(2,3*Y),Z.strokeStyle=o0,Z.fillStyle=o0;let G=I(V);if(V.tool==="rect")Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(V.tool==="arrow")k(Z,V,Y);else if(V.tool==="highlight")Z.fillStyle=U6,Z.fillRect(G.left,G.top,G.right-G.left,G.bottom-G.top);else if(V.tool==="text"&&V.text){let H=V.size??r0;Z.font=`600 ${H}px system-ui, sans-serif`,Z.textBaseline="top";let U=H*0.22;Z.fillStyle="rgba(255,255,255,0.92)",Z.fillRect(G.left-U,G.top-U,G.right-G.left+U*2,G.bottom-G.top+U*2),Z.fillStyle=o0,Z.fillText(V.text,G.left,G.top)}Z.restore()}function P(Z,V,Y){let G=I(V);Z.save(),Z.strokeStyle=e1,Z.lineWidth=Math.max(1,1.5*Y),Z.setLineDash([6*Y,4*Y]),Z.strokeRect(G.left,G.top,G.right-G.left,G.bottom-G.top),Z.setLineDash([]);let H=J2*Y;for(let x of q(V))Z.fillStyle="#fff",Z.strokeStyle=e1,Z.lineWidth=Math.max(1,1.5*Y),Z.beginPath(),Z.rect(x.x-H/2,x.y-H/2,H,H),Z.fill(),Z.stroke();let U=N(V),D=$2*Y;Z.beginPath(),Z.arc(U.x,U.y,D,0,Math.PI*2),Z.fillStyle="#dc2626",Z.fill(),Z.strokeStyle="#fff",Z.lineWidth=Math.max(1.5,2*Y),Z.beginPath(),Z.moveTo(U.x-D*0.4,U.y-D*0.4),Z.lineTo(U.x+D*0.4,U.y+D*0.4),Z.moveTo(U.x+D*0.4,U.y-D*0.4),Z.lineTo(U.x-D*0.4,U.y+D*0.4),Z.stroke(),Z.restore()}function R(){if(!F)return;let Z=M();if(F.clearRect(0,0,J.width,J.height),F.drawImage($,0,0,J.width,J.height),z.forEach((Y,G)=>{if(G!==b)w(F,Y,Z)}),W)w(F,W,Z);let V=z[K];if(V&&!W)P(F,V,Z)}function f(Z,V,Y,G,H){return Math.abs(Z-Y)<=H&&Math.abs(V-G)<=H}function $0(Z,V){let Y=z[K];if(!Y)return null;let G=J2*M()/2+3*M();for(let H of q(Y))if(f(Z,V,H.x,H.y,G))return H.id;return null}function c(Z,V){let Y=z[K];if(!Y)return!1;let G=N(Y);return f(Z,V,G.x,G.y,$2*M())}function m(Z,V){let Y=6*M();for(let G=z.length-1;G>=0;G-=1){let H=z[G];if(H.tool==="arrow"){let D=H.x2-H.x1,x=H.y2-H.y1,p=Math.hypot(D,x)||1,u=Math.max(0,Math.min(1,((Z-H.x1)*D+(V-H.y1)*x)/(p*p)));if(Math.hypot(Z-(H.x1+u*D),V-(H.y1+u*x))<=Y+4*M())return G;continue}let U=I(H);if(Z>=U.left-Y&&Z<=U.right+Y&&V>=U.top-Y&&V<=U.bottom+Y)return G}return-1}function y(Z,V,Y,G,H){if(V==="tail"){Z.x1=Y.x1+G,Z.y1=Y.y1+H;return}if(V==="head"){Z.x2=Y.x2+G,Z.y2=Y.y2+H;return}if(V==="size"){let U2=(Y.size??24)+H;Z.size=Math.max(10,U2);return}let U=I(Y),{left:D,top:x,right:p,bottom:u}=U;if(V.includes("w"))D=Math.min(p-I0,D+G);if(V.includes("e"))p=Math.max(D+I0,p+G);if(V.includes("n"))x=Math.min(u-I0,x+H);if(V.includes("s"))u=Math.max(x+I0,u+H);Z.x1=D,Z.y1=x,Z.x2=p,Z.y2=u}function D0(Z,V,Y,G){Z.x1=V.x1+Y,Z.y1=V.y1+G,Z.x2=V.x2+Y,Z.y2=V.y2+G}let L=null,b=-1,S={x:0,y:0,size:24};function E(){let Z=J.getBoundingClientRect().width;return Z>0?Z/J.width:1}function H2(Z,V){if(!F)return Z.length*V*0.6;F.save(),F.font=`600 ${V}px system-ui, sans-serif`;let Y=F.measureText(Z||" ").width;return F.restore(),Y}function e0(){if(!L)return;let Z=J.parentElement;if(!Z)return;let V=J.getBoundingClientRect(),Y=Z.getBoundingClientRect(),G=E(),H=S.size*G;L.style.left=`${V.left-Y.left+S.x*G}px`,L.style.top=`${V.top-Y.top+S.y*G}px`,L.style.fontSize=`${H}px`,L.style.width=`${Math.max(40,H2(L.value,H)+H)}px`}function Q0(Z){let V=L;if(!V)return;L=null;let Y=V.value.trim(),G=b;if(b=-1,V.remove(),Z&&Y){if(G>=0&&z[G])z[G].text=Y,K=G;else z.push({tool:"text",x1:S.x,y1:S.y,x2:S.x,y2:S.y,text:Y,size:S.size}),K=z.length-1;Q()}else if(G>=0)K=G;J.focus(),R()}function J1(Z,V,Y=-1){Q0(!0);let G=J.parentElement;if(!G)return;if(getComputedStyle(G).position==="static")G.style.position="relative";let H=Y>=0?z[Y]:void 0;b=Y,S={x:H?.x1??Z,y:H?.y1??V,size:H?.size??Math.round(24*M())};let U=document.createElement("input");U.type="text",U.className="text-edit",U.value=H?.text??"",U.setAttribute("aria-label","ข้อความบนภาพ"),U.placeholder="ข้อความ",L=U,G.append(U),e0(),U.addEventListener("input",e0),U.addEventListener("keydown",(D)=>{if(D.stopPropagation(),D.key==="Enter")Q0(!0);else if(D.key==="Escape")Q0(!1)}),requestAnimationFrame(()=>{if(L!==U)return;U.focus(),U.select(),U.addEventListener("blur",()=>Q0(!0))}),R()}function $1(Z){let{x:V,y:Y}=B(Z);if(J.setPointerCapture(Z.pointerId),c(V,Y)){N0();return}let G=$0(V,Y);if(G&&z[K]){X={grip:G,x:V,y:Y,start:{...z[K]}};return}if(j==="text"){if(Z.preventDefault(),J.hasPointerCapture(Z.pointerId))J.releasePointerCapture(Z.pointerId);j=null,Q(),J1(V,Y);return}if(j){W={tool:j,x1:V,y1:Y,x2:V,y2:Y},K=-1;return}let H=m(V,Y);K=H,X=H>=0?{grip:"body",x:V,y:Y,start:{...z[H]}}:null,R()}function Q1(Z){let{x:V,y:Y}=B(Z);if(W){W.x2=V,W.y2=Y,R();return}if(X){let H=z[K];if(!H)return;let U=V-X.x,D=Y-X.y;if(X.grip==="body")D0(H,X.start,U,D);else y(H,X.grip,X.start,U,D);R();return}if(j){J.style.cursor="crosshair";return}if(c(V,Y)){J.style.cursor="pointer";return}let G=$0(V,Y);if(G){let H=z[K]?q(z[K]).find((U)=>U.id===G):null;J.style.cursor=H?.cursor??"pointer";return}J.style.cursor=m(V,Y)>=0?"move":"default"}function X0(){if(W){if(!(Math.abs(W.x2-W.x1)<z2&&Math.abs(W.y2-W.y1)<z2))z.push(W),K=z.length-1,j=null,Q();W=null}if(X)X=null,Q();R()}function z1(Z){let V=J.getBoundingClientRect(),Y=(Z.clientX-V.left)/V.width*J.width,G=(Z.clientY-V.top)/V.height*J.height,H=m(Y,G),U=z[H];if(!U||U.tool!=="text")return;Z.preventDefault(),J1(U.x1,U.y1,H)}function j1(Z){if(K<0)return;if(Z.key==="Delete"||Z.key==="Backspace")Z.preventDefault(),N0();else if(Z.key==="Escape")K=-1,R()}function N0(){if(K<0)return;z.splice(K,1),K=-1,Q(),R()}return J.addEventListener("pointerdown",$1),J.addEventListener("pointermove",Q1),J.addEventListener("pointerup",X0),J.addEventListener("pointercancel",X0),J.addEventListener("dblclick",z1),J.tabIndex=0,J.addEventListener("keydown",j1),R(),{setTool(Z){j=Z,K=-1,J.style.cursor=Z?"crosshair":"default",R()},deleteSelected:N0,clear(){z.length=0,K=-1,Q(),R()},hasShapes:()=>z.length>0,hasSelection:()=>K>=0,toDataUrl(){let Z=document.createElement("canvas");Z.width=$.naturalWidth,Z.height=$.naturalHeight;let V=Z.getContext("2d");if(!V)return J.toDataURL("image/png");V.drawImage($,0,0);let Y=M();for(let G of z)w(V,G,Y);return Z.toDataURL("image/png")},destroy(){Q0(!1),J.removeEventListener("pointerdown",$1),J.removeEventListener("pointermove",Q1),J.removeEventListener("pointerup",X0),J.removeEventListener("pointercancel",X0),J.removeEventListener("dblclick",z1),J.removeEventListener("keydown",j1)}}}var j2=`
|
|
40
|
+
`)}function p4(J){let $=[];for(let Q of J.failedRequests)$.push(`✗ ${Q.status??Q.error??"ERR"} ${Q.method} ${Q.url}`);for(let Q of J.errors)$.push(`⚠ ${Q}`);for(let Q of J.erroredQueries)$.push(`⚠ React Query error: ${Q.key} — ${Q.error}`);return $}function u4(J){let{context:$}=J;return[`User : ${$.user.fullName??"—"} (${$.user.email??"—"})`,`Unit : ${$.user.unit??"—"}`,`Roles : ${$.user.roles?.join(", ")||"—"}`,`Route : ${$.route.href}`,`Module : ${$.module?`${$.module.label} (${$.module.key})`:"—"}`,`App : ${$.app.name} v${$.app.version} · ${$.app.environment}`,`Memory : ${$.performance.memoryUsedMb??"—"}/${$.performance.memoryLimitMb??"—"} MB`,`Client : ${$.client.userAgent}`,`Viewport : ${$.client.viewport.width}×${$.client.viewport.height} @${$.client.viewport.dpr}x`,`Reason : ${m4[J.reason.type]}${J.reason.message?` — ${J.reason.message}`:""}`,`Captured : ${J.network.length} requests · ${J.console.length} console · ${J.actionTrail.length} actions · screenshot=${J.screenshotMethod}${J.replay?` · replay=${Math.round(J.replay.durationMs/1000)}s`:""}`]}function d4(J){let $=p4(J.cause),Q=[`## \uD83D\uDC1E ${J.context.app.name} — Debug Report`,`**Generated:** ${J.context.capturedAt}`,"",...u4(J).map((j)=>`- ${j.replace(/\s{2,}:/,":")}`),"",`**หมายเหตุจากผู้แจ้ง:** ${J.note.trim()||"(ไม่มี)"}`];if($.length>0)Q.push("","### ⚠ สาเหตุที่น่าจะเป็น","```",...$,"```");return Q.push("",`<details><summary>ขั้นตอน (${J.actionTrail.length})</summary>`,"","```",b4(J.actionTrail),"```","</details>","",`<details><summary>Network (${J.network.length})</summary>`,"","```",v4(J.network),"```","</details>","",`<details><summary>Console (${J.console.length})</summary>`,"","```",y4(J.console),"```","</details>","","_ข้อมูลลับ (token, cookie) ถูกปกปิดอัตโนมัติ · ภาพหน้าจออยู่ในไฟล์ .zip_"),Q.join(`
|
|
41
|
+
`)}function c4(J){return J.replace(/[:.]/g,"-").replace("T","_").slice(0,19)}function i4(J,$){return`debug-report_${c4(J.context.capturedAt)}.${$}`}function l4(J){return c1(J.cause)>0}async function b0(){if(typeof navigator<"u"&&Boolean(navigator.mediaDevices?.getDisplayMedia)){let Q=await o4();if(Q.status==="ok")return{dataUrl:Q.dataUrl,method:"display-media"};if(Q.status==="cancelled")return{dataUrl:null,method:"cancelled"}}let $=await n4();if($)return{dataUrl:$,method:"html-to-image"};return{dataUrl:null,method:"none"}}async function o4(){let J=null;try{let $={video:{frameRate:30},audio:!1,preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude"};J=await navigator.mediaDevices.getDisplayMedia($);let Q=await r4(J);return Q?{status:"ok",dataUrl:Q}:{status:"error"}}catch($){if($ instanceof DOMException&&($.name==="NotAllowedError"||$.name==="AbortError"))return{status:"cancelled"};return{status:"error"}}finally{J?.getTracks().forEach(($)=>$.stop())}}async function r4(J){let $=document.createElement("video");$.srcObject=J,$.muted=!0,$.playsInline=!0,await new Promise((W)=>{let G=!1,F=()=>{if(G)return;G=!0,W()};$.onloadedmetadata=()=>{$.play().then(F).catch(F)},window.setTimeout(F,1500)}),await s4($);let{videoWidth:Q,videoHeight:j}=$;if(!Q||!j)return null;let z=document.createElement("canvas");z.width=Q,z.height=j;let K=z.getContext("2d");if(!K)return null;K.drawImage($,0,0,Q,j),$.pause(),$.srcObject=null;try{return z.toDataURL("image/png")}catch{return null}}function s4(J){return new Promise(($)=>{let Q=!1,j=()=>{if(Q)return;Q=!0,$()},z=J;if(typeof z.requestVideoFrameCallback==="function")z.requestVideoFrameCallback(()=>j()),window.setTimeout(j,1000);else window.setTimeout(j,250)})}async function n4(){let J=S().screenshotFallback;if(!J)return null;let $=await J().catch(()=>null);if(!$)return null;try{return await $(document.body,{cacheBust:!0,pixelRatio:Math.min(window.devicePixelRatio||1,2),filter:(Q)=>!(Q instanceof HTMLElement&&Q.dataset?.debugReporter==="true")})}catch{return null}}var a4=2000,t4=0.82,e4=3000000;function J6(J){return new Promise(($,Q)=>{let j=new Image;j.onload=()=>$(j),j.onerror=()=>Q(Error("could not read the screenshot")),j.src=J})}async function r1(J){try{let $=await J6(J),Q=Math.max($.naturalWidth,$.naturalHeight),j=Math.min(1,a4/Q),z=document.createElement("canvas");z.width=Math.max(1,Math.round($.naturalWidth*j)),z.height=Math.max(1,Math.round($.naturalHeight*j));let K=z.getContext("2d");if(!K)return J;K.fillStyle="#fff",K.fillRect(0,0,z.width,z.height),K.drawImage($,0,0,z.width,z.height);let W=t4,G=z.toDataURL("image/jpeg",W);while(G.length>e4&&W>0.4)W-=0.15,G=z.toDataURL("image/jpeg",W);return G}catch{return J}}var $6=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Q6=/^\d+$/,j6=/^[0-9a-f]{16,}$/i;function p0(J){if(J.reason.type==="manual")return null;let $=J.cause?.failedRequests?.[0];if(!$?.url)return null;let Q;try{Q=new URL($.url,"http://x").pathname}catch{Q=$.url}let j=Q.split("/").map((K)=>$6.test(K)||Q6.test(K)||j6.test(K)?":id":K).join("/"),z=$.status??($.error?"ERR":"?");return`${$.method??"REQ"} ${j} ${z}`}var u0=2000000;function I0(J){let{screenshotDataUrl:$,replay:Q,...j}=J;return JSON.stringify(j).length}function d0(J,$=2000000){if(I0(J)<=$)return J;let Q=J.network.map((z)=>({...z})),j={...J,network:Q};for(let z of Q){if(I0(j)<=$)return j;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(j.network.length>1&&I0(j)>$)j.network=j.network.slice(1);while(j.console.length>1&&I0(j)>$)j.console=j.console.slice(1);return j}function W0(J){let $="";for(let Q=0;Q<J.length;Q+=32768)$+=String.fromCharCode(...J.subarray(Q,Q+32768));return btoa($)}var z6=4,Z6=2,K6=3,W6=0,V6=new Set(["href","src","action","formaction","xlink:href","data","poster","srcset"]);function s1(J){if(!J)return;for(let $ of Object.keys(J)){let Q=J[$];if(typeof Q!=="string"||!V6.has($)||!Q.includes("?"))continue;J[$]=f(Q)}}function c0(J){if(!J)return;s1(J.attributes);for(let $ of J.childNodes??[])c0($)}function n1(J){let $=JSON.parse(JSON.stringify(J));for(let Q of $){let j=Q.data;if(!j||typeof j!=="object")continue;if(Q.type===z6&&typeof j.href==="string")j.href=f(j.href);else if(Q.type===Z6)c0(j.node);else if(Q.type===K6&&j.source===W6){for(let z of j.adds??[])c0(z.node);for(let z of j.attributes??[])s1(z.attributes)}}return $}var a1="session-replay.json.gz",X6="session-replay.json";function G6(J){return Boolean(J&&J.events.length>0)}async function Y6(J){if(typeof CompressionStream>"u")return null;try{let $=new Blob([J]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response($).arrayBuffer())}catch{return null}}async function i0(J,$){if(!G6(J))return{summary:{omitted:"empty"}};let j={seconds:Math.round(J.durationMs/1000),events:J.events.length,startedAt:J.startedAt,endedAt:J.endedAt},z=new TextEncoder().encode(JSON.stringify({events:n1(J.events)})),K=await Y6(z),W=K??z;if(W.byteLength>$)return{summary:{...j,bytes:W.byteLength,omitted:"too-large"}};let G=K!==null;return{dataUri:`data:${G?"application/gzip":"application/json"};base64,${W0(W)}`,filename:G?a1:X6,summary:{...j,bytes:W.byteLength,compressed:G}}}function F6(J){let{screenshotDataUrl:$,replay:Q,...j}=J;return{dataUri:`data:application/json;base64,${W0(new TextEncoder().encode(JSON.stringify(j)))}`,filename:"debug-bundle.json"}}async function H6(){let J=S().identity;if(!J)return{};try{let $=await J();return $?{authorization:`Bearer ${$}`}:{}}catch{return{}}}async function l0(J,$){let Q=S(),j=d0($,u0),{context:z,note:K}=j,W=[];if(j.screenshotDataUrl){let I=await r1(j.screenshotDataUrl);W.push({dataUri:I,filename:"screenshot.jpg"})}W.push(F6(j));let G,F=z0();if(F){let I=await i0(j.replay,F.maxBytes);if(G=I.summary,"dataUri"in I)W.push({dataUri:I.dataUri,filename:I.filename})}let M=p0(j),q={title:J,description:K.trim()||void 0,appName:m().name,category:z.module?.label,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:j.reason.type,appName:m().name,module:z.module?.label??""},context:{...M?{signature:M}:{},capturedAt:z.capturedAt,reason:j.reason,cause:j.cause,actionTrail:j.actionTrail,client:z.client,performance:z.performance,apiHeaders:z.apiHeaders,extra:z.extra,counts:{network:j.network.length,console:j.console.length,actions:j.actionTrail.length},screenshotMethod:j.screenshotMethod,...G?{replay:G}:{}},attachments:W},C=await fetch(`${Q.host.replace(/\/$/,"")}/ingest/tickets`,{method:"POST",headers:{"content-type":"application/json","x-realm-key":Q.realmKey,...await H6()},body:JSON.stringify(q)});if(!C.ok){let I=C.headers.get("retry-after"),O=await C.json().then((D)=>D.error).catch(()=>null);throw Error(C.status===429?`Too many reports — try again in ${I??"a moment"}s`:O??`Report failed (${C.status})`)}return await C.json()}var V0=Math.PI/6;function t1(J,$,Q){let j=$.x-J.x,z=$.y-J.y,K=Math.hypot(j,z),W=Math.atan2(z,j),G=[{x:$.x,y:$.y},{x:$.x-Q*Math.cos(W-V0),y:$.y-Q*Math.sin(W-V0)},{x:$.x-Q*Math.cos(W+V0),y:$.y-Q*Math.sin(W+V0)}],F=Q*Math.cos(V0)*0.92;if(K<=F)return{shaft:null,head:G};return{shaft:{from:J,to:{x:$.x-F*Math.cos(W),y:$.y-F*Math.sin(W)}},head:G}}var o0="#f44336",U6="rgba(250, 204, 21, 0.4)",r0=22,e1="#2563eb",J2=9,$2=11,Q2=18,j2=4,P0=8,M6=[{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 s0(J,$,Q){let j=[],z=null,K=-1,W=null,G=null,F=J.getContext("2d");function M(){let Z=J.getBoundingClientRect().width;return Z>0?J.width/Z:1}function q(Z){let V=J.getBoundingClientRect();return{x:(Z.clientX-V.left)/V.width*J.width,y:(Z.clientY-V.top)/V.height*J.height}}function C(Z){let V=Z.size??r0;if(!F)return(Z.text?.length??0)*V*0.6;F.save(),F.font=`600 ${V}px system-ui, sans-serif`;let Y=F.measureText(Z.text??"").width;return F.restore(),Y}function I(Z){if(Z.tool==="text"){let V=Z.size??r0;return{left:Z.x1,top:Z.y1,right:Z.x1+C(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=I(Z);if(Z.tool==="text")return[{id:"size",x:V.right,y:V.bottom,cursor:"nwse-resize"}];return M6.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 D(Z){let V=I(Z);return{x:V.right+Q2*M(),y:V.top-Q2*M()}}function R(Z,V,Y){let{shaft:X,head:H}=t1({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(H[0].x,H[0].y),Z.lineTo(H[1].x,H[1].y),Z.lineTo(H[2].x,H[2].y),Z.closePath(),Z.fill()}function _(Z,V,Y){Z.save(),Z.lineWidth=Math.max(2,3*Y),Z.strokeStyle=o0,Z.fillStyle=o0;let X=I(V);if(V.tool==="rect")Z.strokeRect(X.left,X.top,X.right-X.left,X.bottom-X.top);else if(V.tool==="arrow")R(Z,V,Y);else if(V.tool==="highlight")Z.fillStyle=U6,Z.fillRect(X.left,X.top,X.right-X.left,X.bottom-X.top);else if(V.tool==="text"&&V.text){let H=V.size??r0;Z.font=`600 ${H}px system-ui, sans-serif`,Z.textBaseline="top";let U=H*0.22;Z.fillStyle="rgba(255,255,255,0.92)",Z.fillRect(X.left-U,X.top-U,X.right-X.left+U*2,X.bottom-X.top+U*2),Z.fillStyle=o0,Z.fillText(V.text,X.left,X.top)}Z.restore()}function N(Z,V,Y){let X=I(V);Z.save(),Z.strokeStyle=e1,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 H=J2*Y;for(let x of O(V))Z.fillStyle="#fff",Z.strokeStyle=e1,Z.lineWidth=Math.max(1,1.5*Y),Z.beginPath(),Z.rect(x.x-H/2,x.y-H/2,H,H),Z.fill(),Z.stroke();let U=D(V),P=$2*Y;Z.beginPath(),Z.arc(U.x,U.y,P,0,Math.PI*2),Z.fillStyle="#dc2626",Z.fill(),Z.strokeStyle="#fff",Z.lineWidth=Math.max(1.5,2*Y),Z.beginPath(),Z.moveTo(U.x-P*0.4,U.y-P*0.4),Z.lineTo(U.x+P*0.4,U.y+P*0.4),Z.moveTo(U.x+P*0.4,U.y-P*0.4),Z.lineTo(U.x-P*0.4,U.y+P*0.4),Z.stroke(),Z.restore()}function w(){if(!F)return;let Z=M();if(F.clearRect(0,0,J.width,J.height),F.drawImage($,0,0,J.width,J.height),j.forEach((Y,X)=>{if(X!==b)_(F,Y,Z)}),W)_(F,W,Z);let V=j[K];if(V&&!W)N(F,V,Z)}function v(Z,V,Y,X,H){return Math.abs(Z-Y)<=H&&Math.abs(V-X)<=H}function $0(Z,V){let Y=j[K];if(!Y)return null;let X=J2*M()/2+3*M();for(let H of O(Y))if(v(Z,V,H.x,H.y,X))return H.id;return null}function c(Z,V){let Y=j[K];if(!Y)return!1;let X=D(Y);return v(Z,V,X.x,X.y,$2*M())}function h(Z,V){let Y=6*M();for(let X=j.length-1;X>=0;X-=1){let H=j[X];if(H.tool==="arrow"){let P=H.x2-H.x1,x=H.y2-H.y1,p=Math.hypot(P,x)||1,u=Math.max(0,Math.min(1,((Z-H.x1)*P+(V-H.y1)*x)/(p*p)));if(Math.hypot(Z-(H.x1+u*P),V-(H.y1+u*x))<=Y+4*M())return X;continue}let U=I(H);if(Z>=U.left-Y&&Z<=U.right+Y&&V>=U.top-Y&&V<=U.bottom+Y)return X}return-1}function y(Z,V,Y,X,H){if(V==="tail"){Z.x1=Y.x1+X,Z.y1=Y.y1+H;return}if(V==="head"){Z.x2=Y.x2+X,Z.y2=Y.y2+H;return}if(V==="size"){let U2=(Y.size??24)+H;Z.size=Math.max(10,U2);return}let U=I(Y),{left:P,top:x,right:p,bottom:u}=U;if(V.includes("w"))P=Math.min(p-P0,P+X);if(V.includes("e"))p=Math.max(P+P0,p+X);if(V.includes("n"))x=Math.min(u-P0,x+H);if(V.includes("s"))u=Math.max(x+P0,u+H);Z.x1=P,Z.y1=x,Z.x2=p,Z.y2=u}function N0(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,b=-1,B={x:0,y:0,size:24};function E(){let Z=J.getBoundingClientRect().width;return Z>0?Z/J.width:1}function H2(Z,V){if(!F)return Z.length*V*0.6;F.save(),F.font=`600 ${V}px system-ui, sans-serif`;let Y=F.measureText(Z||" ").width;return F.restore(),Y}function e0(){if(!L)return;let Z=J.parentElement;if(!Z)return;let V=J.getBoundingClientRect(),Y=Z.getBoundingClientRect(),X=E(),H=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=`${H}px`,L.style.width=`${Math.max(40,H2(L.value,H)+H)}px`}function Q0(Z){let V=L;if(!V)return;L=null;let Y=V.value.trim(),X=b;if(b=-1,V.remove(),Z&&Y){if(X>=0&&j[X])j[X].text=Y,K=X;else j.push({tool:"text",x1:B.x,y1:B.y,x2:B.x,y2:B.y,text:Y,size:B.size}),K=j.length-1;Q()}else if(X>=0)K=X;J.focus(),w()}function J1(Z,V,Y=-1){Q0(!0);let X=J.parentElement;if(!X)return;if(getComputedStyle(X).position==="static")X.style.position="relative";let H=Y>=0?j[Y]:void 0;b=Y,B={x:H?.x1??Z,y:H?.y1??V,size:H?.size??Math.round(24*M())};let U=document.createElement("input");U.type="text",U.className="text-edit",U.value=H?.text??"",U.setAttribute("aria-label","ข้อความบนภาพ"),U.placeholder="ข้อความ",L=U,X.append(U),e0(),U.addEventListener("input",e0),U.addEventListener("keydown",(P)=>{if(P.stopPropagation(),P.key==="Enter")Q0(!0);else if(P.key==="Escape")Q0(!1)}),requestAnimationFrame(()=>{if(L!==U)return;U.focus(),U.select(),U.addEventListener("blur",()=>Q0(!0))}),w()}function $1(Z){let{x:V,y:Y}=q(Z);if(J.setPointerCapture(Z.pointerId),c(V,Y)){q0();return}let X=$0(V,Y);if(X&&j[K]){G={grip:X,x:V,y:Y,start:{...j[K]}};return}if(z==="text"){if(Z.preventDefault(),J.hasPointerCapture(Z.pointerId))J.releasePointerCapture(Z.pointerId);z=null,Q(),J1(V,Y);return}if(z){W={tool:z,x1:V,y1:Y,x2:V,y2:Y},K=-1;return}let H=h(V,Y);K=H,G=H>=0?{grip:"body",x:V,y:Y,start:{...j[H]}}:null,w()}function Q1(Z){let{x:V,y:Y}=q(Z);if(W){W.x2=V,W.y2=Y,w();return}if(G){let H=j[K];if(!H)return;let U=V-G.x,P=Y-G.y;if(G.grip==="body")N0(H,G.start,U,P);else y(H,G.grip,G.start,U,P);w();return}if(z){J.style.cursor="crosshair";return}if(c(V,Y)){J.style.cursor="pointer";return}let X=$0(V,Y);if(X){let H=j[K]?O(j[K]).find((U)=>U.id===X):null;J.style.cursor=H?.cursor??"pointer";return}J.style.cursor=h(V,Y)>=0?"move":"default"}function X0(){if(W){if(!(Math.abs(W.x2-W.x1)<j2&&Math.abs(W.y2-W.y1)<j2))j.push(W),K=j.length-1,z=null,Q();W=null}if(G)G=null,Q();w()}function j1(Z){let V=J.getBoundingClientRect(),Y=(Z.clientX-V.left)/V.width*J.width,X=(Z.clientY-V.top)/V.height*J.height,H=h(Y,X),U=j[H];if(!U||U.tool!=="text")return;Z.preventDefault(),J1(U.x1,U.y1,H)}function z1(Z){if(K<0)return;if(Z.key==="Delete"||Z.key==="Backspace")Z.preventDefault(),q0();else if(Z.key==="Escape")K=-1,w()}function q0(){if(K<0)return;j.splice(K,1),K=-1,Q(),w()}return J.addEventListener("pointerdown",$1),J.addEventListener("pointermove",Q1),J.addEventListener("pointerup",X0),J.addEventListener("pointercancel",X0),J.addEventListener("dblclick",j1),J.tabIndex=0,J.addEventListener("keydown",z1),w(),{setTool(Z){z=Z,K=-1,J.style.cursor=Z?"crosshair":"default",w()},deleteSelected:q0,clear(){j.length=0,K=-1,Q(),w()},hasShapes:()=>j.length>0,hasSelection:()=>K>=0,toDataUrl(){let Z=document.createElement("canvas");Z.width=$.naturalWidth,Z.height=$.naturalHeight;let V=Z.getContext("2d");if(!V)return J.toDataURL("image/png");V.drawImage($,0,0);let Y=M();for(let X of j)_(V,X,Y);return Z.toDataURL("image/png")},destroy(){Q0(!1),J.removeEventListener("pointerdown",$1),J.removeEventListener("pointermove",Q1),J.removeEventListener("pointerup",X0),J.removeEventListener("pointercancel",X0),J.removeEventListener("dblclick",j1),J.removeEventListener("keydown",z1)}}}var z2=`
|
|
42
42
|
:host { all: initial; }
|
|
43
43
|
* { box-sizing: border-box; }
|
|
44
44
|
|
|
@@ -76,12 +76,6 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
76
76
|
font-size: 13px; line-height: 1.7; color: #475569; word-break: break-all;
|
|
77
77
|
}
|
|
78
78
|
.meta b { color: #0f172a; font-weight: 600; }
|
|
79
|
-
.meta .check {
|
|
80
|
-
display: flex; align-items: flex-start; gap: 8px; margin: 8px 0 0; padding-top: 8px;
|
|
81
|
-
border-top: 1px solid #e2e8f0; font-weight: 500; color: #0f172a; word-break: normal; cursor: pointer;
|
|
82
|
-
}
|
|
83
|
-
.meta .check input { margin: 5px 0 0; flex: none; accent-color: #2563eb; }
|
|
84
|
-
.meta .check .hint { display: block; font-size: 12px; line-height: 1.5; margin-top: 2px; }
|
|
85
79
|
|
|
86
80
|
.tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
87
81
|
.sep { width: 1px; align-self: stretch; background: #e2e8f0; margin: 0 4px; }
|
|
@@ -127,7 +121,7 @@ canvas { width: 100%; height: auto; display: block; border: 1px solid #e2e8f0; b
|
|
|
127
121
|
border-radius: 0 0 16px 16px;
|
|
128
122
|
}
|
|
129
123
|
.foot .grow { flex: 1; }
|
|
130
|
-
`;var J0="lw-debug-reporter",Z2=()=>[];function C6(J){Z2=J}var I6=[{tool:"rect",key:"toolRect"},{tool:"arrow",key:"toolArrow"},{tool:"highlight",key:"toolHighlight"},{tool:"text",key:"toolText"}];function P6(){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=A0(($)=>void this.open($))}disconnectedCallback(){this.stop?.(),this.stop=null,this.close()}async open($){if(this.busy)return;this.busy=!0;let Q=d(
|
|
124
|
+
`;var J0="lw-debug-reporter",Z2=()=>[];function C6(J){Z2=J}var I6=[{tool:"rect",key:"toolRect"},{tool:"arrow",key:"toolArrow"},{tool:"highlight",key:"toolHighlight"},{tool:"text",key:"toolText"}];function P6(){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=A0(($)=>void this.open($))}disconnectedCallback(){this.stop?.(),this.stop=null,this.close()}async open($){if(this.busy)return;this.busy=!0;let Q=d(S().locale),j=await b0();if(j.method==="cancelled"){this.close();return}this.bundle=y0({reason:$,note:"",screenshotDataUrl:j.dataUrl,screenshotMethod:j.method,erroredQueries:D6()}),this.renderForm(Q)}close(){this.annotator?.destroy(),this.annotator=null,this.bundle=null,this.busy=!1,this.root.replaceChildren()}shell($){let Q=document.createElement("style");Q.textContent=z2;let j=document.createElement("div");j.className="backdrop";let z=document.createElement("div");return z.className="panel",z.setAttribute("role","dialog"),z.setAttribute("aria-modal","true"),z.setAttribute("aria-label",$.title),j.append(z),this.root.replaceChildren(Q,j),z}renderShell($,Q){let j=this.shell($),z=T("div","head");z.append(T("h2","",$.title)),j.append(z,T("p","status",Q))}renderForm($){let Q=this.bundle;if(!Q)return;let j=this.shell($),z=T("div","head"),K=e("✕","icon");K.setAttribute("aria-label",$.close),K.addEventListener("click",()=>this.close()),z.append(T("h2","",$.title),K);let W=document.createElement("input");W.type="text",W.placeholder=$.summaryPlaceholder;let G=n0($.summaryLabel,$.summaryRequired,!0),F=document.createElement("textarea");F.placeholder=$.detailPlaceholder;let M=T("div","meta");M.innerHTML="";let{context:q}=Q;for(let[R,_]of[[$.reporter,`${q.user.fullName??"—"} (${q.user.email??"—"})`],[$.page,q.route.href],[$.captured,`${Q.network.length} network · ${Q.console.length} console · ${Q.actionTrail.length} actions${Q.replay?` · ${$.replay} ${Math.round(Q.replay.durationMs/1000)}s`:""}`]]){let N=document.createElement("div"),w=document.createElement("b");w.textContent=`${R}: `,N.append(w,document.createTextNode(_)),M.append(N)}let C=T("p","status",""),I=e($.submit,"primary");if(I.disabled=!0,W.addEventListener("input",()=>{I.disabled=W.value.trim().length===0}),j.append(z,G,W,n0($.detailLabel),F,M),Q.screenshotDataUrl)j.append(...this.screenshotSection($,Q.screenshotDataUrl));else j.append(T("p","status",$.noScreenshot));let O=T("div","foot"),D=e($.close);D.addEventListener("click",()=>this.close()),O.append(D,C,T("span","grow"),I),j.append(O),I.addEventListener("click",async()=>{I.disabled=!0,C.dataset.tone="",C.textContent=$.submitting;try{let R=await l0(W.value.trim(),{...Q,note:F.value,screenshotDataUrl:this.annotator?.hasShapes()?this.annotator.toDataUrl():Q.screenshotDataUrl}),_=this.dispatchEvent(new CustomEvent("lw-report-submitted",{detail:R,bubbles:!0,composed:!0,cancelable:!0}));if(this.close(),_)t(`${$.submitted} — #${R.number}`,"success")}catch(R){let _=R instanceof Error?R.message:$.failed;C.dataset.tone="error",C.textContent=_,t(`${$.failed} — ${_}`,"error"),I.disabled=!1}}),W.focus()}screenshotSection($,Q){let j=n0($.annotateHint),z=T("div","tools"),K=document.createElement("canvas"),W=T("div","shot");W.append(K);let G=[],F=(I)=>{for(let O of G)O.setAttribute("aria-pressed",String(O===I))};for(let{tool:I,key:O}of I6){let D=e($[O]);D.setAttribute("aria-pressed","false"),D.addEventListener("click",()=>{let R=D.getAttribute("aria-pressed")==="true";F(R?null:D),this.annotator?.setTool(R?null:I)}),G.push(D),z.append(D)}z.append(T("span","sep"));let M=e($.deleteSelected);M.addEventListener("click",()=>this.annotator?.deleteSelected());let q=e($.clearAll);q.addEventListener("click",()=>{this.annotator?.clear(),F(null)}),z.append(M,q);let C=new Image;return C.onload=()=>{K.width=C.naturalWidth,K.height=C.naturalHeight,this.annotator=s0(K,C,()=>{F(null),M.disabled=!this.annotator?.hasSelection()})},C.src=Q,[j,z,T("p","status",$.annotateHelp),W]}}}function D6(){try{return Z2()}catch{return[]}}function T(J,$="",Q=""){let j=document.createElement(J);if($)j.className=$;if(Q)j.textContent=Q;return j}function e(J,$=""){let Q=document.createElement("button");if(Q.type="button",Q.textContent=J,$)Q.className=$;return Q}function n0(J,$="",Q=!1){let j=document.createElement("label");if(j.append(document.createTextNode(J)),Q){let z=document.createElement("span");z.className="req",z.textContent=" *",j.append(z)}if($){let z=document.createElement("span");z.className="hint",z.textContent=` ${$}`,j.append(z)}return j}function a0(){if(typeof window>"u"||customElements.get(J0))return;customElements.define(J0,P6())}var K2=!1;function N6(J={}){if(K2||typeof window>"u")return;if(!j0()){console.error("[debug-capture] configureDebugCapture() must be called before install");return}if(K2=!0,b1(),S1(),P1(),A1(),u1(),J.ui===!1)return;let $=d(S().locale);if(E0((Q)=>{t(Q.message??$.crashed,"error",{label:$.crashAction,onClick:()=>x0(Q)})}),a0(),!document.querySelector(J0))document.body.append(document.createElement(J0))}var q6=new Set(["error","exception","unhandledrejection"]);function W2(J){if(J.error)return!0;return J.status!==null&&J.status>=400}function t0(J){if(!J)return null;let $=Date.parse(J);return Number.isNaN($)?null:$}function B6(J){try{let{pathname:$}=new URL(J,"http://x");try{return decodeURIComponent($)}catch{return $}}catch{return J.split(/[?#]/)[0]??J}}function S6(J,$,Q){let j=(W)=>({elapsedMs:W,requests:[],failedRequests:[],consoleErrors:[],slowestMs:null});if(J.length===0)return[];let z=J.map((W)=>t0(W.at)),K=(W)=>{for(let G=W+1;G<z.length;G+=1){let F=z[G];if(F!=null)return F}return Number.POSITIVE_INFINITY};return J.map((W,G)=>{let F=z[G]??null,M=(G>0?z[G-1]:null)??null,q=F!==null&&M!==null?Math.max(0,F-M):null;if(F===null)return j(q);let C=F,I=Math.max(C,K(G)),O=(N)=>N!==null&&N>=C&&(N<I||I===Number.POSITIVE_INFINITY),D=$.filter((N)=>O(t0(N.startedAt))),R=Q.filter((N)=>q6.has(N.level)&&O(t0(N.at))),_=D.map((N)=>N.durationMs).filter((N)=>typeof N==="number");return{elapsedMs:q,requests:D,failedRequests:D.filter(W2),consoleErrors:R,slowestMs:_.length>0?Math.max(..._):null}})}function O6(J,$){return J.requests.length===0&&J.consoleErrors.length===0&&(J.elapsedMs===null||J.elapsedMs<$)}function w6(J){if(J<1000)return`${Math.round(J)} มิลลิวินาที`;let $=J/1000;if($<10)return`${$.toFixed(1)} วิ`;if($<60)return`${Math.round($)} วิ`;let Q=Math.floor($/60),j=Math.round($%60);return j===0?`${Q} นาที`:`${Q} นาที ${j} วิ`}var R6="lw-portal-handoff",V2=138.23,_6=`
|
|
131
125
|
:host { all: initial; }
|
|
132
126
|
.backdrop {
|
|
133
127
|
position: fixed; inset: 0; z-index: 2147483002;
|
|
@@ -204,7 +198,7 @@ p { margin: 0; font-size: 13px; line-height: 1.6; color: #475569; }
|
|
|
204
198
|
.ring .bar { animation: none; stroke-dashoffset: 0; }
|
|
205
199
|
.spinner { animation-duration: 2s; }
|
|
206
200
|
}
|
|
207
|
-
`;function X2(J){if(typeof document>"u")return J.prepare().then((
|
|
201
|
+
`;function X2(J){if(typeof document>"u")return J.prepare().then((N)=>void J.go(N),()=>{return});let $=d(S().locale),Q=Math.max(1,Math.floor(J.seconds??3)),j=document.createElement(R6),z=j.attachShadow({mode:"open"}),K=document.createElement("style");K.textContent=_6,z.append(K);let W=document.createElement("div");W.className="backdrop",W.innerHTML=`
|
|
208
202
|
<div class="card" role="dialog" aria-modal="true" aria-labelledby="lw-ho-title">
|
|
209
203
|
<div class="dial">
|
|
210
204
|
<svg class="ring" viewBox="0 0 52 52" aria-hidden="true">
|
|
@@ -220,4 +214,4 @@ p { margin: 0; font-size: 13px; line-height: 1.6; color: #475569; }
|
|
|
220
214
|
<button type="button" class="cancel"></button>
|
|
221
215
|
<button type="button" class="go"></button>
|
|
222
216
|
</div>
|
|
223
|
-
</div>`,
|
|
217
|
+
</div>`,z.append(W);let G=(N)=>W.querySelector(N),F=G(".card"),M=G(".bar"),q=G(".count"),C=G("h2"),I=G(".body"),O=G(".host"),D=G(".go"),R=G(".cancel");C.textContent=$.handoffTitle,I.textContent=$.handoffBody;try{O.textContent=new URL(S().host).host}catch{O.textContent=""}D.textContent=$.handoffGo,R.textContent=$.cancel,F.style.setProperty("--secs",`${Q}s`),q.textContent=String(Q),document.body.append(j),requestAnimationFrame(()=>W.setAttribute("data-open","1"));let _=document.activeElement;return D.focus({preventScroll:!0}),new Promise((N)=>{let w=!1,v=null,$0=!1,c=Date.now()+Q*1000,h=window.setInterval(()=>{let B=Math.ceil((c-Date.now())/1000);if(q.textContent=String(Math.max(0,B)),Date.now()>=c)L()},100);function y(B){if(w)return;if(w=!0,window.clearInterval(h),document.removeEventListener("keydown",b,!0),W.removeAttribute("data-open"),window.setTimeout(()=>j.remove(),200),!B)_?.focus?.({preventScroll:!0});N()}function N0(B){window.clearInterval(h),M.classList.remove("spinner"),M.style.animation="none",q.textContent="",C.textContent=$.handoffBlocked,I.textContent=$.handoffBody;let E=document.createElement("a");E.className="go",E.href=B,E.target="_blank",E.rel="noopener noreferrer",E.textContent=$.handoffOpen,E.addEventListener("click",()=>y(!0)),D.replaceWith(E),E.focus({preventScroll:!0})}function L(){if(w||$0)return;if(v)return J.go(v)?y(!0):N0(v);window.clearInterval(h),q.textContent="",M.classList.add("spinner"),C.textContent=$.handoffPreparing}function b(B){if(B.key==="Escape")B.stopPropagation(),y(!1)}document.addEventListener("keydown",b,!0),D.addEventListener("click",L),R.addEventListener("click",()=>y(!1)),W.addEventListener("click",(B)=>{if(B.target===W)y(!1)}),J.prepare().then((B)=>{if(v=B,!w&&Date.now()>=c)L()},()=>{$0=!0,window.clearInterval(h),F.classList.add("error"),M.classList.remove("spinner"),M.style.animation="none",q.textContent="",C.textContent=$.handoffFailed,I.textContent=$.handoffBody,D.remove(),R.textContent=$.close})})}var L6="/sso";function F2(J,$,Q){let j=new URL(L6,J.endsWith("/")?J:`${J}/`);return j.searchParams.set("realm",$),j.searchParams.set("token",Q),j.toString()}class D0 extends Error{constructor(J="No identity provider is configured, or nobody is signed in"){super(J);this.name="NoIdentityError"}}async function G2(){let J=S();if(!J.identity)throw new D0;let $=await J.identity();if(!$)throw new D0;return F2(J.host,J.realmKey,$)}function Y2(J,$){if($==="_self")return window.location.assign(J),!0;let Q=window.open(J,"_blank");if(!Q)return!1;try{Q.opener=null}catch{}return!0}async function T6(J={}){if(J.announce===!1){Y2(await G2(),J.target);return}await X2({seconds:J.seconds,prepare:G2,go:($)=>Y2($,J.target)})}export{d0 as trimToBudget,o1 as toCurl,m0 as takeReplay,F2 as supportPortalUrl,l0 as submitBundle,_4 as stopReplay,t as showToast,C6 as setErroredQueriesSource,B6 as requestPath,d as reporterStrings,f as redactUrl,l as redactLabel,o as redactHeaders,r as redactBody,i0 as packReplay,T6 as openSupportPortal,A0 as onLaunch,E0 as onCrash,N2 as moduleResolver,x0 as launch,R4 as isReplayRecording,O6 as isQuietStep,W2 as isFailedRequest,j0 as isConfigured,N6 as installDebugCapture,l4 as hasCause,h0 as getNetworkLog,k0 as getConsoleLog,S as getConfig,L0 as getActionTrail,w6 as formatDuration,p0 as errorSignature,f0 as emitCrash,a0 as defineReporterElement,s0 as createAnnotator,S6 as correlateActionTrail,I2 as configureDebugCapture,b0 as captureScreen,d4 as bundleToMarkdown,i4 as bundleFileName,y0 as buildBundle,m as appInfo,R0 as actionCountSuffix,J0 as REPORTER_TAG,a1 as REPLAY_FILENAME,i as REDACTED,D0 as NoIdentityError,u0 as BUNDLE_BUDGET_BYTES};
|
package/dist/types.d.ts
CHANGED
|
@@ -196,7 +196,7 @@ export interface ReplaySummary {
|
|
|
196
196
|
bytes?: number;
|
|
197
197
|
compressed?: boolean;
|
|
198
198
|
/** Present when the host records but this report carries no replay. */
|
|
199
|
-
omitted?: "
|
|
199
|
+
omitted?: "too-large" | "empty";
|
|
200
200
|
}
|
|
201
201
|
export interface DebugBundle {
|
|
202
202
|
context: DebugContext;
|
|
@@ -211,10 +211,8 @@ export interface DebugBundle {
|
|
|
211
211
|
screenshotMethod: ScreenshotMethod;
|
|
212
212
|
/**
|
|
213
213
|
* The session replay, when the host records one. Its own attachment on the
|
|
214
|
-
* way out, like the screenshot — never inside the JSON bundle.
|
|
215
|
-
*
|
|
216
|
-
* Absent: nothing was recorded. `null`: there was one and the reporter
|
|
217
|
-
* chose to leave it out — the desk is told which.
|
|
214
|
+
* way out, like the screenshot — never inside the JSON bundle. Absent (or
|
|
215
|
+
* null) when nothing was recorded.
|
|
218
216
|
*/
|
|
219
217
|
replay?: ReplayCapture | null;
|
|
220
218
|
meta: {
|
package/dist/ui/strings.d.ts
CHANGED
|
@@ -38,9 +38,8 @@ export interface Strings {
|
|
|
38
38
|
captured: string;
|
|
39
39
|
reporter: string;
|
|
40
40
|
page: string;
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
replayWhat: string;
|
|
41
|
+
/** In the captured row: "… · replay 14s". */
|
|
42
|
+
replay: string;
|
|
44
43
|
/** The hand-off dialog, shown before leaving for the support portal. */
|
|
45
44
|
handoffTitle: string;
|
|
46
45
|
handoffBody: string;
|
package/dist/ui/styles.d.ts
CHANGED
|
@@ -10,4 +10,4 @@
|
|
|
10
10
|
* Everything is explicit for the same reason: the host's `body` font and colours
|
|
11
11
|
* do not inherit past the boundary, so stating them is not belt-and-braces.
|
|
12
12
|
*/
|
|
13
|
-
export declare const CSS = "\n:host { all: initial; }\n* { box-sizing: border-box; }\n\n.backdrop {\n position: fixed; inset: 0; z-index: 2147483000;\n display: flex; align-items: center; justify-content: center;\n padding: 24px; background: rgba(15, 23, 42, 0.55);\n font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Noto Sans Thai\", sans-serif;\n color: #0f172a;\n}\n.panel {\n display: flex; flex-direction: column; gap: 16px;\n width: min(820px, 100%); max-height: 90vh; overflow-y: auto;\n /* No bottom padding: the footer supplies its own and sits flush, so it can\n stick to the panel's edge without a gap under it. */\n padding: 24px 24px 0; border-radius: 16px; background: #fff;\n box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);\n}\n.head { display: flex; align-items: flex-start; gap: 12px; }\nh2 { margin: 0; font-size: 20px; font-weight: 700; flex: 1; }\nlabel { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; }\n.req { color: #dc2626; }\n.hint { font-weight: 400; color: #64748b; }\ninput[type=\"text\"], textarea {\n width: 100%; padding: 10px 12px; font: inherit; font-size: 14px;\n border: 1px solid #cbd5e1; border-radius: 10px; background: #fff; color: inherit;\n}\ninput[type=\"text\"]:focus, textarea:focus {\n outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);\n}\ntextarea { min-height: 88px; resize: vertical; }\n\n.meta {\n padding: 12px 14px; border-radius: 10px; background: #f8fafc;\n font-size: 13px; line-height: 1.7; color: #475569; word-break: break-all;\n}\n.meta b { color: #0f172a; font-weight: 600; }\n
|
|
13
|
+
export declare const CSS = "\n:host { all: initial; }\n* { box-sizing: border-box; }\n\n.backdrop {\n position: fixed; inset: 0; z-index: 2147483000;\n display: flex; align-items: center; justify-content: center;\n padding: 24px; background: rgba(15, 23, 42, 0.55);\n font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Noto Sans Thai\", sans-serif;\n color: #0f172a;\n}\n.panel {\n display: flex; flex-direction: column; gap: 16px;\n width: min(820px, 100%); max-height: 90vh; overflow-y: auto;\n /* No bottom padding: the footer supplies its own and sits flush, so it can\n stick to the panel's edge without a gap under it. */\n padding: 24px 24px 0; border-radius: 16px; background: #fff;\n box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);\n}\n.head { display: flex; align-items: flex-start; gap: 12px; }\nh2 { margin: 0; font-size: 20px; font-weight: 700; flex: 1; }\nlabel { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; }\n.req { color: #dc2626; }\n.hint { font-weight: 400; color: #64748b; }\ninput[type=\"text\"], textarea {\n width: 100%; padding: 10px 12px; font: inherit; font-size: 14px;\n border: 1px solid #cbd5e1; border-radius: 10px; background: #fff; color: inherit;\n}\ninput[type=\"text\"]:focus, textarea:focus {\n outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.18);\n}\ntextarea { min-height: 88px; resize: vertical; }\n\n.meta {\n padding: 12px 14px; border-radius: 10px; background: #f8fafc;\n font-size: 13px; line-height: 1.7; color: #475569; word-break: break-all;\n}\n.meta b { color: #0f172a; font-weight: 600; }\n\n.tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }\n.sep { width: 1px; align-self: stretch; background: #e2e8f0; margin: 0 4px; }\nbutton {\n display: inline-flex; align-items: center; gap: 6px; cursor: pointer;\n padding: 8px 14px; font: inherit; font-size: 14px; font-weight: 500;\n border: 1px solid #cbd5e1; border-radius: 10px; background: #fff; color: inherit;\n}\nbutton:hover:not(:disabled) { background: #f1f5f9; }\nbutton:disabled { opacity: 0.5; cursor: not-allowed; }\nbutton[aria-pressed=\"true\"] { border-color: #2563eb; background: #eff6ff; color: #1d4ed8; }\nbutton.primary { background: #2563eb; border-color: #2563eb; color: #fff; }\nbutton.primary:hover:not(:disabled) { background: #1d4ed8; }\nbutton.icon { padding: 6px 10px; border-color: transparent; font-size: 18px; line-height: 1; }\n\n/* The on-image text editor. Absolutely placed over the canvas and matched to\n the shape it becomes \u2014 same weight, same red, same white plate \u2014 so what you\n type is what gets drawn, at the position you clicked. Sized in JS, because\n the font size tracks the image's own scale. */\n.text-edit {\n position: absolute; z-index: 2; margin: 0; padding: 2px 4px;\n font-family: system-ui, sans-serif; font-weight: 600; line-height: 1.25;\n color: #e11d48; background: rgba(255, 255, 255, 0.92);\n border: 1px dashed #e11d48; border-radius: 4px; outline: none;\n box-shadow: 0 2px 10px rgba(15, 23, 42, 0.18);\n}\n.text-edit::placeholder { color: rgba(225, 29, 72, 0.45); }\n\ncanvas { width: 100%; height: auto; display: block; border: 1px solid #e2e8f0; border-radius: 10px; touch-action: none; }\n.shot { position: relative; }\n.status { font-size: 13px; color: #64748b; }\n.status[data-tone=\"error\"] { color: #dc2626; }\n/* Pinned to the bottom of the scrolling panel.\n A screenshot is tall \u2014 often taller than the viewport \u2014 so \u0E41\u0E08\u0E49\u0E07\u0E1B\u0E31\u0E0D\u0E2B\u0E32 sat\n below the fold and the last step of filing a report was \"scroll to the end\n and find the button\". Sticky, with its own ground and a rule above it so the\n annotated image scrolls underneath rather than bleeding into it. */\n.foot {\n position: sticky; bottom: 0; z-index: 3;\n display: flex; align-items: center; gap: 12px;\n margin: 4px -24px 0; padding: 12px 24px;\n background: #fff; border-top: 1px solid #e2e8f0;\n border-radius: 0 0 16px 16px;\n}\n.foot .grow { flex: 1; }\n";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightworkai.official/debug-capture",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "Report-a-problem widget: rolling network/console/action capture, optional rrweb session replay, annotated screenshot, and submission to a Lightwork Support host",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.mjs",
|
package/src/bundle.ts
CHANGED
|
@@ -55,9 +55,7 @@ export function buildBundle(input: BuildBundleInput): DebugBundle {
|
|
|
55
55
|
console: consoleLog,
|
|
56
56
|
screenshotDataUrl: input.screenshotDataUrl,
|
|
57
57
|
screenshotMethod: input.screenshotMethod,
|
|
58
|
-
// Taken now, before the reporter's own dialog is on the page.
|
|
59
|
-
// nothing was recorded; the dialog sets it to null when the reporter
|
|
60
|
-
// chooses to leave it out, and the two mean different things to the desk.
|
|
58
|
+
// Taken now, before the reporter's own dialog is on the page.
|
|
61
59
|
replay: takeReplay() ?? undefined,
|
|
62
60
|
meta: {
|
|
63
61
|
generatedBy: 'lightwork-debug-capture',
|
package/src/capture/replay.ts
CHANGED
|
@@ -92,7 +92,11 @@ async function start(options: NonNullable<ReturnType<typeof replayOptions>>): Pr
|
|
|
92
92
|
// Every value typed into anything, masked before it is recorded. The
|
|
93
93
|
// player shows the field being filled with asterisks.
|
|
94
94
|
maskAllInputs: true,
|
|
95
|
-
...
|
|
95
|
+
// ...and the same for what is typed where there is no input: a
|
|
96
|
+
// contenteditable editor's text is DOM text, which maskAllInputs never
|
|
97
|
+
// sees. Masked by selector instead, together with any region the
|
|
98
|
+
// host marks; or everything, when the host says so.
|
|
99
|
+
maskTextSelector: options.maskText ? "*" : options.maskTextSelector,
|
|
96
100
|
blockSelector: `${options.blockSelector}, ${OWN_UI}`,
|
|
97
101
|
// Scripts, comments and <meta> tags are weight the player never uses.
|
|
98
102
|
slimDOMOptions: "all",
|
|
@@ -163,5 +167,5 @@ export function stopReplay(): void {
|
|
|
163
167
|
windows = [];
|
|
164
168
|
}
|
|
165
169
|
|
|
166
|
-
/** Test seam: feed events as the recorder would. */
|
|
167
|
-
export const _replayInternals = { push, reset: () => void (windows = []) };
|
|
170
|
+
/** Test seam: feed events as the recorder would, or start against a fake recorder. */
|
|
171
|
+
export const _replayInternals = { push, reset: () => void (windows = []), start };
|
package/src/config.ts
CHANGED
|
@@ -211,7 +211,15 @@ export interface ReplayOptions {
|
|
|
211
211
|
* dialog and toasts are always excluded.
|
|
212
212
|
*/
|
|
213
213
|
blockSelector?: string;
|
|
214
|
-
/**
|
|
214
|
+
/**
|
|
215
|
+
* Elements whose TEXT is masked (each character a `*`) while their layout
|
|
216
|
+
* is kept. Default: editable `[contenteditable]` and `[data-lw-mask]`. A rich-text editor
|
|
217
|
+
* is where typing happens without an `<input>`, so what is written there is
|
|
218
|
+
* masked the way a field's value is; `data-lw-mask` marks any other region
|
|
219
|
+
* whose words matter but whose shape is enough — a table of names.
|
|
220
|
+
*/
|
|
221
|
+
maskTextSelector?: string;
|
|
222
|
+
/** Mask every piece of text, not only what is typed. Default false. */
|
|
215
223
|
maskText?: boolean;
|
|
216
224
|
/**
|
|
217
225
|
* The most a replay may weigh once compressed. A report still files when its
|
|
@@ -344,6 +352,7 @@ export function overlaySelectors(): string[] {
|
|
|
344
352
|
const REPLAY_DEFAULTS: Required<ReplayOptions> = {
|
|
345
353
|
seconds: 60,
|
|
346
354
|
blockSelector: "[data-lw-private]",
|
|
355
|
+
maskTextSelector: '[contenteditable]:not([contenteditable="false"]), [data-lw-mask]',
|
|
347
356
|
maskText: false,
|
|
348
357
|
maxBytes: 4_000_000,
|
|
349
358
|
};
|
|
@@ -358,6 +367,7 @@ export function replayOptions(): Required<ReplayOptions> | null {
|
|
|
358
367
|
return {
|
|
359
368
|
seconds,
|
|
360
369
|
blockSelector: given.blockSelector?.trim() || REPLAY_DEFAULTS.blockSelector,
|
|
370
|
+
maskTextSelector: given.maskTextSelector?.trim() || REPLAY_DEFAULTS.maskTextSelector,
|
|
361
371
|
maskText: given.maskText === true,
|
|
362
372
|
maxBytes,
|
|
363
373
|
};
|
package/src/submit.ts
CHANGED
|
@@ -76,20 +76,17 @@ export async function submitBundle(title: string, bundle: DebugBundle): Promise<
|
|
|
76
76
|
attachments.push(bundleAttachment(trimmed));
|
|
77
77
|
|
|
78
78
|
/*
|
|
79
|
-
* The replay, when there is one, as the third file.
|
|
80
|
-
*
|
|
81
|
-
* a
|
|
82
|
-
*
|
|
79
|
+
* The replay, when there is one, as the third file. Taken the way the
|
|
80
|
+
* network and console logs are — it is the support team's debug log, not
|
|
81
|
+
* a question put to the reporter — and when a recording host has none to
|
|
82
|
+
* send, the desk is told why rather than left to wonder.
|
|
83
83
|
*/
|
|
84
84
|
let replay: ReplaySummary | undefined;
|
|
85
85
|
const recording = replayOptions();
|
|
86
86
|
if (recording) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
replay = packed.summary;
|
|
91
|
-
if ("dataUri" in packed) attachments.push({ dataUri: packed.dataUri, filename: packed.filename });
|
|
92
|
-
}
|
|
87
|
+
const packed = await packReplay(trimmed.replay, recording.maxBytes);
|
|
88
|
+
replay = packed.summary;
|
|
89
|
+
if ("dataUri" in packed) attachments.push({ dataUri: packed.dataUri, filename: packed.filename });
|
|
93
90
|
}
|
|
94
91
|
|
|
95
92
|
/*
|
package/src/types.ts
CHANGED
|
@@ -195,7 +195,7 @@ export interface ReplaySummary {
|
|
|
195
195
|
bytes?: number;
|
|
196
196
|
compressed?: boolean;
|
|
197
197
|
/** Present when the host records but this report carries no replay. */
|
|
198
|
-
omitted?: "
|
|
198
|
+
omitted?: "too-large" | "empty";
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
export interface DebugBundle {
|
|
@@ -211,10 +211,8 @@ export interface DebugBundle {
|
|
|
211
211
|
screenshotMethod: ScreenshotMethod;
|
|
212
212
|
/**
|
|
213
213
|
* The session replay, when the host records one. Its own attachment on the
|
|
214
|
-
* way out, like the screenshot — never inside the JSON bundle.
|
|
215
|
-
*
|
|
216
|
-
* Absent: nothing was recorded. `null`: there was one and the reporter
|
|
217
|
-
* chose to leave it out — the desk is told which.
|
|
214
|
+
* way out, like the screenshot — never inside the JSON bundle. Absent (or
|
|
215
|
+
* null) when nothing was recorded.
|
|
218
216
|
*/
|
|
219
217
|
replay?: ReplayCapture | null;
|
|
220
218
|
meta: { generatedBy: string; schemaVersion: number };
|
package/src/ui/element.ts
CHANGED
|
@@ -183,9 +183,17 @@ function createReporterClass(): CustomElementConstructor {
|
|
|
183
183
|
// environment became optional, and it was telling the person filing the
|
|
184
184
|
// report something only the person reading it needs — both still travel
|
|
185
185
|
// with the bundle.
|
|
186
|
+
//
|
|
187
|
+
// The replay counts as one more thing captured, listed with the rest.
|
|
188
|
+
// It is the support team's debug log, taken the way the network and
|
|
189
|
+
// console logs are — not a choice put to the reporter. There was a
|
|
190
|
+
// tick box here once; the platform owner's call was that a report
|
|
191
|
+
// should always carry what makes it reproducible.
|
|
186
192
|
[
|
|
187
193
|
t.captured,
|
|
188
|
-
`${bundle.network.length} network · ${bundle.console.length} console · ${bundle.actionTrail.length} actions
|
|
194
|
+
`${bundle.network.length} network · ${bundle.console.length} console · ${bundle.actionTrail.length} actions${
|
|
195
|
+
bundle.replay ? ` · ${t.replay} ${Math.round(bundle.replay.durationMs / 1000)}s` : ""
|
|
196
|
+
}`,
|
|
189
197
|
],
|
|
190
198
|
] as [string, string][]) {
|
|
191
199
|
const row = document.createElement("div");
|
|
@@ -197,15 +205,6 @@ function createReporterClass(): CustomElementConstructor {
|
|
|
197
205
|
meta.append(row);
|
|
198
206
|
}
|
|
199
207
|
|
|
200
|
-
/*
|
|
201
|
-
* The replay is offered, not imposed. A recording of the screen is the
|
|
202
|
-
* most personal thing in a report, and the person filing it decides
|
|
203
|
-
* whether it goes — ticked by default because it is why the host turned
|
|
204
|
-
* it on, with one line saying what it is and is not.
|
|
205
|
-
*/
|
|
206
|
-
const replayRow = bundle.replay ? this.replayConsent(t, bundle.replay.durationMs) : null;
|
|
207
|
-
if (replayRow) meta.append(replayRow.row);
|
|
208
|
-
|
|
209
208
|
const status = el("p", "status", "");
|
|
210
209
|
const submitBtn = button(t.submit, "primary");
|
|
211
210
|
submitBtn.disabled = true;
|
|
@@ -231,8 +230,6 @@ function createReporterClass(): CustomElementConstructor {
|
|
|
231
230
|
const filed = await submitBundle(summary.value.trim(), {
|
|
232
231
|
...bundle,
|
|
233
232
|
note: detail.value,
|
|
234
|
-
// Null, not absent: "left out on purpose" is worth telling the desk.
|
|
235
|
-
...(replayRow && !replayRow.box.checked ? { replay: null } : {}),
|
|
236
233
|
// Take the annotated image, not the raw capture — the drawing IS the
|
|
237
234
|
// report for most people.
|
|
238
235
|
screenshotDataUrl: this.annotator?.hasShapes()
|
|
@@ -268,19 +265,6 @@ function createReporterClass(): CustomElementConstructor {
|
|
|
268
265
|
summary.focus();
|
|
269
266
|
}
|
|
270
267
|
|
|
271
|
-
private replayConsent(t: Strings, durationMs: number): { row: HTMLElement; box: HTMLInputElement } {
|
|
272
|
-
const row = el("label", "check");
|
|
273
|
-
const box = document.createElement("input");
|
|
274
|
-
box.type = "checkbox";
|
|
275
|
-
box.checked = true;
|
|
276
|
-
const text = el("span", "", t.replayAttach.replace("{seconds}", String(Math.round(durationMs / 1000))));
|
|
277
|
-
const what = el("small", "hint", t.replayWhat);
|
|
278
|
-
const words = el("span", "grow");
|
|
279
|
-
words.append(text, what);
|
|
280
|
-
row.append(box, words);
|
|
281
|
-
return { row, box };
|
|
282
|
-
}
|
|
283
|
-
|
|
284
268
|
private screenshotSection(t: Strings, dataUrl: string): HTMLElement[] {
|
|
285
269
|
const label = labelFor(t.annotateHint);
|
|
286
270
|
const tools = el("div", "tools");
|
package/src/ui/strings.ts
CHANGED
|
@@ -38,9 +38,8 @@ export interface Strings {
|
|
|
38
38
|
captured: string;
|
|
39
39
|
reporter: string;
|
|
40
40
|
page: string;
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
replayWhat: string;
|
|
41
|
+
/** In the captured row: "… · replay 14s". */
|
|
42
|
+
replay: string;
|
|
44
43
|
/** The hand-off dialog, shown before leaving for the support portal. */
|
|
45
44
|
handoffTitle: string;
|
|
46
45
|
handoffBody: string;
|
|
@@ -83,8 +82,7 @@ const th: Strings = {
|
|
|
83
82
|
captured: "เก็บข้อมูลแล้ว",
|
|
84
83
|
reporter: "ผู้แจ้ง",
|
|
85
84
|
page: "หน้า",
|
|
86
|
-
|
|
87
|
-
replayWhat: "บันทึกเฉพาะโครงสร้างหน้าจอและการคลิก — ข้อความที่พิมพ์ในช่องกรอกถูกปิดบังไว้",
|
|
85
|
+
replay: "บันทึกหน้าจอ",
|
|
88
86
|
handoffTitle: "กำลังพาไปที่ระบบแจ้งปัญหา",
|
|
89
87
|
handoffBody: "ระบบจะลงชื่อเข้าใช้ให้อัตโนมัติ เพื่อดูเรื่องที่คุณแจ้งไว้",
|
|
90
88
|
handoffGo: "ไปเลย",
|
|
@@ -126,8 +124,7 @@ const en: Strings = {
|
|
|
126
124
|
captured: "Captured",
|
|
127
125
|
reporter: "Reporter",
|
|
128
126
|
page: "Page",
|
|
129
|
-
|
|
130
|
-
replayWhat: "The page and your clicks are recorded, not a video — anything typed into a field is masked",
|
|
127
|
+
replay: "replay",
|
|
131
128
|
handoffTitle: "Opening the support portal",
|
|
132
129
|
handoffBody: "You will be signed in automatically to see what you reported",
|
|
133
130
|
handoffGo: "Go now",
|
package/src/ui/styles.ts
CHANGED
|
@@ -48,12 +48,6 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
48
48
|
font-size: 13px; line-height: 1.7; color: #475569; word-break: break-all;
|
|
49
49
|
}
|
|
50
50
|
.meta b { color: #0f172a; font-weight: 600; }
|
|
51
|
-
.meta .check {
|
|
52
|
-
display: flex; align-items: flex-start; gap: 8px; margin: 8px 0 0; padding-top: 8px;
|
|
53
|
-
border-top: 1px solid #e2e8f0; font-weight: 500; color: #0f172a; word-break: normal; cursor: pointer;
|
|
54
|
-
}
|
|
55
|
-
.meta .check input { margin: 5px 0 0; flex: none; accent-color: #2563eb; }
|
|
56
|
-
.meta .check .hint { display: block; font-size: 12px; line-height: 1.5; margin-top: 2px; }
|
|
57
51
|
|
|
58
52
|
.tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
59
53
|
.sep { width: 1px; align-self: stretch; background: #e2e8f0; margin: 0 4px; }
|