issue-sticker 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +33 -0
- package/dist/{externalUserPayload-k9LSBeMB.js → externalUserPayload-CVp5Hz2L.js} +1027 -601
- package/dist/issue-sticker-headless-react.js +158 -22
- package/dist/issue-sticker-headless.js +43 -10
- package/dist/issue-sticker-react.js +442 -109
- package/dist/{mouse-pointer-2-BR00y3ir.js → three-B7nbYqGK.js} +855 -12
- package/dist/{tooltip-DH02R32-.js → tooltip-BBukUPo_.js} +1 -1
- package/headless-react.d.ts +26 -0
- package/headless.d.ts +28 -0
- package/package.json +6 -2
- package/react.d.ts +28 -0
|
@@ -2,6 +2,772 @@ import * as React from "react";
|
|
|
2
2
|
import { useLayoutEffect, forwardRef, createElement } from "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import * as ReactDOM from "react-dom";
|
|
5
|
+
function forEachElementDeep(root2, callback) {
|
|
6
|
+
if (root2 instanceof Element) {
|
|
7
|
+
callback(root2);
|
|
8
|
+
if (root2.shadowRoot) {
|
|
9
|
+
forEachElementDeep(root2.shadowRoot, callback);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
Array.from(root2.children).forEach((child) => {
|
|
13
|
+
forEachElementDeep(child, callback);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const SESSION_REPLAY_BLOCK_CLASS = "rr-block";
|
|
17
|
+
const SESSION_REPLAY_MASK_CLASS = "rr-mask";
|
|
18
|
+
const SESSION_REPLAY_UNMASK_CLASS = "rr-unmask";
|
|
19
|
+
const FOREIGN_BLOCK_SELECTORS = [
|
|
20
|
+
// FullStory
|
|
21
|
+
".fs-exclude",
|
|
22
|
+
".fs-block",
|
|
23
|
+
// Sentry — ignore 는 의미가 "입력 이벤트를 기록하지 않는다"라 차단과 어긋나지만,
|
|
24
|
+
// 빼면 이미 그것에 기대고 있는 고객에게 회귀다. 과잉 마스킹은 안전한 방향이라 둔다.
|
|
25
|
+
".sentry-block",
|
|
26
|
+
".sentry-ignore",
|
|
27
|
+
"[data-sentry-block]",
|
|
28
|
+
// PostHog
|
|
29
|
+
".ph-no-capture",
|
|
30
|
+
// Hotjar
|
|
31
|
+
"[data-hj-suppress]",
|
|
32
|
+
// OpenReplay
|
|
33
|
+
"[data-openreplay-hidden]",
|
|
34
|
+
// Highlight.io
|
|
35
|
+
".highlight-block",
|
|
36
|
+
".highlight-ignore",
|
|
37
|
+
// Heap
|
|
38
|
+
"[data-heap-ignore]",
|
|
39
|
+
".heap-ignore"
|
|
40
|
+
];
|
|
41
|
+
const FOREIGN_MASK_SELECTORS = [
|
|
42
|
+
// FullStory
|
|
43
|
+
".fs-mask",
|
|
44
|
+
// Sentry
|
|
45
|
+
".sentry-mask",
|
|
46
|
+
"[data-sentry-mask]",
|
|
47
|
+
// LogRocket
|
|
48
|
+
"[data-private]",
|
|
49
|
+
// Microsoft Clarity
|
|
50
|
+
"[data-clarity-mask]",
|
|
51
|
+
// Hotjar
|
|
52
|
+
"[data-hj-masked]",
|
|
53
|
+
// OpenReplay
|
|
54
|
+
"[data-openreplay-obscured]",
|
|
55
|
+
// Highlight.io
|
|
56
|
+
".highlight-mask",
|
|
57
|
+
// ContentSquare
|
|
58
|
+
"[data-cs-mask]",
|
|
59
|
+
"[data-cs-encrypt]",
|
|
60
|
+
// Heap
|
|
61
|
+
"[data-heap-redact-text]",
|
|
62
|
+
"[data-heap-redact-attributes]",
|
|
63
|
+
// Amplitude
|
|
64
|
+
"[data-amp-mask]",
|
|
65
|
+
// Matomo
|
|
66
|
+
"[data-matomo-mask]"
|
|
67
|
+
];
|
|
68
|
+
const FOREIGN_UNMASK_SELECTORS = [
|
|
69
|
+
".fs-unmask",
|
|
70
|
+
".sentry-unmask",
|
|
71
|
+
"[data-clarity-unmask]",
|
|
72
|
+
"[data-amp-unmask]",
|
|
73
|
+
"[data-cs-capture]"
|
|
74
|
+
];
|
|
75
|
+
const SESSION_REPLAY_FULL_MASK_SELECTOR = [
|
|
76
|
+
`.${SESSION_REPLAY_MASK_CLASS}`,
|
|
77
|
+
...FOREIGN_MASK_SELECTORS
|
|
78
|
+
].join(",");
|
|
79
|
+
const SESSION_REPLAY_BLOCK_SELECTOR = [
|
|
80
|
+
`.${SESSION_REPLAY_BLOCK_CLASS}`,
|
|
81
|
+
...FOREIGN_BLOCK_SELECTORS
|
|
82
|
+
].join(",");
|
|
83
|
+
const SESSION_REPLAY_UNMASK_SELECTOR = [
|
|
84
|
+
`.${SESSION_REPLAY_UNMASK_CLASS}`,
|
|
85
|
+
...FOREIGN_UNMASK_SELECTORS
|
|
86
|
+
].join(",");
|
|
87
|
+
function isElementFullyMasked(element, maskSelector = SESSION_REPLAY_FULL_MASK_SELECTOR, unmaskSelector = SESSION_REPLAY_UNMASK_SELECTOR) {
|
|
88
|
+
if (!element) return false;
|
|
89
|
+
try {
|
|
90
|
+
const nearest = element.closest(`${maskSelector},${unmaskSelector}`);
|
|
91
|
+
return nearest !== null && nearest.matches(maskSelector);
|
|
92
|
+
} catch {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const DEFAULT_PRIVACY_CONFIG_V2 = {
|
|
97
|
+
version: "v2",
|
|
98
|
+
maskAllInputs: true,
|
|
99
|
+
maskTextSelector: "*",
|
|
100
|
+
fullMaskSelector: SESSION_REPLAY_FULL_MASK_SELECTOR,
|
|
101
|
+
unmaskSelector: SESSION_REPLAY_UNMASK_SELECTOR,
|
|
102
|
+
blockSelector: SESSION_REPLAY_BLOCK_SELECTOR,
|
|
103
|
+
allowCanvasRecording: false
|
|
104
|
+
};
|
|
105
|
+
function resolvePrivacyConfig(override) {
|
|
106
|
+
if (!override) return DEFAULT_PRIVACY_CONFIG_V2;
|
|
107
|
+
return { ...DEFAULT_PRIVACY_CONFIG_V2, ...override };
|
|
108
|
+
}
|
|
109
|
+
const REDACTED_HEADER_VALUE = "[redacted]";
|
|
110
|
+
const SENSITIVE_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
111
|
+
"authorization",
|
|
112
|
+
"proxy-authorization",
|
|
113
|
+
"cookie",
|
|
114
|
+
"set-cookie",
|
|
115
|
+
"x-api-key",
|
|
116
|
+
"api-key",
|
|
117
|
+
"apikey",
|
|
118
|
+
"x-auth-token",
|
|
119
|
+
"x-access-token",
|
|
120
|
+
"x-refresh-token",
|
|
121
|
+
"x-session-token",
|
|
122
|
+
"x-csrf-token",
|
|
123
|
+
"x-xsrf-token",
|
|
124
|
+
"x-amz-security-token",
|
|
125
|
+
"x-goog-api-key"
|
|
126
|
+
]);
|
|
127
|
+
function isSensitiveHeaderName(headerName) {
|
|
128
|
+
return SENSITIVE_HEADER_NAMES.has(headerName.toLowerCase());
|
|
129
|
+
}
|
|
130
|
+
function redactSensitiveHeaders(headers) {
|
|
131
|
+
if (!headers) return headers;
|
|
132
|
+
let changed = false;
|
|
133
|
+
const redacted = {};
|
|
134
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
135
|
+
if (value && isSensitiveHeaderName(name)) {
|
|
136
|
+
redacted[name] = REDACTED_HEADER_VALUE;
|
|
137
|
+
changed = true;
|
|
138
|
+
} else {
|
|
139
|
+
redacted[name] = value;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return changed ? redacted : headers;
|
|
143
|
+
}
|
|
144
|
+
const REDACTED_BODY_VALUE = "[redacted]";
|
|
145
|
+
const SENSITIVE_KEY_MARKERS = [
|
|
146
|
+
"password",
|
|
147
|
+
"passwd",
|
|
148
|
+
"pwd",
|
|
149
|
+
"secret",
|
|
150
|
+
"token",
|
|
151
|
+
"apikey",
|
|
152
|
+
"privatekey",
|
|
153
|
+
"credential",
|
|
154
|
+
// 결제·본인확인 계열. 토스페이먼츠 공식 문서의 필드명을 그대로 딴다.
|
|
155
|
+
// cardNumber / customerIdentityNumber / businessNumber / accountNumber(가상계좌)
|
|
156
|
+
"cardnumber",
|
|
157
|
+
"identitynumber",
|
|
158
|
+
"businessnumber",
|
|
159
|
+
"registrationnumber",
|
|
160
|
+
"accountnumber"
|
|
161
|
+
];
|
|
162
|
+
const SENSITIVE_KEY_EXACT = /* @__PURE__ */ new Set([
|
|
163
|
+
"otp",
|
|
164
|
+
"auth",
|
|
165
|
+
"authorization",
|
|
166
|
+
"bearer",
|
|
167
|
+
// 토스페이먼츠. billingKey + customerKey 조합이면 결제를 낼 수 있고, authKey 는 일회성
|
|
168
|
+
// 인증 키다(우리 admin 결제 성공 URL 의 쿼리 파라미터로 실제로 실린다).
|
|
169
|
+
// paymentKey 는 넣지 않는다 — 시크릿 키 없이는 아무것도 못 하는 식별자이고, 결제 장애
|
|
170
|
+
// 진단의 출발점이라 가리면 로그가 쓸모를 잃는다.
|
|
171
|
+
"billingkey",
|
|
172
|
+
"customerkey",
|
|
173
|
+
"authkey"
|
|
174
|
+
]);
|
|
175
|
+
const MAX_WALK_DEPTH = 20;
|
|
176
|
+
function isSensitiveFieldName(name) {
|
|
177
|
+
const normalized = name.toLowerCase().replace(/[-_\s]/g, "");
|
|
178
|
+
if (SENSITIVE_KEY_EXACT.has(normalized)) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
return SENSITIVE_KEY_MARKERS.some((marker) => normalized.includes(marker));
|
|
182
|
+
}
|
|
183
|
+
function redactJsonValue(value, depth) {
|
|
184
|
+
if (typeof value === "string") {
|
|
185
|
+
const redacted = redactSensitiveValues(value);
|
|
186
|
+
return { value: redacted, changed: redacted !== value };
|
|
187
|
+
}
|
|
188
|
+
if (depth > MAX_WALK_DEPTH || value === null || typeof value !== "object") {
|
|
189
|
+
return { value, changed: false };
|
|
190
|
+
}
|
|
191
|
+
if (Array.isArray(value)) {
|
|
192
|
+
let changed2 = false;
|
|
193
|
+
const next2 = value.map((item) => {
|
|
194
|
+
const result2 = redactJsonValue(item, depth + 1);
|
|
195
|
+
changed2 || (changed2 = result2.changed);
|
|
196
|
+
return result2.value;
|
|
197
|
+
});
|
|
198
|
+
return changed2 ? { value: next2, changed: changed2 } : { value, changed: changed2 };
|
|
199
|
+
}
|
|
200
|
+
let changed = false;
|
|
201
|
+
const next = {};
|
|
202
|
+
for (const [key, item] of Object.entries(value)) {
|
|
203
|
+
if (item !== "" && item != null && typeof item !== "boolean" && isSensitiveFieldName(key)) {
|
|
204
|
+
next[key] = REDACTED_BODY_VALUE;
|
|
205
|
+
changed = true;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const result2 = redactJsonValue(item, depth + 1);
|
|
209
|
+
changed || (changed = result2.changed);
|
|
210
|
+
next[key] = result2.value;
|
|
211
|
+
}
|
|
212
|
+
return changed ? { value: next, changed } : { value, changed };
|
|
213
|
+
}
|
|
214
|
+
function redactKeyValuePairs(body) {
|
|
215
|
+
let changed = false;
|
|
216
|
+
const redacted = body.split("&").map((pair) => {
|
|
217
|
+
const separator = pair.indexOf("=");
|
|
218
|
+
if (separator <= 0) {
|
|
219
|
+
return pair;
|
|
220
|
+
}
|
|
221
|
+
const rawKey = pair.slice(0, separator);
|
|
222
|
+
const rawValue = pair.slice(separator + 1);
|
|
223
|
+
if (!rawValue) {
|
|
224
|
+
return pair;
|
|
225
|
+
}
|
|
226
|
+
if (isSensitiveFieldName(decodeURIComponent(rawKey))) {
|
|
227
|
+
changed = true;
|
|
228
|
+
return `${rawKey}=${encodeURIComponent(REDACTED_BODY_VALUE)}`;
|
|
229
|
+
}
|
|
230
|
+
const redactedValue = redactSensitiveValues(decodeURIComponent(rawValue));
|
|
231
|
+
if (redactedValue === decodeURIComponent(rawValue)) {
|
|
232
|
+
return pair;
|
|
233
|
+
}
|
|
234
|
+
changed = true;
|
|
235
|
+
return `${rawKey}=${encodeURIComponent(redactedValue)}`;
|
|
236
|
+
}).join("&");
|
|
237
|
+
return changed ? redacted : body;
|
|
238
|
+
}
|
|
239
|
+
function looksLikeFormUrlEncoded(body) {
|
|
240
|
+
return /^[^=&\s]+=[^&]*(&[^=&\s]+=[^&]*)*$/.test(body);
|
|
241
|
+
}
|
|
242
|
+
function redactSensitiveBody(body) {
|
|
243
|
+
if (!body) return body;
|
|
244
|
+
const trimmed = body.trim();
|
|
245
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
246
|
+
try {
|
|
247
|
+
const parsed = JSON.parse(trimmed);
|
|
248
|
+
const { value, changed } = redactJsonValue(parsed, 0);
|
|
249
|
+
return changed ? JSON.stringify(value) : body;
|
|
250
|
+
} catch {
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (looksLikeFormUrlEncoded(trimmed)) {
|
|
254
|
+
const redacted = redactKeyValuePairs(trimmed);
|
|
255
|
+
return redacted === trimmed ? body : redacted;
|
|
256
|
+
}
|
|
257
|
+
return body;
|
|
258
|
+
}
|
|
259
|
+
const JWT_PATTERN = /eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g;
|
|
260
|
+
const BEARER_PATTERN = /(Bearer\s+)[A-Za-z0-9._~+/-]{12,}=*/gi;
|
|
261
|
+
const CARD_CANDIDATE_PATTERN = /\b[2-6](?:[ -]?\d){13,18}\b/g;
|
|
262
|
+
const RRN_CANDIDATE_PATTERN = /\b(\d{2})(\d{2})(\d{2})-?([1-8])(\d{6})\b/g;
|
|
263
|
+
const BRN_CANDIDATE_PATTERN = /\b(\d{3})-?(\d{2})-?(\d{5})\b/g;
|
|
264
|
+
const BRN_WEIGHTS = [1, 3, 7, 1, 3, 7, 1, 3, 5];
|
|
265
|
+
const KR_MOBILE_PATTERN = /\b01[016789]-?\d{3,4}-?\d{4}\b/g;
|
|
266
|
+
const EMAIL_PATTERN = /[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+/g;
|
|
267
|
+
function redactEmails(text) {
|
|
268
|
+
if (!text) return text;
|
|
269
|
+
const out = text.replace(EMAIL_PATTERN, REDACTED_BODY_VALUE);
|
|
270
|
+
return out === text ? text : out;
|
|
271
|
+
}
|
|
272
|
+
function passesBrnChecksum(digits) {
|
|
273
|
+
let sum = 0;
|
|
274
|
+
for (let i2 = 0; i2 < 9; i2 += 1) {
|
|
275
|
+
sum += (digits.charCodeAt(i2) - 48) * BRN_WEIGHTS[i2];
|
|
276
|
+
}
|
|
277
|
+
sum += Math.floor((digits.charCodeAt(8) - 48) * 5 / 10);
|
|
278
|
+
return (10 - sum % 10) % 10 === digits.charCodeAt(9) - 48;
|
|
279
|
+
}
|
|
280
|
+
function passesLuhn(digits) {
|
|
281
|
+
let sum = 0;
|
|
282
|
+
let double = false;
|
|
283
|
+
for (let i2 = digits.length - 1; i2 >= 0; i2 -= 1) {
|
|
284
|
+
let digit = digits.charCodeAt(i2) - 48;
|
|
285
|
+
if (double) {
|
|
286
|
+
digit *= 2;
|
|
287
|
+
if (digit > 9) digit -= 9;
|
|
288
|
+
}
|
|
289
|
+
sum += digit;
|
|
290
|
+
double = !double;
|
|
291
|
+
}
|
|
292
|
+
return sum % 10 === 0;
|
|
293
|
+
}
|
|
294
|
+
function looksLikeBirthDate(month, day) {
|
|
295
|
+
const monthValue = Number(month);
|
|
296
|
+
const dayValue = Number(day);
|
|
297
|
+
return monthValue >= 1 && monthValue <= 12 && dayValue >= 1 && dayValue <= 31;
|
|
298
|
+
}
|
|
299
|
+
function redactSensitiveValues(text) {
|
|
300
|
+
if (!text) return text;
|
|
301
|
+
let out = text;
|
|
302
|
+
out = out.replace(JWT_PATTERN, REDACTED_BODY_VALUE);
|
|
303
|
+
out = out.replace(BEARER_PATTERN, `$1${REDACTED_BODY_VALUE}`);
|
|
304
|
+
out = out.replace(CARD_CANDIDATE_PATTERN, (match) => {
|
|
305
|
+
const digits = match.replace(/[ -]/g, "");
|
|
306
|
+
return digits.length >= 14 && digits.length <= 19 && passesLuhn(digits) ? REDACTED_BODY_VALUE : match;
|
|
307
|
+
});
|
|
308
|
+
out = out.replace(
|
|
309
|
+
RRN_CANDIDATE_PATTERN,
|
|
310
|
+
(match, _year, month, day) => looksLikeBirthDate(month, day) ? REDACTED_BODY_VALUE : match
|
|
311
|
+
);
|
|
312
|
+
out = out.replace(BRN_CANDIDATE_PATTERN, (match) => {
|
|
313
|
+
const digits = match.replace(/-/g, "");
|
|
314
|
+
return passesBrnChecksum(digits) ? REDACTED_BODY_VALUE : match;
|
|
315
|
+
});
|
|
316
|
+
out = out.replace(KR_MOBILE_PATTERN, REDACTED_BODY_VALUE);
|
|
317
|
+
return out === text ? text : out;
|
|
318
|
+
}
|
|
319
|
+
function redactUrlSecrets(url) {
|
|
320
|
+
if (!url) return url;
|
|
321
|
+
const queryStart = url.indexOf("?");
|
|
322
|
+
const fragmentStart = url.indexOf("#");
|
|
323
|
+
if (queryStart < 0 && fragmentStart < 0) {
|
|
324
|
+
return redactSensitiveValues(url);
|
|
325
|
+
}
|
|
326
|
+
const hasQuery = queryStart >= 0 && (fragmentStart < 0 || queryStart < fragmentStart);
|
|
327
|
+
const base = url.slice(0, hasQuery ? queryStart : fragmentStart);
|
|
328
|
+
const query = hasQuery ? url.slice(queryStart + 1, fragmentStart >= 0 ? fragmentStart : void 0) : "";
|
|
329
|
+
const fragment = fragmentStart >= 0 ? url.slice(fragmentStart + 1) : "";
|
|
330
|
+
const redactedQuery = redactKeyValuePairs(query);
|
|
331
|
+
const redactedFragment = fragment.includes("=") ? redactKeyValuePairs(fragment) : fragment;
|
|
332
|
+
const redactedBase = redactSensitiveValues(base);
|
|
333
|
+
if (redactedBase === base && redactedQuery === query && redactedFragment === fragment) {
|
|
334
|
+
return url;
|
|
335
|
+
}
|
|
336
|
+
return redactedBase + (hasQuery ? `?${redactedQuery}` : "") + (fragmentStart >= 0 ? `#${redactedFragment}` : "");
|
|
337
|
+
}
|
|
338
|
+
function redactSensitiveText(text) {
|
|
339
|
+
if (!text) return text;
|
|
340
|
+
return redactSensitiveValues(redactUrlSecrets(redactSensitiveBody(text)));
|
|
341
|
+
}
|
|
342
|
+
const SCREENSHOT_FULL_MASK_SELECTOR = SESSION_REPLAY_FULL_MASK_SELECTOR;
|
|
343
|
+
const SCREENSHOT_BLOCK_SELECTOR = SESSION_REPLAY_BLOCK_SELECTOR;
|
|
344
|
+
const SCREENSHOT_MASK_BACKGROUND = "rgba(148, 148, 148, 0.28)";
|
|
345
|
+
const SCREENSHOT_BLOCK_BACKGROUND = "rgba(148, 148, 148, 0.85)";
|
|
346
|
+
const MASK_LABEL_WIDTH = 44;
|
|
347
|
+
const MASK_LABEL_HEIGHT = 16;
|
|
348
|
+
const MASK_LABEL_IMAGE = `url("data:image/svg+xml;charset=utf-8,${encodeURIComponent(
|
|
349
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="${MASK_LABEL_WIDTH}" height="${MASK_LABEL_HEIGHT}" viewBox="0 0 ${MASK_LABEL_WIDTH} ${MASK_LABEL_HEIGHT}"><text x="${MASK_LABEL_WIDTH / 2}" y="12" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#262626">가려짐</text></svg>`
|
|
350
|
+
)}")`;
|
|
351
|
+
const MASK_LABEL_MIN_WIDTH = MASK_LABEL_WIDTH + 8;
|
|
352
|
+
const MASK_LABEL_MIN_HEIGHT = MASK_LABEL_HEIGHT + 8;
|
|
353
|
+
const TEXT_HIDING_PROPERTIES = [
|
|
354
|
+
["color", "transparent"],
|
|
355
|
+
["-webkit-text-fill-color", "transparent"],
|
|
356
|
+
["text-shadow", "none"],
|
|
357
|
+
["fill", "transparent"]
|
|
358
|
+
];
|
|
359
|
+
const REPLACED_MEDIA_SELECTOR = "img, svg, video, canvas, picture, iframe, object, embed";
|
|
360
|
+
const VALUE_ELEMENT_SELECTOR = "input, textarea, select";
|
|
361
|
+
const SENSITIVE_AUTOCOMPLETE_TOKENS = /* @__PURE__ */ new Set([
|
|
362
|
+
// 자격증명
|
|
363
|
+
"current-password",
|
|
364
|
+
"new-password",
|
|
365
|
+
"one-time-code",
|
|
366
|
+
// 결제
|
|
367
|
+
"cc-number",
|
|
368
|
+
"cc-exp",
|
|
369
|
+
"cc-exp-month",
|
|
370
|
+
"cc-exp-year",
|
|
371
|
+
"cc-csc",
|
|
372
|
+
"cc-name",
|
|
373
|
+
"cc-type",
|
|
374
|
+
"cc-given-name",
|
|
375
|
+
"cc-additional-name",
|
|
376
|
+
"cc-family-name",
|
|
377
|
+
// 신원
|
|
378
|
+
"name",
|
|
379
|
+
"given-name",
|
|
380
|
+
"additional-name",
|
|
381
|
+
"family-name",
|
|
382
|
+
"honorific-prefix",
|
|
383
|
+
"honorific-suffix",
|
|
384
|
+
"nickname",
|
|
385
|
+
"bday",
|
|
386
|
+
"bday-day",
|
|
387
|
+
"bday-month",
|
|
388
|
+
"bday-year",
|
|
389
|
+
"sex",
|
|
390
|
+
// 주소
|
|
391
|
+
"street-address",
|
|
392
|
+
"address-line1",
|
|
393
|
+
"address-line2",
|
|
394
|
+
"address-line3",
|
|
395
|
+
"postal-code",
|
|
396
|
+
// 연락처
|
|
397
|
+
"tel",
|
|
398
|
+
"tel-national",
|
|
399
|
+
"tel-local",
|
|
400
|
+
"tel-area-code",
|
|
401
|
+
"email",
|
|
402
|
+
"impp"
|
|
403
|
+
]);
|
|
404
|
+
function redactScreenshotText(text) {
|
|
405
|
+
return redactEmails(redactSensitiveValues(text));
|
|
406
|
+
}
|
|
407
|
+
function matchesSafely(element, selector) {
|
|
408
|
+
try {
|
|
409
|
+
return element.matches(selector);
|
|
410
|
+
} catch {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function closestSafely(element, selector) {
|
|
415
|
+
if (!element) return null;
|
|
416
|
+
try {
|
|
417
|
+
return element.closest(selector);
|
|
418
|
+
} catch {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
function hasSensitiveValueHint(element) {
|
|
423
|
+
var _a2;
|
|
424
|
+
if (((_a2 = element.getAttribute("type")) == null ? void 0 : _a2.toLowerCase()) === "password") {
|
|
425
|
+
return true;
|
|
426
|
+
}
|
|
427
|
+
const autocomplete = element.getAttribute("autocomplete");
|
|
428
|
+
if (!autocomplete) return false;
|
|
429
|
+
return autocomplete.toLowerCase().split(/\s+/).some((token) => SENSITIVE_AUTOCOMPLETE_TOKENS.has(token));
|
|
430
|
+
}
|
|
431
|
+
const overwriteProperty = (element, name, value) => {
|
|
432
|
+
const style = element.style;
|
|
433
|
+
style == null ? void 0 : style.setProperty(name, value, "important");
|
|
434
|
+
};
|
|
435
|
+
function coverMaskedRegion(region, setProperty) {
|
|
436
|
+
setProperty(region, "background-color", SCREENSHOT_MASK_BACKGROUND);
|
|
437
|
+
forEachElementDeep(region, (node2) => {
|
|
438
|
+
if (!isElementFullyMasked(node2)) return;
|
|
439
|
+
TEXT_HIDING_PROPERTIES.forEach(([name, value]) => setProperty(node2, name, value));
|
|
440
|
+
if (matchesSafely(node2, REPLACED_MEDIA_SELECTOR)) {
|
|
441
|
+
setProperty(node2, "visibility", "hidden");
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
function parsePixels(value) {
|
|
446
|
+
const parsed = Number.parseFloat(value ?? "");
|
|
447
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
448
|
+
}
|
|
449
|
+
function fitsMaskLabel(region) {
|
|
450
|
+
const rect = region.getBoundingClientRect();
|
|
451
|
+
const style = region.style;
|
|
452
|
+
const width = rect.width || parsePixels(style == null ? void 0 : style.width);
|
|
453
|
+
const height = rect.height || parsePixels(style == null ? void 0 : style.height);
|
|
454
|
+
return width >= MASK_LABEL_MIN_WIDTH && height >= MASK_LABEL_MIN_HEIGHT;
|
|
455
|
+
}
|
|
456
|
+
function coverBlockedRegion(region, setProperty) {
|
|
457
|
+
const labeled = fitsMaskLabel(region);
|
|
458
|
+
setProperty(region, "visibility", "visible");
|
|
459
|
+
setProperty(region, "background-color", SCREENSHOT_BLOCK_BACKGROUND);
|
|
460
|
+
setProperty(region, "background-image", labeled ? MASK_LABEL_IMAGE : "none");
|
|
461
|
+
if (labeled) {
|
|
462
|
+
setProperty(region, "background-repeat", "no-repeat");
|
|
463
|
+
setProperty(region, "background-position", "center");
|
|
464
|
+
setProperty(region, "background-size", "auto");
|
|
465
|
+
}
|
|
466
|
+
TEXT_HIDING_PROPERTIES.forEach(([name, value]) => setProperty(region, name, value));
|
|
467
|
+
setProperty(region, "pointer-events", "none");
|
|
468
|
+
forEachElementDeep(region, (descendant) => {
|
|
469
|
+
if (descendant !== region) {
|
|
470
|
+
setProperty(descendant, "visibility", "hidden");
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
function coverPrivateRegions(root2, setProperty) {
|
|
475
|
+
const blocked = [];
|
|
476
|
+
const masked = [];
|
|
477
|
+
forEachElementDeep(root2, (element) => {
|
|
478
|
+
if (matchesSafely(element, SCREENSHOT_BLOCK_SELECTOR)) {
|
|
479
|
+
blocked.push(element);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
if (matchesSafely(element, SCREENSHOT_FULL_MASK_SELECTOR) && isElementFullyMasked(element)) {
|
|
483
|
+
masked.push(element);
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
masked.forEach((region) => coverMaskedRegion(region, setProperty));
|
|
487
|
+
blocked.forEach((region) => coverBlockedRegion(region, setProperty));
|
|
488
|
+
}
|
|
489
|
+
function applyScreenshotPrivacyMask(clonedRoot) {
|
|
490
|
+
coverPrivateRegions(clonedRoot, overwriteProperty);
|
|
491
|
+
const walker = clonedRoot.ownerDocument.createTreeWalker(clonedRoot, NodeFilter.SHOW_TEXT);
|
|
492
|
+
for (let node2 = walker.nextNode(); node2; node2 = walker.nextNode()) {
|
|
493
|
+
const text = node2.nodeValue;
|
|
494
|
+
if (!text) continue;
|
|
495
|
+
node2.nodeValue = redactScreenshotText(text);
|
|
496
|
+
}
|
|
497
|
+
clonedRoot.querySelectorAll(VALUE_ELEMENT_SELECTOR).forEach((element) => {
|
|
498
|
+
const value = element.getAttribute("value");
|
|
499
|
+
if (!value) return;
|
|
500
|
+
const hidden = closestSafely(element, SCREENSHOT_BLOCK_SELECTOR) !== null || isElementFullyMasked(element) || hasSensitiveValueHint(element);
|
|
501
|
+
element.setAttribute("value", hidden ? "" : redactScreenshotText(value));
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
const FRAME_GRAB_TIMEOUT_MS = 300;
|
|
505
|
+
const PROBE_SIZE = 8;
|
|
506
|
+
function matchesSelfOrAncestor(element, selector) {
|
|
507
|
+
try {
|
|
508
|
+
return element.closest(selector) !== null;
|
|
509
|
+
} catch {
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function shouldOverlayCanvas(canvas, excludeSelectors) {
|
|
514
|
+
const rect = canvas.getBoundingClientRect();
|
|
515
|
+
if (rect.width < 1 || rect.height < 1) {
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
if (matchesSelfOrAncestor(canvas, SCREENSHOT_BLOCK_SELECTOR) || matchesSelfOrAncestor(canvas, SCREENSHOT_FULL_MASK_SELECTOR)) {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
return !excludeSelectors.some((selector) => matchesSelfOrAncestor(canvas, selector));
|
|
522
|
+
}
|
|
523
|
+
function rendersBlank(canvas) {
|
|
524
|
+
const probe = document.createElement("canvas");
|
|
525
|
+
probe.width = PROBE_SIZE;
|
|
526
|
+
probe.height = PROBE_SIZE;
|
|
527
|
+
const context = probe.getContext("2d", { willReadFrequently: true });
|
|
528
|
+
if (!context) {
|
|
529
|
+
return false;
|
|
530
|
+
}
|
|
531
|
+
try {
|
|
532
|
+
context.drawImage(canvas, 0, 0, PROBE_SIZE, PROBE_SIZE);
|
|
533
|
+
const { data } = context.getImageData(0, 0, PROBE_SIZE, PROBE_SIZE);
|
|
534
|
+
for (let offset2 = 4; offset2 < data.length; offset2 += 4) {
|
|
535
|
+
if (data[offset2] !== data[0] || data[offset2 + 1] !== data[1] || data[offset2 + 2] !== data[2] || data[offset2 + 3] !== data[3]) {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return true;
|
|
540
|
+
} catch {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
async function grabFrame(canvas) {
|
|
545
|
+
const FrameGrabber = globalThis.ImageCapture;
|
|
546
|
+
if (!FrameGrabber || typeof canvas.captureStream !== "function") {
|
|
547
|
+
return null;
|
|
548
|
+
}
|
|
549
|
+
let track;
|
|
550
|
+
try {
|
|
551
|
+
track = canvas.captureStream().getVideoTracks()[0];
|
|
552
|
+
if (!track) {
|
|
553
|
+
return null;
|
|
554
|
+
}
|
|
555
|
+
return await Promise.race([
|
|
556
|
+
new FrameGrabber(track).grabFrame(),
|
|
557
|
+
new Promise((resolve) => {
|
|
558
|
+
setTimeout(() => resolve(null), FRAME_GRAB_TIMEOUT_MS);
|
|
559
|
+
})
|
|
560
|
+
]);
|
|
561
|
+
} catch {
|
|
562
|
+
return null;
|
|
563
|
+
} finally {
|
|
564
|
+
track == null ? void 0 : track.stop();
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
const threeHandles = /* @__PURE__ */ new Map();
|
|
568
|
+
const registrationListeners = /* @__PURE__ */ new Set();
|
|
569
|
+
function onThreeRendererRegistered(listener) {
|
|
570
|
+
registrationListeners.add(listener);
|
|
571
|
+
return () => {
|
|
572
|
+
registrationListeners.delete(listener);
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
function registerThreeRenderer(handle) {
|
|
576
|
+
var _a2;
|
|
577
|
+
const canvas = (_a2 = handle == null ? void 0 : handle.renderer) == null ? void 0 : _a2.domElement;
|
|
578
|
+
if (!(canvas instanceof HTMLCanvasElement)) {
|
|
579
|
+
return () => void 0;
|
|
580
|
+
}
|
|
581
|
+
const isNew = !threeHandles.has(canvas);
|
|
582
|
+
threeHandles.set(canvas, handle);
|
|
583
|
+
if (isNew) {
|
|
584
|
+
registrationListeners.forEach((listener) => {
|
|
585
|
+
try {
|
|
586
|
+
listener(canvas);
|
|
587
|
+
} catch {
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
return () => {
|
|
592
|
+
threeHandles.delete(canvas);
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
function getThreeHandle(canvas) {
|
|
596
|
+
return threeHandles.get(canvas);
|
|
597
|
+
}
|
|
598
|
+
async function renderAndGrab(handle) {
|
|
599
|
+
try {
|
|
600
|
+
handle.renderer.render(handle.scene, handle.camera);
|
|
601
|
+
return await createImageBitmap(handle.renderer.domElement);
|
|
602
|
+
} catch {
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
async function grabCanvasFrames(root2, excludeSelectors) {
|
|
607
|
+
const targets = [];
|
|
608
|
+
forEachElementDeep(root2, (element) => {
|
|
609
|
+
if (!(element instanceof HTMLCanvasElement) || !shouldOverlayCanvas(element, excludeSelectors)) {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if (threeHandles.has(element) || rendersBlank(element)) {
|
|
613
|
+
targets.push(element);
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
if (targets.length === 0) {
|
|
617
|
+
return [];
|
|
618
|
+
}
|
|
619
|
+
const frames = await Promise.all(
|
|
620
|
+
targets.map(async (canvas) => {
|
|
621
|
+
const handle = threeHandles.get(canvas);
|
|
622
|
+
const bitmap = (handle ? await renderAndGrab(handle) : null) ?? await grabFrame(canvas);
|
|
623
|
+
return bitmap ? { bitmap, rect: canvas.getBoundingClientRect() } : null;
|
|
624
|
+
})
|
|
625
|
+
);
|
|
626
|
+
return frames.filter((frame) => frame !== null);
|
|
627
|
+
}
|
|
628
|
+
function installThreeAutoDetect() {
|
|
629
|
+
if (typeof window === "undefined") {
|
|
630
|
+
return () => void 0;
|
|
631
|
+
}
|
|
632
|
+
const holder = window;
|
|
633
|
+
const restorePatches = [];
|
|
634
|
+
const observe = (event) => {
|
|
635
|
+
const detail = event.detail;
|
|
636
|
+
if ((detail == null ? void 0 : detail.isWebGLRenderer) === true) {
|
|
637
|
+
observeRenderer(detail, restorePatches);
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
const wrap = (hook) => {
|
|
641
|
+
if (!hook) {
|
|
642
|
+
return {
|
|
643
|
+
dispatchEvent(event) {
|
|
644
|
+
observe(event);
|
|
645
|
+
return true;
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
const original = hook.dispatchEvent;
|
|
650
|
+
if (typeof original !== "function" || original.__probed === true) {
|
|
651
|
+
return hook;
|
|
652
|
+
}
|
|
653
|
+
const patched = function(event) {
|
|
654
|
+
observe(event);
|
|
655
|
+
return original.call(this, event);
|
|
656
|
+
};
|
|
657
|
+
patched.__probed = true;
|
|
658
|
+
hook.dispatchEvent = patched;
|
|
659
|
+
restorePatches.push(() => {
|
|
660
|
+
hook.dispatchEvent = original;
|
|
661
|
+
});
|
|
662
|
+
return hook;
|
|
663
|
+
};
|
|
664
|
+
const previousDescriptor = Object.getOwnPropertyDescriptor(window, "__THREE_DEVTOOLS__");
|
|
665
|
+
let current = wrap(holder.__THREE_DEVTOOLS__);
|
|
666
|
+
Object.defineProperty(window, "__THREE_DEVTOOLS__", {
|
|
667
|
+
configurable: true,
|
|
668
|
+
enumerable: true,
|
|
669
|
+
get: () => current,
|
|
670
|
+
set: (next) => {
|
|
671
|
+
current = wrap(next);
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
return () => {
|
|
675
|
+
restorePatches.forEach((restore) => restore());
|
|
676
|
+
restorePatches.length = 0;
|
|
677
|
+
const survivor = current;
|
|
678
|
+
delete window.__THREE_DEVTOOLS__;
|
|
679
|
+
if (previousDescriptor) {
|
|
680
|
+
Object.defineProperty(window, "__THREE_DEVTOOLS__", previousDescriptor);
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
if (survivor && !holder.__THREE_DEVTOOLS__) {
|
|
684
|
+
const isOurs = Object.keys(survivor).length === 1 && "dispatchEvent" in survivor;
|
|
685
|
+
if (!isOurs) {
|
|
686
|
+
holder.__THREE_DEVTOOLS__ = survivor;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
function isSceneLike(value) {
|
|
692
|
+
return (value == null ? void 0 : value.isScene) === true;
|
|
693
|
+
}
|
|
694
|
+
const lastDrawn = /* @__PURE__ */ new WeakMap();
|
|
695
|
+
function observeRenderer(renderer, restorePatches) {
|
|
696
|
+
queueMicrotask(() => {
|
|
697
|
+
const owner = Object.prototype.hasOwnProperty.call(renderer, "render") ? renderer : Object.getPrototypeOf(renderer);
|
|
698
|
+
const original = owner.render;
|
|
699
|
+
if (typeof original !== "function") {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
owner.render = function(scene, camera) {
|
|
703
|
+
const canvas = (this == null ? void 0 : this.domElement) ?? renderer.domElement;
|
|
704
|
+
if (canvas instanceof HTMLCanvasElement) {
|
|
705
|
+
lastDrawn.set(canvas, [scene, camera]);
|
|
706
|
+
if (isSceneLike(scene)) {
|
|
707
|
+
const existing = threeHandles.get(canvas);
|
|
708
|
+
if (existing) {
|
|
709
|
+
existing.scene = scene;
|
|
710
|
+
existing.camera = camera;
|
|
711
|
+
} else {
|
|
712
|
+
registerThreeRenderer({
|
|
713
|
+
// 강제 렌더는 **앱이 마지막으로 그린 그대로** 다시 그린다. 후처리를 쓰면 화면을
|
|
714
|
+
// 그리는 것은 풀스크린 쿼드 패스라, 앱의 씬으로 그리면 후처리가 빠진다.
|
|
715
|
+
// 원본을 부른다 — 우리 래퍼를 다시 타지 않게 한다.
|
|
716
|
+
renderer: {
|
|
717
|
+
domElement: canvas,
|
|
718
|
+
render: (s2, c2) => {
|
|
719
|
+
const last = lastDrawn.get(canvas);
|
|
720
|
+
return last ? original.call(this, last[0], last[1]) : original.call(this, s2, c2);
|
|
721
|
+
}
|
|
722
|
+
},
|
|
723
|
+
scene,
|
|
724
|
+
camera
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return original.call(this, scene, camera);
|
|
730
|
+
};
|
|
731
|
+
restorePatches.push(() => {
|
|
732
|
+
owner.render = original;
|
|
733
|
+
});
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
function frameDestRect(rect, origin, scale) {
|
|
737
|
+
return [
|
|
738
|
+
(rect.left - origin.x) * scale,
|
|
739
|
+
(rect.top - origin.y) * scale,
|
|
740
|
+
rect.width * scale,
|
|
741
|
+
rect.height * scale
|
|
742
|
+
];
|
|
743
|
+
}
|
|
744
|
+
async function overlayCanvasFrames(capture, frames, origin, cssWidth, quality) {
|
|
745
|
+
let captured = null;
|
|
746
|
+
try {
|
|
747
|
+
captured = await createImageBitmap(capture);
|
|
748
|
+
const output = document.createElement("canvas");
|
|
749
|
+
output.width = captured.width;
|
|
750
|
+
output.height = captured.height;
|
|
751
|
+
const context = output.getContext("2d");
|
|
752
|
+
if (!context) {
|
|
753
|
+
return capture;
|
|
754
|
+
}
|
|
755
|
+
context.drawImage(captured, 0, 0);
|
|
756
|
+
const scale = cssWidth > 0 ? captured.width / cssWidth : 1;
|
|
757
|
+
frames.forEach(({ bitmap, rect }) => {
|
|
758
|
+
context.drawImage(bitmap, ...frameDestRect(rect, origin, scale));
|
|
759
|
+
});
|
|
760
|
+
const blob2 = await new Promise((resolve) => {
|
|
761
|
+
output.toBlob(resolve, capture.type || "image/webp", quality);
|
|
762
|
+
});
|
|
763
|
+
return blob2 ?? capture;
|
|
764
|
+
} catch {
|
|
765
|
+
return capture;
|
|
766
|
+
} finally {
|
|
767
|
+
captured == null ? void 0 : captured.close();
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
const CANVAS_INTERACTION_TAG = "issue-sticker:canvas-interaction";
|
|
5
771
|
/*! pako 2.2.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */
|
|
6
772
|
const Z_FIXED$1 = 4;
|
|
7
773
|
const Z_BINARY = 0;
|
|
@@ -15433,6 +16199,42 @@ function inDom(n2) {
|
|
|
15433
16199
|
if (!doc) return false;
|
|
15434
16200
|
return index$2.contains(doc, n2) || shadowHostInDom(n2);
|
|
15435
16201
|
}
|
|
16202
|
+
const utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
16203
|
+
__proto__: null,
|
|
16204
|
+
StyleSheetMirror,
|
|
16205
|
+
get _mirror() {
|
|
16206
|
+
return _mirror;
|
|
16207
|
+
},
|
|
16208
|
+
closestElementOfNode,
|
|
16209
|
+
getBaseDimension,
|
|
16210
|
+
getNestedRule,
|
|
16211
|
+
getPositionsAndIndex,
|
|
16212
|
+
getRootShadowHost,
|
|
16213
|
+
getShadowHost,
|
|
16214
|
+
getWindowHeight,
|
|
16215
|
+
getWindowScroll,
|
|
16216
|
+
getWindowWidth,
|
|
16217
|
+
hasShadowRoot,
|
|
16218
|
+
hookSetter,
|
|
16219
|
+
inDom,
|
|
16220
|
+
isAncestorRemoved,
|
|
16221
|
+
isBlocked,
|
|
16222
|
+
isIgnored,
|
|
16223
|
+
isSerialized,
|
|
16224
|
+
isSerializedIframe,
|
|
16225
|
+
isSerializedStylesheet,
|
|
16226
|
+
iterateResolveTree,
|
|
16227
|
+
legacy_isTouchEvent,
|
|
16228
|
+
get nowTimestamp() {
|
|
16229
|
+
return nowTimestamp;
|
|
16230
|
+
},
|
|
16231
|
+
on,
|
|
16232
|
+
polyfill: polyfill$1,
|
|
16233
|
+
queueToResolveTrees,
|
|
16234
|
+
shadowHostInDom,
|
|
16235
|
+
throttle,
|
|
16236
|
+
uniqueTextMutations
|
|
16237
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
15436
16238
|
var EventType = /* @__PURE__ */ ((EventType2) => {
|
|
15437
16239
|
EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
|
|
15438
16240
|
EventType2[EventType2["Load"] = 1] = "Load";
|
|
@@ -21615,6 +22417,23 @@ class Replayer {
|
|
|
21615
22417
|
const { addCustomEvent } = record;
|
|
21616
22418
|
const { freezePage } = record;
|
|
21617
22419
|
const { takeFullSnapshot } = record;
|
|
22420
|
+
const rrweb = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
22421
|
+
__proto__: null,
|
|
22422
|
+
EventType,
|
|
22423
|
+
IncrementalSource,
|
|
22424
|
+
MouseInteractions,
|
|
22425
|
+
Replayer,
|
|
22426
|
+
ReplayerEvents,
|
|
22427
|
+
addCustomEvent,
|
|
22428
|
+
canvasMutation,
|
|
22429
|
+
freezePage,
|
|
22430
|
+
get mirror() {
|
|
22431
|
+
return _mirror;
|
|
22432
|
+
},
|
|
22433
|
+
record,
|
|
22434
|
+
takeFullSnapshot,
|
|
22435
|
+
utils
|
|
22436
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
21618
22437
|
const OVERLAY_LAYER_INDEX = {
|
|
21619
22438
|
// 익스텐션·SDK 위젯의 shadow host. isolation:isolate 로 stacking context 를 만들기 때문에
|
|
21620
22439
|
// 아래 레이어 값들은 호스트 내부 순서만 정한다. 호스트 페이지의 오버레이와 겨루는 것은
|
|
@@ -27397,17 +28216,41 @@ const MousePointer2 = createLucideIcon("MousePointer2", [
|
|
|
27397
28216
|
}
|
|
27398
28217
|
]
|
|
27399
28218
|
]);
|
|
28219
|
+
function registerThree(handle) {
|
|
28220
|
+
return registerThreeRenderer(handle);
|
|
28221
|
+
}
|
|
28222
|
+
installThreeAutoDetect();
|
|
27400
28223
|
export {
|
|
27401
|
-
|
|
27402
|
-
|
|
28224
|
+
createSlottable as $,
|
|
28225
|
+
record as A,
|
|
28226
|
+
resolvePrivacyConfig as B,
|
|
28227
|
+
CANVAS_INTERACTION_TAG as C,
|
|
27403
28228
|
DismissableLayer as D,
|
|
28229
|
+
isElementFullyMasked as E,
|
|
28230
|
+
grabCanvasFrames as F,
|
|
28231
|
+
applyScreenshotPrivacyMask as G,
|
|
28232
|
+
overlayCanvasFrames as H,
|
|
28233
|
+
forEachElementDeep as I,
|
|
28234
|
+
redactSensitiveText as J,
|
|
28235
|
+
REDACTED_BODY_VALUE as K,
|
|
28236
|
+
isSensitiveFieldName as L,
|
|
27404
28237
|
MousePointer2 as M,
|
|
28238
|
+
redactSensitiveHeaders as N,
|
|
27405
28239
|
OVERLAY_LAYER_INDEX as O,
|
|
27406
28240
|
Presence as P,
|
|
28241
|
+
redactSensitiveBody as Q,
|
|
27407
28242
|
Replayer as R,
|
|
27408
|
-
|
|
27409
|
-
|
|
28243
|
+
Content as S,
|
|
28244
|
+
createPopperScope as T,
|
|
28245
|
+
Root2 as U,
|
|
28246
|
+
Anchor as V,
|
|
28247
|
+
Arrow as W,
|
|
28248
|
+
VISUALLY_HIDDEN_STYLES as X,
|
|
28249
|
+
clsx as Y,
|
|
28250
|
+
Slot as Z,
|
|
28251
|
+
Root as _,
|
|
27410
28252
|
cn as a,
|
|
28253
|
+
rrweb as a0,
|
|
27411
28254
|
usePortalContainer as b,
|
|
27412
28255
|
createLucideIcon as c,
|
|
27413
28256
|
OVERLAY_LAYER as d,
|
|
@@ -27423,14 +28266,14 @@ export {
|
|
|
27423
28266
|
useLayoutEffect2 as n,
|
|
27424
28267
|
useCallbackRef as o,
|
|
27425
28268
|
PortalContainerProvider as p,
|
|
27426
|
-
|
|
27427
|
-
|
|
28269
|
+
onThreeRendererRegistered as q,
|
|
28270
|
+
registerThree as r,
|
|
27428
28271
|
stopEscapePropagation as s,
|
|
27429
|
-
|
|
28272
|
+
shouldOverlayCanvas as t,
|
|
27430
28273
|
ungzip_1 as u,
|
|
27431
|
-
|
|
27432
|
-
|
|
27433
|
-
|
|
27434
|
-
|
|
27435
|
-
|
|
28274
|
+
getThreeHandle as v,
|
|
28275
|
+
rendersBlank as w,
|
|
28276
|
+
gzip_1 as x,
|
|
28277
|
+
redactUrlSecrets as y,
|
|
28278
|
+
redactSensitiveValues as z
|
|
27436
28279
|
};
|