1(globalThis["TURBOPACK"] || (globalThis["TURBOPACK"] = [])).push([typeof document === "object" ? document.currentScript : undefined, 2763639, ((__turbopack_context__) => { 3"use strict"; 4 5var __TURBOPACK__imported__module__444609__ = __turbopack_context__.i(444609); 6__turbopack_context__.s([ 7 "Languages", 8 ()=>__TURBOPACK__imported__module__444609__["default"] 9]); 10}), 11741929, ((__turbopack_context__) => { 12"use strict"; 13 14var __TURBOPACK__imported__module__9734__ = __turbopack_context__.i(9734); 15__turbopack_context__.s([ 16 "FileCode", 17 ()=>__TURBOPACK__imported__module__9734__["default"] 18]); 19}), 20542969, ((__turbopack_context__) => { 21"use strict"; 22 23var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 24var __TURBOPACK__imported__module__306994__ = __turbopack_context__.i(306994); 25var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 26"use client"; 27; 28; 29; 30function DataLoader({ isLoading, children, loadingMessage, spinnerSize = "md", className = "", loadingClassName = "", showSkeleton = false, skeletonComponent }) { 31 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 32 const resolvedLoadingMessage = loadingMessage ?? t("ui.dataLoader.loading", "Loading..."); 33 if (isLoading) { 34 if (showSkeleton && skeletonComponent) { 35 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 36 className, 37 children: skeletonComponent 38 }); 39 } 40 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 41 className: `flex items-center justify-center gap-2 py-4 ${loadingClassName} ${className}`, 42 children: [
43 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__306994__["Spinner"], { 44 size: spinnerSize 45 }), 46 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 47 className: "text-sm text-muted-foreground", 48 children: resolvedLoadingMessage 49 }) 50 ] 51 }); 52 } 53 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 54 className, 55 children 56 }); 57} 58function InlineLoader({ isLoading, children, loadingMessage, spinnerSize = "sm" }) { 59 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(DataLoader, { 60 isLoading, 61 loadingMessage, 62 spinnerSize, 63 className: "inline-flex items-center", 64 loadingClassName: "py-2", 65 children 66 }); 67} 68function PageLoader({ isLoading, children, loadingMessage, spinnerSize = "lg" }) { 69 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(DataLoader, { 70 isLoading, 71 loadingMessage, 72 spinnerSize, 73 className: "min-h-[200px] flex items-center justify-center", 74 children 75 }); 76} 77; 78__turbopack_context__.s([ 79 "DataLoader", 80 0, 81 DataLoader, 82 "InlineLoader", 83 0, 84 InlineLoader, 85 "PageLoader", 86 0, 87 PageLoader 88]); 89}), 90390519, 954922, 91205125, 92730699, 9373526, 94826514, 95((__turbopack_context__) => { 96"use strict"; 97 98// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/shirt.js [app-client] (ecmascript) <export default as Shirt> 99; 100var __TURBOPACK__imported__module__632646__ = __turbopack_context__.i(632646); 101__turbopack_context__.s([ 102 "Shirt", 103 ()=>__TURBOPACK__imported__module__632646__["default"] 104], 390519); 105// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/grid-3x3.js [app-client] (ecmascript) <export default as Grid> 106; 107var __TURBOPACK__imported__module__595828__ = __turbopack_context__.i(595828); 108__turbopack_context__.s([ 109 "Grid", 110 ()=>__TURBOPACK__imported__module__595828__["default"] 111], 954922); 112// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/car.js [app-client] (ecmascript) <export default as Car> 113; 114var __TURBOPACK__imported__module__757740__ = __turbopack_context__.i(757740); 115__turbopack_context__.s([ 116 "Car", 117 ()=>__TURBOPACK__imported__module__757740__["default"] 118], 205125); 119// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/gift.js [app-client] (ecmascript) <export default as Gift> 120; 121var __TURBOPACK__imported__module__935832__ = __turbopack_context__.i(935832); 122__turbopack_context__.s([ 123 "Gift", 124 ()=>__TURBOPACK__imported__module__935832__["default"] 125], 730699); 126// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/map.js [app-client] (ecmascript) <export default as Map> 127; 128var __TURBOPACK__imported__module__744757__ = __turbopack_context__.i(744757); 129__turbopack_context__.s([ 130 "Map", 131 ()=>__TURBOPACK__imported__module__744757__["default"] 132], 73526); 133// MERGED MODULE: [project]/node_modules/date-fns/parseISO.js [app-client] (ecmascript) 134; 135var __TURBOPACK__imported__module__234662__ = __turbopack_context__.i(234662); 136var __TURBOPACK__imported__module__677241__ = __turbopack_context__.i(677241); 137var __TURBOPACK__imported__module__281092__ = __turbopack_context__.i(281092); 138; 139; 140; 141function parseISO(argument, options) { 142 const invalidDate = ()=>(0, __TURBOPACK__imported__module__677241__["constructFrom"])(options?.in, NaN); 143 const additionalDigits = options?.additionalDigits ?? 2; 144 const dateStrings = splitDateString(argument); 145 let date; 146 if (dateStrings.date) { 147 const parseYearResult = parseYear(dateStrings.date, additionalDigits); 148 date = parseDate(parseYearResult.restDateString, parseYearResult.year); 149 } 150 if (!date || isNaN(+date)) return invalidDate(); 151 const timestamp = +date; 152 let time = 0; 153 let offset; 154 if (dateStrings.time) { 155 time = parseTime(dateStrings.time); 156 if (isNaN(time)) return invalidDate(); 157 } 158 if (dateStrings.timezone) { 159 offset = parseTimezone(dateStrings.timezone); 160 if (isNaN(offset)) return invalidDate(); 161 } else { 162 const tmpDate = new Date(timestamp + time); 163 const result = (0, __TURBOPACK__imported__module__281092__["toDate"])(0, options?.in); 164 result.setFullYear(tmpDate.getUTCFullYear(), tmpDate.getUTCMonth(), tmpDate.getUTCDate()); 165 result.setHours(tmpDate.getUTCHours(), tmpDate.getUTCMinutes(), tmpDate.getUTCSeconds(), tmpDate.getUTCMilliseconds()); 166 return result; 167 } 168 return (0, __TURBOPACK__imported__module__281092__["toDate"])(timestamp + time + offset, options?.in); 169} 170const patterns = { 171 dateTimeDelimiter: /[T ]/, 172 timeZoneDelimiter: /[Z ]/i,
173 timezone: /([Z+-].*)$/ 174}; 175const dateRegex = /^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/; 176const timeRegex = /^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/; 177const timezoneRegex = /^([+-])(\d{2})(?::?(\d{2}))?$/; 178function splitDateString(dateString) { 179 const dateStrings = {}; 180 const array = dateString.split(patterns.dateTimeDelimiter); 181 let timeString; 182 // The regex match should only return at maximum two array elements. 183 // [date], [time], or [date, time]. 184 if (array.length > 2) { 185 return dateStrings; 186 } 187 if (/:/.test(array[0])) { 188 timeString = array[0]; 189 } else { 190 dateStrings.date = array[0]; 191 timeString = array[1]; 192 if (patterns.timeZoneDelimiter.test(dateStrings.date)) { 193 dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0]; 194 timeString = dateString.substr(dateStrings.date.length, dateString.length); 195 } 196 } 197 if (timeString) { 198 const token = patterns.timezone.exec(timeString); 199 if (token) {
vendor: 1,222 bytes, lines 200-231
200 dateStrings.time = timeString.replace(token[1], ""); 201 dateStrings.timezone = token[1]; 202 } else { 203 dateStrings.time = timeString; 204 } 205 } 206 return dateStrings; 207} 208function parseYear(dateString, additionalDigits) { 209 const regex = new RegExp("^(?:(\\d{4}|[+-]\\d{" + (4 + additionalDigits) + "})|(\\d{2}|[+-]\\d{" + (2 + additionalDigits) + "})$)"); 210 const captures = dateString.match(regex); 211 // Invalid ISO-formatted year 212 if (!captures) return { 213 year: NaN, 214 restDateString: "" 215 }; 216 const year = captures[1] ? parseInt(captures[1]) : null; 217 const century = captures[2] ? parseInt(captures[2]) : null; 218 // either year or century is null, not both 219 return { 220 year: century === null ? year : century * 100, 221 restDateString: dateString.slice((captures[1] || captures[2]).length) 222 }; 223} 224function parseDate(dateString, year) { 225 // Invalid ISO-formatted year 226 if (year === null) return new Date(NaN); 227 const captures = dateString.match(dateRegex); 228 // Invalid ISO-formatted string 229 if (!captures) return new Date(NaN); 230 const isWeekDate = !!captures[4]; 231 const dayOfYear = parseDateUnit(captures[1]);
232 const month = parseDateUnit(captures[2]) - 1; 233 const day = parseDateUnit(captures[3]); 234 const week = parseDateUnit(captures[4]); 235 const dayOfWeek = parseDateUnit(captures[5]) - 1; 236 if (isWeekDate) { 237 if (!validateWeekDate(year, week, dayOfWeek)) { 238 return new Date(NaN); 239 } 240 return dayOfISOWeekYear(year, week, dayOfWeek); 241 } else { 242 const date = new Date(0); 243 if (!validateDate(year, month, day) || !validateDayOfYearDate(year, dayOfYear)) { 244 return new Date(NaN); 245 } 246 date.setUTCFullYear(year, month, Math.max(dayOfYear, day)); 247 return date; 248 } 249} 250function parseDateUnit(value) { 251 return value ? parseInt(value) : 1; 252} 253function parseTime(timeString) { 254 const captures = timeString.match(timeRegex); 255 if (!captures) return NaN; // Invalid ISO-formatted time 256 const hours = parseTimeUnit(captures[1]); 257 const minutes = parseTimeUnit(captures[2]); 258 const seconds = parseTimeUnit(captures[3]); 259 if (!validateTime(hours, minutes, seconds)) { 260 return NaN; 261 } 262 return hours * __TURBOPACK__imported__module__234662__["millisecondsInHour"] + minutes * __TURBOPACK__imported__module__234662__["millisecondsInMinute"] + seconds * 1000; 263} 264function parseTimeUnit(value) { 265 return value && parseFloat(value.replace(",", ".")) || 0; 266} 267function parseTimezone(timezoneString) { 268 if (timezoneString === "Z") return 0; 269 const captures = timezoneString.match(timezoneRegex); 270 if (!captures) return 0; 271 const sign = captures[1] === "+" ? -1 : 1; 272 const hours = parseInt(captures[2]); 273 const minutes = captures[3] && parseInt(captures[3]) || 0; 274 if (!validateTimezone(hours, minutes)) { 275 return NaN; 276 } 277 return sign * (hours * __TURBOPACK__imported__module__234662__["millisecondsInHour"] + minutes * __TURBOPACK__imported__module__234662__["millisecondsInMinute"]); 278} 279function dayOfISOWeekYear(isoWeekYear, week, day) { 280 const date = new Date(0); 281 date.setUTCFullYear(isoWeekYear, 0, 4); 282 const fourthOfJanuaryDay = date.getUTCDay() || 7; 283 const diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay; 284 date.setUTCDate(date.getUTCDate() + diff); 285 return date; 286} 287// Validation functions 288// February is null to handle the leap year (using ||) 289const daysInMonths = [ 290 31, 291 null, 292 31, 293 30, 294 31, 295 30, 296 31, 297 31, 298 30, 299 31, 300 30, 301 31 302]; 303function isLeapYearIndex(year) { 304 return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0; 305} 306function validateDate(year, month, date) { 307 return month >= 0 && month <= 11 && date >= 1 && date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28)); 308} 309function validateDayOfYearDate(year, dayOfYear) { 310 return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365); 311} 312function validateWeekDate(_year, week, day) { 313 return week >= 1 && week <= 53 && day >= 0 && day <= 6; 314} 315function validateTime(hours, minutes, seconds) { 316 if (hours === 24) { 317 return minutes === 0 && seconds === 0; 318 } 319 return seconds >= 0 && seconds < 60 && minutes >= 0 && minutes < 60 && hours >= 0 && hours < 25; 320} 321function validateTimezone(_hours, minutes) { 322 return minutes >= 0 && minutes <= 59; 323} 324const __TURBOPACK__default__export__ = parseISO; 325__turbopack_context__.s([ 326 "parseISO", 327 0, 328 parseISO 329], 826514); 330}), 331132109, ((__turbopack_context__) => { 332"use strict"; 333 334// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/htmlparser2/dist/index.js [app-client] (ecmascript) 335; 336// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/htmlparser2/dist/index.js [app-client] (ecmascript) <locals> 337; 338// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/htmlparser2/dist/Parser.js [app-client] (ecmascript) 339; 340// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/htmlparser2/dist/Tokenizer.js [app-client] (ecmascript) 341; 342// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/entities/dist/decode.js [app-client] (ecmascript) <locals> 343; 344// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/entities/dist/decode-codepoint.js [a
344pp-client] (ecmascript) 345; 346// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134 347const decodeMap = new Map([ 348 [ 349 0, 350 65_533 351 ], 352 // C1 Unicode control character reference replacements 353 [ 354 128, 355 8364 356 ], 357 [ 358 130, 359 8218 360 ], 361 [ 362 131, 363 402 364 ], 365 [ 366 132, 367 8222 368 ], 369 [ 370 133, 371 8230 372 ], 373 [ 374 134, 375 8224 376 ], 377 [ 378 135, 379 8225 380 ], 381 [ 382 136, 383 710 384 ], 385 [ 386 137, 387 8240 388 ], 389 [ 390 138, 391 352 392 ], 393 [ 394 139, 395 8249 396 ], 397 [ 398 140, 399 338 400 ], 401 [ 402 142, 403 381 404 ], 405 [ 406 145, 407 8216 408 ], 409 [ 410 146, 411 8217 412 ], 413 [ 414 147, 415 8220 416 ], 417 [ 418 148, 419 8221 420 ], 421 [ 422 149, 423 8226 424 ], 425 [ 426 150, 427 8211 428 ], 429 [ 430 151, 431 8212 432 ], 433 [ 434 152, 435 732 436 ], 437 [ 438 153, 439 8482 440 ], 441 [ 442 154, 443 353 444 ], 445 [ 446 155, 447 8250 448 ], 449 [ 450 156, 451 339 452 ], 453 [ 454 158, 455 382 456 ], 457 [ 458 159, 459 376 460 ] 461]); 462function replaceCodePoint(codePoint) { 463 if (codePoint >= 0xd8_00 && codePoint <= 0xdf_ff || codePoint > 0x10_ff_ff) { 464 return 0xff_fd; 465 } 466 return decodeMap.get(codePoint) ?? codePoint; 467} 468// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/entities/dist/generated/decode-data-html.js [app-client] (ecmascript) 469; 470// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/entities/dist/internal/decode-shared.js [app-client] (ecmascript) 471; 472function decodeBase64(input) { 473 const binary = atob(input); 474 const evenLength = binary.length & ~1; // Round down to even length 475 const out = new Uint16Array(evenLength / 2); 476 for(let index = 0, outIndex = 0; index < evenLength; index += 2){ 477 const lo = binary.charCodeAt(index); 478 const hi = binary.charCodeAt(index + 1); 479 out[outIndex++] = lo | hi << 8; 480 } 481 return out; 482} 483;
vendor: 32,260 bytes, lines 483-485
483 484const htmlDecodeTree = /* #__PURE__ */ decodeBase64("QR08ALkAAgH6AYsDNQR2BO0EPgXZBQEGLAbdBxMISQrvCmQLfQurDKQNLw4fD4YPpA+6D/IPAAAAAAAAAAAAAAAAKhBMEY8TmxUWF2EYLBkxGuAa3RsJHDscWR8YIC8jSCSIJcMl6ie3Ku8rEC0CLjoupS7kLgAIRU1hYmNmZ2xtbm9wcnN0dVQAWgBeAGUAaQBzAHcAfgCBAIQAhwCSAJoAoACsALMAbABpAGcAO4DGAMZAUAA7gCYAJkBjAHUAdABlADuAwQDBQHIiZXZlAAJhAAFpeW0AcgByAGMAO4DCAMJAEGRyAADgNdgE3XIAYQB2AGUAO4DAAMBA8CFoYZFj4SFjcgBhZAAAoFMqAAFncIsAjgBvAG4ABGFmAADgNdg43fAlbHlGdW5jdGlvbgCgYSBpAG4AZwA7gMUAxUAAAWNzpACoAHIAAOA12Jzc6SFnbgCgVCJpAGwAZABlADuAwwDDQG0AbAA7gMQAxEAABGFjZWZvcnN1xQDYANoA7QDxAPYA+QD8AAABY3LJAM8AayNzbGFzaAAAoBYidgHTANUAAKDnKmUAZAAAoAYjeQARZIABY3J0AOAA5QDrAGEidXNlAACgNSLuI291bGxpcwCgLCFhAJJjcgAA4DXYBd1wAGYAAOA12Dnd5SF2ZdhiYwDyAOoAbSJwZXEAAKBOIgAHSE9hY2RlZmhpbG9yc3UXARoBHwE6AVIBVQFiAWQBZgGCAakB6QHtAfIBYwB5ACdkUABZADuAqQCpQIABY3B5ACUBKAE1AfUhdGUGYWmg0iJ0KGFsRGlmZmVyZW50aWFsRAAAoEUhbCJleXMAAKAtIQACYWVpb0EBRAFKAU0B8iFvbgxhZABpAGwAO4DHAMdAcgBjAAhhbiJpbnQAAKAwIm8AdAAKYQABZG5ZAV0BaSJsbGEAuGB0I2VyRG90ALdg8gA5AWkAp2NyImNsZQAAAkRNUFRwAXQBeQF9AW8AdAAAoJkiaSJudXMAAKCWIuwhdXMAoJUiaSJtZXMAAKCXIm8AAAFjc4cBlAFrKndpc2VDb250b3VySW50ZWdyYWwAAKAyImUjQ3VybHkAAAFEUZwBpAFvJXVibGVRdW90ZQAAoB0gdSJvdGUAAKAZIAACbG5wdbABtgHNAdgBbwBuAGWgNyIAoHQqgAFnaXQAvAHBAcUB8iJ1ZW50AKBhIm4AdAAAoC8i7yV1ckludGVncmFsAKAuIgABZnLRAdMBAKACIe8iZHVjdACgECJuLnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbAAAoDMi7yFzcwCgLypjAHIAAOA12J7ccABDoNMiYQBwAACgTSKABURKU1phY2VmaW9zAAsCEgIVAhgCGwIsAjQCOQI9AnMCfwNvoEUh9CJyYWhkAKARKWMAeQACZGMAeQAFZGMAeQAPZIABZ3JzACECJQIoAuchZXIAoCEgcgAAoKEhaAB2AACg5CoAAWF5MAIzAvIhb24OYRRkbAB0oAciYQCUY3IAAOA12AfdAAFhZkECawIAAWNtRQJnAvIjaXRpY2FsAAJBREdUUAJUAl8CYwJjInV0ZQC0YG8AdAFZAloC2WJiJGxlQWN1dGUA3WJyImF2ZQBgYGkibGRlANxi7yFuZACgxCJmJWVyZW50aWFsRAAAoEYhcAR9AgAAAAAAAIECjgIAABoDZgAA4DXYO91EoagAhQKJAm8AdAAAoNwgcSJ1YWwAAKBQIuIhbGUAA0NETFJVVpkCqAK1Au8C/wIRA28AbgB0AG8AdQByAEkAbgB0AGUAZwByAGEA7ADEAW8AdAKvAgAAAACwAqhgbiNBcnJvdwAAoNMhAAFlb7kC0AJmAHQAgAFBUlQAwQLGAs0CciJyb3cAAKDQIekkZ2h0QXJyb3cAoNQhZQDlACsCbgBnAAABTFLWAugC5SFmdAABQVLcAuECciJyb3cAAKD4J+kkZ2h0QXJyb3cAoPon6SRnaHRBcnJvdwCg+SdpImdodAAAAUFU9gL7AnIicm93AACg0iFlAGUAAKCoInAAQQIGAwAAAAALA3Iicm93AACg0SFvJHduQXJyb3cAAKDVIWUlcnRpY2FsQmFyAACgJSJuAAADQUJMUlRhJAM2AzoDWgNxA3oDciJyb3cAAKGTIUJVLAMwA2EAcgAAoBMpcCNBcnJvdwAAoPUhciJldmUAEWPlIWZ00gJDAwAASwMAAFIDaSVnaHRWZWN0b3IAAKBQKWUkZVZlY3RvcgAAoF4p5SJjdG9yQqC9IWEAcgAAoFYpaSJnaHQA1AFiAwAAaQNlJGVWZWN0b3IAAKBfKeUiY3RvckKgwSFhAHIAAKBXKWUAZQBBoKQiciJyb3cAAKCnIXIAcgBvAPcAtAIAAWN0gwOHA3IAAOA12J/c8iFvaxBhAAhOVGFjZGZnbG1vcHFzdHV4owOlA6kDsAO/A8IDxgPNA9ID8gP9AwEEFAQeBCAEJQRHAEphSAA7gNAA0EBjAHUAdABlADuAyQDJQIABYWl5ALYDuQO+A/Ihb24aYXIAYwA7gMoAykAtZG8AdAAWYXIAAOA12AjdcgBhAHYAZQA7gMgAyEDlIm1lbnQAoAgiAAFhcNYD2QNjAHIAEmF0AHkAUwLhAwAAAADpA20lYWxsU3F1YXJlAACg+yVlJ3J5U21hbGxTcXVhcmUAAKCrJQABZ3D2A/kDbwBuABhhZgAA4DXYPN3zImlsb26VY3UAAAFhaQYEDgRsAFSgdSppImxkZQAAoEIi7CNpYnJpdW0AoMwhAAFjaRgEGwRyAACgMCFtAACgcyphAJdjbQBsADuAywDLQAABaXApBC0E8yF0cwCgAyLvJG5lbnRpYWxFAKBHIYACY2Zpb3MAPQQ/BEMEXQRyBHkAJGRyAADgNdgJ3WwibGVkAFMCTAQAAAAAVARtJWFsbFNxdWFyZQAAoPwlZSdyeVNtYWxsU3F1YXJlAACgqiVwA2UEAABpBAAAAABtBGYAAOA12D3dwSFsbACgACLyI2llcnRyZgCgMSFjAPIAcQQABkpUYWJjZGZnb3JzdIgEiwSOBJMElwSkBKcEqwStBLIE5QTqBGMAeQADZDuAPgA+QO0hbWFkoJMD3GNyImV2ZQAeYYABZWl5AJ0EoASjBOQhaWwiYXIAYwAcYRNkbwB0ACBhcgAA4DXYCt0AoNkicABmAADgNdg+3eUiYXRlcgADRUZHTFNUvwTIBM8E1QTZBOAEcSJ1YWwATKBlIuUhc3MAoNsidSRsbEVxdWFsAACgZyJyI2VhdGVyAACgoirlIXNzAKB3IuwkYW50RXF1YWwAoH4qaSJsZGUAAKBzImMAcgAA4DXYotwAoGsiAARBYWNmaW9zdfkE/QQFBQgFCwUTBSIFKwVSIkRjeQAqZAABY3QBBQQFZQBrAMdiXmDpIXJjJGFyAACgDCFsJWJlcnRTcGFjZQAAoAsh8AEYBQAAGwVmAACgDSHpJXpvbnRhbExpbmUAoAAlAAFjdCYFKAXyABIF8iFvayZhbQBwAEQBMQU5BW8AdwBuAEgAdQBtAPAAAAFxInVhbAAAoE8iAAdFSk9hY2RmZ21ub3N0dVMFVgVZBVwFYwVtBXAFcwV6BZAFtgXFBckFzQVjAHkAFWTsIWlnMmFjAHkAAWRjAHUAdABlADuAzQDNQAABaXlnBWwFcgBjADuAzgDOQBhkbwB0ADBhcgAAoBEhcgBhAHYAZQA7gMwAzEAAoREhYXB/BYsFAAFjZ4MFhQVyACphaSNuYXJ5SQAAoEghbABpAGUA8wD6AvQBlQUAAKUFZaAsIgABZ3KaBZ4F8iFhbACgKyLzI2VjdGlvbgCgwiJpI3NpYmxlAAABQ1SsBbEFbyJtbWEAAKBjIGkibWVzAACgYiCAAWdwdAC8Bb8FwwVvAG4ALmFmAADgNdhA3WEAmWNjAHIAAKAQIWkibGRlAChh6wHSBQAA1QVjAHkABmRsADuAzwDPQIACY2Zvc3UA4QXpBe0F8gX9BQABaXnlBegFcgBjADRhGWRyAADgNdgN3XAAZgAA4DXYQd3jAfcFAAD7BXIAAOA12KXc8iFjeQhk6yFjeQRkgANISmFjZm9zAAwGDwYSBhUGHQYhBiYGYwB5ACVkYwB5AAxk8CFwYZpjAAFleRkGHAbkIWlsNmEaZHIAAOA12A7dcABmAADgNdhC3WMAcgAA4DXYptyABUpUYWNlZmxtb3N0AD0GQAZDBl4GawZkB2gHcAd0B80H2gdjAHkACWQ7gDwAPECAAmNtbnByAEwGTwZSBlUGWwb1IXRlOWHiIWRhm2NnAACg6ifsI2FjZXRyZgCgEiFyAACgniGAAWFleQBkBmcGagbyIW9uPWHkIWlsO2EbZAABZnNvBjQHdAAABUFDREZSVFVWYXKABp4GpAbGBssG3AYDByEHwQIqBwABbnKEBowGZyVsZUJyYWNrZXQAAKDoJ/Ihb3cAoZAhQlKTBpcGYQByAACg5CHpJGdodEFycm93AKDGIWUjaWxpbmcAAKAII28A9QGqBgAAsgZiJWxlQnJhY2tldAAAoOYnbgDUAbcGAAC+BmUkZVZlY3RvcgAAoGEp5SJjdG9yQqDDIWEAcgAAoFkpbCJvb3IAAKAKI2kiZ2h0AAABQVbSBtcGciJyb3cAAKCUIeUiY3RvcgCgTikAAWVy4AbwBmUAAKGjIkFW5gbrBnIicm93AACgpCHlImN0b3IAoFopaSNhbmdsZQBCorIi+wYAAAAA/wZhAHIAAKDPKXEidWFsAACgtCJwAIABRFRWAAoHEQcYB+8kd25WZWN0b3IAoFEpZSRlVmVjdG9yAACgYCnlImN0b3JCoL8hYQByAACgWCnlImN0b3JCoLwhYQByAACgUilpAGcAaAB0AGEAcgByAG8A9wDMAnMAAANFRkdMU1Q/B0cHTgdUB1gHXwfxJXVhbEdyZWF0ZXIAoNoidSRsbEVxdWFsAACgZiJyI2VhdGVyAACgdiLlIXNzAKChKuwkYW50RXF1YWwAoH0qaSJsZGUAAKByInIAAOA12A/dZaDYIuYjdGFycm93AKDaIWkiZG90AD9hgAFucHcAege1B7kHZwAAAkxSbHKCB5QHmwerB+UhZnQAAUFSiAeNB3Iicm93AACg9SfpJGdodEFycm93AKD3J+kkZ2h0QXJyb3cAoPYn5SFmdAABYXLcAqEHaQBnAGgAdABhAHIAcgBvAPcA5wJpAGcAaAB0AGEAcgByAG8A9wDuAmYAAOA12EPdZQByAAABTFK/B8YHZSRmdEFycm93AACgmSHpJGdodEFycm93AKCYIYABY2h0ANMH1QfXB/IAWgYAoLAh8iFva0FhAKBqIgAEYWNlZmlvc3XpB+wH7gf/BwMICQgOCBEIcAAAoAUpeQAcZAABZGzyB/kHaSR1bVNwYWNlAACgXyBsI2ludHJmAACgMyFyAADgNdgQ3e4jdXNQbHVzAKATInAAZgAA4DXYRN1jAPIA/gecY4AESmFjZWZvc3R1ACEIJAgoCDUIgQiFCDsKQApHCmMAeQAKZGMidXRlAENhgAFhZXkALggxCDQI8iFvbkdh5CFpbEVhHWSAAWdzdwA7CGEIfQjhInRpdmWAAU1UVgBECEwIWQhlJWRpdW1TcGFjZQAAoAsgaABpAAABY25SCFMIawBTAHAAYQBjAOUASwhlAHIAeQBUAGgAaQDuAFQI9CFlZAABR0xnCHUIcgBlAGEAdABlAHIARwByAGUAYQB0AGUA8gDrBGUAcwBzAEwAZQBzAPMA2wdMImluZQAKYHIAAOA12BHdAAJCbnB0jAiRCJkInAhyImVhawAAoGAgwiZyZWFraW5nU3BhY2WgYGYAAKAVIUOq7CqzCMIIzQgAAOcIGwkAAAAAAAAtCQAAbwkAAIcJAACdCcAJGQoAADQKAAFvdbYIvAjuI2dydWVudACgYiJwIkNhcAAAoG0ibyh1YmxlVmVydGljYWxCYXIAAKAmIoABbHF4ANII1wjhCOUibWVudACgCSL1IWFsVKBgImkibGRlAADgQiI4A2kic3RzAACgBCJyI2VhdGVyAACjbyJFRkdMU1T1CPoIAgkJCQ0JFQlxInVhbAAAoHEidSRsbEVxdWFsAADgZyI4A3IjZWF0ZXIAAOBrIjgD5SFzcwCgeSLsJGFudEVxdWFsAOB+KjgDaSJsZGUAAKB1IvUhbXBEASAJJwnvI3duSHVtcADgTiI4A3EidWFsAADgTyI4A2UAAAFmczEJRgn0JFRyaWFuZ2xlQqLqIj0JAAAAAEIJYQByAADgzyk4A3EidWFsAACg7CJzAICibiJFR0xTVABRCVYJXAlhCWkJcSJ1YWwAAKBwInIjZWF0ZXIAAKB4IuUhc3MA4GoiOAPsJGFudEVxdWFsAOB9KjgDaSJsZGUAAKB0IuUic3RlZAABR0x1CX8J8iZlYXRlckdyZWF0ZXIA4KIqOAPlI3NzTGVzcwDgoSo4A/IjZWNlZGVzAKGAIkVTjwmVCXEidWFsAADgryo4A+wkYW50RXF1YWwAoOAiAAFlaaAJqQl2JmVyc2VFbGVtZW50AACgDCLnJWh0VHJpYW5nbGVCousitgkAAAAAuwlhAHIAAODQKTgDcSJ1YWwAAKDtIgABcXXDCeAJdSNhcmVTdQAAAWJwywnVCfMhZXRF4I8iOANxInVhbAAAoOIi5SJyc2V0ReCQIjgDcSJ1YWwAAKDjIoABYmNwAOYJ8AkNCvMhZXRF4IIi0iBxInVhbAAAoIgi4yJlZWRzgKGBIkVTVAD6CQAKBwpxInVhbAAA4LAqOAPsJGFudEVxdWFsAKDhImkibGRlAADgfyI4A+UicnNldEXggyLSIHEidWFsAACgiSJpImxkZQCAoUEiRUZUACIKJwouCnEidWFsAACgRCJ1JGxsRXF1YWwAAKBHImkibGRlAACgSSJlJXJ0aWNhbEJhcgAAoCQiYwByAADgNdip3GkAbABkAGUAO4DRANFAnWMAB0VhY2RmZ21vcHJzdHV2XgphCmgKcgp2CnoKgQqRCpYKqwqtCrsKyArNCuwhaWdSYWMAdQB0AGUAO4DTANNAAAFpeWwKcQpyAGMAO4DUANRAHmRiImxhYwBQYXIAAOA12BLdcgBhAHYAZQA7gNIA0kCAAWFlaQCHCooKjQpjAHIATGFnAGEAqWNjInJvbgCfY3AAZgAA4DXYRt3lI25DdXJseQABRFGeCqYKbyV1YmxlUXVvdGUAAKAcIHUib3RlAACgGCAAoFQqAAFjbLEKtQpyAADgNdiq3GEAcwBoADuA2ADYQGkAbAHACsUKZABlADuA1QDVQGUAcwAAoDcqbQBsADuA1gDWQGUAcgAAAUJQ0wrmCgABYXLXCtoKcgAAoD4gYQBjAAABZWvgCuIKAKDeI2UAdAAAoLQjYSVyZW50aGVzaXMAAKDcI4AEYWNmaGlsb3JzAP0KAwsFCwkLCwsMCxELIwtaC3IjdGlhbEQAAKACInkAH2RyAADgNdgT3WkApmOgY/Ujc01pbnVzsWAAAWlwFQsgC24AYwBhAHIAZQBwAGwAYQBuAOUACgVmAACgGSGAobsqZWlvACoLRQtJC+MiZWRlc4CheiJFU1QANAs5C0ALcSJ1YWwAAKCvKuwkYW50RXF1YWwAoHwiaSJsZGUAAKB+Im0AZQAAoDMgAAFkcE0LUQv1IWN0AKAPIm8jcnRpb24AYaA3ImwAAKAdIgABY2leC2ILcgAA4DXYq9yoYwACVWZvc2oLbwtzC3cLTwBUADuAIgAiQHIAAOA12BTdcABmAACgGiFjAHIAAOA12KzcAAZCRWFjZWZoaW9yc3WPC5MLlwupC7YL2AvbC90LhQyTDJoMowzhIXJyAKAQKUcAO4CuAK5AgAFjbnIAnQugC6ML9SF0ZVRhZwAAoOsncgB0oKAhbAAAoBYpgAFhZXkArwuyC7UL8iFvblhh5CFpbFZhIGR2oBwhZSJyc2UAAAFFVb8LzwsAAWxxwwvIC+UibWVudACgCyL1JGlsaWJyaXVtAKDLIXAmRXF1aWxpYnJpdW0AAKBvKXIAAKAcIW8AoWPnIWh0AARBQ0RGVFVWYewLCgwQDDIMNwxeDHwM9gIAAW5y8Av4C2clbGVCcmFja2V0AACg6SfyIW93AKGSIUJM/wsDDGEAcgAAoOUhZSRmdEFycm93AACgxCFlI2lsaW5nAACgCSNvAPUBFgwAAB4MYiVsZUJyYWNrZXQAAKDnJ24A1AEjDAAAKgxlJGVWZWN0b3IAAKBdKeUiY3RvckKgwiFhAHIAAKBVKWwib29yAACgCyMAAWVyOwxLDGUAAKGiIkFWQQxGDHIicm93AACgpiHlImN0b3IAoFspaSNhbmdsZQBCorMiVgwAAAAAWgxhAHIAAKDQKXEidWFsAACgtSJwAIABRFRWAGUMbAxzDO8kd25WZWN0b3IAoE8pZSRlVmVjdG9yAACgXCnlImN0b3JCoL4hYQByAACgVCnlImN0b3JCoMAhYQByAACgUykAAXB1iQyMDGYAAKAdIe4kZEltcGxpZXMAoHAp6SRnaHRhcnJvdwCg2yEAAWNongyhDHIAAKAbIQCgsSHsJGVEZWxheWVkAKD0KYAGSE9hY2ZoaW1vcXN0dQC/DMgMzAzQDOIM5gwKDQ0NFA0ZDU8NVA1YDQABQ2PDDMYMyCFjeSlkeQAoZEYiVGN5ACxkYyJ1dGUAWmEAorwqYWVpedgM2wzeDOEM8iFvbmBh5CFpbF5hcgBjAFxhIWRyAADgNdgW3e8hcnQAAkRMUlXvDPYM/QwEDW8kd25BcnJvdwAAoJMhZSRmdEFycm93AACgkCHpJGdodEFycm93AKCSIXAjQXJyb3cAAKCRIechbWGjY+EkbGxDaXJjbGUAoBgicABmAADgNdhK3XICHw0AAAAAIg10AACgGiLhIXJlgKGhJUlTVQAqDTINSg3uJXRlcnNlY3Rpb24AoJMidQAAAWJwNw1ADfMhZXRFoI8icSJ1YWwAAKCRIuUicnNldEWgkCJxInVhbAAAoJIibiJpb24AAKCUImMAcgAA4DXYrtxhAHIAAKDGIgACYmNtcF8Nag2ODZANc6DQImUAdABFoNAicSJ1YWwAAKCGIgABY2huDYkNZSJlZHMAgKF7IkVTVAB4DX0NhA1xInVhbAAAoLAq7CRhbnRFcXVhbACgfSJpImxkZQAAoH8iVABoAGEA9ADHCwCgESIAodEiZXOVDZ8NciJzZXQARaCDInEidWFsAACghyJlAHQAAKDRIoAFSFJTYWNmaGlvcnMAtQ27Db8NyA3ODdsN3w3+DRgOHQ4jDk8AUgBOADuA3gDeQMEhREUAoCIhAAFIY8MNxg1jAHkAC2R5ACZkAAFidcwNzQ0JYKRjgAFhZXkA1A3XDdoN8iFvbmRh5CFpbGJhImRyAADgNdgX3QABZWnjDe4N8gHoDQAA7Q3lImZvcmUAoDQiYQCYYwABY27yDfkNayNTcGFjZQAA4F8gCiDTInBhY2UAoAkg7CFkZYChPCJFRlQABw4MDhMOcSJ1YWwAAKBDInUkbGxFcXVhbAAAoEUiaSJsZGUAAKBIInAAZgAA4DXYS93pI3BsZURvdACg2yAAAWN0Jw4rDnIAAOA12K/c8iFva2Zh4QpFDlYOYA5qDgAAbg5yDgAAAAAAAAAAAAB5DnwOqA6zDgAADg8RDxYPGg8AAWNySA5ODnUAdABlADuA2gDaQHIAb6CfIeMhaXIAoEkpcgDjAVsOAABdDnkADmR2AGUAbGEAAWl5Yw5oDnIAYwA7gNsA20AjZGIibGFjAHBhcgAA4DXYGN1yAGEAdgBlADuA2QDZQOEhY3JqYQABZGl/Dp8OZQByAAABQlCFDpcOAAFhcokOiw5yAF9gYQBjAAABZWuRDpMOAKDfI2UAdAAAoLUjYSVyZW50aGVzaXMAAKDdI28AbgBQoMMi7CF1cwCgjiIAAWdwqw6uDm8AbgByYWYAAOA12EzdAARBREVUYWRwc78O0g7ZDuEOBQPqDvMOBw9yInJvdwDCoZEhyA4AAMwOYQByAACgEilvJHduQXJyb3cAAKDFIW8kd25BcnJvdwAAoJUhcSV1aWxpYnJpdW0AAKBuKWUAZQBBoKUiciJyb3cAAKClIW8AdwBuAGEAcgByAG8A9wAQA2UAcgAAAUxS+Q4AD2UkZnRBcnJvdwAAoJYh6SRnaHRBcnJvdwCglyFpAGyg0gNvAG4ApWPpIW5nbmFjAHIAAOA12LDcaSJsZGUAaGFtAGwAO4DcANxAgAREYmNkZWZvc3YALQ8xDzUPNw89D3IPdg97D4AP4SFzaACgqyJhAHIAAKDrKnkAEmThIXNobKCpIgCg5ioAAWVyQQ9DDwCgwSKAAWJ0eQBJD00Paw9hAHIAAKAWIGmgFiDjIWFsAAJCTFNUWA9cD18PZg9hAHIAAKAjIukhbmV8YGUkcGFyYXRvcgAAoFgnaSJsZGUAAKBAItQkaGluU3BhY2UAoAogcgAA4DXYGd1wAGYAAOA12E3dYwByAADgNdix3GQiYXNoAACgqiKAAmNlZm9zAI4PkQ+VD5kPng/pIXJjdGHkIWdlAKDAInIAAOA12BrdcABmAADgNdhO3WMAcgAA4DXYstwAAmZpb3OqD64Prw+0D3IAAOA12BvdnmNwAGYAAOA12E/dYwByAADgNdiz3IAEQUlVYWNmb3N1AMgPyw/OD9EP2A/gD+QP6Q/uD2MAeQAvZGMAeQAHZGMAeQAuZGMAdQB0AGUAO4DdAN1AAAFpedwP3w9yAGMAdmErZHIAAOA12BzdcABmAADgNdhQ3WMAcgAA4DXYtNxtAGwAeGEABEhhY2RlZm9z/g8BEAUQDRAQEB0QIBAkEGMAeQAWZGMidXRlAHlhAAFheQkQDBDyIW9ufWEXZG8AdAB7YfIBFRAAABwQbwBXAGkAZAB0AOgAVAhhAJZjcgAAoCghcABmAACgJCFjAHIAAOA12LXc4QtCEEkQTRAAAGcQbRByEAAAAAAAAAAAeRCKEJcQ8hD9EAAAGxEhETIROREAAD4RYwB1AHQAZQA7gOEA4UByImV2ZQADYYCiPiJFZGl1eQBWEFkQWxBgEGUQAOA+IjMDAKA/InIAYwA7gOIA4kB0AGUAO4C0ALRAMGRsAGkAZwA7gOYA5kByoGEgAOA12B7dcgBhAHYAZQA7gOAA4EAAAWVwfBCGEAABZnCAEIQQ8yF5bQCgNSHoAIMQaABhALFjAAFhcI0QWwAAAWNskRCTEHIAAWFnAACgPypkApwQAAAAALEQAKInImFkc3ajEKcQqRCuEG4AZAAAoFUqAKBcKmwib3BlAACgWCoAoFoqAKMgImVsbXJzersQvRDAEN0Q5RDtEACgpCllAACgICJzAGQAYaAhImEEzhDQENIQ1BDWENgQ2hDcEACgqCkAoKkpAKCqKQCgqykAoKwpAKCtKQCgrikAoK8pdAB2oB8iYgBkoL4iAKCdKQABcHTpEOwQaAAAoCIixWDhIXJyAKB8IwABZ3D1EPgQbwBuAAVhZgAA4DXYUt0Ao0giRWFlaW9wBxEJEQ0RDxESERQRAKBwKuMhaXIAoG8qAKBKImQAAKBLInMAJ2DyIW94ZaBIIvEADhFpAG4AZwA7gOUA5UCAAWN0eQAmESoRKxFyAADgNdi23CpgbQBwAGWgSCLxAPgBaQBsAGQAZQA7gOMA40BtAGwAO4DkAORAAAFjaUERRxFvAG4AaQBuAPQA6AFuAHQAAKARKgAITmFiY2RlZmlrbG5vcHJzdWQRaBGXEZ8RpxGrEdIR1hErEjASexKKEn0RThNbE3oTbwB0AACg7SoAAWNybBGJEWsAAAJjZXBzdBF4EX0RghHvIW5nAKBMInAjc2lsb24A9mNyImltZQAAoDUgaQBtAGWgPSJxAACgzSJ2AY0RkRFlAGUAAKC9ImUAZABnoAUjZQAAoAUjcgBrAHSgtSPiIXJrAKC2IwABb3mjEaYRbgDnAHcRMWTxIXVvAKAeIIACY21wcnQAtBG5Eb4RwRHFEeEhdXPloDUi5ABwInR5dgAAoLApcwDpAH0RbgBvAPUA6gCAAWFodwDLEcwRzhGyYwCgNiHlIWVuAKBsInIAAOA12B/dZwCAA2Nvc3R1dncA4xHyEQUSEhIhEiYSKRKAAWFpdQDpEesR7xHwAKMFcgBjAACg7yVwAACgwyKAAWRwdAD4EfwRABJvAHQAAKAAKuwhdXMAoAEqaSJtZXMAAKACKnECCxIAAAAADxLjIXVwAKAGKmEAcgAAoAUm8iNpYW5nbGUAAWR1GhIeEu8hd24AoL0lcAAAoLMlcCJsdXMAAKAEKmUA5QBCD+UAkg9hInJvdwAAoA0pgAFha28ANhJoEncSAAFjbjoSZRJrAIABbHN0AEESRxJNEm8jemVuZ2UAAKDrKXEAdQBhAHIA5QBcBPIjaWFuZ2xlgKG0JWRscgBYElwSYBLvIXduAKC+JeUhZnQAoMIlaSJnaHQAAKC4JWsAAKAjJLEBbRIAAHUSsgFxEgAAcxIAoJIlAKCRJTQAAKCTJWMAawAAoIglAAFlb38ShxJx4D0A5SD1IWl2AOBhIuUgdAAAoBAjAAJwdHd4kRKVEpsSnxJmAADgNdhT3XSgpSJvAG0AAKClIvQhaWUAoMgiAAZESFVWYmRobXB0dXayEsES0RLgEvcS+xIKExoTHxMjEygTNxMAAkxSbHK5ErsSvRK/EgCgVyUAoFQlAKBWJQCgUyUAolAlRFVkdckSyxLNEs8SAKBmJQCgaSUAoGQlAKBnJQACTFJsctgS2hLcEt4SAKBdJQCgWiUAoFwlAKBZJQCjUSVITFJobHLrEu0S7xLxEvMS9RIAoGwlAKBjJQCgYCUAoGslAKBiJQCgXyVvAHgAAKDJKQACTFJscgITBBMGEwgTAKBVJQCgUiUAoBAlAKAMJQCiACVEVWR1EhMUExYTGBMAoGUlAKBoJQCgLCUAoDQlaSJudXMAAKCfIuwhdXMAoJ4iaSJtZXMAAKCgIgACTFJsci8TMRMzEzUTAKBbJQCgWCUAoBglAKAUJQCjAiVITFJobHJCE0QTRhNIE0oTTBMAoGolAKBhJQCgXiUAoDwlAKAkJQCgHCUAAWV2UhNVE3YA5QD5AGIAYQByADuApgCmQAACY2Vpb2ITZhNqE24TcgAA4DXYt9xtAGkAAKBPIG0A5aA9IogRbAAAoVwAYmh0E3YTAKDFKfMhdWIAoMgnbAF+E4QTbABloCIgdAAAoCIgcAAAoU4iRWWJE4sTAKCuKvGgTyI8BeEMqRMAAN8TABQDFB8UAAAjFDQUAAAAAIUUAAAAAI0UAAAAANcU4xT3FPsUAACIFQAAlhWAAWNwcgCuE7ET1RP1IXRlB2GAoikiYWJjZHMAuxO/E8QTzhPSE24AZAAAoEQqciJjdXAAAKBJKgABYXXIE8sTcAAAoEsqcAAAoEcqbwB0AACgQCoA4CkiAP4AAWVv2RPcE3QAAKBBIO4ABAUAAmFlaXXlE+8T9RP4E/AB6hMAAO0TcwAAoE0qbwBuAA1hZABpAGwAO4DnAOdAcgBjAAlhcABzAHOgTCptAACgUCpvAHQAC2GAAWRtbgAIFA0UEhRpAGwAO4C4ALhAcCJ0eXYAAKCyKXQAAIGiADtlGBQZFKJAcgBkAG8A9ABiAXIAAOA12CDdgAFjZWkAKBQqFDIUeQBHZGMAawBtoBMn4SFyawCgEyfHY3IAAKPLJUVjZWZtcz8UQRRHFHcUfBSAFACgwykAocYCZWxGFEkUcQAAoFciZQBhAlAUAAAAAGAUciJyb3cAAAFsclYUWhTlIWZ0AKC6IWkiZ2h0AACguyGAAlJTYWNkAGgUaRRrFG8UcxSuYACgyCRzAHQAAKCbIukhcmMAoJoi4SFzaACgnSJuImludAAAoBAqaQBkAACg7yrjIWlyAKDCKfUhYnN1oGMmaQB0AACgYybsApMUmhS2FAAAwxRvAG4AZaA6APGgVCKrAG0CnxQAAAAAoxRhAHSgLABAYAChASJmbKcUqRTuABMNZQAAAW14rhSyFOUhbnQAoAEiZQDzANIB5wG6FAAAwBRkoEUibwB0AACgbSpuAPQAzAGAAWZyeQDIFMsUzhQA4DXYVN1vAOQA1wEAgakAO3MeAdMUcgAAoBchAAFhb9oU3hRyAHIAAKC1IXMAcwAAoBcnAAFjdeYU6hRyAADgNdi43AABYnDuFPIUZaDPKgCg0SploNAqAKDSKuQhb3QAoO8igANkZWxwcnZ3AAYVEBUbFSEVRBVlFYQV4SFycgABbHIMFQ4VAKA4KQCgNSlwAhYVAAAAABkVcgAAoN4iYwAAoN8i4SFycnCgtiEAoD0pgKIqImJjZG9zACsVMBU6FT4VQRVyImNhcAAAoEgqAAFhdTQVNxVwAACgRipwAACgSipvAHQAAKCNInIAAKBFKgDgKiIA/gACYWxydksVURVuFXMVcgByAG2gtyEAoDwpeQCAAWV2dwBYFWUVaRVxAHACXxUAAAAAYxVyAGUA4wAXFXUA4wAZFWUAZQAAoM4iZSJkZ2UAAKDPImUAbgA7gKQApEBlI2Fycm93AAABbHJ7FX8V5SFmdACgtiFpImdodAAAoLchZQDkAG0VAAFjaYsVkRVvAG4AaQBuAPQAkwFuAHQAAKAxImwiY3R5AACgLSOACUFIYWJjZGVmaGlqbG9yc3R1d3oAuBW7Fb8V1RXgFegV+RUKFhUWHxZUFlcWZRbFFtsW7xb7FgUXChdyAPIAtAJhAHIAAKBlKQACZ2xyc8YVyhXOFdAV5yFlcgCgICDlIXRoAKA4IfIA9QxoAHagECAAoKMiawHZFd4VYSJyb3cAAKAPKWEA4wBfAgABYXnkFecV8iFvbg9hNGQAoUYhYW/tFfQVAAFnciEC8RVyAACgyiF0InNlcQAAoHcqgAFnbG0A/xUCFgUWO4CwALBAdABhALRjcCJ0eXYAAKCxKQABaXIOFhIW8yFodACgfykA4DXYId1hAHIAAAFschsWHRYAoMMhAKDCIYACYWVnc3YAKBauAjYWOhY+Fm0AAKHEIm9zLhY0Fm4AZABzoMQi9SFpdACgZiZhIm1tYQDdY2kAbgAAoPIiAKH3AGlvQxZRFmQAZQAAgfcAO29KFksW90BuI3RpbWVzAACgxyJuAPgAUBZjAHkAUmRjAG8CXhYAAAAAYhZyAG4AAKAeI28AcAAAoA0jgAJscHR1dwBuFnEWdRaSFp4W7CFhciRgZgAA4DXYVd0AotkCZW1wc30WhBaJFo0WcQBkoFAibwB0AACgUSJpIm51cwAAoDgi7CF1cwCgFCLxInVhcmUAoKEiYgBsAGUAYgBhAHIAdwBlAGQAZwDlANcAbgCAAWFkaAClFqoWtBZyAHIAbwD3APUMbwB3AG4AYQByAHIAbwB3APMA8xVhI3Jwb29uAAABbHK8FsAWZQBmAPQAHBZpAGcAaAD0AB4WYgHJFs8WawBhAHIAbwD3AJILbwLUFgAAAADYFnIAbgAAoB8jbwBwAACgDCOAAWNvdADhFukW7BYAAXJ55RboFgDgNdi53FVkbAAAoPYp8iFvaxFhAAFkcvMW9xZvAHQAAKDxImkA5qC/JVsSAAFhaP8WAhdyAPIANQNhAPIA1wvhIm5nbGUAoKYpAAFjaQ4XEBd5AF9k5yJyYXJyAKD/JwAJRGFjZGVmZ2xtbm9wcXJzdHV4MRc4F0YXWxcyBF4XaRd5F40XrBe0F78X2RcVGCEYLRg1GEAYAAFEbzUXgRZvAPQA+BUAAWNzPBdCF3UAdABlADuA6QDpQPQhZXIAoG4qAAJhaW95TRdQF1YXWhfyIW9uG2FyAGOgViI7gOoA6kDsIW9uAKBVIk1kbwB0ABdhAAFEcmIXZhdvAHQAAKBSIgDgNdgi3XKhmipuF3QXYQB2AGUAO4DoAOhAZKCWKm8AdAAAoJgqgKGZKmlscwCAF4UXhxfuInRlcnMAoOcjAKATIWSglSpvAHQAAKCXKoABYXBzAJMXlheiF2MAcgATYXQAeQBzogUinxcAAAAAoRdlAHQAAKAFInAAMaADIDMBqRerFwCgBCAAoAUgAAFnc7AXsRdLYXAAAKACIAABZ3C4F7sXbwBuABlhZgAA4DXYVt2AAWFscwDFF8sXzxdyAHOg1SJsAACg4yl1AHMAAKBxKmkAAKG1A2x21RfYF28AbgC1Y/VjAAJjc3V24BfoF/0XEBgAAWlv5BdWF3IAYwAAoFYiaQLuFwAAAADwF+0ADQThIW50AAFnbPUX+Rd0AHIAAKCWKuUhc3MAoJUqgAFhZWkAAxgGGAoYbABzAD1gcwB0AACgXyJ2AESgYSJEAACgeCrwImFyc2wAoOUpAAFEYRkYHRhvAHQAAKBTInIAcgAAoHEpgAFjZGkAJxgqGO0XcgAAoC8hbwD0AIwCAAFhaDEYMhi3YzuA8ADwQAABbXI5GD0YbAA7gOsA60BvAACgrCCAAWNpcABGGEgYSxhsACFgcwD0ACwEAAFlb08YVxhjAHQAYQB0AGkAbwDuABoEbgBlAG4AdABpAGEAbADlADME4Ql1GAAAgRgAAIMYiBgAAAAAoRilGAAAqhgAALsYvhjRGAAA1xgnGWwAbABpAG4AZwBkAG8AdABzAGUA8QBlF3kARGRtImFsZQAAoEAmgAFpbHIAjRiRGJ0Y7CFpZwCgA/tpApcYAAAAAJoYZwAAoAD7aQBnAACgBPsA4DXYI93sIWlnAKAB++whaWcA4GYAagCAAWFsdACvGLIYthh0AACgbSZpAGcAAKAC+24AcwAAoLElbwBmAJJh8AHCGAAAxhhmAADgNdhX3QABYWvJGMwYbADsAGsEdqDUIgCg2SphI3J0aW50AACgDSoAAWFv2hgiGQABY3PeGB8ZsQPnGP0YBRkSGRUZAAAdGbID7xjyGPQY9xj5GAAA+xg7gL0AvUAAoFMhO4C8ALxAAKBVIQCgWSEAoFshswEBGQAAAxkAoFQhAKBWIbQCCxkOGQAAAAAQGTuAvgC+QACgVyEAoFwhNQAAoFghtgEZGQAAGxkAoFohAKBdITgAAKBeIWwAAKBEIHcAbgAAoCIjYwByAADgNdi73IAIRWFiY2RlZmdpamxub3JzdHYARhlKGVoZXhlmGWkZkhmWGZkZnRmgGa0ZxhnLGc8Z4BkjGmygZyIAoIwqgAFjbXAAUBlTGVgZ9SF0ZfVhbQBhAOSgswM6FgCghipyImV2ZQAfYQABaXliGWUZcgBjAB1hM2RvAHQAIWGAoWUibHFzAMYEcBl6GfGhZSLOBAAAdhlsAGEAbgD0AN8EgKF+KmNkbACBGYQZjBljAACgqSpvAHQAb6CAKmyggioAoIQqZeDbIgD+cwAAoJQqcgAA4DXYJN3noGsirATtIWVsAKA3IWMAeQBTZIChdyJFYWoApxmpGasZAKCSKgCgpSoAoKQqAAJFYWVztBm2Gb0ZwhkAoGkicABwoIoq8iFveACgiipxoIgq8aCIKrUZaQBtAACg5yJwAGYAAOA12FjdYQB2AOUAYwIAAWNp0xnWGXIAAKAKIW0AAKFzImVs3BneGQCgjioAoJAqAIM+ADtjZGxxco0E6xn0GfgZ/BkBGgABY2nvGfEZAKCnKnIAAKB6Km8AdAAAoNci0CFhcgCglSl1ImVzdAAAoHwqgAJhZGVscwAKGvQZFhrVBCAa8AEPGgAAFBpwAHIAbwD4AFkZcgAAoHgpcQAAAWxxxAQbGmwAZQBzAPMASRlpAO0A5AQAAWVuJxouGnIjdG5lcXEAAOBpIgD+xQAsGgAFQWFiY2Vma29zeUAaQxpmGmoabRqDGocalhrCGtMacgDyAMwCAAJpbG1yShpOGlAaVBpyAHMA8ABxD2YAvWBpAGwA9AASBQABZHJYGlsaYwB5AEpkAKGUIWN3YBpkGmkAcgAAoEgpAKCtIWEAcgAAoA8h6SFyYyVhgAFhbHIAcxp7Gn8a8iF0c3WgZSZpAHQAAKBlJuwhaXAAoCYg4yFvbgCguSJyAADgNdgl3XMAAAFld4wakRphInJvdwAAoCUpYSJyb3cAAKAmKYACYW1vcHIAnxqjGqcauhq+GnIAcgAAoP8h9CFodACgOyJrAAABbHKsGrMaZSRmdGFycm93AACgqSHpJGdodGFycm93AKCqIWYAAOA12Fnd4iFhcgCgFSCAAWNsdADIGswa0BpyAADgNdi93GEAcwDoAGka8iFvaydhAAFicNca2xr1IWxsAKBDIOghZW4AoBAg4Qr2GgAA/RoAAAgbExsaGwAAIRs7GwAAAAA+G2IbmRuVG6sbAACyG80b0htjAHUAdABlADuA7QDtQAChYyBpeQEbBhtyAGMAO4DuAO5AOGQAAWN4CxsNG3kANWRjAGwAO4ChAKFAAAFmcssCFhsA4DXYJt1yAGEAdgBlADuA7ADsQIChSCFpbm8AJxsyGzYbAAFpbisbLxtuAHQAAKAMKnQAAKAtIuYhaW4AoNwpdABhAACgKSHsIWlnM2GAAWFvcABDG1sbXhuAAWNndABJG0sbWRtyACthgAFlbHAAcQVRG1UbaQBuAOUAyAVhAHIA9AByBWgAMWFmAACgtyJlAGQAtWEAoggiY2ZvdGkbbRt1G3kb4SFyZQCgBSFpAG4AdKAeImkAZQAAoN0pZABvAPQAWxsAoisiY2VscIEbhRuPG5QbYQBsAACguiIAAWdyiRuNG2UAcgDzACMQ4wCCG2EicmhrAACgFyryIW9kAKA8KgACY2dwdJ8boRukG6gbeQBRZG8AbgAvYWYAAOA12FrdYQC5Y3UAZQBzAHQAO4C/AL9AAAFjabUbuRtyAADgNdi+3G4AAKIIIkVkc3bCG8QbyBvQAwCg+SJvAHQAAKD1Inag9CIAoPMiaaBiIOwhZGUpYesB1hsAANkbYwB5AFZkbAA7gO8A70AAA2NmbW9zdeYb7hvyG/Ub+hsFHAABaXnqG+0bcgBjADVhOWRyAADgNdgn3eEhdGg3YnAAZgAA4DXYW93jAf8bAAADHHIAAOA12L/c8iFjeVhk6yFjeVRkAARhY2ZnaGpvcxUcGhwiHCYcKhwtHDAcNRzwIXBhdqC6A/BjAAFleR4cIRzkIWlsN2E6ZHIAAOA12CjdciJlZW4AOGFjAHkARWRjAHkAXGRwAGYAAOA12FzdYwByAADgNdjA3IALQUJFSGFiY2RlZmdoamxtbm9wcnN0dXYAXhxtHHEcdRx5HN8cBx0dHTwd3B3tHfEdAR4EHh0eLB5FHrwewx7hHgkfPR9LH4ABYXJ0AGQcZxxpHHIA8gBvB/IAxQLhIWlsAKAbKeEhcnIAoA4pZ6BmIgCgiyphAHIAAKBiKWMJjRwAAJAcAACVHAAAAAAAAAAAAACZHJwcAACmHKgcrRwAANIc9SF0ZTph7SJwdHl2AKC0KXIAYQDuAFoG4iFkYbtjZwAAoegnZGyhHKMcAKCRKeUAiwYAoIUqdQBvADuAqwCrQHIAgKOQIWJmaGxwc3QAuhy/HMIcxBzHHMoczhxmoOQhcwAAoB8pcwAAoB0p6wCyGnAAAKCrIWwAAKA5KWkAbQAAoHMpbAAAoKIhAKGrKmFl1hzaHGkAbAAAoBkpc6CtKgDgrSoA/oABYWJyAOUc6RztHHIAcgAAoAwpcgBrAACgcicAAWFr8Rz4HGMAAAFla/Yc9xx7YFtgAAFlc/wc/hwAoIspbAAAAWR1Ax0FHQCgjykAoI0pAAJhZXV5Dh0RHRodHB3yIW9uPmEAAWRpFR0YHWkAbAA8YewAowbiAPccO2QAAmNxcnMkHScdLB05HWEAAKA2KXUAbwDyoBwgqhEAAWR1MB00HeghYXIAoGcpcyJoYXIAAKBLKWgAAKCyIQCiZCJmZ3FzRB1FB5Qdnh10AIACYWhscnQATh1WHWUdbB2NHXIicm93AHSgkCFhAOkAzxxhI3Jwb29uAAABZHVeHWId7yF3bgCgvSFwAACgvCHlJGZ0YXJyb3dzAKDHIWkiZ2h0AIABYWhzAHUdex2DHXIicm93APOglCGdBmEAcgBwAG8AbwBuAPMAzgtxAHUAaQBnAGEAcgByAG8A9wBlGugkcmVldGltZXMAoMsi8aFkIk0HAACaHWwAYQBuAPQAXgcAon0qY2Rnc6YdqR2xHbcdYwAAoKgqbwB0AG+gfypyoIEqAKCDKmXg2iIA/nMAAKCTKoACYWRlZ3MAwB3GHcod1h3ZHXAAcAByAG8A+ACmHG8AdAAAoNYicQAAAWdxzx3SHXQA8gBGB2cAdADyAHQcdADyAFMHaQDtAGMHgAFpbHIA4h3mHeod8yFodACgfClvAG8A8gDKBgDgNdgp3UWgdiIAoJEqYQH1Hf4dcgAAAWR1YB35HWygvCEAoGopbABrAACghCVjAHkAWWQAomoiYWNodAweDx4VHhkecgDyAGsdbwByAG4AZQDyAGAW4SFyZACgaylyAGkAAKD6JQABaW8hHiQe5CFvdEBh9SFzdGGgsCPjIWhlAKCwIwACRWFlczMeNR48HkEeAKBoInAAcKCJKvIhb3gAoIkqcaCHKvGghyo0HmkAbQAAoOYiAARhYm5vcHR3elIeXB5fHoUelh6mHqsetB4AAW5yVh5ZHmcAAKDsJ3IAAKD9IXIA6wCwBmcAgAFsbXIAZh52Hnse5SFmdAABYXKIB2weaQBnAGgAdABhAHIAcgBvAPcAkwfhInBzdG8AoPwnaQBnAGgAdABhAHIAcgBvAPcAmgdwI2Fycm93AAABbHKNHpEeZQBmAPQAxhxpImdodAAAoKwhgAFhZmwAnB6fHqIecgAAoIUpAOA12F3ddQBzAACgLSppIm1lcwAAoDQqYQGvHrMecwB0AACgFyLhAIoOZaHKJbkeRhLuIWdlAKDKJWEAcgBsoCgAdAAAoJMpgAJhY2htdADMHs8e1R7bHt0ecgDyAJ0GbwByAG4AZQDyANYWYQByAGSgyyEAoG0pAKAOIHIAaQAAoL8iAANhY2hpcXTrHu8e1QfzHv0eBh/xIXVvAKA5IHIAAOA12MHcbQDloXIi+h4AAPweAKCNKgCgjyoAAWJ19xwBH28AcqAYIACgGiDyIW9rQmEAhDwAO2NkaGlscXJCBhcfxh0gHyQfKB8sHzEfAAFjaRsfHR8AoKYqcgAAoHkqcgBlAOUAkx3tIWVzAKDJIuEhcnIAoHYpdSJlc3QAAKB7KgABUGk1HzkfYQByAACglillocMlAgdfEnIAAAFkdUIfRx9zImhhcgAAoEop6CFhcgCgZikAAWVuTx9WH3IjdG5lcXEAAOBoIgD+xQBUHwAHRGFjZGVmaGlsbm9wc3VuH3Ifoh+rH68ftx+7H74f5h/uH/MfBwj/HwsgxCFvdACgOiIAAmNscHJ5H30fiR+eH3IAO4CvAK9AAAFldIEfgx8AoEImZaAgJ3MAZQAAoCAnc6CmIXQAbwCAoaYhZGx1AJQfmB+cH28AdwDuAHkDZQBmAPQA6gbwAOkO6yFlcgCgriUAAW95ph+qH+0hbWEAoCkqPGThIXNoAKAUIOElc3VyZWRhbmdsZQCgISJyAADgNdgq3W8AAKAnIYABY2RuAMQfyR/bH3IAbwA7gLUAtUBhoiMi0B8AANMf1x9zAPQAKxFpAHIAAKDwKm8AdAA7gLcAt0B1AHMA4qESIh4TAADjH3WgOCIAoCoqYwHqH+0fcAAAoNsq8gB+GnAAbAB1APMACAgAAWRw9x/7H+UhbHMAoKciZgAA4DXYXt0AAWN0AyAHIHIAAOA12MLc8CFvcwCgPiJsobwDECAVIPQiaW1hcACguCJhAPAAEyAADEdMUlZhYmNkZWZnaGlqbG1vcHJzdHV2dzwgRyBmIG0geSCqILgg2iDeIBEhFSEyIUMhTSFQIZwhnyHSIQAiIyKLIrEivyIUIwABZ3RAIEMgAODZIjgD9uBrItIgBwmAAWVsdABNIF8gYiBmAHQAAAFhclMgWCByInJvdwAAoM0h6SRnaHRhcnJvdwCgziEA4NgiOAP24Goi0iBfCekkZ2h0YXJyb3cAoM8hAAFEZHEgdSDhIXNoAKCvIuEhc2gAoK4igAJiY25wdACCIIYgiSCNIKIgbABhAACgByL1IXRlRGFnAADgICLSIACiSSJFaW9wlSCYIJwgniAA4HAqOANkAADgSyI4A3MASWFyAG8A+AAyCnUAcgBhoG4mbADzoG4mmwjzAa8gAACzIHAAO4CgAKBAbQBwAOXgTiI4AyoJgAJhZW91eQDBIMogzSDWINkg8AHGIAAAyCAAoEMqbwBuAEhh5CFpbEZhbgBnAGSgRyJvAHQAAOBtKjgDcAAAoEIqPWThIXNoAKATIACjYCJBYWRxc3jpIO0g+SD+IAIhDCFyAHIAAKDXIXIAAAFocvIg9SBrAACgJClvoJch9wAGD28AdAAA4FAiOAN1AGkA9gC7CAABZWkGIQohYQByAACgKCntAN8I6SFzdPOgBCLlCHIAAOA12CvdAAJFZXN0/wgcISshLiHxoXEiIiEAABMJ8aFxIgAJAAAnIWwAYQBuAPQAEwlpAO0AGQlyoG8iAKBvIoABQWFwADghOyE/IXIA8gBeIHIAcgAAoK4hYQByAACg8ipzogsiSiEAAAAAxwtkoPwiAKD6ImMAeQBaZIADQUVhZGVzdABcIV8hYiFmIWkhkyGWIXIA8gBXIADgZiI4A3IAcgAAoJohcgAAoCUggKFwImZxcwBwIYQhjiF0AAABYXJ1IXohcgByAG8A9wBlIWkAZwBoAHQAYQByAHIAbwD3AD4h8aFwImAhAACKIWwAYQBuAPQAZwlz4H0qOAMAoG4iaQDtAG0JcqBuImkA5aDqIkUJaQDkADoKAAFwdKMhpyFmAADgNdhf3YCBrAA7aW4AriGvIcchrEBuAIChCSJFZHYAtyG6Ib8hAOD5IjgDbwB0AADg9SI4A+EB1gjEIcYhAKD3IgCg9iJpAHagDCLhAagJzyHRIQCg/iIAoP0igAFhb3IA2CHsIfEhcgCAoSYiYXN0AOAh5SHpIWwAbABlAOwAywhsAADg/SrlIADgAiI4A2wiaW50AACgFCrjoYAi9yEAAPohdQDlAJsJY+CvKjgDZaCAIvEAkwkAAkFhaXQHIgoiFyIeInIA8gBsIHIAcgAAoZshY3cRIhQiAOAzKTgDAOCdITgDZyRodGFycm93AACgmyFyAGkA5aDrIr4JgANjaGltcHF1AC8iPCJHIpwhTSJQIloigKGBImNlcgA2Iv0JOSJ1AOUABgoA4DXYw9zvIXJ0bQKdIQAAAABEImEAcgDhAOEhbQBloEEi8aBEIiYKYQDyAMsIcwB1AAABYnBWIlgi5QDUCeUA3wmAAWJjcABgInMieCKAoYQiRWVzAGci7glqIgDgxSo4A2UAdABl4IIi0iBxAPGgiCJoImMAZaCBIvEA/gmAoYUiRWVzAH8iFgqCIgDgxio4A2UAdABl4IMi0iBxAPGgiSKAIgACZ2lscpIilCKaIpwi7AAMCWwAZABlADuA8QDxQOcAWwlpI2FuZ2xlAAABbHKkIqoi5SFmdGWg6iLxAEUJaSJnaHQAZaDrIvEAvgltoL0DAKEjAGVzuCK8InIAbwAAoBYhcAAAoAcggARESGFkZ2lscnMAziLSItYi2iLeIugi7SICIw8j4SFzaACgrSLhIXJyAKAEKXAAAOBNItIg4SFzaACgrCIAAWV04iLlIgDgZSLSIADgPgDSIG4iZmluAACg3imAAUFldADzIvci+iJyAHIAAKACKQDgZCLSIHLgPADSIGkAZQAA4LQi0iAAAUF0BiMKI3IAcgAAoAMp8iFpZQDgtSLSIGkAbQAA4Dwi0iCAAUFhbgAaIx4jKiNyAHIAAKDWIXIAAAFociMjJiNrAACgIylvoJYh9wD/DuUhYXIAoCcpUxJqFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVCMAAF4jaSN/I4IjjSOeI8AUAAAAAKYjwCMAANoj3yMAAO8jHiQvJD8kRCQAAWNzVyNsFHUAdABlADuA8wDzQAABaXlhI2cjcgBjoJoiO4D0APRAPmSAAmFiaW9zAHEjdCN3I3EBeiNzAOgAdhTsIWFjUWF2AACgOCrvIWxkAKC8KewhaWdTYQABY3KFI4kjaQByAACgvykA4DXYLN1vA5QjAAAAAJYjAACcI24A22JhAHYAZQA7gPIA8kAAoMEpAAFibaEjjAphAHIAAKC1KQACYWNpdKwjryO6I70jcgDyAFkUAAFpcrMjtiNyAACgvinvIXNzAKC7KW4A5QDZCgCgwCmAAWFlaQDFI8gjyyNjAHIATWFnAGEAyWOAAWNkbgDRI9Qj1iPyIW9uv2MAoLYpdQDzAHgBcABmAADgNdhg3YABYWVsAOQj5yPrI3IAAKC3KXIAcAAAoLkpdQDzAHwBAKMoImFkaW9zdvkj/CMPJBMkFiQbJHIA8gBeFIChXSplZm0AAyQJJAwkcgBvoDQhZgAAoDQhO4CqAKpAO4C6ALpA5yFvZgCgtiJyAACgVipsIm9wZQAAoFcqAKBbKoABY2xvACMkJSQrJPIACCRhAHMAaAA7gPgA+EBsAACgmCJpAGwBMyQ4JGQAZQA7gPUA9UBlAHMAYaCXInMAAKA2Km0AbAA7gPYA9kDiIWFyAKA9I+EKXiQAAHokAAB8JJQkAACYJKkkAAAAALUkEQsAAPAkAAAAAAQleiUAAIMlcgCAoSUiYXN0AGUkbyQBCwCBtgA7bGokayS2QGwAZQDsABgDaQJ1JAAAAAB4JG0AAKDzKgCg/Sp5AD9kcgCAAmNpbXB0AIUkiCSLJJkSjyRuAHQAJWBvAGQALmBpAGwAAKAwIOUhbmsAoDEgcgAA4DXYLd2AAWltbwCdJKAkpCR2oMYD1WNtAGEA9AD+B24AZQAAoA4m9KHAA64kAAC0JGMjaGZvcmsAAKDUItZjAAFhdbgkxCRuAAABY2u9JMIkawBooA8hAKAOIfYAaRpzAACkKwBhYmNkZW1zdNMkIRPXJNsk4STjJOck6yTjIWlyAKAjKmkAcgAAoCIqAAFvdYsW3yQAoCUqAKByKm4AO4CxALFAaQBtAACgJip3AG8AAKAnKoABaXB1APUk+iT+JO4idGludACgFSpmAADgNdhh3W4AZAA7gKMAo0CApHoiRWFjZWlub3N1ABMlFSUYJRslTCVRJVklSSV1JQCgsypwAACgtyp1AOUAPwtjoK8qgKJ6ImFjZW5zACclLSU0JTYlSSVwAHAAcgBvAPgAFyV1AHIAbAB5AGUA8QA/C/EAOAuAAWFlcwA8JUElRSXwInByb3gAoLkqcQBxAACgtSppAG0AAKDoImkA7QBEC20AZQDzoDIgIguAAUVhcwBDJVclRSXwAEAlgAFkZnAATwtfJXElgAFhbHMAZSVpJW0l7CFhcgCgLiPpIW5lAKASI/UhcmYAoBMjdKAdIu8AWQvyIWVsAKCwIgABY2l9JYElcgAA4DXYxdzIY24iY3NwAACgCCAAA2Zpb3BzdZElKxuVJZolnyWkJXIAAOA12C7dcABmAADgNdhi3XIiaW1lAACgVyBjAHIAAOA12MbcgAFhZW8AqiW6JcAldAAAAWVpryW2JXIAbgBpAG8AbgDzABkFbgB0AACgFipzAHQAZaA/APEACRj0AG0LgApBQkhhYmNkZWZoaWxtbm9wcnN0dXgA4yXyJfYl+iVpJpAmpia9JtUm5ib4JlonaCdxJ3UnnietJ7EnyCfiJ+cngAFhcnQA6SXsJe4lcgDyAJkM8gD6AuEhaWwAoBwpYQByAPIA3BVhAHIAAKBkKYADY2RlbnFydAAGJhAmEyYYJiYmKyZaJgABZXUKJg0mAOA9IjEDdABlAFVhaQDjACAN7SJwdHl2AKCzKWcAgKHpJ2RlbAAgJiImJCYAoJIpAKClKeUA9wt1AG8AO4C7ALtAcgAApZIhYWJjZmhscHN0dz0mQCZFJkcmSiZMJk4mUSZVJlgmcAAAoHUpZqDlIXMAAKAgKQCgMylzAACgHinrALka8ACVHmwAAKBFKWkAbQAAoHQpbAAAoKMhAKCdIQABYWleJmImaQBsAACgGilvAG6gNiJhAGwA8wB2C4ABYWJyAG8mciZ2JnIA8gAvEnIAawAAoHMnAAFha3omgSZjAAABZWt/JoAmfWBdYAABZXOFJocmAKCMKWwAAAFkdYwmjiYAoI4pAKCQKQACYWV1eZcmmiajJqUm8iFvbllhAAFkaZ4moSZpAGwAV2HsAA8M4gCAJkBkAAJjbHFzrSawJrUmuiZhAACgNylkImhhcgAAoGkpdQBvAPKgHSCjAWgAAKCzIYABYWNnAMMm0iaUC2wAgKEcIWlwcwDLJs4migxuAOUAoAxhAHIA9ADaC3QAAKCtJYABaWxyANsm3ybjJvMhaHQAoH0pbwBvAPIANgwA4DXYL90AAWFv6ib1JnIAAAFkde8m8SYAoMEhbKDAIQCgbCl2oMED8WOAAWducwD+Jk4nUCdoAHQAAANhaGxyc3QKJxInISc1Jz0nRydyInJvdwB0oJIhYQDpAFYmYSNycG9vbgAAAWR1GiceJ28AdwDuAPAmcAAAoMAh5SFmdAABYWgnJy0ncgByAG8AdwDzAAkMYQByAHAAbwBvAG4A8wATBGklZ2h0YXJyb3dzAACgySFxAHUAaQBnAGEAcgByAG8A9wBZJugkcmVldGltZXMAoMwiZwDaYmkAbgBnAGQAbwB0AHMAZQDxABwYgAFhaG0AYCdjJ2YncgDyAAkMYQDyABMEAKAPIG8idXN0AGGgsSPjIWhlAKCxI+0haWQAoO4qAAJhYnB0fCeGJ4knmScAAW5ygCeDJ2cAAKDtJ3IAAKD+IXIA6wAcDIABYWZsAI8nkieVJ3IAAKCGKQDgNdhj3XUAcwAAoC4qaSJtZXMAAKA1KgABYXCiJ6gncgBnoCkAdAAAoJQp7yJsaW50AKASKmEAcgDyADwnAAJhY2hxuCe8J6EMwCfxIXVvAKA6IHIAAOA12MfcAAFidYAmxCdvAPKgGSCoAYABaGlyAM4n0ifWJ3IAZQDlAE0n7SFlcwCgyiJpAIChuSVlZmwAXAxjEt4n9CFyaQCgzinsInVoYXIAoGgpAKAeIWENBSgJKA0oSyhVKIYoAACLKLAoAAAAAOMo5ygAABApJCkxKW0pcSmHKaYpAACYKgAAAACxKmMidXRlAFthcQB1AO8ABR+ApHsiRWFjZWlucHN5ABwoHignKCooLygyKEEoRihJKACgtCrwASMoAAAlKACguCpvAG4AYWF1AOUAgw1koLAqaQBsAF9hcgBjAF1hgAFFYXMAOCg6KD0oAKC2KnAAAKC6KmkAbQAAoOki7yJsaW50AKATKmkA7QCIDUFkbwB0AGKixSKRFgAAAABTKACgZiqAA0FhY21zdHgAYChkKG8ocyh1KHkogihyAHIAAKDYIXIAAAFocmkoayjrAJAab6CYIfcAzAd0ADuApwCnQGkAO2D3IWFyAKApKW0AAAFpbn4ozQBuAHUA8wDOAHQAAKA2J3IA7+A12DDdIxkAAmFjb3mRKJUonSisKHIAcAAAoG8mAAFoeZkonChjAHkASWRIZHIAdABtAqUoAAAAAKgoaQDkAFsPYQByAGEA7ABsJDuArQCtQAABZ22zKLsobQBhAAChwwNmdroouijCY4CjPCJkZWdsbnByAMgozCjPKNMo1yjaKN4obwB0AACgairxoEMiCw5FoJ4qAKCgKkWgnSoAoJ8qZQAAoEYi7CF1cwCgJCrhIXJyAKByKWEAcgDyAPwMAAJhZWl07Sj8KAEpCCkAAWxz8Sj4KGwAcwBlAHQAbQDpAH8oaABwAACgMyrwImFyc2wAoOQpAAFkbFoPBSllAACgIyNloKoqc6CsKgDgrCoA/oABZmxwABUpGCkfKfQhY3lMZGKgLwBhoMQpcgAAoD8jZgAA4DXYZN1hAAABZHIoKRcDZQBzAHWgYCZpAHQAAKBgJoABY3N1ADYpRilhKQABYXU6KUApcABzoJMiAOCTIgD+cABzoJQiAOCUIgD+dQAAAWJwSylWKQChjyJlcz4NUCllAHQAZaCPIvEAPw0AoZAiZXNIDVspZQB0AGWgkCLxAEkNAKGhJWFmZilbBHIAZQFrKVwEAKChJWEAcgDyAAMNAAJjZW10dyl7KX8pgilyAADgNdjI3HQAbQDuAM4AaQDsAAYpYQByAOYAVw0AAWFyiimOKXIA5qAGJhESAAFhbpIpoylpImdodAAAAWVwmSmgKXAAcwBpAGwAbwDuANkXaADpAKAkcwCvYIACYmNtbnAArin8KY4NJSooKgCkgiJFZGVtbnByc7wpvinCKcgpzCnUKdgp3CkAoMUqbwB0AACgvSpkoIYibwB0AACgwyr1IWx0AKDBKgABRWXQKdIpAKDLKgCgiiLsIXVzAKC/KuEhcnIAoHkpgAFlaXUA4inxKfQpdAAAoYIiZW7oKewpcQDxoIYivSllAHEA8aCKItEpbQAAoMcqAAFicPgp+ikAoNUqAKDTKmMAgKJ7ImFjZW5zAAcqDSoUKhYqRihwAHAAcgBvAPgAIyh1AHIAbAB5AGUA8QCDDfEAfA2AAWFlcwAcKiIqPShwAHAAcgBvAPgAPChxAPEAOShnAACgaiYApoMiMTIzRWRlaGxtbnBzPCo/KkIqRSpHKlIqWCpjKmcqaypzKncqO4C5ALlAO4CyALJAO4CzALNAAKDGKgABb3NLKk4qdAAAoL4qdQBiAACg2CpkoIcibwB0AACgxCpzAAABb3VdKmAqbAAAoMknYgAAoNcq4SFycgCgeyn1IWx0AKDCKgABRWVvKnEqAKDMKgCgiyLsIXVzAKDAKoABZWl1AH0qjCqPKnQAAKGDImVugyqHKnEA8aCHIkYqZQBxAPGgiyJwKm0AAKDIKgABYnCTKpUqAKDUKgCg1iqAAUFhbgCdKqEqrCpyAHIAAKDZIXIAAAFocqYqqCrrAJUab6CZIfcAxQf3IWFyAKAqKWwAaQBnADuA3wDfQOELzyrZKtwq6SrsKvEqAAD1KjQrAAAAAAAAAAAAAEwrbCsAAHErvSsAAAAAAADRK3IC1CoAAAAA2CrnIWV0AKAWI8RjcgDrAOUKgAFhZXkA4SrkKucq8iFvbmVh5CFpbGNhQmRvAPQAIg5sInJlYwAAoBUjcgAA4DXYMd0AAmVpa2/7KhIrKCsuK/IBACsAAAkrZQAAATRm6g0EK28AcgDlAOsNYQBzorgDECsAAAAAEit5AG0A0WMAAWNuFislK2sAAAFhcxsrIStwAHAAcgBvAPgAFw5pAG0AAKA8InMA8AD9DQABYXMsKyEr8AAXDnIAbgA7gP4A/kDsATgrOyswG2QA5QBnAmUAcwCAgdcAO2JkAEMrRCtJK9dAYaCgInIAAKAxKgCgMCqAAWVwcwBRK1MraSvhAAkh4qKkIlsrXysAAAAAYytvAHQAAKA2I2kAcgAAoPEqb+A12GXdcgBrAACg2irhAHgociJpbWUAAKA0IIABYWlwAHYreSu3K2QA5QC+DYADYWRlbXBzdACFK6MrmiunK6wrsCuzK24iZ2xlAACitSVkbHFykCuUK5ornCvvIXduAKC/JeUhZnRloMMl8QACBwCgXCJpImdodABloLkl8QBdDG8AdAAAoOwlaSJudXMAAKA6KuwhdXMAoDkqYgAAoM0p6SFtZQCgOyrlInppdW0AoOIjgAFjaHQAwivKK80rAAFyecYrySsA4DXYydxGZGMAeQBbZPIhb2tnYQABaW/UK9creAD0ANERaCJlYWQAAAFsct4r5ytlAGYAdABhAHIAcgBvAPcAXQbpJGdodGFycm93AKCgIQAJQUhhYmNkZmdobG1vcHJzdHV3CiwNLBEsHSwnLDEsQCxLLFIsYix6LIQsjyzLLOgs7Sz/LAotcgDyAAkDYQByAACgYykAAWNyFSwbLHUAdABlADuA+gD6QPIACQ1yAOMBIywAACUseQBeZHYAZQBtYQABaXkrLDAscgBjADuA+wD7QENkgAFhYmgANyw6LD0scgDyANEO7CFhY3FhYQDyAOAOAAFpckQsSCzzIWh0AKB+KQDgNdgy3XIAYQB2AGUAO4D5APlAYQFWLF8scgAAAWxyWixcLACgvyEAoL4hbABrAACggCUAAWN0Zix2LG8CbCwAAAAAcyxyAG4AZaAcI3IAAKAcI28AcAAAoA8jcgBpAACg+CUAAWFsfiyBLGMAcgBrYTuAqACoQAABZ3CILIssbwBuAHNhZgAA4DXYZt0AA2FkaGxzdZksniynLLgsuyzFLHIAcgBvAPcACQ1vAHcAbgBhAHIAcgBvAPcA2A5hI3Jwb29uAAABbHKvLLMsZQBmAPQAWyxpAGcAaAD0AF0sdQDzAKYOaQAAocUDaGzBLMIs0mNvAG4AxWPwI2Fycm93cwCgyCGAAWNpdADRLOEs5CxvAtcsAAAAAN4scgBuAGWgHSNyAACgHSNvAHAAAKAOI24AZwBvYXIAaQAAoPklYwByAADgNdjK3IABZGlyAPMs9yz6LG8AdAAAoPAi7CFkZWlhaQBmoLUlAKC0JQABYW0DLQYtcgDyAMosbAA7gPwA/EDhIm5nbGUAoKcpgAdBQkRhY2RlZmxub3Byc3oAJy0qLTAtNC2bLZ0toS2/LcMtxy3TLdgt3C3gLfwtcgDyABADYQByAHag6CoAoOkqYQBzAOgA/gIAAW5yOC08LechcnQAoJwpgANla25wcnN0AJkpSC1NLVQtXi1iLYItYQBwAHAA4QAaHG8AdABoAGkAbgDnAKEXgAFoaXIAoSmzJFotbwBwAPQAdCVooJUh7wD4JgABaXVmLWotZwBtAOEAuygAAWJwbi14LXMjZXRuZXEAceCKIgD+AODLKgD+cyNldG5lcQBx4IsiAP4A4MwqAP4AAWhyhi2KLWUAdADhABIraSNhbmdsZQAAAWxyki2WLeUhZnQAoLIiaSJnaHQAAKCzInkAMmThIXNoAKCiIoABZWxyAKcttC24LWKiKCKuLQAAAACyLWEAcgAAoLsicQAAoFoi7CFpcACg7iIAAWJ0vC1eD2EA8gBfD3IAAOA12DPddAByAOkAlS1zAHUAAAFicM0t0C0A4IIi0iAA4IMi0iBwAGYAAOA12GfdcgBvAPAAWQt0AHIA6QCaLQABY3XkLegtcgAA4DXYy9wAAWJw7C30LW4AAAFFZXUt8S0A4IoiAP5uAAABRWV/LfktAOCLIgD+6SJnemFnAKCaKYADY2Vmb3BycwANLhAuJS4pLiMuLi40LukhcmN1YQABZGkULiEuAAFiZxguHC5hAHIAAKBfKmUAcaAnIgCgWSLlIXJwAKAYIXIAAOA12DTdcABmAADgNdho3WWgQCJhAHQA6ABqD2MAcgAA4DXYzNzjCuQRUC4AAFQuAABYLmIuAAAAAGMubS5wLnQuAAAAAIguki4AAJouJxIqEnQAcgDpAB0ScgAA4DXYNd0AAUFhWy5eLnIA8gDnAnIA8gCTB75jAAFBYWYuaS5yAPIA4AJyAPIAjAdhAPAAeh5pAHMAAKD7IoABZHB0APgReS6DLgABZmx9LoAuAOA12GnddQDzAP8RaQBtAOUABBIAAUFhiy6OLnIA8gDuAnIA8gCaBwABY3GVLgoScgAA4DXYzdwAAXB0nS6hLmwAdQDzACUScgDpACASAARhY2VmaW9zdbEuvC7ELsguzC7PLtQu2S5jAAABdXm2LrsudABlADuA/QD9QE9kAAFpecAuwy5yAGMAd2FLZG4AO4ClAKVAcgAA4DXYNt1jAHkAV2RwAGYAAOA12GrdYwByAADgNdjO3AABY23dLt8ueQBOZGwAO4D/AP9AAAVhY2RlZmhpb3N38y73Lv8uAi8MLxAvEy8YLx0vIi9jInV0ZQB6YQABYXn7Lv4u8iFvbn5hN2RvAHQAfGEAAWV0Bi8KL3QAcgDmAB8QYQC2Y3IAAOA12DfdYwB5ADZk5yJyYXJyAKDdIXAAZgAA4DXYa91jAHIAAOA12M/cAAFqbiYvKC8AoA0gagAAoAwg"); 485//
485 MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/entities/dist/generated/decode-data-xml.js [app-client] (ecmascript) 486; 487; 488const xmlDecodeTree = /* #__PURE__ */ decodeBase64("AAJhZ2xxBwARABMAFQBtAg0AAAAAAA8AcAAmYG8AcwAnYHQAPmB0ADxg9SFvdCJg"); 489// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/entities/dist/internal/bin-trie-flags.js [app-client] (ecmascript) 490; 491var BinTrieFlags; 492(function(BinTrieFlags) { 493 BinTrieFlags[BinTrieFlags["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH"; 494 BinTrieFlags[BinTrieFlags["FLAG13"] = 8192] = "FLAG13"; 495 BinTrieFlags[BinTrieFlags["BRANCH_LENGTH"] = 8064] = "BRANCH_LENGTH"; 496 BinTrieFlags[BinTrieFlags["JUMP_TABLE"] = 127] = "JUMP_TABLE"; 497})(BinTrieFlags || (BinTrieFlags = {})); 498; 499; 500; 501; 502var CharCodes; 503(function(CharCodes) {
vendor: 16,384 bytes, lines 504-836
504 CharCodes[CharCodes["NUM"] = 35] = "NUM"; 505 CharCodes[CharCodes["SEMI"] = 59] = "SEMI"; 506 CharCodes[CharCodes["EQUALS"] = 61] = "EQUALS"; 507 CharCodes[CharCodes["ZERO"] = 48] = "ZERO"; 508 CharCodes[CharCodes["NINE"] = 57] = "NINE"; 509 CharCodes[CharCodes["LOWER_A"] = 97] = "LOWER_A"; 510 CharCodes[CharCodes["LOWER_F"] = 102] = "LOWER_F"; 511 CharCodes[CharCodes["LOWER_X"] = 120] = "LOWER_X"; 512 CharCodes[CharCodes["LOWER_Z"] = 122] = "LOWER_Z"; 513 CharCodes[CharCodes["UPPER_A"] = 65] = "UPPER_A"; 514 CharCodes[CharCodes["UPPER_F"] = 70] = "UPPER_F"; 515 CharCodes[CharCodes["UPPER_Z"] = 90] = "UPPER_Z"; 516})(CharCodes || (CharCodes = {})); 517/** Bit that needs to be set to convert an upper case ASCII character to lower case */ const TO_LOWER_BIT = 0b10_0000; 518function isNumber(code) { 519 return code >= CharCodes.ZERO && code <= CharCodes.NINE; 520} 521function isHexadecimalCharacter(code) { 522 return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_F || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_F; 523} 524function isAsciiAlphaNumeric(code) { 525 return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z || isNumber(code); 526} 527/** 528 * Checks if the given character is a valid end character for an entity in an attribute. 529 * 530 * Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error. 531 * See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state 532 * @param code Code point to decode. 533 */ function isEntityInAttributeInvalidEnd(code) { 534 return code === CharCodes.EQUALS || isAsciiAlphaNumeric(code); 535} 536var EntityDecoderState; 537(function(EntityDecoderState) { 538 EntityDecoderState[EntityDecoderState["EntityStart"] = 0] = "EntityStart"; 539 EntityDecoderState[EntityDecoderState["NumericStart"] = 1] = "NumericStart"; 540 EntityDecoderState[EntityDecoderState["NumericDecimal"] = 2] = "NumericDecimal"; 541 EntityDecoderState[EntityDecoderState["NumericHex"] = 3] = "NumericHex"; 542 EntityDecoderState[EntityDecoderState["NamedEntity"] = 4] = "NamedEntity"; 543})(EntityDecoderState || (EntityDecoderState = {})); 544var DecodingMode; 545(function(DecodingMode) { 546 /** Entities in text nodes that can end with any character. */ DecodingMode[DecodingMode["Legacy"] = 0] = "Legacy"; 547 /** Only allow entities terminated with a semicolon. */ DecodingMode[DecodingMode["Strict"] = 1] = "Strict"; 548 /** Entities in attributes have limitations on ending characters. */ DecodingMode[DecodingMode["Attribute"] = 2] = "Attribute"; 549})(DecodingMode || (DecodingMode = {})); 550class EntityDecoder { 551 decodeTree; 552 emitCodePoint; 553 errors; 554 constructor(/** The tree used to decode entities. */ // biome-ignore lint/correctness/noUnusedPrivateClassMembers: False positive 555 decodeTree, /** 556 * The function that is called when a codepoint is decoded. 557 * 558 * For multi-byte named entities, this will be called multiple times, 559 * with the second codepoint, and the same `consumed` value. 560 * @param codepoint The decoded codepoint. 561 * @param consumed The number of bytes consumed by the decoder. 562 */ emitCodePoint, /** An object that is used to produce errors. */ errors){ 563 this.decodeTree = decodeTree; 564 this.emitCodePoint = emitCodePoint; 565 this.errors = errors; 566 } 567 /** The current state of the decoder. */ state = EntityDecoderState.EntityStart; 568 /** Characters that were consumed while parsing an entity. */ consumed = 1; 569 /** 570 * The result of the entity. 571 * 572 * Either the result index of a numeric entity, or the codepoint of a 573 * numeric entity. 574 */ result = 0; 575 /** The current index in the decode tree. */ treeIndex = 0; 576 /** The number of characters that were consumed in excess. */ excess = 1; 577 /** The mode in which the decoder is operating. */ decodeMode = DecodingMode.Strict; 578 /** The number of characters that have been consumed in the current run. */ runConsumed = 0; 579 /** 580 * Resets the instance to make it reusable. 581 * @param decodeMode Entity decoding mode to use. 582 */ startEntity(decodeMode) { 583 this.decodeMode = decodeMode; 584 this.state = EntityDecoderState.EntityStart; 585 this.result = 0; 586 this.treeIndex = 0; 587 this.excess = 1; 588 this.consumed = 1; 589 this.runConsumed = 0; 590 } 591 /** 592 * Write an entity to the decoder. This can be called multiple times with partial entities. 593 * If the entity is incomplete, the decoder will return -1. 594 * 595 * Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the 596 * entity is incomplete, and resume when the next string is written. 597 * @param input The string containing the entity (or a continuation of the entity). 598 * @param offset The offset at which the entity begins. Should be 0 if this is not the first call. 599 * @returns The number of characters that were consumed, or -1 if the entity is incomplete. 600 */ write(input, offset) { 601 switch(this.state){ 602 case EntityDecoderState.EntityStart: 603 { 604 if (input.charCodeAt(offset) === CharCodes.NUM) { 605 this.state = EntityDecoderState.NumericStart; 606 this.consumed += 1; 607 return this.stateNumericStart(input, offset + 1); 608 } 609 this.state = EntityDecoderState.NamedEntity; 610 return this.stateNamedEntity(input, offset); 611 } 612 case EntityDecoderState.NumericStart: 613 { 614 return this.stateNumericStart(input, offset); 615 } 616 case EntityDecoderState.NumericDecimal: 617 { 618 return this.stateNumericDecimal(input, offset); 619 } 620 case EntityDecoderState.NumericHex: 621 { 622 return this.stateNumericHex(input, offset); 623 } 624 case EntityDecoderState.NamedEntity: 625 { 626 return this.stateNamedEntity(input, offset); 627 } 628 } 629 } 630 /** 631 * Switches between the numeric decimal and hexadecimal states. 632 * 633 * Equivalent to the `Numeric character reference state` in the HTML spec. 634 * @param input The string containing the entity (or a continuation of the entity). 635 * @param offset The current offset. 636 * @returns The number of characters that were consumed, or -1 if the entity is incomplete. 637 */ stateNumericStart(input, offset) { 638 if (offset >= input.length) { 639 return -1; 640 } 641 if ((input.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) { 642 this.state = EntityDecoderState.NumericHex; 643 this.consumed += 1; 644 return this.stateNumericHex(input, offset + 1); 645 } 646 this.state = EntityDecoderState.NumericDecimal; 647 return this.stateNumericDecimal(input, offset); 648 } 649 /** 650 * Parses a hexadecimal numeric entity. 651 * 652 * Equivalent to the `Hexademical character reference state` in the HTML spec. 653 * @param input The string containing the entity (or a continuation of the entity). 654 * @param offset The current offset. 655 * @returns The number of characters that were consumed, or -1 if the entity is incomplete. 656 */ stateNumericHex(input, offset) { 657 while(offset < input.length){ 658 const char = input.charCodeAt(offset); 659 if (isNumber(char) || isHexadecimalCharacter(char)) { 660 // Convert hex digit to value (0-15); 'a'/'A' -> 10. 661 const digit = char <= CharCodes.NINE ? char - CharCodes.ZERO : (char | TO_LOWER_BIT) - CharCodes.LOWER_A + 10; 662 this.result = this.result * 16 + digit; 663 this.consumed++; 664 offset++; 665 } else { 666 return this.emitNumericEntity(char, 3); 667 } 668 } 669 return -1; // Incomplete entity 670 } 671 /** 672 * Parses a decimal numeric entity. 673 * 674 * Equivalent to the `Decimal character reference state` in the HTML spec. 675 * @param input The string containing the entity (or a continuation of the entity). 676 * @param offset The current offset. 677 * @returns The number of characters that were consumed, or -1 if the entity is incomplete. 678 */ stateNumericDecimal(input, offset) { 679 while(offset < input.length){ 680 const char = input.charCodeAt(offset); 681 if (isNumber(char)) { 682 this.result = this.result * 10 + (char - CharCodes.ZERO); 683 this.consumed++; 684 offset++; 685 } else { 686 return this.emitNumericEntity(char, 2); 687 } 688 } 689 return -1; // Incomplete entity 690 } 691 /** 692 * Validate and emit a numeric entity. 693 * 694 * Implements the logic from the `Hexademical character reference start 695 * state` and `Numeric character reference end state` in the HTML spec. 696 * @param lastCp The last code point of the entity. Used to see if the 697 * entity was terminated with a semicolon. 698 * @param expectedLength The minimum number of characters that should be 699 * consumed. Used to validate that at least one digit 700 * was consumed. 701 * @returns The number of characters that were consumed. 702 */ emitNumericEntity(lastCp, expectedLength) { 703 // Ensure we consumed at least one digit. 704 if (this.consumed <= expectedLength) { 705 this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed); 706 return 0; 707 } 708 // Figure out if this is a legit end of the entity 709 if (lastCp === CharCodes.SEMI) { 710 this.consumed += 1; 711 } else if (this.decodeMode === DecodingMode.Strict) { 712 return 0; 713 } 714 this.emitCodePoint(replaceCodePoint(this.result), this.consumed); 715 if (this.errors) { 716 if (lastCp !== CharCodes.SEMI) { 717 this.errors.missingSemicolonAfterCharacterReference(); 718 } 719 this.errors.validateNumericCharacterReference(this.result); 720 } 721 return this.consumed; 722 } 723 /** 724 * Parses a named entity. 725 * 726 * Equivalent to the `Named character reference state` in the HTML spec. 727 * @param input The string containing the entity (or a continuation of the entity). 728 * @param offset The current offset. 729 * @returns The number of characters that were consumed, or -1 if the entity is incomplete. 730 */ stateNamedEntity(input, offset) { 731 const { decodeTree } = this; 732 let current = decodeTree[this.treeIndex]; 733 // The length is the number of bytes of the value, including the current byte. 734 let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14; 735 while(offset < input.length){ 736 // Handle compact runs (possibly inline): valueLength == 0 and SEMI_REQUIRED bit set. 737 if (valueLength === 0 && (current & BinTrieFlags.FLAG13) !== 0) { 738 const runLength = (current & BinTrieFlags.BRANCH_LENGTH) >> 7; /* 2..63 */ 739 // If we are starting a run, check the first char. 740 if (this.runConsumed === 0) { 741 const firstChar = current & BinTrieFlags.JUMP_TABLE; 742 if (input.charCodeAt(offset) !== firstChar) { 743 return this.result === 0 ? 0 : this.emitNotTerminatedNamedEntity(); 744 } 745 offset++; 746 this.excess++; 747 this.runConsumed++; 748 } 749 // Check remaining characters in the run. 750 while(this.runConsumed < runLength){ 751 if (offset >= input.length) { 752 return -1; 753 } 754 const charIndexInPacked = this.runConsumed - 1; 755 const packedWord = decodeTree[this.treeIndex + 1 + (charIndexInPacked >> 1)]; 756 const expectedChar = charIndexInPacked % 2 === 0 ? packedWord & 0xff : packedWord >> 8 & 0xff; 757 if (input.charCodeAt(offset) !== expectedChar) { 758 this.runConsumed = 0; 759 return this.result === 0 ? 0 : this.emitNotTerminatedNamedEntity(); 760 } 761 offset++; 762 this.excess++; 763 this.runConsumed++; 764 } 765 this.runConsumed = 0; 766 this.treeIndex += 1 + (runLength >> 1); 767 current = decodeTree[this.treeIndex]; 768 valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14; 769 } 770 if (offset >= input.length) break; 771 const char = input.charCodeAt(offset); 772 /* 773 * Implicit semicolon handling for nodes that require a semicolon but 774 * don't have an explicit ';' branch stored in the trie. If we have 775 * a value on the current node, it requires a semicolon, and the 776 * current input character is a semicolon, emit the entity using the 777 * current node (without descending further). 778 */ if (char === CharCodes.SEMI && valueLength !== 0 && (current & BinTrieFlags.FLAG13) !== 0) { 779 return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess); 780 } 781 this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char); 782 if (this.treeIndex < 0) { 783 return this.result === 0 || this.decodeMode === DecodingMode.Attribute && // We shouldn't have consumed any characters after the entity, 784 (valueLength === 0 || // And there should be no invalid characters. 785 isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity(); 786 } 787 current = decodeTree[this.treeIndex]; 788 valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14; 789 // If the branch is a value, store it and continue 790 if (valueLength !== 0) { 791 // If the entity is terminated by a semicolon, we are done. 792 if (char === CharCodes.SEMI) { 793 return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess); 794 } 795 // If we encounter a non-terminated (legacy) entity while parsing strictly, then ignore it. 796 if (this.decodeMode !== DecodingMode.Strict && (current & BinTrieFlags.FLAG13) === 0) { 797 this.result = this.treeIndex; 798 this.consumed += this.excess; 799 this.excess = 0; 800 } 801 } 802 // Increment offset & excess for next iteration 803 offset++; 804 this.excess++; 805 } 806 return -1; 807 } 808 /** 809 * Emit a named entity that was not terminated with a semicolon. 810 * @returns The number of characters consumed. 811 */ emitNotTerminatedNamedEntity() { 812 const { result, decodeTree } = this; 813 const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14; 814 this.emitNamedEntityData(result, valueLength, this.consumed); 815 this.errors?.missingSemicolonAfterCharacterReference(); 816 return this.consumed; 817 } 818 /** 819 * Emit a named entity. 820 * @param result The index of the entity in the decode tree. 821 * @param valueLength The number of bytes in the entity. 822 * @param consumed The number of characters consumed. 823 * @returns The number of characters consumed. 824 */ emitNamedEntityData(result, valueLength, consumed) { 825 const { decodeTree } = this; 826 this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~(BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13) : decodeTree[result + 1], consumed); 827 if (valueLength === 3) { 828 // For multi-byte values, we need to emit the second byte. 829 this.emitCodePoint(decodeTree[result + 2], consumed); 830 } 831 return consumed; 832 } 833 /** 834 * Signal to the parser that the end of the input was reached. 835 * 836
836 * Remaining data will be emitted and relevant errors will be produced. 837 * @returns The number of characters consumed. 838 */ end() { 839 switch(this.state){ 840 case EntityDecoderState.NamedEntity: 841 { 842 // Emit a named entity if we have one. 843 return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0; 844 } 845 // Otherwise, emit a numeric entity if we have one. 846 case EntityDecoderState.NumericDecimal: 847 { 848 return this.emitNumericEntity(0, 2); 849 } 850 case EntityDecoderState.NumericHex: 851 { 852 return this.emitNumericEntity(0, 3); 853 } 854 case EntityDecoderState.NumericStart: 855 { 856 this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed); 857 return 0; 858 } 859 case EntityDecoderState.EntityStart: 860 { 861 // Return 0 if we have no entity. 862 return 0; 863 } 864 } 865 } 866} 867/** 868 * Creates a function that decodes entities in a string. 869 * @param decodeTree The decode tree. 870 * @returns A function that decodes entities in a string. 871 */ function getDecoder(decodeTree) { 872 let returnValue = ""; 873 const decoder = new EntityDecoder(decodeTree, (data)=>returnValue += String.fromCodePoint(data)); 874 return function decodeWithTrie(input, decodeMode) { 875 let lastIndex = 0; 876 let offset = 0; 877 while((offset = input.indexOf("&", offset)) >= 0){ 878 returnValue += input.slice(lastIndex, offset); 879 decoder.startEntity(decodeMode); 880 const length = decoder.write(input, // Skip the "&" 881 offset + 1); 882 if (length < 0) { 883 lastIndex = offset + decoder.end(); 884 break; 885 } 886 lastIndex = offset + length; 887 // If `length` is 0, skip the current `&` and continue. 888 offset = length === 0 ? lastIndex + 1 : lastIndex; 889 } 890 const result = returnValue + input.slice(lastIndex); 891 // Make sure we don't keep a reference to the final string. 892 returnValue = ""; 893 return result; 894 }; 895} 896function determineBranch(decodeTree, current, nodeIndex, char) { 897 const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7; 898 const jumpOffset = current & BinTrieFlags.JUMP_TABLE; 899 // Case 1: Single branch encoded in jump offset 900 if (branchCount === 0) { 901 return jumpOffset !== 0 && char === jumpOffset ? nodeIndex : -1; 902 } 903 // Case 2: Multiple branches encoded in jump table 904 if (jumpOffset) { 905 const value = char - jumpOffset; 906 return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIndex + value] - 1; 907 } 908 // Case 3: Multiple branches encoded in packed dictionary (two keys per uint16) 909 const packedKeySlots = branchCount + 1 >> 1; 910 /* 911 * Treat packed keys as a virtual sorted array of length `branchCount`. 912 * Key(i) = low byte for even i, high byte for odd i in slot i>>1. 913 */ let lo = 0; 914 let hi = branchCount - 1; 915 while(lo <= hi){ 916 const mid = lo + hi >>> 1; 917 const slot = mid >> 1; 918 const packed = decodeTree[nodeIndex + slot]; 919 const midKey = packed >> (mid & 1) * 8 & 0xff; 920 if (midKey < char) { 921 lo = mid + 1; 922 } else if (midKey > char) { 923 hi = mid - 1; 924 } else { 925 return decodeTree[nodeIndex + packedKeySlots + mid]; 926 } 927 } 928 return -1; 929} 930const htmlDecoder = /* #__PURE__ */ getDecoder(htmlDecodeTree); 931const xmlDecoder = /* #__PURE__ */ getDecoder(xmlDecodeTree); 932function decodeHTML(htmlString, mode = DecodingMode.Legacy) { 933 return htmlDecoder(htmlString, mode); 934} 935function decodeHTMLAttribute(htmlAttribute) { 936 return htmlDecoder(htmlAttribute, DecodingMode.Attribute); 937} 938function decodeHTMLStrict(htmlString) { 939 return htmlDecoder(htmlString, DecodingMode.Strict); 940} 941function decodeXML(xmlString) { 942 return xmlDecoder(xmlString, DecodingMode.Strict); 943} 944; 945; 946; 947; 948var CharCodes1; 949(function(CharCodes) {
950 CharCodes[CharCodes["Tab"] = 9] = "Tab"; 951 CharCodes[CharCodes["NewLine"] = 10] = "NewLine"; 952 CharCodes[CharCodes["FormFeed"] = 12] = "FormFeed"; 953 CharCodes[CharCodes["CarriageReturn"] = 13] = "CarriageReturn"; 954 CharCodes[CharCodes["Space"] = 32] = "Space"; 955 CharCodes[CharCodes["ExclamationMark"] = 33] = "ExclamationMark"; 956 CharCodes[CharCodes["Number"] = 35] = "Number"; 957 CharCodes[CharCodes["Amp"] = 38] = "Amp"; 958 CharCodes[CharCodes["SingleQuote"] = 39] = "SingleQuote"; 959 CharCodes[CharCodes["DoubleQuote"] = 34] = "DoubleQuote"; 960 CharCodes[CharCodes["Dash"] = 45] = "Dash"; 961 CharCodes[CharCodes["Slash"] = 47] = "Slash"; 962 CharCodes[CharCodes["Zero"] = 48] = "Zero"; 963 CharCodes[CharCodes["Nine"] = 57] = "Nine"; 964 CharCodes[CharCodes["Semi"] = 59] = "Semi"; 965 CharCodes[CharCodes["Lt"] = 60] = "Lt"; 966 CharCodes[CharCodes["Eq"] = 61] = "Eq"; 967 CharCodes[CharCodes["Gt"] = 62] = "Gt"; 968 CharCodes[CharCodes["Questionmark"] = 63] = "Questionmark"; 969 CharCodes[CharCodes["UpperA"] = 65] = "UpperA"; 970 CharCodes[CharCodes["LowerA"] = 97] = "LowerA"; 971 CharCodes[CharCodes["UpperF"] = 70] = "UpperF"; 972 CharCodes[CharCodes["LowerF"] = 102] = "LowerF"; 973 CharCodes[CharCodes["UpperZ"] = 90] = "UpperZ"; 974 CharCodes[CharCodes["LowerZ"] = 122] = "LowerZ"; 975 CharCodes[CharCodes["LowerX"] = 120] = "LowerX"; 976 CharCodes[CharCodes["OpeningSquareBracket"] = 91] = "OpeningSquareBracket"; 977})(CharCodes1 || (CharCodes1 = {})); 978/** All the states the tokenizer can be in. */ var State; 979(function(State) { 980 State[State["Text"] = 1] = "Text"; 981 State[State["BeforeTagName"] = 2] = "BeforeTagName"; 982 State[State["InTagName"] = 3] = "InTagName"; 983 State[State["InSelfClosingTag"] = 4] = "InSelfClosingTag"; 984 State[State["BeforeClosingTagName"] = 5] = "BeforeClosingTagName"; 985 State[State["InClosingTagName"] = 6] = "InClosingTagName"; 986 State[State["AfterClosingTagName"] = 7] = "AfterClosingTagName"; 987 // Attributes 988 State[State["BeforeAttributeName"] = 8] = "BeforeAttributeName"; 989 State[State["InAttributeName"] = 9] = "InAttributeName"; 990 State[State["AfterAttributeName"] = 10] = "AfterAttributeName"; 991 State[State["BeforeAttributeValue"] = 11] = "BeforeAttributeValue"; 992 State[State["InAttributeValueDq"] = 12] = "InAttributeValueDq"; 993 State[State["InAttributeValueSq"] = 13] = "InAttributeValueSq"; 994 State[State["InAttributeValueNq"] = 14] = "InAttributeValueNq"; 995 // Declarations 996 State[State["BeforeDeclaration"] = 15] = "BeforeDeclaration"; 997 State[State["InDeclaration"] = 16] = "InDeclaration"; 998 // Processing instructions 999 State[State["InProcessingInstruction"] = 17] = "InProcessingInstruction"; 1000 // Comments & CDATA 1001 State[State["BeforeComment"] = 18] = "BeforeComment"; 1002 State[State["CDATASequence"] = 19] = "CDATASequence"; 1003 State[State["DeclarationSequence"] = 20] = "DeclarationSequence"; 1004 State[State["InSpecialComment"] = 21] = "InSpecialComment"; 1005 State[State["InCommentLike"] = 22] = "InCommentLike"; 1006 // Special tags 1007 State[State["SpecialStartSequence"] = 23] = "SpecialStartSequence"; 1008 State[State["InSpecialTag"] = 24] = "InSpecialTag"; 1009 State[State["InPlainText"] = 25] = "InPlainText"; 1010 State[State["InEntity"] = 26] = "InEntity"; 1011})(State || (State = {})); 1012function isWhitespace(c) { 1013 return c === CharCodes1.Space || c === CharCodes1.NewLine || c === CharCodes1.Tab || c === CharCodes1.FormFeed || c === CharCodes1.CarriageReturn; 1014} 1015function isEndOfTagSection(c) { 1016 return c === CharCodes1.Slash || c === CharCodes1.Gt || isWhitespace(c); 1017} 1018function isASCIIAlpha(c) { 1019 return c >= CharCodes1.LowerA && c <= CharCodes1.LowerZ || c >= CharCodes1.UpperA && c <= CharCodes1.UpperZ; 1020} 1021var QuoteType; 1022(function(QuoteType) { 1023 QuoteType[QuoteType["NoValue"] = 0] = "NoValue"; 1024 QuoteType[QuoteType["Unquoted"] = 1] = "Unquoted"; 1025 QuoteType[QuoteType["Single"] = 2] = "Single"; 1026 QuoteType[QuoteType["Double"] = 3] = "Double"; 1027})(QuoteType || (QuoteType = {})); 1028/** 1029 * Sequences used to match longer strings. 1030 * 1031 * We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End 1032 * sequences with an increased offset. 1033 */ const Sequences = { 1034 Empty: new Uint8Array(0), 1035 Cdata: new Uint8Array([ 1036 0x43, 1037 0x44, 1038 0x41, 1039 0x54, 1040 0x41, 1041 0x5b 1042 ]), 1043 CdataEnd: new Uint8Array([ 1044 0x5d, 1045 0x5d, 1046 0x3e 1047 ]), 1048 CommentEnd: new Uint8Array([ 1049 0x2d, 1050 0x2d, 1051 0x21, 1052 0x3e 1053 ]), 1054 Doctype: new Uint8Array([ 1055 0x64, 1056 0x6f, 1057 0x63, 1058 0x74, 1059 0x79, 1060 0x70, 1061 0x65 1062 ]), 1063 IframeEnd: new Uint8Array([ 1064 0x3c, 1065 0x2f, 1066 0x69, 1067 0x66, 1068 0x72, 1069 0x61, 1070 0x6d, 1071 0x65 1072 ]), 1073 NoembedEnd: new Uint8Array([ 1074 0x3c, 1075 0x2f, 1076 0x6e, 1077 0x6f, 1078 0x65, 1079 0x6d, 1080 0x62, 1081 0x65, 1082 0x64 1083 ]), 1084 NoframesEnd: new Uint8Array([ 1085 0x3c, 1086 0x2f, 1087 0x6e, 1088 0x6f, 1089 0x66, 1090 0x72, 1091 0x61, 1092 0x6d, 1093 0x65, 1094 0x73 1095 ]), 1096 Plaintext: new Uint8Array([ 1097 0x3c, 1098 0x2f, 1099 0x70, 1100 0x6c, 1101 0x61, 1102 0x69, 1103 0x6e, 1104 0x74, 1105 0x65, 1106 0x78, 1107 0x74 1108 ]), 1109 ScriptEnd: new Uint8Array([ 1110 0x3c, 1111 0x2f, 1112 0x73, 1113 0x63, 1114 0x72, 1115 0x69, 1116 0x70, 1117 0x74 1118 ]), 1119 StyleEnd: new Uint8Array([ 1120 0x3c, 1121 0x2f, 1122 0x73, 1123 0x74, 1124 0x79, 1125 0x6c, 1126 0x65 1127 ]), 1128 TitleEnd: new Uint8Array([ 1129 0x3c, 1130 0x2f, 1131 0x74, 1132 0x69, 1133 0x74, 1134 0x6c, 1135 0x65 1136 ]), 1137 TextareaEnd: new Uint8Array([ 1138 0x3c, 1139 0x2f, 1140 0x74, 1141 0x65, 1142 0x78, 1143 0x74, 1144 0x61, 1145 0x72, 1146 0x65, 1147 0x61 1148 ]), 1149 XmpEnd: new Uint8Array([ 1150 0x3c, 1151 0x2f, 1152 0x78, 1153 0x6d, 1154 0x70 1155 ]) 1156}; 1157/** 1158 * Maps the first lowercase character of an HTML tag name to the sequence 1159 * used for special-tag detection. All sequences share a common layout 1160 * where index 2 is the first tag-name character, so matching always 1161 * continues from offset 3. 1162 */ const specialStartSequences = new Map([ 1163 [ 1164 Sequences.IframeEnd[2], 1165 Sequences.IframeEnd 1166 ], 1167 [ 1168 Sequences.NoembedEnd[2], 1169 Sequences.NoembedEnd 1170 ], 1171 [ 1172 Sequences.Plaintext[2], 1173 Sequences.Plaintext 1174 ], 1175 [ 1176 Sequences.ScriptEnd[2], 1177 Sequences.ScriptEnd 1178 ], 1179 [ 1180 Sequences.TitleEnd[2], 1181 Sequences.TitleEnd 1182 ], 1183 [ 1184 Sequences.XmpEnd[2], 1185 Sequences.XmpEnd 1186 ] 1187]); 1188class Tokenizer { 1189 cbs; 1190 /** The current state the tokenizer is in. */ state = State.Text; 1191 /** The read buffer. */ buffer = ""; 1192 /** The beginning of the section that is currently being read. */ sectionStart = 0; 1193 /** The index within the buffer that we are currently looking at. */ index = 0; 1194 /** The start of the last entity. */ entityStart = 0; 1195 /** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */ baseState = State.Text; 1196 /** For special parsing behavior inside of script and style tags. */ isSpecial = false;
vendor: 9,230 bytes, lines 1197-1412
1197 /** Indicates whether the tokenizer has been paused. */ running = true; 1198 /** The offset of the current buffer. */ offset = 0; 1199 xmlMode; 1200 decodeEntities; 1201 recognizeSelfClosing; 1202 entityDecoder; 1203 constructor({ xmlMode = false, decodeEntities = true, recognizeSelfClosing = xmlMode }, cbs){ 1204 this.cbs = cbs; 1205 this.xmlMode = xmlMode; 1206 this.decodeEntities = decodeEntities; 1207 this.recognizeSelfClosing = recognizeSelfClosing; 1208 this.entityDecoder = new EntityDecoder(xmlMode ? xmlDecodeTree : htmlDecodeTree, (cp, consumed)=>this.emitCodePoint(cp, consumed)); 1209 } 1210 reset() { 1211 this.state = State.Text; 1212 this.buffer = ""; 1213 this.sectionStart = 0; 1214 this.index = 0; 1215 this.baseState = State.Text; 1216 this.isSpecial = false; 1217 this.currentSequence = Sequences.Empty; 1218 this.sequenceIndex = 0; 1219 this.running = true; 1220 this.offset = 0; 1221 } 1222 write(chunk) { 1223 this.offset += this.buffer.length; 1224 this.buffer = chunk; 1225 this.parse(); 1226 } 1227 end() { 1228 if (this.running) this.finish(); 1229 } 1230 pause() { 1231 this.running = false; 1232 } 1233 resume() { 1234 this.running = true; 1235 if (this.index < this.buffer.length + this.offset) { 1236 this.parse(); 1237 } 1238 } 1239 stateText(c) { 1240 if (c === CharCodes1.Lt || !this.decodeEntities && this.fastForwardTo(CharCodes1.Lt)) { 1241 if (this.index > this.sectionStart) { 1242 this.cbs.ontext(this.sectionStart, this.index); 1243 } 1244 this.state = State.BeforeTagName; 1245 this.sectionStart = this.index; 1246 } else if (this.decodeEntities && c === CharCodes1.Amp) { 1247 this.startEntity(); 1248 } 1249 } 1250 currentSequence = Sequences.Empty; 1251 sequenceIndex = 0; 1252 enterTagBody() { 1253 if (this.currentSequence === Sequences.Plaintext) { 1254 this.currentSequence = Sequences.Empty; 1255 this.state = State.InPlainText; 1256 } else if (this.isSpecial) { 1257 this.state = State.InSpecialTag; 1258 this.sequenceIndex = 0; 1259 } else { 1260 this.state = State.Text; 1261 } 1262 } 1263 /** 1264 * Match the opening tag name against an HTML text-only tag sequence. 1265 * 1266 * Some tags share an initial prefix (`script`/`style`, `title`/`textarea`, 1267 * `noembed`/`noframes`), so we may switch to an alternate sequence at the 1268 * first distinguishing byte. On a successful full match we fall back to 1269 * the normal tag-name state; a later `>` will enter raw-text, RCDATA, or 1270 * plaintext mode based on `currentSequence` / `isSpecial`. 1271 * @param c Current character code point. 1272 */ stateSpecialStartSequence(c) { 1273 const lower = c | 0x20; 1274 // Still matching â check for an alternate sequence at branch points. 1275 if (this.sequenceIndex < this.currentSequence.length) { 1276 if (lower === this.currentSequence[this.sequenceIndex]) { 1277 this.sequenceIndex++; 1278 return; 1279 } 1280 if (this.sequenceIndex === 3) { 1281 if (this.currentSequence === Sequences.ScriptEnd && lower === Sequences.StyleEnd[3]) { 1282 this.currentSequence = Sequences.StyleEnd; 1283 this.sequenceIndex = 4; 1284 return; 1285 } 1286 if (this.currentSequence === Sequences.TitleEnd && lower === Sequences.TextareaEnd[3]) { 1287 this.currentSequence = Sequences.TextareaEnd; 1288 this.sequenceIndex = 4; 1289 return; 1290 } 1291 } else if (this.sequenceIndex === 4 && this.currentSequence === Sequences.NoembedEnd && lower === Sequences.NoframesEnd[4]) { 1292 this.currentSequence = Sequences.NoframesEnd; 1293 this.sequenceIndex = 5; 1294 return; 1295 } 1296 } else if (isEndOfTagSection(c)) { 1297 // Full match on a valid tag boundary â keep the sequence. 1298 this.sequenceIndex = 0; 1299 this.state = State.InTagName; 1300 this.stateInTagName(c); 1301 return; 1302 } 1303 // No match â abandon special-tag detection. 1304 this.isSpecial = false; 1305 this.currentSequence = Sequences.Empty; 1306 this.sequenceIndex = 0; 1307 this.state = State.InTagName; 1308 this.stateInTagName(c); 1309 } 1310 stateCDATASequence(c) { 1311 if (c === Sequences.Cdata[this.sequenceIndex]) { 1312 if (++this.sequenceIndex === Sequences.Cdata.length) { 1313 this.state = State.InCommentLike; 1314 this.currentSequence = Sequences.CdataEnd; 1315 this.sequenceIndex = 0; 1316 this.sectionStart = this.index + 1; 1317 } 1318 } else { 1319 this.sequenceIndex = 0; 1320 if (this.xmlMode) { 1321 this.state = State.InDeclaration; 1322 this.stateInDeclaration(c); // Reconsume the character 1323 } else { 1324 this.state = State.InSpecialComment; 1325 this.stateInSpecialComment(c); // Reconsume the character 1326 } 1327 } 1328 } 1329 /** 1330 * When we wait for one specific character, we can speed things up 1331 * by skipping through the buffer until we find it. 1332 * @param c Current character code point. 1333 * @returns Whether the character was found. 1334 */ fastForwardTo(c) { 1335 while(++this.index < this.buffer.length + this.offset){ 1336 if (this.buffer.charCodeAt(this.index - this.offset) === c) { 1337 return true; 1338 } 1339 } 1340 /* 1341 * We increment the index at the end of the `parse` loop, 1342 * so set it to `buffer.length - 1` here. 1343 * 1344 * TODO: Refactor `parse` to increment index before calling states. 1345 */ this.index = this.buffer.length + this.offset - 1; 1346 return false; 1347 } 1348 /** 1349 * Emit a comment token and return to the text state. 1350 * @param offset Number of characters in the end sequence that have already been matched. 1351 */ emitComment(offset) { 1352 this.cbs.oncomment(this.sectionStart, this.index, offset); 1353 this.sequenceIndex = 0; 1354 this.sectionStart = this.index + 1; 1355 this.state = State.Text; 1356 } 1357 /** 1358 * Comments and CDATA end with `-->` and `]]>`. 1359 * 1360 * Their common qualities are: 1361 * - Their end sequences have a distinct character they start with. 1362 * - That character is then repeated, so we have to check multiple repeats. 1363 * - All characters but the start character of the sequence can be skipped. 1364 * @param c Current character code point. 1365 */ stateInCommentLike(c) { 1366 if (!this.xmlMode && this.currentSequence === Sequences.CommentEnd && this.sequenceIndex <= 1 && /* 1367 * We're still at the very start of the comment: the only 1368 * characters consumed since `<!--` are the dashes that 1369 * advanced sequenceIndex (0 for `<!-->`, 1 for `<!--->`). 1370 */ this.index === this.sectionStart + this.sequenceIndex && c === CharCodes1.Gt) { 1371 // Abruptly closed empty HTML comment. 1372 this.emitComment(this.sequenceIndex); 1373 } else if (this.currentSequence === Sequences.CommentEnd && this.sequenceIndex === 2 && c === CharCodes1.Gt) { 1374 // `!` is optional here, so the same sequence also accepts `-->`. 1375 this.emitComment(2); 1376 } else if (this.currentSequence === Sequences.CommentEnd && this.sequenceIndex === this.currentSequence.length - 1 && c !== CharCodes1.Gt) { 1377 this.sequenceIndex = Number(c === CharCodes1.Dash); 1378 } else if (c === this.currentSequence[this.sequenceIndex]) { 1379 if (++this.sequenceIndex === this.currentSequence.length) { 1380 if (this.currentSequence === Sequences.CdataEnd) { 1381 this.cbs.oncdata(this.sectionStart, this.index, 2); 1382 } else { 1383 this.cbs.oncomment(this.sectionStart, this.index, 3); 1384 } 1385 this.sequenceIndex = 0; 1386 this.sectionStart = this.index + 1; 1387 this.state = State.Text; 1388 } 1389 } else if (this.sequenceIndex === 0) { 1390 // Fast-forward to the first character of the sequence 1391 if (this.fastForwardTo(this.currentSequence[0])) { 1392 this.sequenceIndex = 1; 1393 } 1394 } else if (c !== this.currentSequence[this.sequenceIndex - 1]) { 1395 // Allow long sequences, eg. --->, ]]]> 1396 this.sequenceIndex = 0; 1397 } 1398 } 1399 /** 1400 * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name. 1401 * 1402 * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar). 1403 * We allow anything that wouldn't end the tag. 1404 * @param c Current character code point. 1405 */ isTagStartChar(c) { 1406 return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c); 1407 } 1408 /** 1409 * Scan raw-text / RCDATA content for the matching end tag. 1410 * 1411 * For RCDATA tags (`<title>`, `<textarea>`) entities are decoded inline. 1412 * For raw-text tags (`<script>`, `<style>
1412`, etc.) we fast-forward to `<`. 1413 * @param c Current character code point. 1414 */ stateInSpecialTag(c) { 1415 if (this.sequenceIndex === this.currentSequence.length) { 1416 if (isEndOfTagSection(c)) { 1417 const endOfText = this.index - this.currentSequence.length; 1418 if (this.sectionStart < endOfText) { 1419 // Spoof the index so that reported locations match up. 1420 const actualIndex = this.index; 1421 this.index = endOfText; 1422 this.cbs.ontext(this.sectionStart, endOfText); 1423 this.index = actualIndex; 1424 } 1425 this.isSpecial = false; 1426 this.sectionStart = endOfText + 2; // Skip over the `</` 1427 this.stateInClosingTagName(c); 1428 return; // We are done; skip the rest of the function. 1429 } 1430 this.sequenceIndex = 0; 1431 } 1432 if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) { 1433 this.sequenceIndex += 1; 1434 } else if (this.sequenceIndex === 0) { 1435 if (this.currentSequence === Sequences.TitleEnd || this.currentSequence === Sequences.TextareaEnd) { 1436 // RCDATA tags have to parse entities while still looking for their end tag. 1437 if (this.decodeEntities && c === CharCodes1.Amp) { 1438 this.startEntity(); 1439 } 1440 } else if (this.fastForwardTo(CharCodes1.Lt)) { 1441 // Outside of RCDATA tags, we can fast-forward. 1442 this.sequenceIndex = 1; 1443 } 1444 } else { 1445 // If we see a `<`, set the sequence index to 1; useful for eg. `<</script>`. 1446 this.sequenceIndex = Number(c === CharCodes1.Lt); 1447 } 1448 } 1449 stateBeforeTagName(c) { 1450 if (c === CharCodes1.ExclamationMark) { 1451 this.state = State.BeforeDeclaration; 1452 this.sectionStart = this.index + 1; 1453 } else if (c === CharCodes1.Questionmark) { 1454 if (this.xmlMode) { 1455 this.state = State.InProcessingInstruction; 1456 this.sequenceIndex = 0; 1457 this.sectionStart = this.index + 1; 1458 } else { 1459 this.state = State.InSpecialComment; 1460 this.sectionStart = this.index; 1461 } 1462 } else if (this.isTagStartChar(c)) { 1463 this.sectionStart = this.index; 1464 const special = this.xmlMode || this.cbs.isInForeignContext?.() ? undefined : specialStartSequences.get(c | 0x20); 1465 if (special === undefined) { 1466 this.state = State.InTagName; 1467 } else { 1468 this.isSpecial = true; 1469 this.currentSequence = special; 1470 this.sequenceIndex = 3; 1471 this.state = State.SpecialStartSequence; 1472 } 1473 } else if (c === CharCodes1.Slash) { 1474 this.state = State.BeforeClosingTagName; 1475 } else { 1476 this.state = State.Text; 1477 this.stateText(c); 1478 } 1479 } 1480 stateInTagName(c) { 1481 if (isEndOfTagSection(c)) { 1482 this.cbs.onopentagname(this.sectionStart, this.index); 1483 this.sectionStart = -1; 1484 this.state = State.BeforeAttributeName; 1485 this.stateBeforeAttributeName(c); 1486 } 1487 } 1488 stateBeforeClosingTagName(c) { 1489 if (isWhitespace(c)) { 1490 if (this.xmlMode) { 1491 // Ignore 1492 } else { 1493 this.state = State.InSpecialComment; 1494 this.sectionStart = this.index; 1495 } 1496 } else if (c === CharCodes1.Gt) { 1497 this.state = State.Text; 1498 if (!this.xmlMode) { 1499 this.sectionStart = this.index + 1; 1500 } 1501 } else { 1502 this.state = this.isTagStartChar(c) ? State.InClosingTagName : State.InSpecialComment; 1503 this.sectionStart = this.index; 1504 } 1505 } 1506 stateInClosingTagName(c) { 1507 if (isEndOfTagSection(c)) { 1508 this.cbs.onclosetag(this.sectionStart, this.index); 1509 this.sectionStart = -1; 1510 this.state = State.AfterClosingTagName; 1511 this.stateAfterClosingTagName(c); 1512 } 1513 } 1514 stateAfterClosingTagName(c) { 1515 // Skip everything until ">" 1516 if (c === CharCodes1.Gt || this.fastForwardTo(CharCodes1.Gt)) { 1517 this.state = State.Text; 1518 this.sectionStart = this.index + 1; 1519 } 1520 } 1521 stateBeforeAttributeName(c) { 1522 if (c === CharCodes1.Gt) { 1523 this.cbs.onopentagend(this.index); 1524 this.enterTagBody(); 1525 this.sectionStart = this.index + 1; 1526 } else if (c === CharCodes1.Slash) { 1527 this.state = State.InSelfClosingTag; 1528 } else if (!isWhitespace(c)) { 1529 this.state = State.InAttributeName; 1530 this.sectionStart = this.index; 1531 } 1532 } 1533 /** 1534 * Handle `/` before `>` in an opening tag. 1535 * 1536 * In HTML mode, text-only tags ignore the self-closing flag and still enter 1537 * their raw-text/RCDATA/plaintext state unless self-closing tags are being 1538 * recognized. In XML mode, or for ordinary tags, the tokenizer returns to 1539 * regular text parsing after emitting the self-closing callback. 1540 * @param c Current character code point. 1541 */ stateInSelfClosingTag(c) { 1542 if (c === CharCodes1.Gt) { 1543 this.cbs.onselfclosingtag(this.index); 1544 this.sectionStart = this.index + 1; 1545 if (!this.recognizeSelfClosing) { 1546 this.enterTagBody(); 1547 return; 1548 } 1549 this.state = State.Text; 1550 this.isSpecial = false; // Reset special state, in case of self-closing special tags 1551 this.currentSequence = Sequences.Empty; 1552 } else if (!isWhitespace(c)) { 1553 this.state = State.BeforeAttributeName; 1554 this.stateBeforeAttributeName(c); 1555 } 1556 } 1557 stateInAttributeName(c) { 1558 if (c === CharCodes1.Eq || isEndOfTagSection(c)) { 1559 this.cbs.onattribname(this.sectionStart, this.index); 1560 this.sectionStart = this.index; 1561 this.state = State.AfterAttributeName; 1562 this.stateAfterAttributeName(c); 1563 } 1564 } 1565 stateAfterAttributeName(c) { 1566 if (c === CharCodes1.Eq) { 1567 this.state = State.BeforeAttributeValue; 1568 } else if (c === CharCodes1.Slash || c === CharCodes1.Gt) { 1569 this.cbs.onattribend(QuoteType.NoValue, this.sectionStart); 1570 this.sectionStart = -1; 1571 this.state = State.BeforeAttributeName; 1572 this.stateBeforeAttributeName(c); 1573 } else if (!isWhitespace(c)) { 1574 this.cbs.onattribend(QuoteType.NoValue, this.sectionStart); 1575 this.state = State.InAttributeName; 1576 this.sectionStart = this.index; 1577 } 1578 } 1579 stateBeforeAttributeValue(c) { 1580 if (c === CharCodes1.DoubleQuote) { 1581 this.state = State.InAttributeValueDq; 1582 this.sectionStart = this.index + 1; 1583 } else if (c === CharCodes1.SingleQuote) { 1584 this.state = State.InAttributeValueSq; 1585 this.sectionStart = this.index + 1; 1586 } else if (!isWhitespace(c)) { 1587 this.sectionStart = this.index; 1588 this.state = State.InAttributeValueNq; 1589 this.stateInAttributeValueNoQuotes(c); // Reconsume token 1590 } 1591 } 1592 handleInAttributeValue(c, quote) { 1593 if (c === quote || !this.decodeEntities && this.fastForwardTo(quote)) { 1594 this.cbs.onattribdata(this.sectionStart, this.index); 1595 this.sectionStart = -1; 1596 this.cbs.onattribend(quote === CharCodes1.DoubleQuote ? QuoteType.Double : QuoteType.Single, this.index + 1); 1597 this.state = State.BeforeAttributeName; 1598 } else if (this.decodeEntities && c === CharCodes1.Amp) { 1599 this.startEntity(); 1600 } 1601 } 1602 stateInAttributeValueDoubleQuotes(c) { 1603 this.handleInAttributeValue(c, CharCodes1.DoubleQuote); 1604 } 1605 stateInAttributeValueSingleQuotes(c) { 1606 this.handleInAttributeValue(c, CharCodes1.SingleQuote); 1607 } 1608 stateInAttributeValueNoQuotes(c) { 1609 if (isWhitespace(c) || c === CharCodes1.Gt) { 1610 this.cbs.onattribdata(this.sectionStart, this.index); 1611 this.sectionStart = -1; 1612 this.cbs.onattribend(QuoteType.Unquoted, this.index); 1613 this.state = State.BeforeAttributeName; 1614 this.stateBeforeAttributeName(c); 1615 } else if (this.decodeEntities && c === CharCodes1.Amp) { 1616 this.startEntity(); 1617 } 1618 } 1619 /** 1620 * Distinguish between CDATA, declarations, HTML comments, and HTML bogus 1621 * comments after `<!`. 1622 * 1623 * In HTML mode, only real comments and doctypes stay on declaration paths;
vendor: 11,308 bytes, lines 1624-1913
1624 * everything else becomes a bogus comment terminated by the next `>`. 1625 * @param c Current character code point. 1626 */ stateBeforeDeclaration(c) { 1627 if (c === CharCodes1.OpeningSquareBracket) { 1628 this.state = State.CDATASequence; 1629 this.sequenceIndex = 0; 1630 } else if (this.xmlMode) { 1631 this.state = c === CharCodes1.Dash ? State.BeforeComment : State.InDeclaration; 1632 } else if ((c | 0x20) === Sequences.Doctype[0]) { 1633 this.state = State.DeclarationSequence; 1634 this.currentSequence = Sequences.Doctype; 1635 this.sequenceIndex = 1; 1636 } else if (c === CharCodes1.Gt) { 1637 this.cbs.oncomment(this.sectionStart, this.index, 0); 1638 this.state = State.Text; 1639 this.sectionStart = this.index + 1; 1640 } else if (c === CharCodes1.Dash) { 1641 this.state = State.BeforeComment; 1642 } else { 1643 this.state = State.InSpecialComment; 1644 } 1645 } 1646 /** 1647 * Continue matching `doctype` after `<!d`. 1648 * 1649 * A full `doctype` match stays on the declaration path; any other name falls 1650 * back to an HTML bogus comment, which matches browser behavior for 1651 * non-doctype `<!...>` constructs. 1652 * @param c Current character code point. 1653 */ stateDeclarationSequence(c) { 1654 if (this.sequenceIndex === this.currentSequence.length) { 1655 this.state = State.InDeclaration; 1656 this.stateInDeclaration(c); 1657 } else if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) { 1658 this.sequenceIndex += 1; 1659 } else if (c === CharCodes1.Gt) { 1660 this.cbs.oncomment(this.sectionStart, this.index, 0); 1661 this.state = State.Text; 1662 this.sectionStart = this.index + 1; 1663 } else { 1664 this.state = State.InSpecialComment; 1665 } 1666 } 1667 stateInDeclaration(c) { 1668 if (c === CharCodes1.Gt || this.fastForwardTo(CharCodes1.Gt)) { 1669 this.cbs.ondeclaration(this.sectionStart, this.index); 1670 this.state = State.Text; 1671 this.sectionStart = this.index + 1; 1672 } 1673 } 1674 /** 1675 * XML processing instructions (`<?...?>`). 1676 * 1677 * In HTML mode `<?` is routed to `InSpecialComment` instead, so this 1678 * state is only reachable in XML mode. 1679 * @param c Current character code point. 1680 */ stateInProcessingInstruction(c) { 1681 if (c === CharCodes1.Questionmark) { 1682 // Remember that we just consumed `?`, so the next `>` closes the PI. 1683 this.sequenceIndex = 1; 1684 } else if (c === CharCodes1.Gt && this.sequenceIndex === 1) { 1685 this.cbs.onprocessinginstruction(this.sectionStart, this.index - 1); 1686 this.sequenceIndex = 0; 1687 this.state = State.Text; 1688 this.sectionStart = this.index + 1; 1689 } else { 1690 // Keep scanning for the next `?`, which can start a closing `?>`. 1691 this.sequenceIndex = Number(this.fastForwardTo(CharCodes1.Questionmark)); 1692 } 1693 } 1694 stateBeforeComment(c) { 1695 if (c === CharCodes1.Dash) { 1696 this.state = State.InCommentLike; 1697 this.currentSequence = Sequences.CommentEnd; 1698 this.sequenceIndex = 0; 1699 this.sectionStart = this.index + 1; 1700 } else if (this.xmlMode) { 1701 this.state = State.InDeclaration; 1702 } else if (c === CharCodes1.Gt) { 1703 this.cbs.oncomment(this.sectionStart, this.index, 0); 1704 this.state = State.Text; 1705 this.sectionStart = this.index + 1; 1706 } else { 1707 this.state = State.InSpecialComment; 1708 } 1709 } 1710 stateInSpecialComment(c) { 1711 if (c === CharCodes1.Gt || this.fastForwardTo(CharCodes1.Gt)) { 1712 this.cbs.oncomment(this.sectionStart, this.index, 0); 1713 this.state = State.Text; 1714 this.sectionStart = this.index + 1; 1715 } 1716 } 1717 startEntity() { 1718 this.baseState = this.state; 1719 this.state = State.InEntity; 1720 this.entityStart = this.index; 1721 this.entityDecoder.startEntity(this.xmlMode ? DecodingMode.Strict : this.baseState === State.Text || this.baseState === State.InSpecialTag ? DecodingMode.Legacy : DecodingMode.Attribute); 1722 } 1723 stateInEntity() { 1724 const indexInBuffer = this.index - this.offset; 1725 const length = this.entityDecoder.write(this.buffer, indexInBuffer); 1726 // If `length` is positive, we are done with the entity. 1727 if (length >= 0) { 1728 this.state = this.baseState; 1729 if (length === 0) { 1730 this.index -= 1; 1731 } 1732 } else { 1733 if (indexInBuffer < this.buffer.length && this.buffer.charCodeAt(indexInBuffer) === CharCodes1.Amp) { 1734 this.state = this.baseState; 1735 this.index -= 1; 1736 return; 1737 } 1738 // Mark buffer as consumed. 1739 this.index = this.offset + this.buffer.length - 1; 1740 } 1741 } 1742 /** 1743 * Remove data that has already been consumed from the buffer. 1744 */ cleanup() { 1745 // If we are inside of text or attributes, emit what we already have. 1746 if (this.running && this.sectionStart !== this.index) { 1747 if (this.state === State.Text || this.state === State.InPlainText || this.state === State.InSpecialTag && this.sequenceIndex === 0) { 1748 this.cbs.ontext(this.sectionStart, this.index); 1749 this.sectionStart = this.index; 1750 } else if (this.state === State.InAttributeValueDq || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueNq) { 1751 this.cbs.onattribdata(this.sectionStart, this.index); 1752 this.sectionStart = this.index; 1753 } 1754 } 1755 } 1756 shouldContinue() { 1757 return this.index < this.buffer.length + this.offset && this.running; 1758 } 1759 /** 1760 * Iterates through the buffer, calling the function corresponding to the current state. 1761 * 1762 * States that are more likely to be hit are higher up, as a performance improvement. 1763 */ parse() { 1764 while(this.shouldContinue()){ 1765 const c = this.buffer.charCodeAt(this.index - this.offset); 1766 switch(this.state){ 1767 case State.Text: 1768 { 1769 this.stateText(c); 1770 break; 1771 } 1772 case State.InPlainText: 1773 { 1774 // Skip to end of buffer; cleanup() emits the text. 1775 this.index = this.buffer.length + this.offset - 1; 1776 break; 1777 } 1778 case State.SpecialStartSequence: 1779 { 1780 this.stateSpecialStartSequence(c); 1781 break; 1782 } 1783 case State.InSpecialTag: 1784 { 1785 this.stateInSpecialTag(c); 1786 break; 1787 } 1788 case State.CDATASequence: 1789 { 1790 this.stateCDATASequence(c); 1791 break; 1792 } 1793 case State.DeclarationSequence: 1794 { 1795 this.stateDeclarationSequence(c); 1796 break; 1797 } 1798 case State.InAttributeValueDq: 1799 { 1800 this.stateInAttributeValueDoubleQuotes(c); 1801 break; 1802 } 1803 case State.InAttributeName: 1804 { 1805 this.stateInAttributeName(c); 1806 break; 1807 } 1808 case State.InCommentLike: 1809 { 1810 this.stateInCommentLike(c); 1811 break; 1812 } 1813 case State.InSpecialComment: 1814 { 1815 this.stateInSpecialComment(c); 1816 break; 1817 } 1818 case State.BeforeAttributeName: 1819 { 1820 this.stateBeforeAttributeName(c); 1821 break; 1822 } 1823 case State.InTagName: 1824 { 1825 this.stateInTagName(c); 1826 break; 1827 } 1828 case State.InClosingTagName: 1829 { 1830 this.stateInClosingTagName(c); 1831 break; 1832 } 1833 case State.BeforeTagName: 1834 { 1835 this.stateBeforeTagName(c); 1836 break; 1837 } 1838 case State.AfterAttributeName: 1839 { 1840 this.stateAfterAttributeName(c); 1841 break; 1842 } 1843 case State.InAttributeValueSq: 1844 { 1845 this.stateInAttributeValueSingleQuotes(c); 1846 break; 1847 } 1848 case State.BeforeAttributeValue: 1849 { 1850 this.stateBeforeAttributeValue(c); 1851 break; 1852 } 1853 case State.BeforeClosingTagName: 1854 { 1855 this.stateBeforeClosingTagName(c); 1856 break; 1857 } 1858 case State.AfterClosingTagName: 1859 { 1860 this.stateAfterClosingTagName(c); 1861 break; 1862 } 1863 case State.InAttributeValueNq: 1864 { 1865 this.stateInAttributeValueNoQuotes(c); 1866 break; 1867 } 1868 case State.InSelfClosingTag: 1869 { 1870 this.stateInSelfClosingTag(c); 1871 break; 1872 } 1873 case State.InDeclaration: 1874 { 1875 this.stateInDeclaration(c); 1876 break; 1877 } 1878 case State.BeforeDeclaration: 1879 { 1880 this.stateBeforeDeclaration(c); 1881 break; 1882 } 1883 case State.BeforeComment: 1884 { 1885 this.stateBeforeComment(c); 1886 break; 1887 } 1888 case State.InProcessingInstruction: 1889 { 1890 this.stateInProcessingInstruction(c); 1891 break; 1892 } 1893 case State.InEntity: 1894 { 1895 this.stateInEntity(); 1896 break; 1897 } 1898 } 1899 this.index++; 1900 } 1901 this.cleanup(); 1902 } 1903 finish() { 1904 if (this.state === State.InEntity) { 1905 this.entityDecoder.end(); 1906 this.state = this.baseState; 1907 } 1908 this.handleTrailingData(); 1909 this.cbs.onend(); 1910 } 1911 handleTrailingCommentLikeData(endIndex) { 1912 if (this.state !== State.InCommentLike) { 1913 return false;
1914 } 1915 if (this.currentSequence === Sequences.CdataEnd) { 1916 if (this.xmlMode) { 1917 if (this.sectionStart < endIndex) { 1918 this.cbs.oncdata(this.sectionStart, endIndex, 0); 1919 } 1920 } else { 1921 /* In HTML mode, unclosed CDATA is a bogus comment. */ const cdataStart = this.sectionStart - Sequences.Cdata.length - 1; 1922 this.cbs.oncomment(cdataStart, endIndex, 0); 1923 } 1924 } else { 1925 const offset = this.xmlMode ? 0 : Math.min(this.sequenceIndex, Sequences.CommentEnd.length - 1); 1926 this.cbs.oncomment(this.sectionStart, endIndex, offset); 1927 } 1928 return true; 1929 } 1930 handleTrailingMarkupDeclaration(endIndex) { 1931 if (this.xmlMode) { 1932 switch(this.state){ 1933 case State.InSpecialComment: 1934 case State.BeforeComment: 1935 case State.CDATASequence: 1936 case State.DeclarationSequence: 1937 case State.InDeclaration: 1938 { 1939 this.cbs.ontext(this.sectionStart, endIndex); 1940 return true; 1941 } 1942 default: 1943 { 1944 return false; 1945 } 1946 } 1947 } 1948 switch(this.state){ 1949 case State.BeforeDeclaration: 1950 case State.InSpecialComment: 1951 case State.BeforeComment: 1952 case State.CDATASequence: 1953 { 1954 this.cbs.oncomment(this.sectionStart, endIndex, 0); 1955 return true; 1956 } 1957 case State.DeclarationSequence: 1958 { 1959 if (this.sequenceIndex !== Sequences.Doctype.length) { 1960 this.cbs.oncomment(this.sectionStart, endIndex, 0); 1961 } 1962 return true; 1963 } 1964 case State.InDeclaration: 1965 { 1966 return true; 1967 } 1968 default: 1969 { 1970 return false; 1971 } 1972 } 1973 } 1974 /** Handle any trailing data. */ handleTrailingData() { 1975 const endIndex = this.buffer.length + this.offset; 1976 if (this.handleTrailingCommentLikeData(endIndex) || this.handleTrailingMarkupDeclaration(endIndex)) { 1977 return; 1978 } 1979 // If there is no remaining data, we are done. 1980 if (this.sectionStart >= endIndex) { 1981 return; 1982 } 1983 switch(this.state){ 1984 case State.InTagName: 1985 case State.BeforeAttributeName: 1986 case State.BeforeAttributeValue: 1987 case State.AfterAttributeName: 1988 case State.InAttributeName: 1989 case State.InAttributeValueSq: 1990 case State.InAttributeValueDq: 1991 case State.InAttributeValueNq: 1992 case State.InClosingTagName: 1993 { 1994 break; 1995 } 1996 default: 1997 { 1998 this.cbs.ontext(this.sectionStart, endIndex); 1999 } 2000 } 2001 } 2002 emitCodePoint(cp, consumed) { 2003 if (this.baseState !== State.Text && this.baseState !== State.InSpecialTag) { 2004 if (this.sectionStart < this.entityStart) { 2005 this.cbs.onattribdata(this.sectionStart, this.entityStart); 2006 } 2007 this.sectionStart = this.entityStart + consumed; 2008 this.index = this.sectionStart - 1; 2009 this.cbs.onattribentity(cp); 2010 } else { 2011 if (this.sectionStart < this.entityStart) { 2012 this.cbs.ontext(this.sectionStart, this.entityStart); 2013 } 2014 this.sectionStart = this.entityStart + consumed; 2015 this.index = this.sectionStart - 1; 2016 this.cbs.ontextentity(cp, this.sectionStart); 2017 } 2018 } 2019} 2020const { fromCodePoint } = String; 2021; 2022const formTags = new Set([ 2023 "input", 2024 "option", 2025 "optgroup", 2026 "select", 2027 "button", 2028 "datalist", 2029 "textarea" 2030]); 2031const pTag = new Set([ 2032 "p" 2033]); 2034const headingTags = new Set([ 2035 "h1", 2036 "h2", 2037 "h3", 2038 "h4", 2039 "h5", 2040 "h6", 2041 "p" 2042]); 2043const tableSectionTags = new Set([ 2044 "thead", 2045 "tbody" 2046]); 2047const ddtTags = new Set([ 2048 "dd", 2049 "dt" 2050]); 2051const rtpTags = new Set([ 2052 "rt", 2053 "rp" 2054]); 2055const openImpliesClose = new Map([ 2056 [ 2057 "tr", 2058 new Set([ 2059 "tr", 2060 "th", 2061 "td" 2062 ]) 2063 ], 2064 [ 2065 "th", 2066 new Set([ 2067 "th" 2068 ]) 2069 ], 2070 [ 2071 "td", 2072 new Set([ 2073 "thead", 2074 "th", 2075 "td" 2076 ]) 2077 ], 2078 [ 2079 "body", 2080 new Set([ 2081 "head", 2082 "link", 2083 "script" 2084 ]) 2085 ], 2086 [ 2087 "a", 2088 new Set([ 2089 "a" 2090 ]) 2091 ], 2092 [ 2093 "li", 2094 new Set([ 2095 "li" 2096 ]) 2097 ], 2098 [ 2099 "p", 2100 pTag 2101 ], 2102 [ 2103 "h1", 2104 headingTags 2105 ], 2106 [ 2107 "h2", 2108 headingTags 2109 ], 2110 [ 2111 "h3", 2112 headingTags 2113 ], 2114 [ 2115 "h4", 2116 headingTags 2117 ], 2118 [ 2119 "h5", 2120 headingTags 2121 ], 2122 [ 2123 "h6", 2124 headingTags 2125 ], 2126 [ 2127 "select", 2128 formTags 2129 ], 2130 [ 2131 "input", 2132 formTags 2133 ], 2134 [ 2135 "output", 2136 formTags 2137 ], 2138 [ 2139 "button", 2140 formTags 2141 ], 2142 [ 2143 "datalist", 2144 formTags 2145 ], 2146 [ 2147 "textarea", 2148 formTags 2149 ], 2150 [ 2151 "option", 2152 new Set([ 2153 "option" 2154 ]) 2155 ], 2156 [ 2157 "optgroup", 2158 new Set([ 2159 "optgroup", 2160 "option" 2161 ]) 2162 ], 2163 [ 2164 "dd", 2165 ddtTags 2166 ], 2167 [ 2168 "dt", 2169 ddtTags 2170 ], 2171 [ 2172 "address", 2173 pTag 2174 ], 2175 [ 2176 "article", 2177 pTag 2178 ], 2179 [ 2180 "aside", 2181 pTag 2182 ], 2183 [ 2184 "blockquote", 2185 pTag 2186 ], 2187 [ 2188 "details", 2189 pTag 2190 ], 2191 [ 2192 "div", 2193 pTag 2194 ], 2195 [ 2196 "dl", 2197 pTag 2198 ], 2199 [ 2200 "fieldset", 2201 pTag 2202 ], 2203 [ 2204 "figcaption", 2205 pTag 2206 ], 2207 [ 2208 "figure", 2209 pTag 2210 ], 2211 [ 2212 "footer", 2213 pTag 2214 ], 2215 [ 2216 "form", 2217 pTag 2218 ], 2219 [ 2220 "header", 2221 pTag 2222 ], 2223 [ 2224 "hr", 2225 pTag 2226 ], 2227 [ 2228 "main", 2229 pTag 2230 ], 2231 [ 2232 "nav", 2233 pTag 2234 ], 2235 [ 2236 "ol", 2237 pTag 2238 ], 2239 [ 2240 "pre", 2241 pTag 2242 ], 2243 [ 2244 "section", 2245 pTag 2246 ], 2247 [ 2248 "table", 2249 pTag 2250 ], 2251 [ 2252 "ul", 2253 pTag 2254 ], 2255 [ 2256 "rt", 2257 rtpTags 2258 ], 2259 [ 2260 "rp", 2261 rtpTags 2262 ], 2263 [ 2264 "tbody", 2265 tableSectionTags 2266 ], 2267 [ 2268 "tfoot", 2269 tableSectionTags 2270 ] 2271]); 2272const DOCUMENT_TYPE = "doctype"; 2273const voidElements = new Set([ 2274 "area", 2275 "base", 2276 "basefont", 2277 "br", 2278 "col", 2279 "command", 2280 "embed", 2281 "frame", 2282 "hr", 2283 "img", 2284 "input", 2285 "isindex",
2286 "keygen", 2287 "link", 2288 "meta", 2289 "param", 2290 "source", 2291 "track", 2292 "wbr" 2293]); 2294const foreignContextElements = new Set([ 2295 "math", 2296 "svg" 2297]); 2298/** 2299 * Elements that can be used to integrate HTML content within foreign namespaces (e.g., SVG or MathML). 2300 * 2301 * Entries must use the SVG-adjusted casing (e.g. "foreignObject" not 2302 * "foreignobject") since they are compared against adjusted tag names. 2303 */ const htmlIntegrationElements = new Set([ 2304 "mi", 2305 "mo", 2306 "mn", 2307 "ms", 2308 "mtext", 2309 "annotation-xml", 2310 "foreignObject", 2311 "desc", 2312 "title" 2313]); 2314const svgTagNameAdjustments = new Map([ 2315 [ 2316 "altglyph", 2317 "altGlyph" 2318 ], 2319 [ 2320 "altglyphdef", 2321 "altGlyphDef" 2322 ], 2323 [ 2324 "altglyphitem", 2325 "altGlyphItem" 2326 ], 2327 [ 2328 "animatecolor", 2329 "animateColor" 2330 ], 2331 [ 2332 "animatemotion", 2333 "animateMotion" 2334 ], 2335 [ 2336 "animatetransform", 2337 "animateTransform" 2338 ], 2339 [ 2340 "clippath", 2341 "clipPath" 2342 ], 2343 [ 2344 "feblend", 2345 "feBlend" 2346 ], 2347 [ 2348 "fecolormatrix", 2349 "feColorMatrix" 2350 ], 2351 [ 2352 "fecomponenttransfer", 2353 "feComponentTransfer" 2354 ], 2355 [ 2356 "fecomposite", 2357 "feComposite" 2358 ], 2359 [ 2360 "feconvolvematrix", 2361 "feConvolveMatrix" 2362 ], 2363 [ 2364 "fediffuselighting", 2365 "feDiffuseLighting" 2366 ], 2367 [ 2368 "fedisplacementmap", 2369 "feDisplacementMap" 2370 ], 2371 [ 2372 "fedistantlight", 2373 "feDistantLight" 2374 ], 2375 [ 2376 "fedropshadow", 2377 "feDropShadow" 2378 ], 2379 [ 2380 "feflood", 2381 "feFlood" 2382 ], 2383 [ 2384 "fefunca", 2385 "feFuncA" 2386 ], 2387 [ 2388 "fefuncb", 2389 "feFuncB" 2390 ], 2391 [ 2392 "fefuncg", 2393 "feFuncG" 2394 ], 2395 [ 2396 "fefuncr", 2397 "feFuncR" 2398 ], 2399 [ 2400 "fegaussianblur", 2401 "feGaussianBlur" 2402 ], 2403 [ 2404 "feimage", 2405 "feImage" 2406 ], 2407 [ 2408 "femerge", 2409 "feMerge" 2410 ], 2411 [ 2412 "femergenode", 2413 "feMergeNode" 2414 ], 2415 [ 2416 "femorphology", 2417 "feMorphology" 2418 ], 2419 [ 2420 "feoffset", 2421 "feOffset" 2422 ], 2423 [ 2424 "fepointlight", 2425 "fePointLight" 2426 ], 2427 [ 2428 "fespecularlighting", 2429 "feSpecularLighting" 2430 ], 2431 [ 2432 "fespotlight", 2433 "feSpotLight" 2434 ], 2435 [ 2436 "fetile", 2437 "feTile" 2438 ], 2439 [ 2440 "feturbulence", 2441 "feTurbulence" 2442 ], 2443 [ 2444 "foreignobject", 2445 "foreignObject" 2446 ], 2447 [ 2448 "glyphref", 2449 "glyphRef" 2450 ], 2451 [ 2452 "lineargradient", 2453 "linearGradient" 2454 ], 2455 [ 2456 "radialgradient", 2457 "radialGradient" 2458 ], 2459 [ 2460 "textpath", 2461 "textPath" 2462 ] 2463]); 2464var ForeignContext; 2465(function(ForeignContext) { 2466 ForeignContext[ForeignContext["None"] = 0] = "None"; 2467 ForeignContext[ForeignContext["Svg"] = 1] = "Svg"; 2468 ForeignContext[ForeignContext["MathML"] = 2] = "MathML"; 2469})(ForeignContext || (ForeignContext = {})); 2470const reNameEnd = /\s|\//; 2471class Parser { 2472 options; 2473 /** The start index of the last event. */ startIndex = 0; 2474 /** The end index of the last event. */ endIndex = 0; 2475 /** 2476 * Store the start index of the current open tag, 2477 * so we can update the start index for attributes. 2478 */ openTagStart = 0; 2479 tagname = ""; 2480 attribname = ""; 2481 attribvalue = ""; 2482 attribs = null; 2483 stack = []; 2484 foreignContext; 2485 cbs; 2486 lowerCaseTagNames; 2487 lowerCaseAttributeNames; 2488 recognizeSelfClosing; 2489 /** We are parsing HTML. Inverse of the `xmlMode` option. */ htmlMode; 2490 tokenizer; 2491 buffers = []; 2492 bufferOffset = 0; 2493 /** The index of the last written buffer. Used when resuming after a `pause()`. */ writeIndex = 0; 2494 /** Indicates whether the parser has finished running / `.end` has been called. */ ended = false; 2495 constructor(cbs, options = {}){ 2496 this.options = options; 2497 this.cbs = cbs ?? {}; 2498 this.htmlMode = !this.options.xmlMode; 2499 this.lowerCaseTagNames = options.lowerCaseTags ?? this.htmlMode; 2500 this.lowerCaseAttributeNames = options.lowerCaseAttributeNames ?? this.htmlMode; 2501 this.recognizeSelfClosing = options.recognizeSelfClosing ?? !this.htmlMode; 2502 this.tokenizer = new (options.Tokenizer ?? Tokenizer)(this.options, this); 2503 this.foreignContext = [ 2504 ForeignContext.None 2505 ]; 2506 this.cbs.onparserinit?.(this); 2507 } 2508 // Tokenizer event handlers 2509 /** 2510 * @param start Start index for the current parser event. 2511 * @param endIndex End index for the current parser event. 2512 * @internal 2513 */ ontext(start, endIndex) {
vendor: 12,451 bytes, lines 2514-2828
2514 const data = this.getSlice(start, endIndex); 2515 this.endIndex = endIndex - 1; 2516 this.cbs.ontext?.(data); 2517 this.startIndex = endIndex; 2518 } 2519 /** 2520 * @param cp Current Unicode code point. 2521 * @param endIndex End index for the current parser event. 2522 * @internal 2523 */ ontextentity(cp, endIndex) { 2524 this.endIndex = endIndex - 1; 2525 this.cbs.ontext?.(fromCodePoint(cp)); 2526 this.startIndex = endIndex; 2527 } 2528 /** @internal */ isInForeignContext() { 2529 return this.foreignContext[0] !== ForeignContext.None; 2530 } 2531 /** 2532 * Checks if the current tag is a void element. Override this if you want 2533 * to specify your own additional void elements. 2534 * @param name Name of the pseudo selector. 2535 */ isVoidElement(name) { 2536 return this.htmlMode && voidElements.has(name); 2537 } 2538 /** 2539 * Read a tag name from the buffer. 2540 * 2541 * When `lowerCaseTagNames` is enabled (the default in HTML mode), the name 2542 * is lowercased and may be adjusted for SVG casing or the `image` â `img` 2543 * alias. 2544 * @param start Start index of the tag name in the buffer. 2545 * @param endIndex End index of the tag name in the buffer. 2546 */ readTagName(start, endIndex) { 2547 const name = this.lowerCaseTagNames ? this.getSlice(start, endIndex).toLowerCase() : this.getSlice(start, endIndex); 2548 if (!(this.lowerCaseTagNames && this.htmlMode)) { 2549 return name; 2550 } 2551 if (this.foreignContext[0] === ForeignContext.Svg) { 2552 return svgTagNameAdjustments.get(name) ?? name; 2553 } 2554 /* 2555 * Closing tags for SVG elements inside HTML integration points 2556 * (e.g. </foreignObject> while inside its own content) need case 2557 * adjustment so the name matches what was pushed to the stack. 2558 * `foreignContext.length > 1` means a foreign ancestor exists â 2559 * the base [None] entry plus at least one pushed context. 2560 */ if (this.foreignContext.length > 1) { 2561 const adjusted = svgTagNameAdjustments.get(name); 2562 if (adjusted !== undefined && this.stack.includes(adjusted)) { 2563 return adjusted; 2564 } 2565 } 2566 if (!this.isInForeignContext()) { 2567 return name === "image" ? "img" : name; 2568 } 2569 return name; 2570 } 2571 /** 2572 * @param start Start index for the current parser event. 2573 * @param endIndex End index for the current parser event. 2574 * @internal 2575 */ onopentagname(start, endIndex) { 2576 this.endIndex = endIndex; 2577 this.emitOpenTag(this.readTagName(start, endIndex)); 2578 } 2579 emitOpenTag(name) { 2580 this.openTagStart = this.startIndex; 2581 this.tagname = name; 2582 /* 2583 * The spec ignores a second <form> when one is already open. 2584 * Setting tagname to "" suppresses all downstream effects: attribs 2585 * stays null so endOpenTag is a no-op, and closeCurrentTag can't 2586 * match "" on the stack. 2587 */ if (this.htmlMode && name === "form" && this.stack.includes("form")) { 2588 this.tagname = ""; 2589 return; 2590 } 2591 const impliesClose = this.htmlMode && openImpliesClose.get(name); 2592 if (impliesClose) { 2593 while(this.stack.length > 0 && impliesClose.has(this.stack[0])){ 2594 this.popElement(true); 2595 } 2596 } 2597 if (!this.isVoidElement(name)) { 2598 this.stack.unshift(name); 2599 if (this.htmlMode) { 2600 if (name === "svg") { 2601 this.foreignContext.unshift(ForeignContext.Svg); 2602 } else if (name === "math") { 2603 this.foreignContext.unshift(ForeignContext.MathML); 2604 } else if (htmlIntegrationElements.has(name)) { 2605 this.foreignContext.unshift(ForeignContext.None); 2606 } 2607 } 2608 } 2609 this.cbs.onopentagname?.(name); 2610 if (this.cbs.onopentag) this.attribs = {}; 2611 } 2612 endOpenTag(isImplied) { 2613 this.startIndex = this.openTagStart; 2614 if (this.attribs) { 2615 this.cbs.onopentag?.(this.tagname, this.attribs, isImplied); 2616 this.attribs = null; 2617 } 2618 if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) { 2619 this.cbs.onclosetag(this.tagname, true); 2620 } 2621 this.tagname = ""; 2622 } 2623 /** 2624 * @param endIndex End index for the current parser event. 2625 * @internal 2626 */ onopentagend(endIndex) { 2627 this.endIndex = endIndex; 2628 this.endOpenTag(false); 2629 // Set `startIndex` for next node 2630 this.startIndex = endIndex + 1; 2631 } 2632 /** 2633 * @param start Start index for the current parser event. 2634 * @param endIndex End index for the current parser event. 2635 * @internal 2636 */ onclosetag(start, endIndex) { 2637 this.endIndex = endIndex; 2638 const name = this.readTagName(start, endIndex); 2639 if (!this.isVoidElement(name)) { 2640 const pos = this.stack.indexOf(name); 2641 if (pos !== -1) { 2642 for(let index = 0; index < pos; index++){ 2643 this.popElement(true); 2644 } 2645 this.popElement(false); 2646 } else if (this.htmlMode && name === "p") { 2647 // Implicit open before close 2648 this.emitOpenTag("p"); 2649 this.closeCurrentTag(true); 2650 } 2651 } else if (this.htmlMode && name === "br") { 2652 // We can't use `emitOpenTag` for implicit open, as `br` would be implicitly closed. 2653 this.cbs.onopentagname?.("br"); 2654 this.cbs.onopentag?.("br", {}, true); 2655 this.cbs.onclosetag?.("br", false); 2656 } 2657 // Set `startIndex` for next node 2658 this.startIndex = endIndex + 1; 2659 } 2660 /** 2661 * @param endIndex End index for the current parser event. 2662 * @internal 2663 */ onselfclosingtag(endIndex) { 2664 this.endIndex = endIndex; 2665 if (this.recognizeSelfClosing || this.isInForeignContext()) { 2666 this.closeCurrentTag(false); 2667 // Set `startIndex` for next node 2668 this.startIndex = endIndex + 1; 2669 } else { 2670 // Ignore the fact that the tag is self-closing. 2671 this.onopentagend(endIndex); 2672 } 2673 } 2674 /** 2675 * Pop the top element off the stack, emit a close event, and maintain 2676 * the foreign context stack. 2677 * @param implied Whether this close is implied (not from an explicit end tag). 2678 */ popElement(implied) { 2679 // biome-ignore lint/style/noNonNullAssertion: The element is guaranteed to exist. 2680 const element = this.stack.shift(); 2681 if (this.htmlMode && (foreignContextElements.has(element) || htmlIntegrationElements.has(element))) { 2682 this.foreignContext.shift(); 2683 } 2684 this.cbs.onclosetag?.(element, implied); 2685 } 2686 closeCurrentTag(isOpenImplied) { 2687 const name = this.tagname; 2688 this.endOpenTag(isOpenImplied); 2689 // Self-closing tags will be on the top of the stack 2690 if (this.stack[0] === name) { 2691 this.popElement(!isOpenImplied); 2692 } 2693 } 2694 /** 2695 * @param start Start index for the current parser event. 2696 * @param endIndex End index for the current parser event. 2697 * @internal 2698 */ onattribname(start, endIndex) { 2699 this.startIndex = start; 2700 const name = this.getSlice(start, endIndex); 2701 this.attribname = this.lowerCaseAttributeNames ? name.toLowerCase() : name; 2702 } 2703 /** 2704 * @param start Start index for the current parser event. 2705 * @param endIndex End index for the current parser event. 2706 * @internal 2707 */ onattribdata(start, endIndex) { 2708 this.attribvalue += this.getSlice(start, endIndex); 2709 } 2710 /** 2711 * @param cp Current Unicode code point. 2712 * @internal 2713 */ onattribentity(cp) { 2714 this.attribvalue += fromCodePoint(cp); 2715 } 2716 /** 2717 * @param quote Quote type used for the current attribute. 2718 * @param endIndex End index for the current parser event. 2719 * @internal 2720 */ onattribend(quote, endIndex) { 2721 this.endIndex = endIndex; 2722 this.cbs.onattribute?.(this.attribname, this.attribvalue, quote === QuoteType.Double ? '"' : quote === QuoteType.Single ? "'" : quote === QuoteType.NoValue ? undefined : null); 2723 if (this.attribs && !Object.hasOwn(this.attribs, this.attribname)) { 2724 this.attribs[this.attribname] = this.attribvalue; 2725 } 2726 this.attribvalue = ""; 2727 } 2728 getInstructionName(value) { 2729 const index = value.search(reNameEnd); 2730 let name = index < 0 ? value : value.substr(0, index); 2731 if (this.lowerCaseTagNames) { 2732 name = name.toLowerCase(); 2733 } 2734 return name; 2735 } 2736 /** 2737 * @param start Start index for the current parser event. 2738 * @param endIndex End index for the current parser event. 2739 * @internal 2740 */ ondeclaration(start, endIndex) { 2741 this.endIndex = endIndex; 2742 const value = this.getSlice(start, endIndex); 2743 if (this.cbs.onprocessinginstruction) { 2744 /* 2745 * In HTML mode, ondeclaration is only reached for DOCTYPE 2746 * (the tokenizer routes everything else to bogus comments). 2747 */ const name = this.htmlMode ? this.lowerCaseTagNames ? DOCUMENT_TYPE : value.slice(0, DOCUMENT_TYPE.length) : this.getInstructionName(value); 2748 this.cbs.onprocessinginstruction(`!${name}`, `!${value}`); 2749 } 2750 // Set `startIndex` for next node 2751 this.startIndex = endIndex + 1; 2752 } 2753 /** 2754 * @param start Start index for the current parser event. 2755 * @param endIndex End index for the current parser event. 2756 * @internal 2757 */ onprocessinginstruction(start, endIndex) { 2758 this.endIndex = endIndex; 2759 const value = this.getSlice(start, endIndex); 2760 if (this.cbs.onprocessinginstruction) { 2761 const name = this.getInstructionName(value); 2762 this.cbs.onprocessinginstruction(`?${name}`, `?${value}`); 2763 } 2764 // Set `startIndex` for next node 2765 this.startIndex = endIndex + 1; 2766 } 2767 /** 2768 * @param start Start index for the current parser event. 2769 * @param endIndex End index for the current parser event. 2770 * @param offset Offset applied when computing parser indices. 2771 * @internal 2772 */ oncomment(start, endIndex, offset) { 2773 this.endIndex = endIndex; 2774 this.cbs.oncomment?.(this.getSlice(start, endIndex - offset)); 2775 this.cbs.oncommentend?.(); 2776 // Set `startIndex` for next node 2777 this.startIndex = endIndex + 1; 2778 } 2779 /** 2780 * @param start Start index for the current parser event. 2781 * @param endIndex End index for the current parser event. 2782 * @param offset Offset applied when computing parser indices. 2783 * @internal 2784 */ oncdata(start, endIndex, offset) { 2785 this.endIndex = endIndex; 2786 const value = this.getSlice(start, endIndex - offset); 2787 if (!this.htmlMode || this.options.recognizeCDATA) { 2788 this.cbs.oncdatastart?.(); 2789 this.cbs.ontext?.(value); 2790 this.cbs.oncdataend?.(); 2791 } else if (this.isInForeignContext()) { 2792 this.cbs.ontext?.(value); 2793 } else { 2794 this.cbs.oncomment?.(`[CDATA[${value}]]`); 2795 this.cbs.oncommentend?.(); 2796 } 2797 // Set `startIndex` for next node 2798 this.startIndex = endIndex + 1; 2799 } 2800 /** @internal */ onend() { 2801 if (this.cbs.onclosetag) { 2802 // Set the end index for all remaining tags 2803 this.endIndex = this.startIndex; 2804 for(let index = 0; index < this.stack.length; index++){ 2805 this.cbs.onclosetag(this.stack[index], true); 2806 } 2807 } 2808 this.cbs.onend?.(); 2809 } 2810 /** 2811 * Resets the parser to a blank state, ready to parse a new HTML document 2812 */ reset() { 2813 this.cbs.onreset?.(); 2814 this.tokenizer.reset(); 2815 this.tagname = ""; 2816 this.attribname = ""; 2817 this.attribvalue = ""; 2818 this.attribs = null; 2819 this.stack.length = 0; 2820 this.startIndex = 0; 2821 this.endIndex = 0; 2822 this.cbs.onparserinit?.(this); 2823 this.buffers.length = 0; 2824 this.foreignContext.length = 0; 2825 this.foreignContext.unshift(ForeignContext.None); 2826 this.bufferOffset = 0; 2827 this.writeIndex = 0; 2828 this.ended = false;
2829 } 2830 /** 2831 * Resets the parser, then parses a complete document and 2832 * pushes it to the handler. 2833 * @param data Document to parse. 2834 */ parseComplete(data) { 2835 this.reset(); 2836 this.end(data); 2837 } 2838 getSlice(start, end) { 2839 if (start === end) { 2840 return ""; 2841 } 2842 while(start - this.bufferOffset >= this.buffers[0].length){ 2843 this.shiftBuffer(); 2844 } 2845 let slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset); 2846 while(end - this.bufferOffset > this.buffers[0].length){ 2847 this.shiftBuffer(); 2848 slice += this.buffers[0].slice(0, end - this.bufferOffset); 2849 } 2850 return slice; 2851 } 2852 shiftBuffer() { 2853 this.bufferOffset += this.buffers[0].length; 2854 this.writeIndex--; 2855 this.buffers.shift(); 2856 } 2857 /** 2858 * Parses a chunk of data and calls the corresponding callbacks. 2859 * @param chunk Chunk to parse. 2860 */ write(chunk) { 2861 if (this.ended) { 2862 this.cbs.onerror?.(new Error(".write() after done!")); 2863 return; 2864 } 2865 this.buffers.push(chunk); 2866 if (this.tokenizer.running) { 2867 this.tokenizer.write(chunk); 2868 this.writeIndex++; 2869 } 2870 } 2871 /** 2872 * Parses the end of the buffer and clears the stack, calls onend. 2873 * @param chunk Optional final chunk to parse. 2874 */ end(chunk) { 2875 if (this.ended) { 2876 this.cbs.onerror?.(new Error(".end() after done!")); 2877 return; 2878 } 2879 if (chunk) this.write(chunk); 2880 this.ended = true; 2881 this.tokenizer.end(); 2882 } 2883 /** 2884 * Pauses parsing. The parser won't emit events until `resume` is called. 2885 */ pause() { 2886 this.tokenizer.pause(); 2887 } 2888 /** 2889 * Resumes parsing after `pause` was called. 2890 */ resume() { 2891 this.tokenizer.resume(); 2892 while(this.tokenizer.running && this.writeIndex < this.buffers.length){ 2893 this.tokenizer.write(this.buffers[this.writeIndex++]); 2894 } 2895 if (this.ended) this.tokenizer.end(); 2896 } 2897} 2898// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domhandler/dist/index.js [app-client] (ecmascript) <locals> 2899; 2900// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domelementtype/dist/index.js [app-client] (ecmascript) 2901; 2902var ElementType; 2903(function(ElementType) { 2904 /** Type for the root element of a document */ ElementType["Root"] = "root"; 2905 /** Type for Text */ ElementType["Text"] = "text"; 2906 /** Type for <? ... ?> */ ElementType["Directive"] = "directive"; 2907 /** Type for <!-- ... --> */ ElementType["Comment"] = "comment"; 2908 /** Type for <script> tags */ ElementType["Script"] = "script"; 2909 /** Type for <style> tags */ ElementType["Style"] = "style"; 2910 /** Type for Any tag */ ElementType["Tag"] = "tag"; 2911 /** Type for <![CDATA[ ... ]]> */ ElementType["CDATA"] = "cdata"; 2912 /** Type for <!doctype ...> */ ElementType["Doctype"] = "doctype"; 2913})(ElementType || (ElementType = {})); 2914function isTag(element) { 2915 return element.type === ElementType.Tag || element.type === ElementType.Script || element.type === ElementType.Style; 2916} 2917const Root = ElementType.Root; 2918const Text = ElementType.Text; 2919const Directive = ElementType.Directive; 2920const Comment = ElementType.Comment; 2921const Script = ElementType.Script; 2922const Style = ElementType.Style; 2923const Tag = ElementType.Tag; 2924const CDATA = ElementType.CDATA; 2925const Doctype = ElementType.Doctype; 2926__turbopack_context__.s([ 2927 "CDATA", 2928 0, 2929 CDATA, 2930 "Comment", 2931 0, 2932 Comment, 2933 "Directive", 2934 0, 2935 Directive, 2936 "Doctype", 2937 0, 2938 Doctype, 2939 "ElementType", 2940 0, 2941 ElementType, 2942 "Root", 2943 0, 2944 Root, 2945 "Script", 2946 0, 2947 Script, 2948 "Style", 2949 0, 2950 Style, 2951 "Tag", 2952 0, 2953 Tag, 2954 "Text", 2955 0, 2956 Text, 2957 "isTag", 2958 0, 2959 isTag 2960], 546806); 2961// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domhandler/dist/node.js [app-client] (ecmascript) 2962; 2963; 2964class Node { 2965 /** Parent of the node */ parent = null; 2966 /** Previous sibling */ prev = null; 2967 /** Next sibling */ next = null; 2968 /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */ startIndex = null; 2969 /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */ endIndex = null; 2970 // Read-write aliases for properties 2971 /** 2972 * Same as {@link parent}. 2973 * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. 2974 */ get parentNode() { 2975 return this.parent; 2976 } 2977 set parentNode(parent) { 2978 this.parent = parent; 2979 } 2980 /** 2981 * Same as {@link prev}. 2982 * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. 2983 */ get previousSibling() { 2984 return this.prev; 2985 } 2986 set previousSibling(previous) { 2987 this.prev = previous; 2988 } 2989 /** 2990 * Same as {@link next}. 2991 * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. 2992 */ get nextSibling() { 2993 return this.next; 2994 } 2995 set nextSibling(next) { 2996 this.next = next; 2997 } 2998 /** 2999 * Clone this node, and optionally its children. 3000 * @param recursive Clone child nodes as well. 3001 * @returns A clone of the node. 3002 */ cloneNode(recursive = false) { 3003 return cloneNode(this, recursive); 3004 } 3005} 3006class DataNode extends Node { 3007 data; 3008 /** 3009 * @param data The content of the data node 3010 */ constructor(data){ 3011 super(); 3012 this.data = data; 3013 } 3014 /** 3015 * Same as {@link data}. 3016 * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. 3017 */ get nodeValue() { 3018 return this.data; 3019 } 3020 set nodeValue(data) { 3021 this.data = data; 3022 } 3023} 3024class Text1 extends DataNode { 3025 type = ElementType.Text; 3026 get nodeType() { 3027 return 3; 3028 } 3029} 3030class Comment1 extends DataNode { 3031 type = ElementType.Comment; 3032 get nodeType() { 3033 return 8; 3034 } 3035} 3036class ProcessingInstruction extends DataNode { 3037 type = ElementType.Directive; 3038 name; 3039 constructor(name, data){ 3040 super(data); 3041 this.name = name; 3042 } 3043 get nodeType() { 3044 return 1; 3045 } 3046 /** If this is a doctype, the document type name (parse5 only). */ "x-name"; 3047 /** If this is a doctype, the document type public identifier (parse5 only). */ "x-publicId"; 3048 /** If this is a doctype, the document type system identifier (parse5 only). */ "x-systemId"; 3049} 3050class NodeWithChildren extends Node { 3051 children; 3052 /**
3053 * @param children Children of the node. Only certain node types can have children. 3054 */ constructor(children){ 3055 super(); 3056 this.children = children; 3057 } 3058 // Aliases 3059 /** First child of the node. */ get firstChild() { 3060 return this.children[0] ?? null; 3061 } 3062 /** Last child of the node. */ get lastChild() { 3063 return this.children.length > 0 ? this.children[this.children.length - 1] : null; 3064 } 3065 /** 3066 * Same as {@link children}. 3067 * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. 3068 */ get childNodes() { 3069 return this.children; 3070 } 3071 set childNodes(children) { 3072 this.children = children; 3073 } 3074} 3075class CDATA1 extends NodeWithChildren { 3076 type = ElementType.CDATA; 3077 get nodeType() { 3078 return 4; 3079 } 3080} 3081class Document extends NodeWithChildren { 3082 type = ElementType.Root; 3083 get nodeType() { 3084 return 9; 3085 } 3086} 3087class Element extends NodeWithChildren { 3088 name; 3089 attribs; 3090 type; 3091 /** 3092 * @param name Name of the tag, eg. `div`, `span`. 3093 * @param attribs Object mapping attribute names to attribute values. 3094 * @param children Children of the node. 3095 * @param type Node type used for the new node instance. 3096 */ constructor(name, attribs, children = [], type = name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag){ 3097 super(children); 3098 this.name = name; 3099 this.attribs = attribs; 3100 this.type = type; 3101 } 3102 get nodeType() { 3103 return 1; 3104 } 3105 // DOM Level 1 aliases 3106 /** 3107 * Same as {@link name}. 3108 * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. 3109 */ get tagName() { 3110 return this.name; 3111 } 3112 set tagName(name) { 3113 this.name = name; 3114 } 3115 get attributes() { 3116 return Object.keys(this.attribs).map((name)=>({ 3117 name, 3118 value: this.attribs[name], 3119 namespace: this["x-attribsNamespace"]?.[name], 3120 prefix: this["x-attribsPrefix"]?.[name] 3121 })); 3122 } 3123 /** Element namespace (parse5 only). */ namespace; 3124 /** Element attribute namespaces (parse5 only). */ "x-attribsNamespace"; 3125 /** Element attribute namespace-related prefixes (parse5 only). */ "x-attribsPrefix"; 3126} 3127function isTag1(node) { 3128 return isTag(node); 3129} 3130function isCDATA(node) { 3131 return node.type === ElementType.CDATA; 3132} 3133function isText(node) { 3134 return node.type === ElementType.Text; 3135} 3136function isComment(node) { 3137 return node.type === ElementType.Comment; 3138} 3139function isDirective(node) { 3140 return node.type === ElementType.Directive; 3141} 3142function isDocument(node) { 3143 return node.type === ElementType.Root; 3144} 3145function hasChildren(node) { 3146 return Object.hasOwn(node, "children"); 3147} 3148function cloneNode(node, recursive = false) { 3149 let result; 3150 if (isText(node)) { 3151 result = new Text1(node.data); 3152 } else if (isComment(node)) { 3153 result = new Comment1(node.data); 3154 } else if (isTag1(node)) { 3155 const children = recursive ? cloneChildren(node.children) : []; 3156 const clone = new Element(node.name, { 3157 ...node.attribs 3158 }, children); 3159 for (const child of children){ 3160 child.parent = clone; 3161 } 3162 if (node.namespace != null) { 3163 clone.namespace = node.namespace; 3164 } 3165 if (node["x-attribsNamespace"]) { 3166 clone["x-attribsNamespace"] = { 3167 ...node["x-attribsNamespace"] 3168 }; 3169 } 3170 if (node["x-attribsPrefix"]) { 3171 clone["x-attribsPrefix"] = { 3172 ...node["x-attribsPrefix"] 3173 }; 3174 } 3175 result = clone; 3176 } else if (isCDATA(node)) { 3177 const children = recursive ? cloneChildren(node.children) : []; 3178 const clone = new CDATA1(children); 3179 for (const child of children){ 3180 child.parent = clone; 3181 } 3182 result = clone; 3183 } else if (isDocument(node)) { 3184 const children = recursive ? cloneChildren(node.children) : []; 3185 const clone = new Document(children); 3186 for (const child of children){ 3187 child.parent = clone; 3188 } 3189 if (node["x-mode"]) { 3190 clone["x-mode"] = node["x-mode"]; 3191 } 3192 result = clone; 3193 } else if (isDirective(node)) { 3194 const instruction = new ProcessingInstruction(node.name, node.data); 3195 if (node["x-name"] != null) { 3196 instruction["x-name"] = node["x-name"]; 3197 instruction["x-publicId"] = node["x-publicId"]; 3198 instruction["x-systemId"] = node["x-systemId"]; 3199 } 3200 result = instruction; 3201 } else { 3202 throw new Error(`Not implemented yet: ${node.type}`); 3203 } 3204 result.startIndex = node.startIndex; 3205 result.endIndex = node.endIndex; 3206 if (node.sourceCodeLocation != null) { 3207 result.sourceCodeLocation = node.sourceCodeLocation; 3208 } 3209 return result; 3210} 3211/** 3212 * Clone a list of child nodes. 3213 * @param childs The child nodes to clone. 3214 * @returns A list of cloned child nodes. 3215 */ function cloneChildren(childs) { 3216 const children = childs.map((child)=>cloneNode(child, true)); 3217 for(let index = 1; index < children.length; index++){ 3218 children[index].prev = children[index - 1]; 3219 children[index - 1].next = children[index]; 3220 } 3221 return children; 3222} 3223; 3224; 3225; 3226// Default options 3227const defaultOptions = { 3228 withStartIndices: false, 3229 withEndIndices: false, 3230 xmlMode: false 3231}; 3232class DomHandler { 3233 /** The elements of the DOM */ dom = []; 3234 /** The root element for the DOM */ root = new Document(this.dom); 3235 /** Called once parsing has completed. */ callback; 3236 /** Settings for the handler. */ options; 3237 /** Callback whenever a tag is closed. */ elementCB; 3238 /** Indicated whether parsing has been completed. */ done = false;
vendor: 4,402 bytes, lines 3239-3371
3239 /** Stack of open tags. */ tagStack = [ 3240 this.root 3241 ]; 3242 /** A data node that is still being written to. */ lastNode = null; 3243 /** Reference to the parser instance. Used for location information. */ parser = null; 3244 /** 3245 * @param callback Called once parsing has completed. 3246 * @param options Settings for the handler. 3247 * @param elementCB Callback whenever a tag is closed. 3248 */ constructor(callback, options, elementCB){ 3249 // Make it possible to skip arguments, for backwards-compatibility 3250 if (typeof options === "function") { 3251 elementCB = options; 3252 options = defaultOptions; 3253 } 3254 if (typeof callback === "object") { 3255 options = callback; 3256 callback = undefined; 3257 } 3258 this.callback = callback ?? null; 3259 this.options = options ?? defaultOptions; 3260 this.elementCB = elementCB ?? null; 3261 } 3262 onparserinit(parser) { 3263 this.parser = parser; 3264 } 3265 // Resets the handler back to starting state 3266 onreset() { 3267 this.dom = []; 3268 this.root = new Document(this.dom); 3269 this.done = false; 3270 this.tagStack = [ 3271 this.root 3272 ]; 3273 this.lastNode = null; 3274 this.parser = null; 3275 } 3276 // Signals the handler that parsing is done 3277 onend() { 3278 if (this.done) return; 3279 this.done = true; 3280 this.parser = null; 3281 this.handleCallback(null); 3282 } 3283 onerror(error) { 3284 this.handleCallback(error); 3285 } 3286 onclosetag() { 3287 this.lastNode = null; 3288 const element = this.tagStack.pop(); 3289 if (this.options.withEndIndices && this.parser) { 3290 element.endIndex = this.parser.endIndex; 3291 } 3292 if (this.elementCB) this.elementCB(element); 3293 } 3294 onopentag(name, attribs) { 3295 const type = this.options.xmlMode ? ElementType.Tag : undefined; 3296 const element = new Element(name, attribs, undefined, type); 3297 this.addNode(element); 3298 this.tagStack.push(element); 3299 } 3300 ontext(data) { 3301 const { lastNode } = this; 3302 if (lastNode && lastNode.type === ElementType.Text) { 3303 lastNode.data += data; 3304 if (this.options.withEndIndices && this.parser) { 3305 lastNode.endIndex = this.parser.endIndex; 3306 } 3307 } else { 3308 const node = new Text1(data); 3309 this.addNode(node); 3310 this.lastNode = node; 3311 } 3312 } 3313 oncomment(data) { 3314 if (this.lastNode && this.lastNode.type === ElementType.Comment) { 3315 this.lastNode.data += data; 3316 return; 3317 } 3318 const node = new Comment1(data); 3319 this.addNode(node); 3320 this.lastNode = node; 3321 } 3322 oncommentend() { 3323 this.lastNode = null; 3324 } 3325 oncdatastart() { 3326 const text = new Text1(""); 3327 const node = new CDATA1([ 3328 text 3329 ]); 3330 this.addNode(node); 3331 text.parent = node; 3332 this.lastNode = text; 3333 } 3334 oncdataend() { 3335 this.lastNode = null; 3336 } 3337 onprocessinginstruction(name, data) { 3338 const node = new ProcessingInstruction(name, data); 3339 this.addNode(node); 3340 } 3341 handleCallback(error) { 3342 if (typeof this.callback === "function") { 3343 this.callback(error, this.dom); 3344 } else if (error) { 3345 throw error; 3346 } 3347 } 3348 addNode(node) { 3349 const parent = this.tagStack[this.tagStack.length - 1]; 3350 const previousSibling = parent.children[parent.children.length - 1]; 3351 if (this.options.withStartIndices && this.parser) { 3352 node.startIndex = this.parser.startIndex; 3353 } 3354 if (this.options.withEndIndices && this.parser) { 3355 node.endIndex = this.parser.endIndex; 3356 } 3357 parent.children.push(node); 3358 if (previousSibling) { 3359 node.prev = previousSibling; 3360 previousSibling.next = node; 3361 } 3362 node.parent = parent; 3363 this.lastNode = null; 3364 } 3365} 3366const __TURBOPACK__default__export__ = DomHandler; 3367// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/feeds.js [app-client] (ecmascript) 3368; 3369// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/legacy.js [app-client] (ecmascript) 3370; 3371// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/querying.js [a
3371pp-client] (ecmascript) 3372; 3373; 3374function filter(test, node, recurse = true, limit = Number.POSITIVE_INFINITY) { 3375 return find(test, Array.isArray(node) ? node : [ 3376 node 3377 ], recurse, limit); 3378} 3379function find(test, nodes, recurse, limit) { 3380 const result = []; 3381 /** Stack of the arrays we are looking at. */ const nodeStack = [ 3382 Array.isArray(nodes) ? nodes : [ 3383 nodes 3384 ] 3385 ]; 3386 /** Stack of the indices within the arrays. */ const indexStack = [ 3387 0 3388 ]; 3389 for(;;){ 3390 // First, check if the current array has any more elements to look at. 3391 if (indexStack[0] >= nodeStack[0].length) { 3392 // If we have no more arrays to look at, we are done. 3393 if (indexStack.length === 1) { 3394 return result; 3395 } 3396 // Otherwise, remove the current array from the stack. 3397 nodeStack.shift(); 3398 indexStack.shift(); 3399 continue; 3400 } 3401 const element = nodeStack[0][indexStack[0]++]; 3402 if (test(element)) { 3403 result.push(element); 3404 if (--limit <= 0) return result; 3405 } 3406 if (recurse && hasChildren(element) && element.children.length > 0) { 3407 /* 3408 * Add the children to the stack. We are depth-first, so this is 3409 * the next array we look at. 3410 */ indexStack.unshift(0); 3411 nodeStack.unshift(element.children); 3412 } 3413 } 3414} 3415function findOne(test, nodes, recurse = true) { 3416 const searchedNodes = Array.isArray(nodes) ? nodes : [ 3417 nodes 3418 ]; 3419 for (const node of searchedNodes){ 3420 if (isTag1(node) && test(node)) { 3421 return node; 3422 } 3423 if (recurse && hasChildren(node) && node.children.length > 0) { 3424 const found = findOne(test, node.children, true); 3425 if (found) return found; 3426 } 3427 } 3428 return null; 3429} 3430function existsOne(test, nodes) { 3431 return (Array.isArray(nodes) ? nodes : [ 3432 nodes 3433 ]).some((node)=>isTag1(node) && test(node) || hasChildren(node) && existsOne(test, node.children)); 3434} 3435function findAll(test, nodes) { 3436 const result = []; 3437 const nodeStack = [ 3438 Array.isArray(nodes) ? nodes : [ 3439 nodes 3440 ] 3441 ]; 3442 const indexStack = [ 3443 0 3444 ]; 3445 for(;;){ 3446 if (indexStack[0] >= nodeStack[0].length) { 3447 if (nodeStack.length === 1) { 3448 return result; 3449 } 3450 // Otherwise, remove the current array from the stack. 3451 nodeStack.shift(); 3452 indexStack.shift(); 3453 continue; 3454 } 3455 const element = nodeStack[0][indexStack[0]++]; 3456 if (isTag1(element) && test(element)) result.push(element); 3457 if (hasChildren(element) && element.children.length > 0) { 3458 indexStack.unshift(0); 3459 nodeStack.unshift(element.children); 3460 } 3461 } 3462} 3463__turbopack_context__.s([ 3464 "existsOne", 3465 0, 3466 existsOne, 3467 "filter", 3468 0, 3469 filter, 3470 "find", 3471 0, 3472 find, 3473 "findAll", 3474 0, 3475 findAll, 3476 "findOne", 3477 0, 3478 findOne 3479], 890961); 3480; 3481; 3482/** 3483 * A map of functions to check nodes against. 3484 */ const Checks = { 3485 tag_name (name) { 3486 if (typeof name === "function") { 3487 return (element)=>isTag1(element) && name(element.name); 3488 } 3489 if (name === "*") { 3490 return isTag1; 3491 } 3492 return (element)=>isTag1(element) && element.name === name; 3493 }, 3494 tag_type (type) { 3495 if (typeof type === "function") { 3496 return (element)=>type(element.type); 3497 } 3498 return (element)=>element.type === type; 3499 }, 3500 tag_contains (data) { 3501 if (typeof data === "function") { 3502 return (element)=>isText(element) && data(element.data); 3503 } 3504 return (element)=>isText(element) && element.data === data; 3505 } 3506}; 3507/** 3508 * Returns a function to check whether a node has an attribute with a particular 3509 * value. 3510 * 3511 * @param attrib Attribute to check. 3512 * @param value Attribute value to look for. 3513 * @returns A function to check whether the a node has an attribute with a 3514 * particular value. 3515 */ function getAttribCheck(attrib, value) { 3516 if (typeof value === "function") { 3517 return (element)=>isTag1(element) && value(element.attribs[attrib]); 3518 } 3519 return (element)=>isTag1(element) && element.attribs[attrib] === value; 3520} 3521/** 3522 * Returns a function that returns `true` if either of the input functions 3523 * returns `true` for a node. 3524 * 3525 * @param a First function to combine. 3526 * @param b Second function to combine. 3527 * @returns A function taking a node and returning `true` if either of the input 3528 * functions returns `true` for the node. 3529 */ function combineFuncs(a, b) { 3530 return (element)=>a(element) || b(element); 3531} 3532/** 3533 * Returns a function that executes all checks in `options` and returns `true`
3534 * if any of them match a node. 3535 * 3536 * @param options An object describing nodes to look for. 3537 * @returns A function that executes all checks in `options` and returns `true` 3538 * if any of them match a node. 3539 */ function compileTest(options) { 3540 const funcs = Object.keys(options).map((key)=>{ 3541 const value = options[key]; 3542 return Object.hasOwn(Checks, key) ? Checks[key](value) : getAttribCheck(key, value); 3543 }); 3544 return funcs.length === 0 ? null : funcs.reduce(combineFuncs); 3545} 3546function testElement(options, node) { 3547 const test = compileTest(options); 3548 return test ? test(node) : true; 3549} 3550function getElements(options, nodes, recurse, limit = Number.POSITIVE_INFINITY) { 3551 const test = compileTest(options); 3552 return test ? filter(test, nodes, recurse, limit) : []; 3553} 3554function getElementById(id, nodes, recurse = true) { 3555 if (!Array.isArray(nodes)) nodes = [ 3556 nodes 3557 ]; 3558 return findOne(getAttribCheck("id", id), nodes, recurse); 3559} 3560function getElementsByTagName(tagName, nodes, recurse = true, limit = Number.POSITIVE_INFINITY) { 3561 return filter(Checks["tag_name"](tagName), nodes, recurse, limit); 3562} 3563function getElementsByClassName(className, nodes, recurse = true, limit = Number.POSITIVE_INFINITY) { 3564 return filter(getAttribCheck("class", className), nodes, recurse, limit); 3565} 3566function getElementsByTagType(type, nodes, recurse = true, limit = Number.POSITIVE_INFINITY) { 3567 return filter(Checks["tag_type"](type), nodes, recurse, limit); 3568} 3569__turbopack_context__.s([ 3570 "getElementById", 3571 0, 3572 getElementById, 3573 "getElements", 3574 0, 3575 getElements, 3576 "getElementsByClassName", 3577 0, 3578 getElementsByClassName, 3579 "getElementsByTagName", 3580 0, 3581 getElementsByTagName, 3582 "getElementsByTagType", 3583 0, 3584 getElementsByTagType, 3585 "testElement", 3586 0, 3587 testElement 3588], 764451); 3589// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/stringify.js [app-client] (ecmascript) 3590; 3591// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/dom-serializer/dist/index.js [app-client] (ecmascript) 3592; 3593// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/entities/dist/escape.js [app-client] (ecmascript) 3594; 3595const xmlCodeMap = new Map([ 3596 [ 3597 34, 3598 """ 3599 ], 3600 [ 3601 38, 3602 "&" 3603 ], 3604 [ 3605 39, 3606 "'" 3607 ], 3608 [ 3609 60, 3610 "<" 3611 ], 3612 [ 3613 62, 3614 ">" 3615 ] 3616]); 3617const getCodePoint = typeof String.prototype.codePointAt === "function" ? (input, index)=>input.codePointAt(index) : (c, index)=>(c.charCodeAt(index) & 0xfc_00) === 0xd8_00 ? (c.charCodeAt(index) - 0xd8_00) * 0x4_00 + c.charCodeAt(index + 1) - 0xdc_00 + 0x1_00_00 : c.charCodeAt(index); 3618const XML_BITSET_VALUE = 0x50_00_00_c4; // 32..63 -> 34 ("),38 (&),39 ('),60 (<),62 (>) 3619function encodeXML(input) { 3620 let out; 3621 let last = 0; 3622 const { length } = input; 3623 for(let index = 0; index < length; index++){ 3624 const char = input.charCodeAt(index); 3625 // Check for ASCII chars that don't need escaping 3626 if (char < 0x80 && ((XML_BITSET_VALUE >>> char & 1) === 0 || char >= 64 || char < 32)) { 3627 continue; 3628 } 3629 if (out === undefined) out = input.substring(0, index); 3630 else if (last !== index) out += input.substring(last, index); 3631 if (char < 64) { 3632 // Known replacement 3633 out += xmlCodeMap.get(char); 3634 last = index + 1; 3635 continue; 3636 } 3637 // Non-ASCII: encode as numeric entity (handle surrogate pair) 3638 const cp = getCodePoint(input, index); 3639 out += `&#x${cp.toString(16)};`; 3640 if (cp !== char) index++; // Skip trailing surrogate 3641 last = index + 1; 3642 } 3643 if (out === undefined) return input; 3644 if (last < length) out += input.substr(last); 3645 return out; 3646} 3647const escape = encodeXML; 3648/** 3649 * Creates a function that escapes all characters matched by the given regular
3650 * expression using the given map of characters to escape to their entities. 3651 * @param regex Regular expression to match characters to escape. 3652 * @param map Map of characters to escape to their entities. 3653 * @returns Function that escapes all characters matched by the given regular 3654 * expression using the given map of characters to escape to their entities. 3655 */ function getEscaper(regex, map) { 3656 return function escape(data) { 3657 let match; 3658 let lastIndex = 0; 3659 let result = ""; 3660 while(match = regex.exec(data)){ 3661 if (lastIndex !== match.index) { 3662 result += data.substring(lastIndex, match.index); 3663 } 3664 // We know that this character will be in the map. 3665 result += map.get(match[0].charCodeAt(0)); 3666 // Every match will be of length 1 3667 lastIndex = match.index + 1; 3668 } 3669 return result + data.substring(lastIndex); 3670 }; 3671} 3672const escapeUTF8 = /* #__PURE__ */ getEscaper(/["&'<>]/g, xmlCodeMap); 3673const escapeAttribute = /* #__PURE__ */ getEscaper(/["&\u00A0]/g, new Map([ 3674 [ 3675 34, 3676 """ 3677 ], 3678 [ 3679 38, 3680 "&" 3681 ], 3682 [ 3683 160, 3684 " " 3685 ] 3686])); 3687const escapeText = /* #__PURE__ */ getEscaper(/[&<>\u00A0]/g, new Map([ 3688 [ 3689 38, 3690 "&" 3691 ], 3692 [ 3693 60, 3694 "<" 3695 ], 3696 [ 3697 62, 3698 ">" 3699 ], 3700 [ 3701 160, 3702 " " 3703 ] 3704])); 3705// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/dom-serializer/dist/foreign-names.js [app-client] (ecmascript) 3706; 3707const elementNames = new Map("altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feDropShadow feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath".split(" ").map((name)=>[ 3708 name.toLowerCase(), 3709 name 3710 ])); 3711const attributeNames = new Map("definitionURL attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits diffuseConstant edgeMode filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan".split(" ").map((name)=>[ 3712 name.toLowerCase(), 3713 name 3714 ])); 3715; 3716; 3717; 3718// ââ Constants ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 3719/** Elements whose text content is never entity-encoded. */ const unencodedElements = new Set("style script xmp iframe noembed noframes plaintext noscript".split(" ")); 3720/** HTML void elements â they cannot have children. */ const voidElements1 = new Set("area base basefont br col command embed frame hr img input isindex keygen link meta param source track wbr".split(" ")); 3721/** Elements that switch the parser into foreign (XML-like) mode. */ const foreignElements = new Set([ 3722 "svg", 3723 "math" 3724]); 3725/** 3726 * Foreign-mode integration points: children of these elements are parsed 3727 * as HTML again, not as foreign content. 3728 */ const foreignModeIntegrationPoints = new Set("mi mo mn ms mtext annotation-xml foreignObject desc title".split(" ")); 3729function render(node, options = {}) { 3730 const nodes = "length" in node ? node : [ 3731 node 3732 ]; 3733 /* 3734 * `xmlMode` is threaded as a separate argument through the internal 3735 * functions so that foreign-mode transitions (svg/mathml â html) can 3736 * adjust it without copying the options object on every element. 3737 */ const xmlMode = options.xmlMode ?? false; 3738 let output = ""; 3739 // eslint-disable-next-line unicorn/no-for-loop 3740 for(let index = 0;
3740 index < nodes.length; index++){ 3741 output += renderNode(nodes[index], options, xmlMode); 3742 } 3743 return output; 3744} 3745const __TURBOPACK__default__export__1 = render; 3746// ââ Internal rendering âââââââââââââââââââââââââââââââââââââââââââââââ 3747/** 3748 * Render an array of child nodes (skips the single-node wrapping in `render`). 3749 * @param children The child nodes to render. 3750 * @param options The serialization options. 3751 * @param xmlMode The XML mode to use. 3752 */ function renderChildren(children, options, xmlMode) { 3753 let output = ""; 3754 // eslint-disable-next-line unicorn/no-for-loop 3755 for(let index = 0; index < children.length; index++){ 3756 output += renderNode(children[index], options, xmlMode); 3757 } 3758 return output; 3759} 3760function renderNode(node, options, xmlMode) { 3761 switch(node.type){ 3762 case Root: 3763 { 3764 return renderChildren(node.children, options, xmlMode); 3765 } 3766 case Directive: 3767 { 3768 return `<${node.data}>`; 3769 } 3770 case Comment: 3771 { 3772 return `<!--${node.data}-->`; 3773 } 3774 case CDATA: 3775 { 3776 return `<![CDATA[${node.children[0].data}]]>`; 3777 } 3778 case Script: 3779 case Style: 3780 case Tag: 3781 { 3782 return renderTag(node, options, xmlMode); 3783 } 3784 case Text: 3785 { 3786 const element = node; 3787 const data = element.data || ""; 3788 /* 3789 * Skip encoding when entities weren't decoded on input, or when 3790 * inside a raw-text element (script, style, etc.) in HTML mode. 3791 */ if ((options.encodeEntities ?? options.decodeEntities) !== false && !(!xmlMode && element.parent && unencodedElements.has(element.parent.name))) { 3792 // `xmlMode: "foreign"` is truthy 3793 return xmlMode || options.encodeEntities !== "utf8" ? encodeXML(data) : escapeText(data); 3794 } 3795 return data; 3796 } 3797 } 3798} 3799function renderTag(element, options, xmlMode) { 3800 if (xmlMode === "foreign") { 3801 // Correct lowercase element names back to their canonical mixed-case form 3802 element.name = elementNames.get(element.name) ?? element.name; 3803 // Integration points exit foreign mode: their children are HTML 3804 if (element.parent && foreignModeIntegrationPoints.has(element.parent.name)) { 3805 xmlMode = false; 3806 } 3807 } 3808 if (!xmlMode && foreignElements.has(element.name)) { 3809 xmlMode = "foreign"; 3810 } 3811 const { name, children } = element; 3812 // Cache the void-element check â used for both self-closing and closing-tag logic 3813 const isVoid = !xmlMode && voidElements1.has(name); 3814 let tag = `<${name}${formatAttributes(element.attribs, options, xmlMode)}`; 3815 if (children.length === 0 && (xmlMode ? options.selfClosingTags !== false : options.selfClosingTags && isVoid)) { 3816 // XML: `<br/>`, HTML: `<br />` 3817 tag += xmlMode ? "/>" : " />"; 3818 } else { 3819 tag += ">"; 3820 if (children.length > 0) { 3821 tag += renderChildren(children, options, xmlMode); 3822 } 3823 if (!isVoid) { 3824 tag += `</${name}>`; 3825 } 3826 } 3827 return tag; 3828} 3829// ââ Attribute formatting âââââââââââââââââââââââââââââââââââââââââââââ 3830function replaceQuotes(value) { 3831 return value.replaceAll('"', """); 3832} 3833/** 3834 * Serialize an element's attribute map to a string. 3835 * 3836 * Returns a string with a leading space before each attribute, or an 3837 * empty string if there are no attributes. This convention lets the 3838 * caller unconditionally concatenate the result onto the tag name. 3839 * @param attributes 3840 * @param options 3841 * @param xmlMode 3842 */ function formatAttributes(attributes, options, xmlMode) { 3843 if (!attributes) return ""; 3844 /* 3845 * Pick the right encoder: 3846 * - Encoding disabled â only escape double-quotes (for valid attributes) 3847 * - XML / non-utf8 â full numeric entity encoding (encodeXML) 3848 * - HTML + utf8 â minimal escaping (escapeAttribute) 3849 */ const encode = (options.encodeEntities ?? options.decodeEntities) === false ? replaceQuotes : xmlMode || options.encodeEntities !== "utf8" ? encodeXML : escapeAttribute; 3850 const isForeign = xmlMode === "foreign"; 3851 const showEmpty = !!(options.emptyAttrs ?? xmlMode); 3852 let result = ""; 3853 for(const key in attributes){ 3854 if (!Object.hasOwn(attributes, key)) continue; 3855 const value = attributes[key];
3856 const k = isForeign ? attributeNames.get(key) ?? key : key; 3857 result += !showEmpty && (value == null || value === "") ? ` ${k}` : ` ${k}="${encode(value == null ? "" : String(value))}"`; 3858 } 3859 return result; 3860} 3861; 3862; 3863; 3864function getOuterHTML(node, options) { 3865 return __TURBOPACK__default__export__1(node, options); 3866} 3867function getInnerHTML(node, options) { 3868 return hasChildren(node) ? node.children.map((node)=>getOuterHTML(node, options)).join("") : ""; 3869} 3870function getText(node) { 3871 if (Array.isArray(node)) return node.map(getText).join(""); 3872 if (isTag1(node)) return node.name === "br" ? "\n" : getText(node.children); 3873 if (isCDATA(node)) return getText(node.children); 3874 if (isText(node)) return node.data; 3875 return ""; 3876} 3877function textContent(node) { 3878 if (Array.isArray(node)) return node.map(textContent).join(""); 3879 if (hasChildren(node) && !isComment(node)) { 3880 return textContent(node.children); 3881 } 3882 if (isText(node)) return node.data; 3883 return ""; 3884} 3885function innerText(node) { 3886 if (Array.isArray(node)) return node.map(innerText).join(""); 3887 if (hasChildren(node) && (node.type === ElementType.Tag || isCDATA(node))) { 3888 return innerText(node.children); 3889 } 3890 if (isText(node)) return node.data; 3891 return ""; 3892} 3893__turbopack_context__.s([ 3894 "getInnerHTML", 3895 0, 3896 getInnerHTML, 3897 "getOuterHTML", 3898 0, 3899 getOuterHTML, 3900 "getText", 3901 0, 3902 getText, 3903 "innerText", 3904 0, 3905 innerText, 3906 "textContent", 3907 0, 3908 textContent 3909], 107100); 3910; 3911; 3912function getFeed(document) { 3913 const feedRoot = getOneElement(isValidFeed, document); 3914 return feedRoot ? feedRoot.name === "feed" ? getAtomFeed(feedRoot) : getRssFeed(feedRoot) : null; 3915} 3916/** 3917 * Parse an Atom feed. 3918 * 3919 * @param feedRoot The root of the feed. 3920 * @returns The parsed feed. 3921 */ function getAtomFeed(feedRoot) { 3922 const childs = feedRoot.children; 3923 const feed = { 3924 type: "atom", 3925 items: getElementsByTagName("entry", childs).map((item)=>{ 3926 const { children } = item; 3927 const entry = { 3928 media: getMediaElements(children) 3929 }; 3930 addConditionally(entry, "id", "id", children); 3931 addConditionally(entry, "title", "title", children); 3932 const href = getOneElement("link", children)?.attribs["href"]; 3933 if (href) { 3934 entry.link = href; 3935 } 3936 const description = fetch("summary", children) || fetch("content", children); 3937 if (description) { 3938 entry.description = description; 3939 } 3940 const pubDate = fetch("updated", children); 3941 if (pubDate) { 3942 entry.pubDate = new Date(pubDate); 3943 } 3944 return entry; 3945 }) 3946 }; 3947 addConditionally(feed, "id", "id", childs); 3948 addConditionally(feed, "title", "title", childs); 3949 const href = getOneElement("link", childs)?.attribs["href"]; 3950 if (href) { 3951 feed.link = href; 3952 } 3953 addConditionally(feed, "description", "subtitle", childs); 3954 const updated = fetch("updated", childs); 3955 if (updated) { 3956 feed.updated = new Date(updated); 3957 } 3958 addConditionally(feed, "author", "email", childs, true); 3959 return feed; 3960} 3961/** 3962 * Parse a RSS feed. 3963 * 3964 * @param feedRoot The root of the feed. 3965 * @returns The parsed feed. 3966 */ function getRssFeed(feedRoot) { 3967 const childs = getOneElement("channel", feedRoot.children)?.children ?? []; 3968 const feed = { 3969 type: feedRoot.name.substr(0, 3), 3970 id: "", 3971 items: getElementsByTagName("item", feedRoot.children).map((item)=>{ 3972 const { children } = item; 3973 const entry = { 3974 media: getMediaElements(children) 3975 }; 3976 addConditionally(entry, "id", "guid", children); 3977 addConditionally(entry, "title", "title", children); 3978 addConditionally(entry, "link", "link", children); 3979 addConditionally(entry, "description", "description", children); 3980 const pubDate = fetch("pubDate", children) || fetch("dc:date", children); 3981 if (pubDate) entry.pubDate = new Date(pubDate); 3982 return entry; 3983 }) 3984 }; 3985 addConditionally(feed, "title", "title", childs); 3986 addConditionally(feed, "link", "link", childs); 3987 addConditionally(feed, "description", "description", childs); 3988 const updated = fetch("lastBuildDate", childs); 3989 if (updated) { 3990 feed.updated = new Date(updated); 3991 } 3992 addConditionally(feed, "author", "managingEditor", childs, true); 3993 return feed; 3994} 3995const MEDIA_KEYS_STRING = [ 3996 "url", 3997 "type", 3998 "lang" 3999]; 4000const MEDIA_KEYS_INT = [ 4001 "fileSize", 4002 "bitrate", 4003 "framerate", 4004 "samplingrate", 4005 "channels", 4006 "duration", 4007 "height", 4008 "width" 4009]; 4010/** 4011 * Get all media elements of a feed item. 4012 * 4013 * @param where Nodes to search in. 4014 * @returns Media elements. 4015 */ function getMediaElements(where) { 4016 return getElementsByTagName("media:content", where).map((element)=>{ 4017 const { attribs } = element; 4018 const media = { 4019 medium: attribs["medium"], 4020 isDefault: !!attribs["isDefault"] 4021 }; 4022 for (const attrib of MEDIA_KEYS_STRING){ 4023 if (attribs[attrib]) { 4024 media[attrib] = attribs[attrib]; 4025 } 4026 } 4027 for (const attrib of MEDIA_KEYS_INT){ 4028 if (attribs[attrib]) { 4029 media[attrib] = Number.parseInt(attribs[attrib], 10); 4030 } 4031 } 4032 if (attribs["expression"]) { 4033 media.expression = attribs["expression"]; 4034 } 4035 return media; 4036 }); 4037} 4038/** 4039 * Get one element by tag name. 4040 * 4041 * @param tagName Tag name to look for 4042 * @param node Node to search in 4043 * @returns The element or null 4044 */ function getOneElement(tagName, node) {
4045 return getElementsByTagName(tagName, node, true, 1)[0]; 4046} 4047/** 4048 * Get the text content of an element with a certain tag name. 4049 * 4050 * @param tagName Tag name to look for. 4051 * @param where Node to search in. 4052 * @param recurse Whether to recurse into child nodes. 4053 * @returns The text content of the element. 4054 */ function fetch(tagName, where, recurse = false) { 4055 return textContent(getElementsByTagName(tagName, where, recurse, 1)).trim(); 4056} 4057/** 4058 * Adds a property to an object if it has a value. 4059 * 4060 * @param object Object to be extended. 4061 * @param property Property name. 4062 * @param tagName Tag name that contains the conditionally added property. 4063 * @param where Element to search for the property. 4064 * @param recurse Whether to recurse into child nodes. 4065 */ function addConditionally(object, property, tagName, where, recurse = false) { 4066 const value = fetch(tagName, where, recurse); 4067 if (value) object[property] = value; 4068} 4069/** 4070 * Checks if an element is a feed root node. 4071 * 4072 * @param value The name of the element to check. 4073 * @returns Whether an element is a feed root node. 4074 */ function isValidFeed(value) { 4075 return value === "rss" || value === "feed" || value === "rdf:RDF"; 4076} 4077__turbopack_context__.s([ 4078 "getFeed", 4079 0, 4080 getFeed 4081], 325137); 4082; 4083; 4084; 4085; 4086function parseDocument(data, options) { 4087 const handler = new DomHandler(undefined, options); 4088 new Parser(handler, options).end(data); 4089 return handler.root; 4090} 4091function createDocumentStream(callback, options, elementCallback) { 4092 const handler = new DomHandler((error)=>callback(error, handler.root), options, elementCallback); 4093 return new Parser(handler, options); 4094} 4095; 4096; 4097; 4098; 4099const parseFeedDefaultOptions = { 4100 xmlMode: true 4101}; 4102function parseFeed(feed, options = parseFeedDefaultOptions) { 4103 return getFeed(parseDocument(feed, options).children); 4104} 4105; 4106__turbopack_context__.s([ 4107 "createDocumentStream", 4108 0, 4109 createDocumentStream, 4110 "parseDocument", 4111 0, 4112 parseDocument, 4113 "parseFeed", 4114 0, 4115 parseFeed 4116], 177627); 4117var __TURBOPACK__imported__module__177627__ = __turbopack_context__.i(177627); 4118var __TURBOPACK__imported__module__546806__ = __turbopack_context__.i(546806); 4119// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/index.js [app-client] (ecmascript) 4120; 4121// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/index.js [app-client] (ecmascript) <locals> 4122; 4123; 4124; 4125; 4126; 4127; 4128; 4129; 4130__turbopack_context__.s([], 662614); 4131var __TURBOPACK__imported__module__662614__ = __turbopack_context__.i(662614); 4132var __TURBOPACK__imported__module__325137__ = __turbopack_context__.i(325137); 4133// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/helpers.js [app-client] (ecmascript) 4134; 4135; 4136function removeSubsets(nodes) { 4137 let index = nodes.length; 4138 /* 4139 * Check if each node (or one of its ancestors) is already contained in the 4140 * array. 4141 */ while(--index >= 0){ 4142 const node = nodes[index]; 4143 /* 4144 * Remove the node if it is not unique. 4145 * We are going through the array from the end, so we only 4146 * have to check nodes that preceed the node under consideration in the array. 4147 */ if (index > 0 && nodes.lastIndexOf(node, index - 1) >= 0) { 4148 nodes.splice(index, 1); 4149 continue; 4150 } 4151 for(let ancestor = node.parent; ancestor; ancestor = ancestor.parent){ 4152 if (nodes.includes(ancestor)) { 4153 nodes.splice(index, 1); 4154 break; 4155 } 4156 } 4157 } 4158 return nodes; 4159} 4160var DocumentPosition; 4161(function(DocumentPosition) { 4162 DocumentPosition[DocumentPosition["DISCONNECTED"] = 1] = "DISCONNECTED"; 4163 DocumentPosition[DocumentPosition["PRECEDING"] = 2] = "PRECEDING"; 4164 DocumentPosition[DocumentPosition["FOLLOWING"] = 4] = "FOLLOWING"; 4165 DocumentPosition[DocumentPosition["CONTAINS"] = 8] = "CONTAINS"; 4166 DocumentPosition[DocumentPosition["CONTAINED_BY"] = 16] = "CONTAINED_BY"; 4167})(DocumentPosition || (DocumentPosition = {})); 4168function compareDocumentPosition(nodeA, nodeB) { 4169 const aParents = []; 4170 const bParents = []; 4171 if (nodeA === nodeB) { 4172 return 0; 4173 }
4174 let current = hasChildren(nodeA) ? nodeA : nodeA.parent; 4175 while(current){ 4176 aParents.unshift(current); 4177 current = current.parent; 4178 } 4179 current = hasChildren(nodeB) ? nodeB : nodeB.parent; 4180 while(current){ 4181 bParents.unshift(current); 4182 current = current.parent; 4183 } 4184 const maxIndex = Math.min(aParents.length, bParents.length); 4185 let index = 0; 4186 while(index < maxIndex && aParents[index] === bParents[index]){ 4187 index++; 4188 } 4189 if (index === 0) { 4190 return DocumentPosition.DISCONNECTED; 4191 } 4192 const sharedParent = aParents[index - 1]; 4193 const siblings = sharedParent.children; 4194 const aSibling = aParents[index]; 4195 const bSibling = bParents[index]; 4196 if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) { 4197 if (sharedParent === nodeB) { 4198 return DocumentPosition.FOLLOWING | DocumentPosition.CONTAINED_BY; 4199 } 4200 return DocumentPosition.FOLLOWING; 4201 } 4202 if (sharedParent === nodeA) { 4203 return DocumentPosition.PRECEDING | DocumentPosition.CONTAINS; 4204 } 4205 return DocumentPosition.PRECEDING; 4206} 4207function uniqueSort(nodes) { 4208 nodes = nodes.filter((node, index, array)=>!array.includes(node, index + 1)); 4209 nodes.sort((a, b)=>{ 4210 const relative = compareDocumentPosition(a, b); 4211 if (relative & DocumentPosition.PRECEDING) { 4212 return -1; 4213 } 4214 if (relative & DocumentPosition.FOLLOWING) { 4215 return 1; 4216 } 4217 return 0; 4218 }); 4219 return nodes; 4220} 4221__turbopack_context__.s([ 4222 "DocumentPosition", 4223 0, 4224 DocumentPosition, 4225 "compareDocumentPosition", 4226 0, 4227 compareDocumentPosition, 4228 "removeSubsets", 4229 0, 4230 removeSubsets, 4231 "uniqueSort", 4232 0, 4233 uniqueSort 4234], 986053); 4235var __TURBOPACK__imported__module__986053__ = __turbopack_context__.i(986053); 4236var __TURBOPACK__imported__module__764451__ = __turbopack_context__.i(764451); 4237// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/manipulation.js [app-client] (ecmascript) 4238; 4239function removeElement(element) { 4240 if (element.prev) element.prev.next = element.next; 4241 if (element.next) element.next.prev = element.prev; 4242 if (element.parent) { 4243 const childs = element.parent.children; 4244 const childsIndex = childs.lastIndexOf(element); 4245 if (childsIndex !== -1) { 4246 childs.splice(childsIndex, 1); 4247 } 4248 } 4249 element.next = null; 4250 element.prev = null; 4251 element.parent = null; 4252} 4253function replaceElement(element, replacement) { 4254 replacement.prev = element.prev; 4255 if (replacement.prev) { 4256 replacement.prev.next = replacement; 4257 } 4258 replacement.next = element.next; 4259 if (replacement.next) { 4260 replacement.next.prev = replacement; 4261 } 4262 replacement.parent = element.parent; 4263 if (replacement.parent) { 4264 const { children } = replacement.parent; 4265 const elementIndex = children.lastIndexOf(element); 4266 if (elementIndex === -1) { 4267 return; 4268 } 4269 children[elementIndex] = replacement; 4270 element.parent = null; 4271 } 4272} 4273function appendChild(parent, child) { 4274 removeElement(child); 4275 child.next = null; 4276 child.parent = parent; 4277 if (parent.children.push(child) > 1) { 4278 const sibling = parent.children[parent.children.length - 2]; 4279 sibling.next = child; 4280 child.prev = sibling; 4281 } else { 4282 child.prev = null; 4283 } 4284} 4285function append(element, next) { 4286 removeElement(next); 4287 const { parent } = element; 4288 const currentNext = element.next; 4289 next.next = currentNext; 4290 next.prev = element; 4291 element.next = next; 4292 next.parent = parent; 4293 if (currentNext) { 4294 currentNext.prev = next; 4295 if (parent) { 4296 const childs = parent.children; 4297 childs.splice(childs.lastIndexOf(currentNext), 0, next); 4298 } 4299 } else if (parent) { 4300 parent.children.push(next); 4301 } 4302} 4303function prependChild(parent, child) { 4304 removeElement(child); 4305 child.parent = parent; 4306 child.prev = null; 4307 if (parent.children.unshift(child) === 1) { 4308 child.next = null; 4309 } else { 4310 const sibling = parent.children[1]; 4311 sibling.prev = child; 4312 child.next = sibling; 4313 } 4314} 4315function prepend(element, previous) { 4316 removeElement(previous); 4317 const { parent } = element; 4318 if (parent) { 4319 const childs = parent.children; 4320 childs.splice(childs.indexOf(element), 0, previous); 4321 } 4322 if (element.prev) { 4323 element.prev.next = previous; 4324 } 4325 previous.parent = parent; 4326 previous.prev = element.prev; 4327 previous.next = element; 4328 element.prev = previous; 4329} 4330__turbopack_context__.s([ 4331 "append", 4332 0, 4333 append, 4334 "appendChild", 4335 0, 4336 appendChild, 4337 "prepend", 4338 0, 4339 prepend, 4340 "prependChild", 4341 0, 4342 prependChild, 4343 "removeElement", 4344 0, 4345 removeElement, 4346 "replaceElement", 4347 0, 4348 replaceElement 4349], 849404); 4350var __TURBOPACK__imported__module__849404__ = __turbopack_context__.i(849404); 4351var __TURBOPACK__imported__module__890961__ = __turbopack_context__.i(890961); 4352var __TURBOPACK__imported__module__107100__ = __turbopack_context__.i(107100); 4353// MERGED MODULE: [project]/node_modules/sanitize-html/node_modules/domutils/dist/traversal.js [app-client] (ecmascript) 4354; 4355; 4356function getChildren(element) { 4357 return hasChildren(element) ? element.children : []; 4358} 4359function getParent(element) { 4360 return element.parent || null; 4361} 4362function getSiblings(element) { 4363 const parent = getParent(element); 4364 if (parent != null) return getChildren(parent); 4365 const siblings = [ 4366 element 4367 ]; 4368 let { prev, next } = element; 4369 while(prev != null){ 4370 siblings.unshift(prev); 4371 ({ prev } = prev); 4372 } 4373 while(next != null){ 4374 siblings.push(next); 4375 ({ next } = next); 4376 } 4377 return siblings; 4378} 4379function getAttributeValue(element, name) { 4380 const { attribs } = element; 4381 return attribs?.[name]; 4382} 4383function hasAttrib(element, name) { 4384 const { attribs } = element; 4385 return attribs != null && Object.hasOwn(attribs, name) && attribs[name] != null; 4386} 4387function getName(element) { 4388 return element.name; 4389} 4390function nextElementSibling(element) { 4391 let { next } = element; 4392 while(next !== null && !isTag1(next))({ next } = next); 4393 return next; 4394} 4395function prevElementSibling(element) { 4396 let { prev } = element; 4397 while(prev !== null && !isTag1(prev))({ prev } = prev); 4398 return prev; 4399} 4400__turbopack_context__.s([ 4401 "getAttributeValue", 4402 0, 4403 getAttributeValue, 4404 "getChildren", 4405 0, 4406 getChildren, 4407 "getName", 4408 0, 4409 getName, 4410 "getParent", 4411 0, 4412 getParent, 4413 "getSiblings", 4414 0, 4415 getSiblings, 4416 "hasAttrib", 4417 0, 4418 hasAttrib, 4419 "nextElementSibling", 4420 0, 4421 nextElementSibling, 4422 "prevElementSibling", 4423 0, 4424 prevElementSibling 4425], 143747); 4426var __TURBOPACK__imported__module__143747__ = __turbopack_context__.i(143747); 4427__turbopack_context__.s([ 4428 "DocumentPosition", 4429 0, 4430 DocumentPosition, 4431 "append", 4432 0, 4433 append, 4434 "appendChild", 4435 0, 4436 appendChild, 4437 "compareDocumentPosition", 4438 0, 4439 compareDocumentPosition, 4440 "existsOne", 4441 0, 4442 existsOne, 4443 "filter", 4444 0, 4445 filter, 4446 "find", 4447 0, 4448 find, 4449 "findAll", 4450 0, 4451 findAll, 4452 "findOne", 4453 0, 4454 findOne, 4455 "getAttributeValue", 4456 0, 4457 getAttributeValue, 4458 "getChildren", 4459 0, 4460 getChildren, 4461 "getElementById", 4462 0, 4463 getElementById, 4464 "getElements", 4465 0, 4466 getElements, 4467 "getElementsByClassName", 4468 0, 4469 getElementsByClassName, 4470 "getElementsByTagName", 4471 0, 4472 getElementsByTagName, 4473 "getElementsByTagType", 4474 0, 4475 getElementsByTagType, 4476 "getFeed", 4477 0, 4478 getFeed, 4479 "getInnerHTML", 4480 0, 4481 getInnerHTML, 4482 "getName", 4483 0, 4484 getName, 4485 "getOuterHTML", 4486 0, 4487 getOuterHTML, 4488 "getParent", 4489 0, 4490 getParent, 4491 "getSiblings", 4492 0, 4493 getSiblings, 4494 "getText", 4495 0, 4496 getText, 4497 "hasAttrib", 4498 0, 4499 hasAttrib, 4500 "innerText", 4501 0, 4502 innerText, 4503 "nextElementSibling", 4504 0, 4505 nextElementSibling, 4506 "prepend", 4507 0, 4508 prepend, 4509 "prependChild", 4510 0, 4511 prependChild, 4512 "prevElementSibling", 4513 0, 4514 prevElementSibling, 4515 "removeElement", 4516 0, 4517 removeElement, 4518 "removeSubsets", 4519 0, 4520 removeSubsets, 4521 "replaceElement", 4522 0, 4523 replaceElement, 4524 "testElement", 4525 0, 4526 testElement, 4527 "textContent", 4528 0, 4529 textContent, 4530 "uniqueSort", 4531 0, 4532 uniqueSort 4533], 834585); 4534var __TURBOPACK__imported__module__834585__ = __turbopack_context__.i(834585); 4535__turbopack_context__.s([ 4536 "DefaultHandler", 4537 0, 4538 DomHandler, 4539 "DomHandler", 4540 0, 4541 DomHandler, 4542 "DomUtils", 4543 0, 4544 __TURBOPACK__imported__module__834585__, 4545 "ElementType", 4546 0, 4547 __TURBOPACK__imported__module__546806__, 4548 "Parser", 4549 0, 4550 Parser, 4551 "QuoteType", 4552 0, 4553 QuoteType, 4554 "Tokenizer", 4555 ()=>Tokenizer, 4556 "createDocumentStream", 4557 0, 4558 createDocumentStream, 4559 "getFeed", 4560 0, 4561 getFeed, 4562 "parseDocument", 4563 0, 4564 parseDocument, 4565 "parseFeed", 4566 0, 4567 parseFeed 4568], 132109); 4569}),
457064873, ((__turbopack_context__, module, exports) => { 4571"use strict"; 4572 4573module.exports = (string)=>{ 4574 if (typeof string !== 'string') { 4575 throw new TypeError('Expected a string'); 4576 } 4577 // Escape characters with special meaning either inside or outside character sets. 4578 // Use a simple backslash escape when itâs always valid, and a \unnnn escape when the simpler form would be disallowed by Unicode patternsâ stricter grammar. 4579 return string.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d'); 4580}; 4581}), 4582875654, ((__turbopack_context__, module, exports) => { 4583"use strict"; 4584 4585Object.defineProperty(exports, '__esModule', { 4586 value: true 4587}); 4588/*! 4589 * is-plain-object <https://github.com/jonschlinkert/is-plain-object> 4590 * 4591 * Copyright (c) 2014-2017, Jon Schlinkert. 4592 * Released under the MIT License. 4593 */ function isObject(o) { 4594 return Object.prototype.toString.call(o) === '[object Object]'; 4595} 4596function isPlainObject(o) { 4597 var ctor, prot; 4598 if (isObject(o) === false) return false; 4599 // If has modified constructor 4600 ctor = o.constructor; 4601 if (ctor === undefined) return true; 4602 // If has modified prototype 4603 prot = ctor.prototype; 4604 if (isObject(prot) === false) return false; 4605 // If constructor does not have an Object-specific method 4606 if (prot.hasOwnProperty('isPrototypeOf') === false) { 4607 return false; 4608 } 4609 // Most likely a plain Object 4610 return true; 4611} 4612exports.isPlainObject = isPlainObject; 4613}), 4614130860, ((__turbopack_context__, module, exports) => { 4615"use strict"; 4616 4617var isMergeableObject = function isMergeableObject(value) { 4618 return isNonNullObject(value) && !isSpecial(value); 4619}; 4620function isNonNullObject(value) { 4621 return !!value && typeof value === 'object'; 4622} 4623function isSpecial(value) { 4624 var stringValue = Object.prototype.toString.call(value); 4625 return stringValue === '[object RegExp]' || stringValue === '[object Date]' || isReactElement(value); 4626} 4627// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25 4628var canUseSymbol = typeof Symbol === 'function' && Symbol.for; 4629var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7; 4630function isReactElement(value) { 4631 return value.$$typeof === REACT_ELEMENT_TYPE; 4632} 4633function emptyTarget(val) { 4634 return Array.isArray(val) ? [] : {}; 4635} 4636function cloneUnlessOtherwiseSpecified(value, options) { 4637 return options.clone !== false && options.isMergeableObject(value) ? deepmerge(emptyTarget(value), value, options) : value; 4638} 4639function defaultArrayMerge(target, source, options) { 4640 return target.concat(source).map(function(element) { 4641 return cloneUnlessOtherwiseSpecified(element, options); 4642 }); 4643} 4644function getMergeFunction(key, options) { 4645 if (!options.customMerge) { 4646 return deepmerge; 4647 } 4648 var customMerge = options.customMerge(key); 4649 return typeof customMerge === 'function' ? customMerge : deepmerge; 4650} 4651function getEnumerableOwnPropertySymbols(target) { 4652 return Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(target).filter(function(symbol) { 4653 return Object.propertyIsEnumerable.call(target, symbol); 4654 }) : []; 4655} 4656function getKeys(target) { 4657 return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)); 4658} 4659function propertyIsOnObject(object, property) { 4660 try { 4661 return property in object; 4662 } catch (_) { 4663 return false; 4664 } 4665} 4666// Protects from prototype poisoning and unexpected merging up the prototype chain. 4667function propertyIsUnsafe(target, key) { 4668 return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet, 4669 && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain, 4670 && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable. 4671 ; 4672} 4673function mergeObject(target, source, options) { 4674 var destination = {}; 4675 if (options.isMergeableObject(target)) { 4676 getKeys(target).forEach(function(key) { 4677 destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); 4678 }); 4679 } 4680 getKeys(source).forEach(function(key) { 4681 if (propertyIsUnsafe(target, key)) { 4682 return; 4683 } 4684 if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) { 4685 destination[key] = getMergeFunction(key, options)(target[key], source[key], options); 4686 } else { 4687 destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); 4688 } 4689 }); 4690 return destination; 4691} 4692function deepmerge(target, source, options) { 4693 options = options || {}; 4694 options.arrayMerge = options.arrayMerge || defaultArrayMerge; 4695 options.isMergeableObject = options.isMergeableObject || isMergeableObject; 4696 // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() 4697 // implementations can use it. The caller may not replace it. 4698 options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; 4699 var sourceIsArray = Array.isArray(source); 4700 var targetIsArray = Array.isArray(target); 4701 var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; 4702 if (!sourceAndTargetTypesMatch) { 4703 return cloneUnlessOtherwiseSpecified(source, options); 4704 } else if (sourceIsArray) { 4705 return options.arrayMerge(target, source, options); 4706 } else { 4707 return mergeObject(target, source, options); 4708 } 4709} 4710deepmerge.all = function deepmergeAll(array, options) { 4711 if (!Array.isArray(array)) { 4712 throw new Error('first argument should be an array'); 4713 } 4714 return array.reduce(function(prev, next) { 4715 return deepmerge(prev, next, options); 4716 }, {}); 4717}; 4718var deepmerge_1 = deepmerge; 4719module.exports = deepmerge_1; 4720}),
4721661840, ((__turbopack_context__, module, exports) => { 4722 4723/** 4724 * Srcset Parser 4725 * 4726 * By Alex Bell | MIT License 4727 * 4728 * JS Parser for the string value that appears in markup <img srcset="here"> 4729 * 4730 * @returns Array [{url: _, d: _, w: _, h:_}, ...] 4731 * 4732 * Based super duper closely on the reference algorithm at: 4733 * https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute 4734 * 4735 * Most comments are copied in directly from the spec 4736 * (except for comments in parens). 4737 */ (function(root, factory) { 4738 if (typeof define === 'function' && define.amd) { 4739 // AMD. Register as an anonymous module. 4740 ((r)=>r !== undefined && __turbopack_context__.v(r))(factory()); 4741 } else if (("TURBOPACK compile-time value", "object") === 'object' && module.exports) { 4742 // Node. Does not work with strict CommonJS, but 4743 // only CommonJS-like environments that support module.exports, 4744 // like Node. 4745 module.exports = factory(); 4746 } else { 4747 // Browser globals (root is window) 4748 root.parseSrcset = factory(); 4749 } 4750})(/*TURBOPACK member replacement*/ __turbopack_context__.e, function() { 4751 // 1. Let input be the value passed to this algorithm. 4752 return function(input) { 4753 // UTILITY FUNCTIONS 4754 // Manual is faster than RegEx 4755 // http://bjorn.tipling.com/state-and-regular-expressions-in-javascript 4756 // http://jsperf.com/whitespace-character/5 4757 function isSpace(c) { 4758 return c === "\u0020" || // space 4759 c === "\u0009" || // horizontal tab 4760 c === "\u000A" || // new line 4761 c === "\u000C" || // form feed 4762 c === "\u000D"; // carriage return 4763 } 4764 function collectCharacters(regEx) { 4765 var chars, match = regEx.exec(input.substring(pos)); 4766 if (match) { 4767 chars = match[0]; 4768 pos += chars.length; 4769 return chars; 4770 } 4771 } 4772 var inputLength = input.length, // (Don't use \s, to avoid matching non-breaking space) 4773 regexLeadingSpaces = /^[ \t\n\r\u000c]+/, regexLeadingCommasOrSpaces = /^[, \t\n\r\u000c]+/, regexLeadingNotSpaces = /^[^ \t\n\r\u000c]+/, regexTrailingCommas = /[,]+$/, regexNonNegativeInteger = /^\d+$/, // ( Positive or negative or unsigned integers or decimals, without or without exponents. 4774 // Must include at least one digit. 4775 // According to spec tests any decimal point must be followed by a digit. 4776 // No leading plus sign is allowed.) 4777 // https://html.spec.whatwg.org/multipage/infrastructure.html#valid-floating-point-number 4778 regexFloatingPoint = /^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/, url, descriptors, currentDescriptor, state, c, // 2. Let position be a pointer into input, initially pointing at the start 4779 // of the string. 4780 pos = 0, // 3. Let candidates be an initially empty source set. 4781 candidates = []; 4782 // 4. Splitting loop: Collect a sequence of characters that are space 4783 // characters or U+002C COMMA characters. If any U+002C COMMA characters 4784 // were collected, that is a parse error. 4785 while(true){ 4786 collectCharacters(regexLeadingCommasOrSpaces); 4787 // 5. If position is past the end of input, return candidates and abort these steps. 4788 if (pos >= inputLength) { 4789 return candidates; // (we're done, this is the sole return path) 4790 } 4791 // 6. Collect a sequence of characters that are not space characters, 4792 // and let that be url. 4793 url = collectCharacters(regexLeadingNotSpaces); 4794 // 7. Let descriptors be a new empty list. 4795 descriptors = []; 4796 // 8. If url ends with a U+002C COMMA character (,), follow these substeps: 4797 // (1). Remove all trailing U+002C COMMA characters from url. If this removed 4798 // more than one character, that is a parse error. 4799 if (url.slice(-1) === ",") { 4800 url = url.replace(regexTrailingCommas, ""); 4801 // (Jump ahead to step 9 to skip tokenization and just push the candidate). 4802 parseDescriptors(); 4803 // Otherwise, follow these substeps: 4804 } else { 4805 tokenize(); 4806 } // (close else of step 8) 4807 // 16. Return to the step labeled splitting loop. 4808 } // (Close of big while loop.) 4809 /** 4810 * Tokenizes descriptor properties prior to parsing 4811 * Returns undefined. 4812 */ function tokenize() { 4813 // 8.1. Descriptor tokeniser: Skip whitespace 4814 collectCharacters(regexLeadingSpaces); 4815 // 8.2. Let current descriptor be the empty string. 4816 currentDescriptor = ""; 4817 // 8.3. Let state be in descriptor. 4818 state = "in descriptor"; 4819 while(true){ 4820 // 8.4. Let c be the character at position. 4821 c = input.charAt(pos); 4822 // Do the following depending on the value of state. 4823 // For the purpose of this step, "EOF" is a special character representing 4824 // that position is past the end of input. 4825 // In descriptor 4826 if (state === "in descriptor") { 4827 // Do the following, depending on the value of c: 4828 // Space character 4829 // If current descriptor is not empty, append current descriptor to 4830 // descriptors and let current descriptor be the empty string. 4831 // Set state to after descriptor. 4832 if (isSpace(c)) { 4833 if (currentDescriptor) { 4834 descriptors.push(currentDescriptor); 4835 currentDescriptor = ""; 4836 state = "after descriptor"; 4837 } 4838 // U+002C COMMA (,) 4839 // Advance position to the next character in input. If current descriptor 4840 // is not empty, append current descriptor to descriptors. Jump to the step 4841 // labeled descriptor parser. 4842 } else if (c === ",") { 4843 pos += 1; 4844 if (currentDescriptor) { 4845 descriptors.push(currentDescriptor); 4846 } 4847 parseDescriptors(); 4848 return; 4849 // U+0028 LEFT PARENTHESIS (() 4850 // Append c to current descriptor. Set state to in parens. 4851 } else if (c === "\u0028") { 4852 currentDescriptor = currentDescriptor + c; 4853 state = "in parens"; 4854 // EOF 4855 // If current descriptor is not empty, append current descriptor to 4856 // descriptors. Jump to the step labeled descriptor parser. 4857 } else if (c === "") { 4858 if (currentDescriptor) { 4859 descriptors.push(currentDescriptor); 4860 } 4861 parseDescriptors(); 4862 return; 4863 // Anything else 4864 // Append c to current descriptor. 4865 } else { 4866 currentDescriptor = currentDescriptor + c; 4867 } 4868 // (end "in descriptor" 4869 // In parens 4870 } else if (state === "in parens") { 4871 // U+0029 RIGHT PARENTHESIS ()) 4872 // Append c to current descriptor. Set state to in descriptor. 4873 if (c === ")") { 4874 currentDescriptor = currentDescriptor + c; 4875 state = "in descriptor"; 4876 // EOF 4877 // Append current descriptor to descriptors. Jump to the step labeled 4878 // descriptor parser. 4879 } else if (c === "") { 4880 descriptors.push(currentDescriptor); 4881 parseDescriptors(); 4882 return; 4883 // Anything else 4884 // Append c to current descriptor. 4885 } else { 4886 currentDescriptor = currentDescriptor + c; 4887 } 4888 // After descriptor 4889 } else if (state === "after descriptor") { 4890 // Do the following, depending on the value of c: 4891 // Space character: Stay in this state. 4892 if (isSpace(c)) { 4893 // EOF: Jump to the step labeled descriptor parser. 4894 } else if (c === "") { 4895 parseDescriptors(); 4896 return; 4897 // Anything else 4898 // Set state to in descriptor. Set position to the previous character in input. 4899 } else { 4900 state = "in descriptor"; 4901 pos -= 1; 4902 } 4903 } 4904 // Advance position to the next character in input. 4905 pos += 1; 4906 // Repeat this step. 4907 } // (close while true loop) 4908 } 4909 /** 4910 * Adds descriptor properties to a candidate, pushes to the candidates array 4911 * @return undefined 4912 */ // Declared outside of the while loop so that it's only created once. 4913 function parseDescriptors() { 4914 // 9. Descriptor parser: Let error be no. 4915 var pError = false, // 10. Let width be absent. 4916 // 11. Let density be absent. 4917 // 12. Let future-compat-h be absent. (We're implementing it now as h) 4918 w, d, h, i, candidate = {}, desc, lastChar, value, intVal, floatVal; 4919 // 13. For each descriptor in descriptors, run the appropriate set of steps 4920 // from the following list: 4921 for(i = 0; i < descriptors.length; i++){ 4922 desc = descriptors[i]; 4923 lastChar = desc[desc.length - 1]; 4924 value = desc.substring(0, desc.length - 1); 4925 intVal = parseInt(value, 10); 4926 floatVal = parseFloat(value); 4927 // If the descriptor consists of a valid non-negative integer followed by 4928 // a U+0077 LATIN SMALL LETTER W character 4929 if (regexNonNegativeInteger.test(value) && lastChar === "w") { 4930 // If width and density are not both absent, then let error be yes. 4931 if (w || d) { 4932 pError = true; 4933 } 4934 // Apply the rules for parsing non-negative integers to the descriptor. 4935 // If the result is zero, let error be yes. 4936 // Otherwise, let width be the result. 4937 if (intVal === 0) { 4938 pError = true; 4939 } else { 4940 w = intVal; 4941 } 4942 // If the descriptor consists of a valid floating-point number followed by 4943 // a U+0078 LATIN SMALL LETTER X character 4944 } else if (regexFloatingPoint.test(value) && lastChar === "x") { 4945 // If width, density and future-compat-h are not all absent, then let error 4946 // be yes. 4947 if (w || d || h) { 4948 pError = true; 4949 } 4950 // Apply the rules for parsing floating-point number values to the descriptor. 4951 // If the result is less than zero, let error be yes. Otherwise, let density 4952 // be the result. 4953 if (floatVal < 0) { 4954 pError = true; 4955 } else { 4956 d = floatVal; 4957 } 4958 // If the descriptor consists of a valid non-negative integer followed by 4959 // a U+0068 LATIN SMALL LETTER H character 4960 } else if (regexNonNegativeInteger.test(value) && lastChar === "h") { 4961 // If height and density are not both absent, then let error be yes. 4962 if (h || d) { 4963 pError = true; 4964 } 4965 // Apply the rules for parsing non-negative integers to the descriptor. 4966 // If the result is zero, let error be yes. Otherwise, let future-compat-h 4967 // be the result. 4968 if (intVal === 0) { 4969 pError = true; 4970 } else { 4971 h = intVal; 4972 } 4973 // Anything else, Let error be yes. 4974 } else { 4975 pError = true; 4976 } 4977 } // (close step 13 for loop) 4978 // 15. If error is still no, then append a new image source to candidates whose 4979 // URL is url, associated with a width width if not absent and a pixel 4980 // density density if not absent. Otherwise, there is a parse error. 4981 if (!pError) { 4982 candidate.url = url; 4983 if (w) { 4984 candidate.w = w; 4985 } 4986 if (d) { 4987 candidate.d = d; 4988 } 4989 if (h) { 4990 candidate.h = h; 4991 } 4992 candidates.push(candidate); 4993 } else if (console && console.log) { 4994 console.log("Invalid srcset descriptor found in '" + input + "' at '" + desc + "'."); 4995 } 4996 } // (close parseDescriptors fn) 4997 }; 4998}); 4999}),
vendor: 4,627 bytes, lines 5000-5142
5000305526, ((__turbopack_context__, module, exports) => { 5001 5002var x = String; 5003var create = function() { 5004 return { 5005 isColorSupported: false, 5006 reset: x, 5007 bold: x, 5008 dim: x, 5009 italic: x, 5010 underline: x, 5011 inverse: x, 5012 hidden: x, 5013 strikethrough: x, 5014 black: x, 5015 red: x, 5016 green: x, 5017 yellow: x, 5018 blue: x, 5019 magenta: x, 5020 cyan: x, 5021 white: x, 5022 gray: x, 5023 bgBlack: x, 5024 bgRed: x, 5025 bgGreen: x, 5026 bgYellow: x, 5027 bgBlue: x, 5028 bgMagenta: x, 5029 bgCyan: x, 5030 bgWhite: x, 5031 blackBright: x, 5032 redBright: x, 5033 greenBright: x, 5034 yellowBright: x, 5035 blueBright: x, 5036 magentaBright: x, 5037 cyanBright: x, 5038 whiteBright: x, 5039 bgBlackBright: x, 5040 bgRedBright: x, 5041 bgGreenBright: x, 5042 bgYellowBright: x, 5043 bgBlueBright: x, 5044 bgMagentaBright: x, 5045 bgCyanBright: x, 5046 bgWhiteBright: x 5047 }; 5048}; 5049module.exports = create(); 5050module.exports.createColors = create; 5051}), 505271528, ((__turbopack_context__, module, exports) => { 5053"use strict"; 5054 5055let pico = __turbopack_context__.r(305526); 5056let terminalHighlight = {}; 5057class CssSyntaxError extends Error { 5058 constructor(message, line, column, source, file, plugin){ 5059 super(message); 5060 this.name = 'CssSyntaxError'; 5061 this.reason = message; 5062 if (file) { 5063 this.file = file; 5064 } 5065 if (source) { 5066 this.source = source; 5067 } 5068 if (plugin) { 5069 this.plugin = plugin; 5070 } 5071 if (typeof line !== 'undefined' && typeof column !== 'undefined') { 5072 if (typeof line === 'number') { 5073 this.line = line; 5074 this.column = column; 5075 } else { 5076 this.line = line.line; 5077 this.column = line.column; 5078 this.endLine = column.line; 5079 this.endColumn = column.column; 5080 } 5081 } 5082 this.setMessage(); 5083 if (Error.captureStackTrace) { 5084 Error.captureStackTrace(this, CssSyntaxError); 5085 } 5086 } 5087 setMessage() { 5088 this.message = this.plugin ? this.plugin + ': ' : ''; 5089 this.message += this.file ? this.file : '<css input>'; 5090 if (typeof this.line !== 'undefined') { 5091 this.message += ':' + this.line + ':' + this.column; 5092 } 5093 this.message += ': ' + this.reason; 5094 } 5095 showSourceCode(color) { 5096 if (!this.source) return ''; 5097 let css = this.source; 5098 if (color == null) color = pico.isColorSupported; 5099 let aside = (text)=>text; 5100 let mark = (text)=>text; 5101 let highlight = (text)=>text; 5102 if (color) { 5103 let { bold, gray, red } = pico.createColors(true); 5104 mark = (text)=>bold(red(text)); 5105 aside = (text)=>gray(text); 5106 if (terminalHighlight) { 5107 highlight = (text)=>terminalHighlight(text); 5108 } 5109 } 5110 let lines = css.split(/\r?\n/); 5111 let start = Math.max(this.line - 3, 0); 5112 let end = Math.min(this.line + 2, lines.length); 5113 let maxWidth = String(end).length; 5114 return lines.slice(start, end).map((line, index)=>{ 5115 let number = start + 1 + index; 5116 let gutter = ' ' + (' ' + number).slice(-maxWidth) + ' | '; 5117 if (number === this.line) { 5118 if (line.length > 160) { 5119 let padding = 20; 5120 let subLineStart = Math.max(0, this.column - padding); 5121 let subLineEnd = Math.max(this.column + padding, this.endColumn + padding); 5122 let subLine = line.slice(subLineStart, subLineEnd); 5123 let spacing = aside(gutter.replace(/\d/g, ' ')) + line.slice(0, Math.min(this.column - 1, padding - 1)).replace(/[^\t]/g, ' '); 5124 return mark('>') + aside(gutter) + highlight(subLine) + '\n ' + spacing + mark('^'); 5125 } 5126 let spacing = aside(gutter.replace(/\d/g, ' ')) + line.slice(0, this.column - 1).replace(/[^\t]/g, ' '); 5127 return mark('>') + aside(gutter) + highlight(line) + '\n ' + spacing + mark('^'); 5128 } 5129 return ' ' + aside(gutter) + highlight(line); 5130 }).join('\n'); 5131 } 5132 toString() { 5133 let code = this.showSourceCode(); 5134 if (code) { 5135 code = '\n\n' + code + '\n'; 5136 } 5137 return this.name + ': ' + this.message + code; 5138 } 5139} 5140module.exports = CssSyntaxError; 5141CssSyntaxError.default = CssSyntaxError; 5142}),
5143981864, ((__turbopack_context__, module, exports) => { 5144"use strict"; 5145 5146// Escapes sequences that could break out of an HTML <style> context. 5147// Uses CSS unicode escaping (\3c = '<') which is valid CSS and parsed 5148// correctly by all compliant CSS consumers. 5149const STYLE_TAG = /(<)(\/?style\b)/gi; 5150const COMMENT_OPEN = /(<)(!--)/g; 5151function escapeHTMLInCSS(str) { 5152 if (typeof str !== 'string') return str; 5153 if (!str.includes('<')) return str; 5154 return str.replace(STYLE_TAG, '\\3c $2').replace(COMMENT_OPEN, '\\3c $2'); 5155} 5156const DEFAULT_RAW = { 5157 after: '\n', 5158 beforeClose: '\n', 5159 beforeComment: '\n', 5160 beforeDecl: '\n', 5161 beforeOpen: ' ', 5162 beforeRule: '\n', 5163 colon: ': ', 5164 commentLeft: ' ', 5165 commentRight: ' ', 5166 emptyBody: '', 5167 indent: ' ', 5168 semicolon: false 5169}; 5170function capitalize(str) { 5171 return str[0].toUpperCase() + str.slice(1); 5172} 5173class Stringifier { 5174 constructor(builder){ 5175 this.builder = builder; 5176 } 5177 atrule(node, semicolon) { 5178 let name = '@' + node.name; 5179 let params = node.params ? this.rawValue(node, 'params') : ''; 5180 if (typeof node.raws.afterName !== 'undefined') { 5181 name += node.raws.afterName; 5182 } else if (params) { 5183 name += ' '; 5184 } 5185 if (node.nodes) { 5186 this.block(node, name + params); 5187 } else { 5188 let end = (node.raws.between || '') + (semicolon ? ';' : ''); 5189 this.builder(escapeHTMLInCSS(name + params + end), node); 5190 } 5191 } 5192 beforeAfter(node, detect) { 5193 let value; 5194 if (node.type === 'decl') { 5195 value = this.raw(node, null, 'beforeDecl'); 5196 } else if (node.type === 'comment') { 5197 value = this.raw(node, null, 'beforeComment'); 5198 } else if (detect === 'before') { 5199 value = this.raw(node, null, 'beforeRule'); 5200 } else { 5201 value = this.raw(node, null, 'beforeClose'); 5202 } 5203 let buf = node.parent; 5204 let depth = 0; 5205 while(buf && buf.type !== 'root'){ 5206 depth += 1; 5207 buf = buf.parent; 5208 } 5209 if (value.includes('\n')) { 5210 let indent = this.raw(node, null, 'indent'); 5211 if (indent.length) { 5212 for(let step = 0; step < depth; step++)value += indent; 5213 } 5214 } 5215 return value; 5216 } 5217 block(node, start) { 5218 let between = this.raw(node, 'between', 'beforeOpen'); 5219 this.builder(escapeHTMLInCSS(start + between) + '{', node, 'start'); 5220 let after; 5221 if (node.nodes && node.nodes.length) { 5222 this.body(node); 5223 after = this.raw(node, 'after'); 5224 } else { 5225 after = this.raw(node, 'after', 'emptyBody'); 5226 } 5227 if (after) this.builder(escapeHTMLInCSS(after)); 5228 this.builder('}', node, 'end'); 5229 } 5230 body(node) { 5231 let last = node.nodes.length - 1; 5232 while(last > 0){ 5233 if (node.nodes[last].type !== 'comment') break; 5234 last -= 1; 5235 } 5236 let semicolon = this.raw(node, 'semicolon'); 5237 let isDocument = node.type === 'document'; 5238 for(let i = 0; i < node.nodes.length; i++){ 5239 let child = node.nodes[i]; 5240 let before = this.raw(child, 'before'); 5241 if (before) this.builder(isDocument ? before : escapeHTMLInCSS(before)); 5242 this.stringify(child, last !== i || semicolon); 5243 } 5244 } 5245 comment(node) { 5246 let left = this.raw(node, 'left', 'commentLeft'); 5247 let right = this.raw(node, 'right', 'commentRight'); 5248 this.builder(escapeHTMLInCSS('/*' + left + node.text + right + '*/'), node); 5249 } 5250 decl(node, semicolon) { 5251 let between = this.raw(node, 'between', 'colon'); 5252 let string = node.prop + between + this.rawValue(node, 'value'); 5253 if (node.important) { 5254 string += node.raws.important || ' !important'; 5255 } 5256 if (semicolon) string += ';'; 5257 this.builder(escapeHTMLInCSS(string), node); 5258 } 5259 document(node) { 5260 this.body(node); 5261 } 5262 raw(node, own, detect) { 5263 let value; 5264 if (!detect) detect = own; 5265 // Already had 5266 if (own) { 5267 value = node.raws[own]; 5268 if (typeof value !== 'undefined') return value; 5269 } 5270 let parent = node.parent; 5271 if (detect === 'before') { 5272 // Hack for first rule in CSS 5273 if (!parent || parent.type === 'root' && parent.first === node) { 5274 return ''; 5275 } 5276 // `root` nodes in `document` should use only their own raws 5277 if (parent && parent.type === 'document') { 5278 return ''; 5279 } 5280 } 5281 // Floating child without parent 5282 if (!parent) return DEFAULT_RAW[detect]; 5283 // Detect style by other nodes
vendor: 4,271 bytes, lines 5284-5414
5284 let root = node.root(); 5285 if (!root.rawCache) root.rawCache = {}; 5286 if (typeof root.rawCache[detect] !== 'undefined') { 5287 return root.rawCache[detect]; 5288 } 5289 if (detect === 'before' || detect === 'after') { 5290 return this.beforeAfter(node, detect); 5291 } else { 5292 let method = 'raw' + capitalize(detect); 5293 if (this[method]) { 5294 value = this[method](root, node); 5295 } else { 5296 root.walk((i)=>{ 5297 value = i.raws[own]; 5298 if (typeof value !== 'undefined') return false; 5299 }); 5300 } 5301 } 5302 if (typeof value === 'undefined') value = DEFAULT_RAW[detect]; 5303 root.rawCache[detect] = value; 5304 return value; 5305 } 5306 rawBeforeClose(root) { 5307 let value; 5308 root.walk((i)=>{ 5309 if (i.nodes && i.nodes.length > 0) { 5310 if (typeof i.raws.after !== 'undefined') { 5311 value = i.raws.after; 5312 if (value.includes('\n')) { 5313 value = value.replace(/[^\n]+$/, ''); 5314 } 5315 return false; 5316 } 5317 } 5318 }); 5319 if (value) value = value.replace(/\S/g, ''); 5320 return value; 5321 } 5322 rawBeforeComment(root, node) { 5323 let value; 5324 root.walkComments((i)=>{ 5325 if (typeof i.raws.before !== 'undefined') { 5326 value = i.raws.before; 5327 if (value.includes('\n')) { 5328 value = value.replace(/[^\n]+$/, ''); 5329 } 5330 return false; 5331 } 5332 }); 5333 if (typeof value === 'undefined') { 5334 value = this.raw(node, null, 'beforeDecl'); 5335 } else if (value) { 5336 value = value.replace(/\S/g, ''); 5337 } 5338 return value; 5339 } 5340 rawBeforeDecl(root, node) { 5341 let value; 5342 root.walkDecls((i)=>{ 5343 if (typeof i.raws.before !== 'undefined') { 5344 value = i.raws.before; 5345 if (value.includes('\n')) { 5346 value = value.replace(/[^\n]+$/, ''); 5347 } 5348 return false; 5349 } 5350 }); 5351 if (typeof value === 'undefined') { 5352 value = this.raw(node, null, 'beforeRule'); 5353 } else if (value) { 5354 value = value.replace(/\S/g, ''); 5355 } 5356 return value; 5357 } 5358 rawBeforeOpen(root) { 5359 let value; 5360 root.walk((i)=>{ 5361 if (i.type !== 'decl') { 5362 value = i.raws.between; 5363 if (typeof value !== 'undefined') return false; 5364 } 5365 }); 5366 return value; 5367 } 5368 rawBeforeRule(root) { 5369 let value; 5370 root.walk((i)=>{ 5371 if (i.nodes && (i.parent !== root || root.first !== i)) { 5372 if (typeof i.raws.before !== 'undefined') { 5373 value = i.raws.before; 5374 if (value.includes('\n')) { 5375 value = value.replace(/[^\n]+$/, ''); 5376 } 5377 return false; 5378 } 5379 } 5380 }); 5381 if (value) value = value.replace(/\S/g, ''); 5382 return value; 5383 } 5384 rawColon(root) { 5385 let value; 5386 root.walkDecls((i)=>{ 5387 if (typeof i.raws.between !== 'undefined') { 5388 value = i.raws.between.replace(/[^\s:]/g, ''); 5389 return false; 5390 } 5391 }); 5392 return value; 5393 } 5394 rawEmptyBody(root) { 5395 let value; 5396 root.walk((i)=>{ 5397 if (i.nodes && i.nodes.length === 0) { 5398 value = i.raws.after; 5399 if (typeof value !== 'undefined') return false; 5400 } 5401 }); 5402 return value; 5403 } 5404 rawIndent(root) { 5405 if (root.raws.indent) return root.raws.indent; 5406 let value; 5407 root.walk((i)=>{ 5408 let p = i.parent; 5409 if (p && p !== root && p.parent && p.parent === root) { 5410 if (typeof i.raws.before !== 'undefined') { 5411 let parts = i.raws.before.split('\n'); 5412 value = parts[parts.length - 1]; 5413 value = value.replace(/\S/g, ''); 5414 return false;
5415 } 5416 } 5417 }); 5418 return value; 5419 } 5420 rawSemicolon(root) { 5421 let value; 5422 root.walk((i)=>{ 5423 if (i.nodes && i.nodes.length && i.last.type === 'decl') { 5424 value = i.raws.semicolon; 5425 if (typeof value !== 'undefined') return false; 5426 } 5427 }); 5428 return value; 5429 } 5430 rawValue(node, prop) { 5431 let value = node[prop]; 5432 let raw = node.raws[prop]; 5433 if (raw && raw.value === value) { 5434 return raw.raw; 5435 } 5436 return value; 5437 } 5438 root(node) { 5439 this.body(node); 5440 if (node.raws.after) { 5441 let after = node.raws.after; 5442 let isDocument = node.parent && node.parent.type === 'document'; 5443 this.builder(isDocument ? after : escapeHTMLInCSS(after)); 5444 } 5445 } 5446 rule(node) { 5447 this.block(node, this.rawValue(node, 'selector')); 5448 if (node.raws.ownSemicolon) { 5449 this.builder(escapeHTMLInCSS(node.raws.ownSemicolon), node, 'end'); 5450 } 5451 } 5452 stringify(node, semicolon) { 5453 /* c8 ignore start */ if (!this[node.type]) { 5454 throw new Error('Unknown AST node type ' + node.type + '. ' + 'Maybe you need to change PostCSS stringifier.'); 5455 } 5456 /* c8 ignore stop */ this[node.type](node, semicolon); 5457 } 5458} 5459module.exports = Stringifier; 5460Stringifier.default = Stringifier; 5461}), 5462140293, ((__turbopack_context__, module, exports) => { 5463"use strict"; 5464 5465let Stringifier = __turbopack_context__.r(981864); 5466function stringify(node, builder) { 5467 let str = new Stringifier(builder); 5468 str.stringify(node); 5469} 5470module.exports = stringify; 5471stringify.default = stringify; 5472}), 5473322302, ((__turbopack_context__, module, exports) => { 5474"use strict"; 5475 5476module.exports.isClean = Symbol('isClean'); 5477module.exports.my = Symbol('my'); 5478}), 5479657612, ((__turbopack_context__, module, exports) => { 5480"use strict"; 5481 5482let CssSyntaxError = __turbopack_context__.r(71528); 5483let Stringifier = __turbopack_context__.r(981864); 5484let stringify = __turbopack_context__.r(140293); 5485let { isClean, my } = __turbopack_context__.r(322302); 5486function cloneNode(obj, parent) { 5487 let cloned = new obj.constructor(); 5488 for(let i in obj){ 5489 if (!Object.prototype.hasOwnProperty.call(obj, i)) { 5490 continue; 5491 } 5492 if (i === 'proxyCache') continue; 5493 let value = obj[i]; 5494 let type = typeof value; 5495 if (i === 'parent' && type === 'object') { 5496 if (parent) cloned[i] = parent; 5497 } else if (i === 'source') { 5498 cloned[i] = value; 5499 } else if (Array.isArray(value)) { 5500 cloned[i] = value.map((j)=>cloneNode(j, cloned)); 5501 } else { 5502 if (type === 'object' && value !== null) value = cloneNode(value); 5503 cloned[i] = value; 5504 } 5505 } 5506 return cloned; 5507} 5508function sourceOffset(inputCSS, position) { 5509 // Not all custom syntaxes support `offset` in `source.start` and `source.end` 5510 if (position && typeof position.offset !== 'undefined') { 5511 return position.offset; 5512 } 5513 let column = 1; 5514 let line = 1; 5515 let offset = 0; 5516 for(let i = 0; i < inputCSS.length; i++){ 5517 if (line === position.line && column === position.column) { 5518 offset = i; 5519 break; 5520 } 5521 if (inputCSS[i] === '\n') { 5522 column = 1; 5523 line += 1; 5524 } else { 5525 column += 1; 5526 } 5527 } 5528 return offset; 5529} 5530class Node { 5531 get proxyOf() { 5532 return this; 5533 } 5534 constructor(defaults = {}){ 5535 this.raws = {}; 5536 this[isClean] = false; 5537 this[my] = true; 5538 for(let name in defaults){ 5539 if (name === 'nodes') { 5540 this.nodes = []; 5541 for (let node of defaults[name]){ 5542 if (typeof node.clone === 'function') { 5543 this.append(node.clone()); 5544 } else { 5545 this.append(node); 5546 } 5547 } 5548 } else { 5549 this[name] = defaults[name]; 5550 } 5551 } 5552 } 5553 addToError(error) { 5554 error.postcssNode = this; 5555 if (error.stack && this.source && /\n\s{4}at /.test(error.stack)) { 5556 let s = this.source; 5557 error.stack = error.stack.replace(/\n\s{4}at /, `$&${s.input.from}:${s.start.line}:${s.start.column}$&`); 5558 } 5559 return error; 5560 } 5561 after(add) { 5562 this.parent.insertAfter(this, add); 5563 return this; 5564 } 5565 assign(overrides = {}) { 5566 for(let name in overrides){ 5567 this[name] = overrides[name]; 5568 } 5569 return this; 5570 } 5571 before(add) { 5572 this.parent.insertBefore(this, add); 5573 return this; 5574 } 5575 cleanRaws(keepBetween) { 5576 delete this.raws.before; 5577 delete this.raws.after; 5578 if (!keepBetween) delete this.raws.between; 5579 } 5580 clone(overrides = {}) { 5581 let cloned = cloneNode(this); 5582 for(let name in overrides){ 5583 cloned[name] = overrides[name]; 5584 } 5585 return cloned; 5586 } 5587 cloneAfter(overrides = {}) { 5588 let cloned = this.clone(overrides); 5589 this.parent.insertAfter(this, cloned); 5590 return cloned; 5591 } 5592 cloneBefore(overrides = {}) { 5593 let cloned = this.clone(overrides); 5594 this.parent.insertBefore(this, cloned); 5595 return cloned; 5596 } 5597 error(message, opts = {}) { 5598 if (this.source) { 5599 let { end, start } = this.rangeBy(opts); 5600 return this.source.input.error(message, { 5601 column: start.column, 5602 line: start.line 5603 }, { 5604 column: end.column, 5605 line: end.line 5606 }, opts); 5607 } 5608 return new CssSyntaxError(message); 5609 } 5610 getProxyProcessor() { 5611 return { 5612 get (node, prop) { 5613 if (prop === 'proxyOf') { 5614 return node; 5615 } else if (prop === 'root') { 5616 return ()=>
vendor: 5,177 bytes, lines 5616-5758
5616node.root().toProxy(); 5617 } else { 5618 return node[prop]; 5619 } 5620 }, 5621 set (node, prop, value) { 5622 if (node[prop] === value) return true; 5623 node[prop] = value; 5624 if (prop === 'prop' || prop === 'value' || prop === 'name' || prop === 'params' || prop === 'important' || /* c8 ignore next */ prop === 'text') { 5625 node.markDirty(); 5626 } 5627 return true; 5628 } 5629 }; 5630 } 5631 /* c8 ignore next 3 */ markClean() { 5632 this[isClean] = true; 5633 } 5634 markDirty() { 5635 if (this[isClean]) { 5636 this[isClean] = false; 5637 let next = this; 5638 while(next = next.parent){ 5639 next[isClean] = false; 5640 } 5641 } 5642 } 5643 next() { 5644 if (!this.parent) return undefined; 5645 let index = this.parent.index(this); 5646 return this.parent.nodes[index + 1]; 5647 } 5648 positionBy(opts = {}) { 5649 let pos = this.source.start; 5650 if (opts.index) { 5651 pos = this.positionInside(opts.index); 5652 } else if (opts.word) { 5653 let inputString = 'document' in this.source.input ? this.source.input.document : this.source.input.css; 5654 let stringRepresentation = inputString.slice(sourceOffset(inputString, this.source.start), sourceOffset(inputString, this.source.end)); 5655 let index = stringRepresentation.indexOf(opts.word); 5656 if (index !== -1) pos = this.positionInside(index); 5657 } 5658 return pos; 5659 } 5660 positionInside(index) { 5661 let column = this.source.start.column; 5662 let line = this.source.start.line; 5663 let inputString = 'document' in this.source.input ? this.source.input.document : this.source.input.css; 5664 let offset = sourceOffset(inputString, this.source.start); 5665 let end = offset + index; 5666 for(let i = offset; i < end; i++){ 5667 if (inputString[i] === '\n') { 5668 column = 1; 5669 line += 1; 5670 } else { 5671 column += 1; 5672 } 5673 } 5674 return { 5675 column, 5676 line, 5677 offset: end 5678 }; 5679 } 5680 prev() { 5681 if (!this.parent) return undefined; 5682 let index = this.parent.index(this); 5683 return this.parent.nodes[index - 1]; 5684 } 5685 rangeBy(opts = {}) { 5686 let inputString = 'document' in this.source.input ? this.source.input.document : this.source.input.css; 5687 let start = { 5688 column: this.source.start.column, 5689 line: this.source.start.line, 5690 offset: sourceOffset(inputString, this.source.start) 5691 }; 5692 let end = this.source.end ? { 5693 column: this.source.end.column + 1, 5694 line: this.source.end.line, 5695 offset: typeof this.source.end.offset === 'number' ? this.source.end.offset : // the `sourceOffset(... , this.source.end)` returns an inclusive offset. 5696 // So, we add 1 to convert it to exclusive. 5697 sourceOffset(inputString, this.source.end) + 1 5698 } : { 5699 column: start.column + 1, 5700 line: start.line, 5701 offset: start.offset + 1 5702 }; 5703 if (opts.word) { 5704 let stringRepresentation = inputString.slice(sourceOffset(inputString, this.source.start), sourceOffset(inputString, this.source.end)); 5705 let index = stringRepresentation.indexOf(opts.word); 5706 if (index !== -1) { 5707 start = this.positionInside(index); 5708 end = this.positionInside(index + opts.word.length); 5709 } 5710 } else { 5711 if (opts.start) { 5712 start = { 5713 column: opts.start.column, 5714 line: opts.start.line, 5715 offset: sourceOffset(inputString, opts.start) 5716 }; 5717 } else if (opts.index) { 5718 start = this.positionInside(opts.index); 5719 } 5720 if (opts.end) { 5721 end = { 5722 column: opts.end.column, 5723 line: opts.end.line, 5724 offset: sourceOffset(inputString, opts.end) 5725 }; 5726 } else if (typeof opts.endIndex === 'number') { 5727 end = this.positionInside(opts.endIndex); 5728 } else if (opts.index) { 5729 end = this.positionInside(opts.index + 1); 5730 } 5731 } 5732 if (end.line < start.line || end.line === start.line && end.column <= start.column) { 5733 end = { 5734 column: start.column + 1, 5735 line: start.line, 5736 offset: start.offset + 1 5737 }; 5738 } 5739 return { 5740 end, 5741 start 5742 }; 5743 } 5744 raw(prop, defaultType) { 5745 let str = new Stringifier(); 5746 return str.raw(this, prop, defaultType); 5747 } 5748 remove() { 5749 if (this.parent) { 5750 this.parent.removeChild(this); 5751 } 5752 this.parent = undefined; 5753 return this; 5754 } 5755 replaceWith(...nodes) { 5756 if (this.parent) { 5757 let bookmark = this; 5758 let foundSelf = false;
5759 for (let node of nodes){ 5760 if (node === this) { 5761 foundSelf = true; 5762 } else if (foundSelf) { 5763 this.parent.insertAfter(bookmark, node); 5764 bookmark = node; 5765 } else { 5766 this.parent.insertBefore(bookmark, node); 5767 } 5768 } 5769 if (!foundSelf) { 5770 this.remove(); 5771 } 5772 } 5773 return this; 5774 } 5775 root() { 5776 let result = this; 5777 while(result.parent && result.parent.type !== 'document'){ 5778 result = result.parent; 5779 } 5780 return result; 5781 } 5782 toJSON(_, inputs) { 5783 let fixed = {}; 5784 let emitInputs = inputs == null; 5785 inputs = inputs || new Map(); 5786 let inputsNextIndex = 0; 5787 for(let name in this){ 5788 if (!Object.prototype.hasOwnProperty.call(this, name)) { 5789 continue; 5790 } 5791 if (name === 'parent' || name === 'proxyCache') continue; 5792 let value = this[name]; 5793 if (Array.isArray(value)) { 5794 fixed[name] = value.map((i)=>{ 5795 if (typeof i === 'object' && i.toJSON) { 5796 return i.toJSON(null, inputs); 5797 } else { 5798 return i; 5799 } 5800 }); 5801 } else if (typeof value === 'object' && value.toJSON) { 5802 fixed[name] = value.toJSON(null, inputs); 5803 } else if (name === 'source') { 5804 if (value == null) continue; 5805 let inputId = inputs.get(value.input); 5806 if (inputId == null) { 5807 inputId = inputsNextIndex; 5808 inputs.set(value.input, inputsNextIndex); 5809 inputsNextIndex++; 5810 } 5811 fixed[name] = { 5812 end: value.end, 5813 inputId, 5814 start: value.start 5815 }; 5816 } else { 5817 fixed[name] = value; 5818 } 5819 } 5820 if (emitInputs) { 5821 fixed.inputs = [ 5822 ...inputs.keys() 5823 ].map((input)=>input.toJSON()); 5824 } 5825 return fixed; 5826 } 5827 toProxy() { 5828 if (!this.proxyCache) { 5829 this.proxyCache = new Proxy(this, this.getProxyProcessor()); 5830 } 5831 return this.proxyCache; 5832 } 5833 toString(stringifier = stringify) { 5834 if (stringifier.stringify) stringifier = stringifier.stringify; 5835 let result = ''; 5836 stringifier(this, (i)=>{ 5837 result += i; 5838 }); 5839 return result; 5840 } 5841 warn(result, text, opts = {}) { 5842 let data = { 5843 node: this 5844 }; 5845 for(let i in opts)data[i] = opts[i]; 5846 return result.warn(text, data); 5847 } 5848} 5849module.exports = Node; 5850Node.default = Node; 5851}), 5852877906, ((__turbopack_context__, module, exports) => { 5853"use strict"; 5854 5855let Node = __turbopack_context__.r(657612); 5856class Comment extends Node { 5857 constructor(defaults){ 5858 super(defaults); 5859 this.type = 'comment'; 5860 } 5861} 5862module.exports = Comment; 5863Comment.default = Comment; 5864}), 5865721772, ((__turbopack_context__, module, exports) => { 5866"use strict"; 5867 5868let Node = __turbopack_context__.r(657612); 5869class Declaration extends Node { 5870 get variable() { 5871 return this.prop.startsWith('--') || this.prop[0] === '$'; 5872 } 5873 constructor(defaults){ 5874 if (defaults && typeof defaults.value !== 'undefined' && typeof defaults.value !== 'string') { 5875 defaults = { 5876 ...defaults, 5877 value: String(defaults.value) 5878 }; 5879 } 5880 super(defaults); 5881 this.type = 'decl'; 5882 } 5883} 5884module.exports = Declaration; 5885Declaration.default = Declaration; 5886}), 5887296045, ((__turbopack_context__, module, exports) => { 5888"use strict"; 5889 5890let Comment = __turbopack_context__.r(877906); 5891let Declaration = __turbopack_context__.r(721772); 5892let Node = __turbopack_context__.r(657612); 5893let { isClean, my } = __turbopack_context__.r(322302); 5894let AtRule, parse, Root, Rule; 5895function cleanSource(nodes) { 5896 return nodes.map((i)=>{ 5897 if (i.nodes) i.nodes = cleanSource(i.nodes); 5898 delete i.source; 5899 return i; 5900 }); 5901} 5902function markTreeDirty(node) { 5903 node[isClean] = false;
vendor: 11,974 bytes, lines 5904-6261
5904 if (node.proxyOf.nodes) { 5905 for (let i of node.proxyOf.nodes){ 5906 markTreeDirty(i); 5907 } 5908 } 5909} 5910class Container extends Node { 5911 get first() { 5912 if (!this.proxyOf.nodes) return undefined; 5913 return this.proxyOf.nodes[0]; 5914 } 5915 get last() { 5916 if (!this.proxyOf.nodes) return undefined; 5917 return this.proxyOf.nodes[this.proxyOf.nodes.length - 1]; 5918 } 5919 append(...children) { 5920 for (let child of children){ 5921 let nodes = this.normalize(child, this.last); 5922 for (let node of nodes)this.proxyOf.nodes.push(node); 5923 } 5924 this.markDirty(); 5925 return this; 5926 } 5927 cleanRaws(keepBetween) { 5928 super.cleanRaws(keepBetween); 5929 if (this.nodes) { 5930 for (let node of this.nodes)node.cleanRaws(keepBetween); 5931 } 5932 } 5933 each(callback) { 5934 if (!this.proxyOf.nodes) return undefined; 5935 let iterator = this.getIterator(); 5936 let index, result; 5937 while(this.indexes[iterator] < this.proxyOf.nodes.length){ 5938 index = this.indexes[iterator]; 5939 result = callback(this.proxyOf.nodes[index], index); 5940 if (result === false) break; 5941 this.indexes[iterator] += 1; 5942 } 5943 delete this.indexes[iterator]; 5944 return result; 5945 } 5946 every(condition) { 5947 return this.nodes.every(condition); 5948 } 5949 getIterator() { 5950 if (!this.lastEach) this.lastEach = 0; 5951 if (!this.indexes) this.indexes = {}; 5952 this.lastEach += 1; 5953 let iterator = this.lastEach; 5954 this.indexes[iterator] = 0; 5955 return iterator; 5956 } 5957 getProxyProcessor() { 5958 return { 5959 get (node, prop) { 5960 if (prop === 'proxyOf') { 5961 return node; 5962 } else if (!node[prop]) { 5963 return node[prop]; 5964 } else if (prop === 'each' || typeof prop === 'string' && prop.startsWith('walk')) { 5965 return (...args)=>{ 5966 return node[prop](...args.map((i)=>{ 5967 if (typeof i === 'function') { 5968 return (child, index)=>i(child.toProxy(), index); 5969 } else { 5970 return i; 5971 } 5972 })); 5973 }; 5974 } else if (prop === 'every' || prop === 'some') { 5975 return (cb)=>{ 5976 return node[prop]((child, ...other)=>cb(child.toProxy(), ...other)); 5977 }; 5978 } else if (prop === 'root') { 5979 return ()=>node.root().toProxy(); 5980 } else if (prop === 'nodes') { 5981 return node.nodes.map((i)=>i.toProxy()); 5982 } else if (prop === 'first' || prop === 'last') { 5983 return node[prop].toProxy(); 5984 } else { 5985 return node[prop]; 5986 } 5987 }, 5988 set (node, prop, value) { 5989 if (node[prop] === value) return true; 5990 node[prop] = value; 5991 if (prop === 'name' || prop === 'params' || prop === 'selector') { 5992 node.markDirty(); 5993 } 5994 return true; 5995 } 5996 }; 5997 } 5998 index(child) { 5999 if (typeof child === 'number') return child; 6000 if (child.proxyOf) child = child.proxyOf; 6001 return this.proxyOf.nodes.indexOf(child); 6002 } 6003 insertAfter(exist, add) { 6004 let existIndex = this.index(exist); 6005 let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse(); 6006 existIndex = this.index(exist); 6007 for (let node of nodes)this.proxyOf.nodes.splice(existIndex + 1, 0, node); 6008 let index; 6009 for(let id in this.indexes){ 6010 index = this.indexes[id]; 6011 if (existIndex < index) { 6012 this.indexes[id] = index + nodes.length; 6013 } 6014 } 6015 this.markDirty(); 6016 return this; 6017 } 6018 insertBefore(exist, add) { 6019 let existIndex = this.index(exist); 6020 let type = existIndex === 0 ? 'prepend' : false; 6021 let nodes = this.normalize(add, this.proxyOf.nodes[existIndex], type).reverse(); 6022 existIndex = this.index(exist); 6023 for (let node of nodes)this.proxyOf.nodes.splice(existIndex, 0, node); 6024 let index; 6025 for(let id in this.indexes){ 6026 index = this.indexes[id]; 6027 if (existIndex <= index) { 6028 this.indexes[id] = index + nodes.length; 6029 } 6030 } 6031 this.markDirty(); 6032 return this; 6033 } 6034 normalize(nodes, sample) { 6035 if (typeof nodes === 'string') { 6036 nodes = cleanSource(parse(nodes).nodes); 6037 } else if (typeof nodes === 'undefined') { 6038 nodes = []; 6039 } else if (Array.isArray(nodes)) { 6040 nodes = nodes.slice(0); 6041 for (let i of nodes){ 6042 if (i.parent) i.parent.removeChild(i, 'ignore'); 6043 } 6044 } else if (nodes.type === 'root' && this.type !== 'document') { 6045 nodes = nodes.nodes.slice(0); 6046 for (let i of nodes){ 6047 if (i.parent) i.parent.removeChild(i, 'ignore'); 6048 } 6049 } else if (nodes.type) { 6050 nodes = [ 6051 nodes 6052 ]; 6053 } else if (nodes.prop) { 6054 if (typeof nodes.value === 'undefined') { 6055 throw new Error('Value field is missed in node creation'); 6056 } else if (typeof nodes.value !== 'string') { 6057 nodes.value = String(nodes.value); 6058 } 6059 nodes = [ 6060 new Declaration(nodes) 6061 ]; 6062 } else if (nodes.selector || nodes.selectors) { 6063 nodes = [ 6064 new Rule(nodes) 6065 ]; 6066 } else if (nodes.name) { 6067 nodes = [ 6068 new AtRule(nodes) 6069 ]; 6070 } else if (nodes.text) { 6071 nodes = [ 6072 new Comment(nodes) 6073 ]; 6074 } else { 6075 throw new Error('Unknown node type in node creation'); 6076 } 6077 let processed = nodes.map((i)=>{ 6078 /* c8 ignore next */ if (!i[my]) Container.rebuild(i); 6079 i = i.proxyOf; 6080 if (i.parent) i.parent.removeChild(i); 6081 if (i[isClean]) markTreeDirty(i); 6082 if (!i.raws) i.raws = {}; 6083 if (typeof i.raws.before === 'undefined') { 6084 if (sample && typeof sample.raws.before !== 'undefined') { 6085 i.raws.before = sample.raws.before.replace(/\S/g, ''); 6086 } 6087 } 6088 i.parent = this.proxyOf; 6089 return i; 6090 }); 6091 return processed; 6092 } 6093 prepend(...children) { 6094 children = children.reverse(); 6095 for (let child of children){ 6096 let nodes = this.normalize(child, this.first, 'prepend').reverse(); 6097 for (let node of nodes)this.proxyOf.nodes.unshift(node); 6098 for(let id in this.indexes){ 6099 this.indexes[id] = this.indexes[id] + nodes.length; 6100 } 6101 } 6102 this.markDirty(); 6103 return this; 6104 } 6105 push(child) { 6106 child.parent = this; 6107 this.proxyOf.nodes.push(child); 6108 return this; 6109 } 6110 removeAll() { 6111 for (let node of this.proxyOf.nodes)node.parent = undefined; 6112 this.proxyOf.nodes = []; 6113 this.markDirty(); 6114 return this; 6115 } 6116 removeChild(child) { 6117 child = this.index(child); 6118 this.proxyOf.nodes[child].parent = undefined; 6119 this.proxyOf.nodes.splice(child, 1); 6120 let index; 6121 for(let id in this.indexes){ 6122 index = this.indexes[id]; 6123 if (index >= child) { 6124 this.indexes[id] = index - 1; 6125 } 6126 } 6127 this.markDirty(); 6128 return this; 6129 } 6130 replaceValues(pattern, opts, callback) { 6131 if (!callback) { 6132 callback = opts; 6133 opts = {}; 6134 } 6135 this.walkDecls((decl)=>{ 6136 if (opts.props && !opts.props.includes(decl.prop)) return; 6137 if (opts.fast && !decl.value.includes(opts.fast)) return; 6138 decl.value = decl.value.replace(pattern, callback); 6139 }); 6140 this.markDirty(); 6141 return this; 6142 } 6143 some(condition) { 6144 return this.nodes.some(condition); 6145 } 6146 walk(callback) { 6147 return this.each((child, i)=>{ 6148 let result; 6149 try { 6150 result = callback(child, i); 6151 } catch (e) { 6152 throw child.addToError(e); 6153 } 6154 if (result !== false && child.walk) { 6155 result = child.walk(callback); 6156 } 6157 return result; 6158 }); 6159 } 6160 walkAtRules(name, callback) { 6161 if (!callback) { 6162 callback = name; 6163 return this.walk((child, i)=>{ 6164 if (child.type === 'atrule') { 6165 return callback(child, i); 6166 } 6167 }); 6168 } 6169 if (name instanceof RegExp) { 6170 return this.walk((child, i)=>{ 6171 if (child.type === 'atrule' && name.test(child.name)) { 6172 return callback(child, i); 6173 } 6174 }); 6175 } 6176 return this.walk((child, i)=>{ 6177 if (child.type === 'atrule' && child.name === name) { 6178 return callback(child, i); 6179 } 6180 }); 6181 } 6182 walkComments(callback) { 6183 return this.walk((child, i)=>{ 6184 if (child.type === 'comment') { 6185 return callback(child, i); 6186 } 6187 }); 6188 } 6189 walkDecls(prop, callback) { 6190 if (!callback) { 6191 callback = prop; 6192 return this.walk((child, i)=>{ 6193 if (child.type === 'decl') { 6194 return callback(child, i); 6195 } 6196 }); 6197 } 6198 if (prop instanceof RegExp) { 6199 return this.walk((child, i)=>{ 6200 if (child.type === 'decl' && prop.test(child.prop)) { 6201 return callback(child, i); 6202 } 6203 }); 6204 } 6205 return this.walk((child, i)=>{ 6206 if (child.type === 'decl' && child.prop === prop) { 6207 return callback(child, i); 6208 } 6209 }); 6210 } 6211 walkRules(selector, callback) { 6212 if (!callback) { 6213 callback = selector; 6214 return this.walk((child, i)=>{ 6215 if (child.type === 'rule') { 6216 return callback(child, i); 6217 } 6218 }); 6219 } 6220 if (selector instanceof RegExp) { 6221 return this.walk((child, i)=>{ 6222 if (child.type === 'rule' && selector.test(child.selector)) { 6223 return callback(child, i); 6224 } 6225 }); 6226 } 6227 return this.walk((child, i)=>{ 6228 if (child.type === 'rule' && child.selector === selector) { 6229 return callback(child, i); 6230 } 6231 }); 6232 } 6233} 6234Container.registerParse = (dependant)=>{ 6235 parse = dependant; 6236}; 6237Container.registerRule = (dependant)=>{ 6238 Rule = dependant; 6239}; 6240Container.registerAtRule = (dependant)=>{ 6241 AtRule = dependant; 6242}; 6243Container.registerRoot = (dependant)=>{ 6244 Root = dependant; 6245}; 6246module.exports = Container; 6247Container.default = Container; 6248/* c8 ignore start */ Container.rebuild = (node)=>{ 6249 if (node.type === 'atrule') { 6250 Object.setPrototypeOf(node, AtRule.prototype); 6251 } else if (node.type === 'rule') { 6252 Object.setPrototypeOf(node, Rule.prototype); 6253 } else if (node.type === 'decl') { 6254 Object.setPrototypeOf(node, Declaration.prototype); 6255 } else if (node.type === 'comment') { 6256 Object.setPrototypeOf(node, Comment.prototype); 6257 } else if (node.type === 'root') { 6258 Object.setPrototypeOf(node, Root.prototype); 6259 } 6260 node[my] = true; 6261 if (node.nodes) {
6262 node.nodes.forEach((child)=>{ 6263 Container.rebuild(child); 6264 }); 6265 } 6266}; /* c8 ignore stop */ 6267}), 6268670255, ((__turbopack_context__, module, exports) => { 6269"use strict"; 6270 6271let Container = __turbopack_context__.r(296045); 6272class AtRule extends Container { 6273 constructor(defaults){ 6274 super(defaults); 6275 this.type = 'atrule'; 6276 } 6277 append(...children) { 6278 if (!this.proxyOf.nodes) this.nodes = []; 6279 return super.append(...children); 6280 } 6281 prepend(...children) { 6282 if (!this.proxyOf.nodes) this.nodes = []; 6283 return super.prepend(...children); 6284 } 6285} 6286module.exports = AtRule; 6287AtRule.default = AtRule; 6288Container.registerAtRule(AtRule); 6289}), 6290698475, ((__turbopack_context__, module, exports) => { 6291"use strict"; 6292 6293let Container = __turbopack_context__.r(296045); 6294let LazyResult, Processor; 6295class Document extends Container { 6296 constructor(defaults){ 6297 // type needs to be passed to super, otherwise child roots won't be normalized correctly 6298 super({ 6299 type: 'document', 6300 ...defaults 6301 }); 6302 if (!this.nodes) { 6303 this.nodes = []; 6304 } 6305 } 6306 toResult(opts = {}) { 6307 let lazy = new LazyResult(new Processor(), this, opts); 6308 return lazy.stringify(); 6309 } 6310} 6311Document.registerLazyResult = (dependant)=>{ 6312 LazyResult = dependant; 6313}; 6314Document.registerProcessor = (dependant)=>{ 6315 Processor = dependant; 6316}; 6317module.exports = Document; 6318Document.default = Document; 6319}), 6320802658, ((__turbopack_context__, module, exports) => { 6321 6322// This alphabet uses `A-Za-z0-9_-` symbols. 6323// The order of characters is optimized for better gzip and brotli compression. 6324// References to the same file (works both for gzip and brotli): 6325// `'use`, `andom`, and `rict'` 6326// References to the brotli default dictionary: 6327// `-26T`, `1983`, `40px`, `75px`, `bush`, `jack`, `mind`, `very`, and `wolf` 6328let urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; 6329let customAlphabet = (alphabet, defaultSize = 21)=>{ 6330 return (size = defaultSize)=>{ 6331 let id = ''; 6332 // A compact alternative for `for (var i = 0; i < step; i++)`. 6333 let i = size | 0; 6334 while(i--){ 6335 // `| 0` is more compact and faster than `Math.floor()`. 6336 id += alphabet[Math.random() * alphabet.length | 0]; 6337 } 6338 return id; 6339 }; 6340}; 6341let nanoid = (size = 21)=>{ 6342 let id = ''; 6343 // A compact alternative for `for (var i = 0; i < step; i++)`. 6344 let i = size | 0; 6345 while(i--){ 6346 // `| 0` is more compact and faster than `Math.floor()`. 6347 id += urlAlphabet[Math.random() * 64 | 0]; 6348 } 6349 return id; 6350}; 6351module.exports = { 6352 nanoid, 6353 customAlphabet 6354}; 6355}), 6356343954, ((__turbopack_context__, module, exports) => { 6357 6358(function() { 6359 "use strict"; 6360 var e = { 6361 815: function(e) { 6362 function hasOwnProperty(e, r) { 6363 return Object.prototype.hasOwnProperty.call(e, r); 6364 } 6365 e.exports = function(e, n, t, o) { 6366 n = n || "&"; 6367 t = t || "="; 6368 var a = {}; 6369 if (typeof e !== "string" || e.length === 0) { 6370 return a; 6371 } 6372 var i = /\+/g; 6373 e = e.split(n); 6374 var u = 1e3; 6375 if (o && typeof o.maxKeys === "number") { 6376 u = o.maxKeys; 6377 } 6378 var c = e.length; 6379 if (u > 0 && c > u) { 6380 c = u; 6381 } 6382 for(var p = 0; p < c; ++p){ 6383 var f = e[p].replace(i, "%20"), s = f.indexOf(t), _, l, y, d; 6384 if (s >= 0) { 6385 _ = f.substr(0, s); 6386 l = f.substr(s + 1); 6387 } else { 6388 _ = f; 6389 l = ""; 6390 } 6391 y = decodeURIComponent(_); 6392 d = decodeURIComponent(l); 6393 if (!hasOwnProperty(a, y)) { 6394 a[y] = d; 6395 } else if (r(a[y])) { 6396 a[y].push(d); 6397 } else { 6398 a[y] = [ 6399 a[y], 6400 d 6401 ]; 6402 } 6403 } 6404 return a; 6405 }; 6406 var r = Array.isArray || function(e) { 6407 return Object.prototype.toString.call(e) === "[object Array]"; 6408 }; 6409 }, 6410 577: function(e) { 6411 var stringifyPrimitive = function(e) { 6412 switch(typeof e){ 6413 case "string": 6414 return e; 6415 case "boolean": 6416 return e ? "true" : "false"; 6417 case "number": 6418 return isFinite(e) ? e : ""; 6419 default: 6420 return ""; 6421 } 6422 }; 6423 e.exports = function(e, t, o, a) { 6424 t = t || "&"; 6425 o = o || "="; 6426 if (e === null) { 6427 e = undefined; 6428 } 6429 if (typeof e === "object") { 6430 return map(n(e), function(n) { 6431 var a = encodeURIComponent(stringifyPrimitive(n)) + o; 6432 if (r(e[n])) { 6433 return map(e[n], function(e) { 6434 return a + encodeURIComponent(stringifyPrimitive(e)); 6435 }).join(t); 6436 } else { 6437 return a + encodeURIComponent(stringifyPrimitive(e[n])); 6438 } 6439 }).join(t); 6440 } 6441 if (!a) return ""; 6442 return encodeURIComponent(stringifyPrimitive(a)) + o + encodeURIComponent(stringifyPrimitive(e)); 6443 }; 6444 var r = Array.isArray || function(e) { 6445 return Object.prototype.toString.call(e) === "[object Array]"; 6446 }; 6447 function map(e, r) { 6448 if (e.map) return e.map(r); 6449 var n = []; 6450 for(var t = 0; t < e.length; t++){
6451 n.push(r(e[t], t)); 6452 } 6453 return n; 6454 } 6455 var n = Object.keys || function(e) { 6456 var r = []; 6457 for(var n in e){ 6458 if (Object.prototype.hasOwnProperty.call(e, n)) r.push(n); 6459 } 6460 return r; 6461 }; 6462 } 6463 }; 6464 var r = {}; 6465 function __nccwpck_require__(n) { 6466 var t = r[n]; 6467 if (t !== undefined) { 6468 return t.exports; 6469 } 6470 var o = r[n] = { 6471 exports: {} 6472 }; 6473 var a = true; 6474 try { 6475 e[n](o, o.exports, __nccwpck_require__); 6476 a = false; 6477 } finally{ 6478 if (a) delete r[n]; 6479 } 6480 return o.exports; 6481 } 6482 if (typeof __nccwpck_require__ !== "undefined") __nccwpck_require__.ab = ("TURBOPACK compile-time value", "/ROOT/node_modules/next/dist/compiled/querystring-es3") + "/"; 6483 var n = {}; 6484 !function() { 6485 var e = n; 6486 e.decode = e.parse = __nccwpck_require__(815); 6487 e.encode = e.stringify = __nccwpck_require__(577); 6488 }(); 6489 module.exports = n; 6490})(); 6491}), 6492421342, ((__turbopack_context__, module, exports) => { 6493 6494(function() { 6495 var e = { 6496 452: function(e) { 6497 "use strict"; 6498 e.exports = __turbopack_context__.r(343954); 6499 } 6500 }; 6501 var t = {}; 6502 function __nccwpck_require__(o) { 6503 var a = t[o]; 6504 if (a !== undefined) { 6505 return a.exports; 6506 } 6507 var s = t[o] = { 6508 exports: {} 6509 }; 6510 var n = true; 6511 try { 6512 e[o](s, s.exports, __nccwpck_require__); 6513 n = false; 6514 } finally{ 6515 if (n) delete t[o]; 6516 } 6517 return s.exports; 6518 } 6519 if (typeof __nccwpck_require__ !== "undefined") __nccwpck_require__.ab = ("TURBOPACK compile-time value", "/ROOT/node_modules/next/dist/compiled/native-url") + "/"; 6520 var o = {}; 6521 !function() { 6522 var e = o; 6523 var t, a = (t = __nccwpck_require__(452)) && "object" == typeof t && "default" in t ? t.default : t, s = /https?|ftp|gopher|file/; 6524 function r(e) { 6525 "string" == typeof e && (e = d(e)); 6526 var t = function(e, t, o) { 6527 var a = e.auth, s = e.hostname, n = e.protocol || "", p = e.pathname || "", c = e.hash || "", i = e.query || "", u = !1; 6528 a = a ? encodeURIComponent(a).replace(/%3A/i, ":") + "@" : "", e.host ? u = a + e.host : s && (u = a + (~s.indexOf(":") ? "[" + s + "]" : s), e.port && (u += ":" + e.port)), i && "object" == typeof i && (i = t.encode(i)); 6529 var f = e.search || i && "?" + i || ""; 6530 return n && ":" !== n.substr(-1) && (n += ":"), e.slashes || (!n || o.test(n)) && !1 !== u ? (u = "//" + (u || ""), p && "/" !== p[0] && (p = "/" + p)) : u || (u = ""), c && "#" !== c[0] && (c = "#" + c), f && "?" !== f[0] && (f = "?" + f), { 6531 protocol: n, 6532 host: u, 6533 pathname: p = p.replace(/[?#]/g, encodeURIComponent), 6534 search: f = f.replace("#", "%23"), 6535 hash: c 6536 }; 6537 }(e, a, s); 6538 return "" + t.protocol + t.host + t.pathname + t.search + t.hash; 6539 } 6540 var n = "http://", p = "w.w", c = n + p, i = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i, u = /https?|ftp|gopher|file/; 6541 function h(e, t) { 6542 var o = "string" == typeof e ? d(e) : e; 6543 e = "object" == typeof e ? r(e) : e; 6544 var a = d(t), s = ""; 6545 o.protocol && !o.slashes && (s = o.protocol, e = e.replace(o.protocol, ""), s += "/" === t[0] || "/" === e[0] ? "/" : ""), s && a.protocol && (s = "", a.slashes || (s = a.protocol, t = t.replace(a.protocol, ""))); 6546 var p = e.match(i); 6547 p && !a.protocol && (e = e.substr((s = p[1] + (p[2] || "")).length), /^\/\/[^/]/.test(t) && (s = s.slice(0, -1))); 6548 var f = new URL(e, c + "/"), m = new URL(t, f).toString().replace(c, ""), v = a.protocol || o.protocol; 6549 return v += o.slashes || a.slashes ? "//" : "", !s && v ? m = m.replace(n, v) : s && (m = m.replace(n, "")), u.test(m) || ~t.indexOf(".") || "/" === e.slice(-1) || "/" === t.slice(-1) || "/" !== m.slice(-1) || (m = m.
6549slice(0, -1)), s && (m = s + ("/" === m[0] ? m.substr(1) : m)), m; 6550 } 6551 function l() {} 6552 l.prototype.parse = d, l.prototype.format = r, l.prototype.resolve = h, l.prototype.resolveObject = h; 6553 var f = /^https?|ftp|gopher|file/, m = /^(.*?)([#?].*)/, v = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i, _ = /^([a-z0-9.+-]*:)?\/\/\/*/i, b = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i; 6554 function d(e, t, o) { 6555 if (void 0 === t && (t = !1), void 0 === o && (o = !1), e && "object" == typeof e && e instanceof l) return e; 6556 var s = (e = e.trim()).match(m); 6557 e = s ? s[1].replace(/\\/g, "/") + s[2] : e.replace(/\\/g, "/"), b.test(e) && "/" !== e.slice(-1) && (e += "/"); 6558 var n = !/(^javascript)/.test(e) && e.match(v), i = _.test(e), u = ""; 6559 n && (f.test(n[1]) || (u = n[1].toLowerCase(), e = "" + n[2] + n[3]), n[2] || (i = !1, f.test(n[1]) ? (u = n[1], e = "" + n[3]) : e = "//" + n[3]), 3 !== n[2].length && 1 !== n[2].length || (u = n[1], e = "/" + n[3])); 6560 var g, y = (s ? s[1] : e).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/), w = y && y[1], x = new l, C = "", U = ""; 6561 try { 6562 g = new URL(e); 6563 } catch (t) { 6564 C = t, u || o || !/^\/\//.test(e) || /^\/\/.+[@.]/.test(e) || (U = "/", e = e.substr(1)); 6565 try { 6566 g = new URL(e, c); 6567 } catch (e) { 6568 return x.protocol = u, x.href = u, x; 6569 } 6570 } 6571 x.slashes = i && !U, x.host = g.host === p ? "" : g.host, x.hostname = g.hostname === p ? "" : g.hostname.replace(/(\[|\])/g, ""), x.protocol = C ? u || null : g.protocol, x.search = g.search.replace(/\\/g, "%5C"), x.hash = g.hash.replace(/\\/g, "%5C"); 6572 var j = e.split("#"); 6573 !x.search && ~j[0].indexOf("?") && (x.search = "?"), x.hash || "" !== j[1] || (x.hash = "#"), x.query = t ? a.decode(g.search.substr(1)) : x.search.substr(1), x.pathname = U + (n ? function(e) { 6574 return e.replace(/['^|`]/g, function(e) { 6575 return "%" + e.charCodeAt().toString(16).toUpperCase(); 6576 }).replace(/((?:%[0-9A-F]{2})+)/g, function(e, t) { 6577 try { 6578 return decodeURIComponent(t).split("").map(function(e) { 6579 var t = e.charCodeAt(); 6580 return t > 256 || /^[a-z0-9]$/i.test(e) ? e : "%" + t.toString(16).toUpperCase(); 6581 }).join(""); 6582 } catch (e) { 6583 return t; 6584 } 6585 }); 6586 }(g.pathname) : g.pathname), "about:" === x.protocol && "blank" === x.pathname && (x.protocol = "", x.pathname = ""), C && "/" !== e[0] && (x.pathname = x.pathname.substr(1)), u && !f.test(u) && "/" !== e.slice(-1) && "/" === x.pathname && (x.pathname = ""), x.path = x.pathname + x.search, x.auth = [ 6587 g.username, 6588 g.password 6589 ].map(decodeURIComponent).filter(Boolean).join(":"), x.port = g.port, w && !x.host.endsWith(w) && (x.host += w, x.port = w.slice(1)), x.href = U ? "" + x.pathname + x.search + x.hash : r(x); 6590 var q = /^(file)/.test(x.href) ? [ 6591 "host", 6592 "hostname" 6593 ] : []; 6594 return Object.keys(x).forEach(function(e) { 6595 ~q.indexOf(e) || (x[e] = x[e] || null); 6596 }), x; 6597 } 6598 e.parse = d, e.format = r, e.resolve = h, e.resolveObject = function(e, t) { 6599 return d(h(e, t)); 6600 }, e.Url = l; 6601 }(); 6602 module.exports = o; 6603})(); 6604}), 6605804468, ((__turbopack_context__, module, exports) => { 6606"use strict"; 6607 6608var __TURBOPACK__imported__module__467034__ = /*#__PURE__*/ __turbopack_context__.i(467034); 6609'use strict'; 6610let { existsSync, readFileSync } = {}; 6611let { dirname, join } = {}; 6612let { SourceMapConsumer, SourceMapGenerator } = {}; 6613function fromBase64(str) { 6614 if ("TURBOPACK compile-time truthy", 1) { 6615 return __TURBOPACK__imported__module__467034__["Buffer"].from(str, 'base64').toString(); 6616 } else //TURBOPACK unreachable 6617 ; 6618} 6619class PreviousMap { 6620 constructor(css, opts){ 6621 if (opts.map === false) return; 6622 this.loadAnnotation(css); 6623 this.inline = this.startWith(this.annotation, 'data:'); 6624 let prev = opts.map ? opts.map.prev : undefined; 6625 let text = this.loadMap(opts.from, prev); 6626 if (!this.mapFile && opts.from) { 6627 this.mapFile = opts.from; 6628 } 6629 if (this.mapFile) this.root = dirname(this.mapFile); 6630 if (text) this.text = text; 6631 } 6632 consumer() { 6633 if (!this.consumerCache) { 6634 this.consumerCache = new SourceMapConsumer(this.text); 6635 } 6636 return this.consumerCache; 6637 } 6638 decodeInline(text) { 6639 let baseCharsetUri = /^data:application\/json;charset=utf-?8;base64,/; 6640 let baseUri = /^data:application\/json;base64,/; 6641 let charsetUri = /^data:application\/json;charset=utf-?8,/; 6642 let uri = /^data:application\/json,/; 6643 let uriMatch = text.match(charsetUri) || text.match(uri); 6644 if (uriMatch) { 6645 return decodeURIComponent(text.substr(uriMatch[0].length)); 6646 } 6647 let baseUriMatch = text.match(baseCharsetUri) || text.match(baseUri); 6648 if (baseUriMatch) { 6649 return fromBase64(text.substr(baseUriMatch[0].length)); 6650 } 6651 let encoding = text.slice('data:application/json;'.length); 6652 encoding = encoding.slice(0, encoding.indexOf(',')); 6653 throw new Error('Unsupported source map encoding ' + encoding); 6654 } 6655 getAnnotationURL(sourceMapString) { 6656 return sourceMapString.replace(/^\/\*\s*# sourceMappingURL=/, '').trim(); 6657 } 6658 isMap(map) { 6659 if (typeof map !== 'object') return false;
vendor: 10,206 bytes, lines 6660-6951
6660 return typeof map.mappings === 'string' || typeof map._mappings === 'string' || Array.isArray(map.sections); 6661 } 6662 loadAnnotation(css) { 6663 let comments = css.match(/\/\*\s*# sourceMappingURL=/g); 6664 if (!comments) return; 6665 // sourceMappingURLs from comments, strings, etc. 6666 let start = css.lastIndexOf(comments.pop()); 6667 let end = css.indexOf('*/', start); 6668 if (start > -1 && end > -1) { 6669 // Locate the last sourceMappingURL to avoid pickin 6670 this.annotation = this.getAnnotationURL(css.substring(start, end)); 6671 } 6672 } 6673 loadFile(path) { 6674 this.root = dirname(path); 6675 if (existsSync(path)) { 6676 this.mapFile = path; 6677 return readFileSync(path, 'utf-8').toString().trim(); 6678 } 6679 } 6680 loadMap(file, prev) { 6681 if (prev === false) return false; 6682 if (prev) { 6683 if (typeof prev === 'string') { 6684 return prev; 6685 } else if (typeof prev === 'function') { 6686 let prevPath = prev(file); 6687 if (prevPath) { 6688 let map = this.loadFile(prevPath); 6689 if (!map) { 6690 throw new Error('Unable to load previous source map: ' + prevPath.toString()); 6691 } 6692 return map; 6693 } 6694 } else if (prev instanceof SourceMapConsumer) { 6695 return SourceMapGenerator.fromSourceMap(prev).toString(); 6696 } else if (prev instanceof SourceMapGenerator) { 6697 return prev.toString(); 6698 } else if (this.isMap(prev)) { 6699 return JSON.stringify(prev); 6700 } else { 6701 throw new Error('Unsupported previous source map format: ' + prev.toString()); 6702 } 6703 } else if (this.inline) { 6704 return this.decodeInline(this.annotation); 6705 } else if (this.annotation) { 6706 let map = this.annotation; 6707 if (file) map = join(dirname(file), map); 6708 return this.loadFile(map); 6709 } 6710 } 6711 startWith(string, start) { 6712 if (!string) return false; 6713 return string.substr(0, start.length) === start; 6714 } 6715 withContent() { 6716 return !!(this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0); 6717 } 6718} 6719module.exports = PreviousMap; 6720PreviousMap.default = PreviousMap; 6721}), 67222278, ((__turbopack_context__, module, exports) => { 6723"use strict"; 6724 6725let { nanoid } = __turbopack_context__.r(802658); 6726let { isAbsolute, resolve } = {}; 6727let { SourceMapConsumer, SourceMapGenerator } = {}; 6728let { fileURLToPath, pathToFileURL } = __turbopack_context__.r(421342); 6729let CssSyntaxError = __turbopack_context__.r(71528); 6730let PreviousMap = __turbopack_context__.r(804468); 6731let terminalHighlight = {}; 6732let lineToIndexCache = Symbol('lineToIndexCache'); 6733let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator); 6734let pathAvailable = Boolean(resolve && isAbsolute); 6735function getLineToIndex(input) { 6736 if (input[lineToIndexCache]) return input[lineToIndexCache]; 6737 let lines = input.css.split('\n'); 6738 let lineToIndex = new Array(lines.length); 6739 let prevIndex = 0; 6740 for(let i = 0, l = lines.length; i < l; i++){ 6741 lineToIndex[i] = prevIndex; 6742 prevIndex += lines[i].length + 1; 6743 } 6744 input[lineToIndexCache] = lineToIndex; 6745 return lineToIndex; 6746} 6747class Input { 6748 get from() { 6749 return this.file || this.id; 6750 } 6751 constructor(css, opts = {}){ 6752 if (css === null || typeof css === 'undefined' || typeof css === 'object' && !css.toString) { 6753 throw new Error(`PostCSS received ${css} instead of CSS string`); 6754 } 6755 this.css = css.toString(); 6756 if (this.css[0] === '\uFEFF' || this.css[0] === '\uFFFE') { 6757 this.hasBOM = true; 6758 this.css = this.css.slice(1); 6759 } else { 6760 this.hasBOM = false; 6761 } 6762 this.document = this.css; 6763 if (opts.document) this.document = opts.document.toString(); 6764 if (opts.from) { 6765 if (!pathAvailable || /^\w+:\/\//.test(opts.from) || isAbsolute(opts.from)) { 6766 this.file = opts.from; 6767 } else { 6768 this.file = resolve(opts.from); 6769 } 6770 } 6771 if (pathAvailable && sourceMapAvailable) { 6772 let map = new PreviousMap(this.css, opts); 6773 if (map.text) { 6774 this.map = map; 6775 let file = map.consumer().file; 6776 if (!this.file && file) this.file = this.mapResolve(file); 6777 } 6778 } 6779 if (!this.file) { 6780 this.id = '<input css ' + nanoid(6) + '>'; 6781 } 6782 if (this.map) this.map.file = this.from; 6783 } 6784 error(message, line, column, opts = {}) { 6785 let endColumn, endLine, endOffset, offset, result; 6786 if (line && typeof line === 'object') { 6787 let start = line; 6788 let end = column; 6789 if (typeof start.offset === 'number') { 6790 offset = start.offset; 6791 let pos = this.fromOffset(offset); 6792 line = pos.line; 6793 column = pos.col; 6794 } else { 6795 line = start.line; 6796 column = start.column; 6797 offset = this.fromLineAndColumn(line, column); 6798 } 6799 if (typeof end.offset === 'number') { 6800 endOffset = end.offset; 6801 let pos = this.fromOffset(endOffset); 6802 endLine = pos.line; 6803 endColumn = pos.col; 6804 } else { 6805 endLine = end.line; 6806 endColumn = end.column; 6807 endOffset = this.fromLineAndColumn(end.line, end.column); 6808 } 6809 } else if (!column) { 6810 offset = line; 6811 let pos = this.fromOffset(offset); 6812 line = pos.line; 6813 column = pos.col; 6814 } else { 6815 offset = this.fromLineAndColumn(line, column); 6816 } 6817 let origin = this.origin(line, column, endLine, endColumn); 6818 if (origin) { 6819 result = new CssSyntaxError(message, origin.endLine === undefined ? origin.line : { 6820 column: origin.column, 6821 line: origin.line 6822 }, origin.endLine === undefined ? origin.column : { 6823 column: origin.endColumn, 6824 line: origin.endLine 6825 }, origin.source, origin.file, opts.plugin); 6826 } else { 6827 result = new CssSyntaxError(message, endLine === undefined ? line : { 6828 column, 6829 line 6830 }, endLine === undefined ? column : { 6831 column: endColumn, 6832 line: endLine 6833 }, this.css, this.file, opts.plugin); 6834 } 6835 result.input = { 6836 column, 6837 endColumn, 6838 endLine, 6839 endOffset, 6840 line, 6841 offset, 6842 source: this.css 6843 }; 6844 if (this.file) { 6845 if (pathToFileURL) { 6846 result.input.url = pathToFileURL(this.file).toString(); 6847 } 6848 result.input.file = this.file; 6849 } 6850 return result; 6851 } 6852 fromLineAndColumn(line, column) { 6853 let lineToIndex = getLineToIndex(this); 6854 let index = lineToIndex[line - 1]; 6855 return index + column - 1; 6856 } 6857 fromOffset(offset) { 6858 let lineToIndex = getLineToIndex(this); 6859 let lastLine = lineToIndex[lineToIndex.length - 1]; 6860 let min = 0; 6861 if (offset >= lastLine) { 6862 min = lineToIndex.length - 1; 6863 } else { 6864 let max = lineToIndex.length - 2; 6865 let mid; 6866 while(min < max){ 6867 mid = min + (max - min >> 1); 6868 if (offset < lineToIndex[mid]) { 6869 max = mid - 1; 6870 } else if (offset >= lineToIndex[mid + 1]) { 6871 min = mid + 1; 6872 } else { 6873 min = mid; 6874 break; 6875 } 6876 } 6877 } 6878 return { 6879 col: offset - lineToIndex[min] + 1, 6880 line: min + 1 6881 }; 6882 } 6883 mapResolve(file) { 6884 if (/^\w+:\/\//.test(file)) { 6885 return file; 6886 } 6887 return resolve(this.map.consumer().sourceRoot || this.map.root || '.', file); 6888 } 6889 origin(line, column, endLine, endColumn) { 6890 if (!this.map) return false; 6891 let consumer = this.map.consumer(); 6892 let from = consumer.originalPositionFor({ 6893 column, 6894 line 6895 }); 6896 if (!from.source) return false; 6897 let to; 6898 if (typeof endLine === 'number') { 6899 to = consumer.originalPositionFor({ 6900 column: endColumn, 6901 line: endLine 6902 }); 6903 } 6904 let fromUrl; 6905 if (isAbsolute(from.source)) { 6906 fromUrl = pathToFileURL(from.source); 6907 } else { 6908 fromUrl = new URL(from.source, this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile)); 6909 } 6910 let result = { 6911 column: from.column, 6912 endColumn: to && to.column, 6913 endLine: to && to.line, 6914 line: from.line, 6915 url: fromUrl.toString() 6916 }; 6917 if (fromUrl.protocol === 'file:') { 6918 if (fileURLToPath) { 6919 result.file = fileURLToPath(fromUrl); 6920 } else { 6921 /* c8 ignore next 2 */ throw new Error(`file: protocol is not available in this PostCSS build`); 6922 } 6923 } 6924 let source = consumer.sourceContentFor(from.source); 6925 if (source) result.source = source; 6926 return result; 6927 } 6928 toJSON() { 6929 let json = {}; 6930 for (let name of [ 6931 'hasBOM', 6932 'css', 6933 'file', 6934 'id' 6935 ]){ 6936 if (this[name] != null) { 6937 json[name] = this[name]; 6938 } 6939 } 6940 if (this.map) { 6941 json.map = { 6942 ...this.map 6943 }; 6944 if (json.map.consumerCache) { 6945 json.map.consumerCache = undefined; 6946 } 6947 } 6948 return json; 6949 } 6950} 6951module.exports = Input;
6952Input.default = Input; 6953if (terminalHighlight && terminalHighlight.registerInput) { 6954 terminalHighlight.registerInput(Input); 6955} 6956}), 6957551517, ((__turbopack_context__, module, exports) => { 6958"use strict"; 6959 6960let Container = __turbopack_context__.r(296045); 6961let LazyResult, Processor; 6962class Root extends Container { 6963 constructor(defaults){ 6964 super(defaults); 6965 this.type = 'root'; 6966 if (!this.nodes) this.nodes = []; 6967 } 6968 normalize(child, sample, type) { 6969 let nodes = super.normalize(child); 6970 if (sample) { 6971 if (type === 'prepend') { 6972 if (this.nodes.length > 1) { 6973 sample.raws.before = this.nodes[1].raws.before; 6974 } else { 6975 delete sample.raws.before; 6976 } 6977 } else if (this.first !== sample) { 6978 for (let node of nodes){ 6979 node.raws.before = sample.raws.before; 6980 } 6981 } 6982 } 6983 return nodes; 6984 } 6985 removeChild(child, ignore) { 6986 let index = this.index(child); 6987 if (!ignore && index === 0 && this.nodes.length > 1) { 6988 this.nodes[1].raws.before = this.nodes[index].raws.before; 6989 } 6990 return super.removeChild(child); 6991 } 6992 toResult(opts = {}) { 6993 let lazy = new LazyResult(new Processor(), this, opts); 6994 return lazy.stringify(); 6995 } 6996} 6997Root.registerLazyResult = (dependant)=>{ 6998 LazyResult = dependant; 6999}; 7000Root.registerProcessor = (dependant)=>{ 7001 Processor = dependant; 7002}; 7003module.exports = Root; 7004Root.default = Root; 7005Container.registerRoot(Root); 7006}), 7007350215, ((__turbopack_context__, module, exports) => { 7008"use strict"; 7009 7010let list = { 7011 comma (string) { 7012 return list.split(string, [ 7013 ',' 7014 ], true); 7015 }, 7016 space (string) { 7017 let spaces = [ 7018 ' ', 7019 '\n', 7020 '\t' 7021 ]; 7022 return list.split(string, spaces); 7023 }, 7024 split (string, separators, last) { 7025 let array = []; 7026 let current = ''; 7027 let split = false; 7028 let func = 0; 7029 let inQuote = false; 7030 let prevQuote = ''; 7031 let escape = false;
vendor: 11,780 bytes, lines 7032-7367
7032 for (let letter of string){ 7033 if (escape) { 7034 escape = false; 7035 } else if (letter === '\\') { 7036 escape = true; 7037 } else if (inQuote) { 7038 if (letter === prevQuote) { 7039 inQuote = false; 7040 } 7041 } else if (letter === '"' || letter === "'") { 7042 inQuote = true; 7043 prevQuote = letter; 7044 } else if (letter === '(') { 7045 func += 1; 7046 } else if (letter === ')') { 7047 if (func > 0) func -= 1; 7048 } else if (func === 0) { 7049 if (separators.includes(letter)) split = true; 7050 } 7051 if (split) { 7052 if (current !== '') array.push(current.trim()); 7053 current = ''; 7054 split = false; 7055 } else { 7056 current += letter; 7057 } 7058 } 7059 if (last || current !== '') array.push(current.trim()); 7060 return array; 7061 } 7062}; 7063module.exports = list; 7064list.default = list; 7065}), 7066893894, ((__turbopack_context__, module, exports) => { 7067"use strict"; 7068 7069let Container = __turbopack_context__.r(296045); 7070let list = __turbopack_context__.r(350215); 7071class Rule extends Container { 7072 get selectors() { 7073 return list.comma(this.selector); 7074 } 7075 set selectors(values) { 7076 let match = this.selector ? this.selector.match(/,\s*/) : null; 7077 let sep = match ? match[0] : ',' + this.raw('between', 'beforeOpen'); 7078 this.selector = values.join(sep); 7079 } 7080 constructor(defaults){ 7081 super(defaults); 7082 this.type = 'rule'; 7083 if (!this.nodes) this.nodes = []; 7084 } 7085} 7086module.exports = Rule; 7087Rule.default = Rule; 7088Container.registerRule(Rule); 7089}), 7090498729, ((__turbopack_context__, module, exports) => { 7091"use strict"; 7092 7093let AtRule = __turbopack_context__.r(670255); 7094let Comment = __turbopack_context__.r(877906); 7095let Declaration = __turbopack_context__.r(721772); 7096let Input = __turbopack_context__.r(2278); 7097let PreviousMap = __turbopack_context__.r(804468); 7098let Root = __turbopack_context__.r(551517); 7099let Rule = __turbopack_context__.r(893894); 7100function fromJSON(json, inputs) { 7101 if (Array.isArray(json)) return json.map((n)=>fromJSON(n)); 7102 let { inputs: ownInputs, ...defaults } = json; 7103 if (ownInputs) { 7104 inputs = []; 7105 for (let input of ownInputs){ 7106 let inputHydrated = { 7107 ...input, 7108 __proto__: Input.prototype 7109 }; 7110 if (inputHydrated.map) { 7111 inputHydrated.map = { 7112 ...inputHydrated.map, 7113 __proto__: PreviousMap.prototype 7114 }; 7115 } 7116 inputs.push(inputHydrated); 7117 } 7118 } 7119 if (defaults.nodes) { 7120 defaults.nodes = json.nodes.map((n)=>fromJSON(n, inputs)); 7121 } 7122 if (defaults.source) { 7123 let { inputId, ...source } = defaults.source; 7124 defaults.source = source; 7125 if (inputId != null) { 7126 defaults.source.input = inputs[inputId]; 7127 } 7128 } 7129 if (defaults.type === 'root') { 7130 return new Root(defaults); 7131 } else if (defaults.type === 'decl') { 7132 return new Declaration(defaults); 7133 } else if (defaults.type === 'rule') { 7134 return new Rule(defaults); 7135 } else if (defaults.type === 'comment') { 7136 return new Comment(defaults); 7137 } else if (defaults.type === 'atrule') { 7138 return new AtRule(defaults); 7139 } else { 7140 throw new Error('Unknown node type: ' + json.type); 7141 } 7142} 7143module.exports = fromJSON; 7144fromJSON.default = fromJSON; 7145}), 7146320194, ((__turbopack_context__, module, exports) => { 7147"use strict"; 7148 7149var __TURBOPACK__imported__module__467034__ = /*#__PURE__*/ __turbopack_context__.i(467034); 7150'use strict'; 7151let { dirname, relative, resolve, sep } = {}; 7152let { SourceMapConsumer, SourceMapGenerator } = {}; 7153let { pathToFileURL } = __turbopack_context__.r(421342); 7154let Input = __turbopack_context__.r(2278); 7155let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator); 7156let pathAvailable = Boolean(dirname && resolve && relative && sep); 7157class MapGenerator { 7158 constructor(stringify, root, opts, cssString){ 7159 this.stringify = stringify; 7160 this.mapOpts = opts.map || {}; 7161 this.root = root; 7162 this.opts = opts; 7163 this.css = cssString; 7164 this.originalCSS = cssString; 7165 this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute; 7166 this.memoizedFileURLs = new Map(); 7167 this.memoizedPaths = new Map(); 7168 this.memoizedURLs = new Map(); 7169 } 7170 addAnnotation() { 7171 let content; 7172 if (this.isInline()) { 7173 content = 'data:application/json;base64,' + this.toBase64(this.map.toString()); 7174 } else if (typeof this.mapOpts.annotation === 'string') { 7175 content = this.mapOpts.annotation; 7176 } else if (typeof this.mapOpts.annotation === 'function') { 7177 content = this.mapOpts.annotation(this.opts.to, this.root); 7178 } else { 7179 content = this.outputFile() + '.map'; 7180 } 7181 let eol = '\n'; 7182 if (this.css.includes('\r\n')) eol = '\r\n'; 7183 this.css += eol + '/*# sourceMappingURL=' + content + ' */'; 7184 } 7185 applyPrevMaps() { 7186 for (let prev of this.previous()){ 7187 let from = this.toUrl(this.path(prev.file)); 7188 let root = prev.root || dirname(prev.file); 7189 let map; 7190 if (this.mapOpts.sourcesContent === false) { 7191 map = new SourceMapConsumer(prev.text); 7192 if (map.sourcesContent) { 7193 map.sourcesContent = null; 7194 } 7195 } else { 7196 map = prev.consumer(); 7197 } 7198 this.map.applySourceMap(map, from, this.toUrl(this.path(root))); 7199 } 7200 } 7201 clearAnnotation() { 7202 if (this.mapOpts.annotation === false) return; 7203 if (this.root) { 7204 let node; 7205 for(let i = this.root.nodes.length - 1; i >= 0; i--){ 7206 node = this.root.nodes[i]; 7207 if (node.type !== 'comment') continue; 7208 if (node.text.startsWith('# sourceMappingURL=')) { 7209 this.root.removeChild(i); 7210 } 7211 } 7212 } else if (this.css) { 7213 let startIndex; 7214 while((startIndex = this.css.lastIndexOf('/*#')) !== -1){ 7215 let endIndex = this.css.indexOf('*/', startIndex + 3); 7216 if (endIndex === -1) break; 7217 while(startIndex > 0 && this.css[startIndex - 1] === '\n'){ 7218 startIndex--; 7219 } 7220 this.css = this.css.slice(0, startIndex) + this.css.slice(endIndex + 2); 7221 } 7222 } 7223 } 7224 generate() { 7225 this.clearAnnotation(); 7226 if (pathAvailable && sourceMapAvailable && this.isMap()) { 7227 return this.generateMap(); 7228 } else { 7229 let result = ''; 7230 this.stringify(this.root, (i)=>{ 7231 result += i; 7232 }); 7233 return [ 7234 result 7235 ]; 7236 } 7237 } 7238 generateMap() { 7239 if (this.root) { 7240 this.generateString(); 7241 } else if (this.previous().length === 1) { 7242 let prev = this.previous()[0].consumer(); 7243 prev.file = this.outputFile(); 7244 this.map = SourceMapGenerator.fromSourceMap(prev, { 7245 ignoreInvalidMapping: true 7246 }); 7247 } else { 7248 this.map = new SourceMapGenerator({ 7249 file: this.outputFile(), 7250 ignoreInvalidMapping: true 7251 }); 7252 this.map.addMapping({ 7253 generated: { 7254 column: 0, 7255 line: 1 7256 }, 7257 original: { 7258 column: 0, 7259 line: 1 7260 }, 7261 source: this.opts.from ? this.toUrl(this.path(this.opts.from)) : '<no source>' 7262 }); 7263 } 7264 if (this.isSourcesContent()) this.setSourcesContent(); 7265 if (this.root && this.previous().length > 0) this.applyPrevMaps(); 7266 if (this.isAnnotation()) this.addAnnotation(); 7267 if (this.isInline()) { 7268 return [ 7269 this.css 7270 ]; 7271 } else { 7272 return [ 7273 this.css, 7274 this.map 7275 ]; 7276 } 7277 } 7278 generateString() { 7279 this.css = ''; 7280 this.map = new SourceMapGenerator({ 7281 file: this.outputFile(), 7282 ignoreInvalidMapping: true 7283 }); 7284 let line = 1; 7285 let column = 1; 7286 let noSource = '<no source>'; 7287 let mapping = { 7288 generated: { 7289 column: 0, 7290 line: 0 7291 }, 7292 original: { 7293 column: 0, 7294 line: 0 7295 }, 7296 source: '' 7297 }; 7298 let last, lines; 7299 this.stringify(this.root, (str, node, type)=>{ 7300 this.css += str; 7301 if (node && type !== 'end') { 7302 mapping.generated.line = line; 7303 mapping.generated.column = column - 1; 7304 if (node.source && node.source.start) { 7305 mapping.source = this.sourcePath(node); 7306 mapping.original.line = node.source.start.line; 7307 mapping.original.column = node.source.start.column - 1; 7308 this.map.addMapping(mapping); 7309 } else { 7310 mapping.source = noSource; 7311 mapping.original.line = 1; 7312 mapping.original.column = 0; 7313 this.map.addMapping(mapping); 7314 } 7315 } 7316 lines = str.match(/\n/g); 7317 if (lines) { 7318 line += lines.length; 7319 last = str.lastIndexOf('\n'); 7320 column = str.length - last; 7321 } else { 7322 column += str.length; 7323 } 7324 if (node && type !== 'start') { 7325 let p = node.parent || { 7326 raws: {} 7327 }; 7328 let childless = node.type === 'decl' || node.type === 'atrule' && !node.nodes; 7329 if (!childless || node !== p.last || p.raws.semicolon) { 7330 if (node.source && node.source.end) { 7331 mapping.source = this.sourcePath(node); 7332 mapping.original.line = node.source.end.line; 7333 mapping.original.column = node.source.end.column - 1; 7334 mapping.generated.line = line; 7335 mapping.generated.column = column - 2; 7336 this.map.addMapping(mapping); 7337 } else { 7338 mapping.source = noSource; 7339 mapping.original.line = 1; 7340 mapping.original.column = 0; 7341 mapping.generated.line = line; 7342 mapping.generated.column = column - 1; 7343 this.map.addMapping(mapping); 7344 } 7345 } 7346 } 7347 }); 7348 } 7349 isAnnotation() { 7350 if (this.isInline()) { 7351 return true; 7352 } 7353 if (typeof this.mapOpts.annotation !== 'undefined') { 7354 return this.mapOpts.annotation; 7355 } 7356 if (this.previous().length) { 7357 return this.previous().some((i)=>i.annotation); 7358 } 7359 return true; 7360 } 7361 isInline() { 7362 if (typeof this.mapOpts.inline !== 'undefined') { 7363 return this.mapOpts.inline; 7364 } 7365 let annotation = this.mapOpts.annotation; 7366 if (typeof annotation !== 'undefined' && annotation !== true) { 7367 return false;
vendor: 19,150 bytes, lines 7368-7908
7368 } 7369 if (this.previous().length) { 7370 return this.previous().some((i)=>i.inline); 7371 } 7372 return true; 7373 } 7374 isMap() { 7375 if (typeof this.opts.map !== 'undefined') { 7376 return !!this.opts.map; 7377 } 7378 return this.previous().length > 0; 7379 } 7380 isSourcesContent() { 7381 if (typeof this.mapOpts.sourcesContent !== 'undefined') { 7382 return this.mapOpts.sourcesContent; 7383 } 7384 if (this.previous().length) { 7385 return this.previous().some((i)=>i.withContent()); 7386 } 7387 return true; 7388 } 7389 outputFile() { 7390 if (this.opts.to) { 7391 return this.path(this.opts.to); 7392 } else if (this.opts.from) { 7393 return this.path(this.opts.from); 7394 } else { 7395 return 'to.css'; 7396 } 7397 } 7398 path(file) { 7399 if (this.mapOpts.absolute) return file; 7400 if (file.charCodeAt(0) === 60 /* `<` */ ) return file; 7401 if (/^\w+:\/\//.test(file)) return file; 7402 let cached = this.memoizedPaths.get(file); 7403 if (cached) return cached; 7404 let from = this.opts.to ? dirname(this.opts.to) : '.'; 7405 if (typeof this.mapOpts.annotation === 'string') { 7406 from = dirname(resolve(from, this.mapOpts.annotation)); 7407 } 7408 let path = relative(from, file); 7409 this.memoizedPaths.set(file, path); 7410 return path; 7411 } 7412 previous() { 7413 if (!this.previousMaps) { 7414 this.previousMaps = []; 7415 if (this.root) { 7416 this.root.walk((node)=>{ 7417 if (node.source && node.source.input.map) { 7418 let map = node.source.input.map; 7419 if (!this.previousMaps.includes(map)) { 7420 this.previousMaps.push(map); 7421 } 7422 } 7423 }); 7424 } else { 7425 let input = new Input(this.originalCSS, this.opts); 7426 if (input.map) this.previousMaps.push(input.map); 7427 } 7428 } 7429 return this.previousMaps; 7430 } 7431 setSourcesContent() { 7432 let already = {}; 7433 if (this.root) { 7434 this.root.walk((node)=>{ 7435 if (node.source) { 7436 let from = node.source.input.from; 7437 if (from && !already[from]) { 7438 already[from] = true; 7439 let fromUrl = this.usesFileUrls ? this.toFileUrl(from) : this.toUrl(this.path(from)); 7440 this.map.setSourceContent(fromUrl, node.source.input.css); 7441 } 7442 } 7443 }); 7444 } else if (this.css) { 7445 let from = this.opts.from ? this.toUrl(this.path(this.opts.from)) : '<no source>'; 7446 this.map.setSourceContent(from, this.css); 7447 } 7448 } 7449 sourcePath(node) { 7450 if (this.mapOpts.from) { 7451 return this.toUrl(this.mapOpts.from); 7452 } else if (this.usesFileUrls) { 7453 return this.toFileUrl(node.source.input.from); 7454 } else { 7455 return this.toUrl(this.path(node.source.input.from)); 7456 } 7457 } 7458 toBase64(str) { 7459 if ("TURBOPACK compile-time truthy", 1) { 7460 return __TURBOPACK__imported__module__467034__["Buffer"].from(str).toString('base64'); 7461 } else //TURBOPACK unreachable 7462 ; 7463 } 7464 toFileUrl(path) { 7465 let cached = this.memoizedFileURLs.get(path); 7466 if (cached) return cached; 7467 if (pathToFileURL) { 7468 let fileURL = pathToFileURL(path).toString(); 7469 this.memoizedFileURLs.set(path, fileURL); 7470 return fileURL; 7471 } else { 7472 throw new Error('`map.absolute` option is not available in this PostCSS build'); 7473 } 7474 } 7475 toUrl(path) { 7476 let cached = this.memoizedURLs.get(path); 7477 if (cached) return cached; 7478 if (sep === '\\') { 7479 path = path.replace(/\\/g, '/'); 7480 } 7481 let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent); 7482 this.memoizedURLs.set(path, url); 7483 return url; 7484 } 7485} 7486module.exports = MapGenerator; 7487}), 748846980, ((__turbopack_context__, module, exports) => { 7489"use strict"; 7490 7491const SINGLE_QUOTE = "'".charCodeAt(0); 7492const DOUBLE_QUOTE = '"'.charCodeAt(0); 7493const BACKSLASH = '\\'.charCodeAt(0); 7494const SLASH = '/'.charCodeAt(0); 7495const NEWLINE = '\n'.charCodeAt(0); 7496const SPACE = ' '.charCodeAt(0); 7497const FEED = '\f'.charCodeAt(0); 7498const TAB = '\t'.charCodeAt(0); 7499const CR = '\r'.charCodeAt(0); 7500const OPEN_SQUARE = '['.charCodeAt(0); 7501const CLOSE_SQUARE = ']'.charCodeAt(0); 7502const OPEN_PARENTHESES = '('.charCodeAt(0); 7503const CLOSE_PARENTHESES = ')'.charCodeAt(0); 7504const OPEN_CURLY = '{'.charCodeAt(0); 7505const CLOSE_CURLY = '}'.charCodeAt(0); 7506const SEMICOLON = ';'.charCodeAt(0); 7507const ASTERISK = '*'.charCodeAt(0); 7508const COLON = ':'.charCodeAt(0); 7509const AT = '@'.charCodeAt(0); 7510const RE_AT_END = /[\t\n\f\r "#'()/;[\\\]{}]/g; 7511const RE_WORD_END = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g; 7512const RE_BAD_BRACKET = /.[\r\n"'(/\\]/; 7513const RE_HEX_ESCAPE = /[\da-f]/i; 7514module.exports = function tokenizer(input, options = {}) { 7515 let css = input.css.valueOf(); 7516 let ignore = options.ignoreErrors; 7517 let code, content, escape, next, quote; 7518 let currentToken, escaped, escapePos, n, prev; 7519 let length = css.length; 7520 let pos = 0; 7521 let buffer = []; 7522 let returned = []; 7523 function position() { 7524 return pos; 7525 } 7526 function unclosed(what) { 7527 throw input.error('Unclosed ' + what, pos); 7528 } 7529 function endOfFile() { 7530 return returned.length === 0 && pos >= length; 7531 } 7532 function nextToken(opts) { 7533 if (returned.length) return returned.pop(); 7534 if (pos >= length) return; 7535 let ignoreUnclosed = opts ? opts.ignoreUnclosed : false; 7536 code = css.charCodeAt(pos); 7537 switch(code){ 7538 case NEWLINE: 7539 case SPACE: 7540 case TAB: 7541 case CR: 7542 case FEED: 7543 { 7544 next = pos; 7545 do { 7546 next += 1; 7547 code = css.charCodeAt(next); 7548 }while (code === SPACE || code === NEWLINE || code === TAB || code === CR || code === FEED) 7549 currentToken = [ 7550 'space', 7551 css.slice(pos, next) 7552 ]; 7553 pos = next - 1; 7554 break; 7555 } 7556 case OPEN_SQUARE: 7557 case CLOSE_SQUARE: 7558 case OPEN_CURLY: 7559 case CLOSE_CURLY: 7560 case COLON: 7561 case SEMICOLON: 7562 case CLOSE_PARENTHESES: 7563 { 7564 let controlChar = String.fromCharCode(code); 7565 currentToken = [ 7566 controlChar, 7567 controlChar, 7568 pos 7569 ]; 7570 break; 7571 } 7572 case OPEN_PARENTHESES: 7573 { 7574 prev = buffer.length ? buffer.pop()[1] : ''; 7575 n = css.charCodeAt(pos + 1); 7576 if (prev === 'url' && n !== SINGLE_QUOTE && n !== DOUBLE_QUOTE && n !== SPACE && n !== NEWLINE && n !== TAB && n !== FEED && n !== CR) { 7577 next = pos; 7578 do { 7579 escaped = false; 7580 next = css.indexOf(')', next + 1); 7581 if (next === -1) { 7582 if (ignore || ignoreUnclosed) { 7583 next = pos; 7584 break; 7585 } else { 7586 unclosed('bracket'); 7587 } 7588 } 7589 escapePos = next; 7590 while(css.charCodeAt(escapePos - 1) === BACKSLASH){ 7591 escapePos -= 1; 7592 escaped = !escaped; 7593 } 7594 }while (escaped) 7595 currentToken = [ 7596 'brackets', 7597 css.slice(pos, next + 1), 7598 pos, 7599 next 7600 ]; 7601 pos = next; 7602 } else { 7603 next = css.indexOf(')', pos + 1); 7604 content = css.slice(pos, next + 1); 7605 if (next === -1 || RE_BAD_BRACKET.test(content)) { 7606 currentToken = [ 7607 '(', 7608 '(', 7609 pos 7610 ]; 7611 } else { 7612 currentToken = [ 7613 'brackets', 7614 content, 7615 pos, 7616 next 7617 ]; 7618 pos = next; 7619 } 7620 } 7621 break; 7622 } 7623 case SINGLE_QUOTE: 7624 case DOUBLE_QUOTE: 7625 { 7626 quote = code === SINGLE_QUOTE ? "'" : '"'; 7627 next = pos; 7628 do { 7629 escaped = false; 7630 next = css.indexOf(quote, next + 1); 7631 if (next === -1) { 7632 if (ignore || ignoreUnclosed) { 7633 next = pos + 1; 7634 break; 7635 } else { 7636 unclosed('string'); 7637 } 7638 } 7639 escapePos = next; 7640 while(css.charCodeAt(escapePos - 1) === BACKSLASH){ 7641 escapePos -= 1; 7642 escaped = !escaped; 7643 } 7644 }while (escaped) 7645 currentToken = [ 7646 'string', 7647 css.slice(pos, next + 1), 7648 pos, 7649 next 7650 ]; 7651 pos = next; 7652 break; 7653 } 7654 case AT: 7655 { 7656 RE_AT_END.lastIndex = pos + 1; 7657 RE_AT_END.test(css); 7658 if (RE_AT_END.lastIndex === 0) { 7659 next = css.length - 1; 7660 } else { 7661 next = RE_AT_END.lastIndex - 2; 7662 } 7663 currentToken = [ 7664 'at-word', 7665 css.slice(pos, next + 1), 7666 pos, 7667 next 7668 ]; 7669 pos = next; 7670 break; 7671 } 7672 case BACKSLASH: 7673 { 7674 next = pos; 7675 escape = true; 7676 while(css.charCodeAt(next + 1) === BACKSLASH){ 7677 next += 1; 7678 escape = !escape; 7679 } 7680 code = css.charCodeAt(next + 1); 7681 if (escape && code !== SLASH && code !== SPACE && code !== NEWLINE && code !== TAB && code !== CR && code !== FEED) { 7682 next += 1; 7683 if (RE_HEX_ESCAPE.test(css.charAt(next))) { 7684 while(RE_HEX_ESCAPE.test(css.charAt(next + 1))){ 7685 next += 1; 7686 } 7687 if (css.charCodeAt(next + 1) === SPACE) { 7688 next += 1; 7689 } 7690 } 7691 } 7692 currentToken = [ 7693 'word', 7694 css.slice(pos, next + 1), 7695 pos, 7696 next 7697 ]; 7698 pos = next; 7699 break; 7700 } 7701 default: 7702 { 7703 if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) { 7704 next = css.indexOf('*/', pos + 2) + 1; 7705 if (next === 0) { 7706 if (ignore || ignoreUnclosed) { 7707 next = css.length; 7708 } else { 7709 unclosed('comment'); 7710 } 7711 } 7712 currentToken = [ 7713 'comment', 7714 css.slice(pos, next + 1), 7715 pos, 7716 next 7717 ]; 7718 pos = next; 7719 } else { 7720 RE_WORD_END.lastIndex = pos + 1; 7721 RE_WORD_END.test(css); 7722 if (RE_WORD_END.lastIndex === 0) { 7723 next = css.length - 1; 7724 } else { 7725 next = RE_WORD_END.lastIndex - 2; 7726 } 7727 currentToken = [ 7728 'word', 7729 css.slice(pos, next + 1), 7730 pos, 7731 next 7732 ]; 7733 buffer.push(currentToken); 7734 pos = next; 7735 } 7736 break; 7737 } 7738 } 7739 pos++; 7740 return currentToken; 7741 } 7742 function back(token) { 7743 returned.push(token); 7744 } 7745 return { 7746 back, 7747 endOfFile, 7748 nextToken, 7749 position 7750 }; 7751}; 7752}), 7753552371, ((__turbopack_context__, module, exports) => { 7754"use strict"; 7755 7756let AtRule = __turbopack_context__.r(670255); 7757let Comment = __turbopack_context__.r(877906); 7758let Declaration = __turbopack_context__.r(721772); 7759let Root = __turbopack_context__.r(551517); 7760let Rule = __turbopack_context__.r(893894); 7761let tokenizer = __turbopack_context__.r(46980); 7762const SAFE_COMMENT_NEIGHBOR = { 7763 empty: true, 7764 space: true 7765}; 7766function findLastWithPosition(tokens) { 7767 for(let i = tokens.length - 1; i >= 0; i--){ 7768 let token = tokens[i]; 7769 let pos = token[3] || token[2]; 7770 if (pos) return pos; 7771 } 7772} 7773class Parser { 7774 constructor(input){ 7775 this.input = input; 7776 this.root = new Root(); 7777 this.current = this.root; 7778 this.spaces = ''; 7779 this.semicolon = false; 7780 this.createTokenizer(); 7781 this.root.source = { 7782 input, 7783 start: { 7784 column: 1, 7785 line: 1, 7786 offset: 0 7787 } 7788 }; 7789 } 7790 atrule(token) { 7791 let node = new AtRule(); 7792 node.name = token[1].slice(1); 7793 if (node.name === '') { 7794 this.unnamedAtrule(node, token); 7795 } 7796 this.init(node, token[2]); 7797 let type; 7798 let prev; 7799 let shift; 7800 let last = false; 7801 let open = false; 7802 let params = []; 7803 let brackets = []; 7804 while(!this.tokenizer.endOfFile()){ 7805 token = this.tokenizer.nextToken(); 7806 type = token[0]; 7807 if (type === '(' || type === '[') { 7808 brackets.push(type === '(' ? ')' : ']'); 7809 } else if (type === '{' && brackets.length > 0) { 7810 brackets.push('}'); 7811 } else if (type === brackets[brackets.length - 1]) { 7812 brackets.pop(); 7813 } 7814 if (brackets.length === 0) { 7815 if (type === ';') { 7816 node.source.end = this.getPosition(token[2]); 7817 node.source.end.offset++; 7818 this.semicolon = true; 7819 break; 7820 } else if (type === '{') { 7821 open = true; 7822 break; 7823 } else if (type === '}') { 7824 if (params.length > 0) { 7825 shift = params.length - 1; 7826 prev = params[shift]; 7827 while(prev && prev[0] === 'space'){ 7828 prev = params[--shift]; 7829 } 7830 if (prev) { 7831 node.source.end = this.getPosition(prev[3] || prev[2]); 7832 node.source.end.offset++; 7833 } 7834 } 7835 this.end(token); 7836 break; 7837 } else { 7838 params.push(token); 7839 } 7840 } else { 7841 params.push(token); 7842 } 7843 if (this.tokenizer.endOfFile()) { 7844 last = true; 7845 break; 7846 } 7847 } 7848 node.raws.between = this.spacesAndCommentsFromEnd(params); 7849 if (params.length) { 7850 node.raws.afterName = this.spacesAndCommentsFromStart(params); 7851 this.raw(node, 'params', params); 7852 if (last) { 7853 token = params[params.length - 1]; 7854 node.source.end = this.getPosition(token[3] || token[2]); 7855 node.source.end.offset++; 7856 this.spaces = node.raws.between; 7857 node.raws.between = ''; 7858 } 7859 } else { 7860 node.raws.afterName = ''; 7861 node.params = ''; 7862 } 7863 if (open) { 7864 node.nodes = []; 7865 this.current = node; 7866 } 7867 } 7868 checkMissedSemicolon(tokens) { 7869 let colon = this.colon(tokens); 7870 if (colon === false) return; 7871 let founded = 0; 7872 let token; 7873 for(let j = colon - 1; j >= 0; j--){ 7874 token = tokens[j]; 7875 if (token[0] !== 'space') { 7876 founded += 1; 7877 if (founded === 2) break; 7878 } 7879 } 7880 // If the token is a word, e.g. `!important`, `red` or any other valid property's value. 7881 // Then we need to return the colon after that word token. [3] is the "end" colon of that word. 7882 // And because we need it after that one we do +1 to get the next one. 7883 throw this.input.error('Missed semicolon', token[0] === 'word' ? token[3] + 1 : token[2]); 7884 } 7885 colon(tokens) { 7886 let brackets = 0; 7887 let prev, token, type; 7888 for (let [i, element] of tokens.entries()){ 7889 token = element; 7890 type = token[0]; 7891 if (type === '(') { 7892 brackets += 1; 7893 } 7894 if (type === ')') { 7895 brackets -= 1; 7896 } 7897 if (brackets === 0 && type === ':') { 7898 if (!prev) { 7899 this.doubleColon(token); 7900 } else if (prev[0] === 'word' && prev[1] === 'progid') { 7901 continue; 7902 } else { 7903 return i; 7904 } 7905 } 7906 prev = token; 7907 } 7908 return false;
vendor: 9,702 bytes, lines 7909-8187
7909 } 7910 comment(token) { 7911 let node = new Comment(); 7912 this.init(node, token[2]); 7913 node.source.end = this.getPosition(token[3] || token[2]); 7914 node.source.end.offset++; 7915 let text = token[1].slice(2, -2); 7916 if (!text.trim()) { 7917 node.text = ''; 7918 node.raws.left = text; 7919 node.raws.right = ''; 7920 } else { 7921 let match = text.match(/^(\s*)([^]*\S)(\s*)$/); 7922 node.text = match[2]; 7923 node.raws.left = match[1]; 7924 node.raws.right = match[3]; 7925 } 7926 } 7927 createTokenizer() { 7928 this.tokenizer = tokenizer(this.input); 7929 } 7930 decl(tokens, customProperty) { 7931 let node = new Declaration(); 7932 this.init(node, tokens[0][2]); 7933 let last = tokens[tokens.length - 1]; 7934 if (last[0] === ';') { 7935 this.semicolon = true; 7936 tokens.pop(); 7937 } 7938 node.source.end = this.getPosition(last[3] || last[2] || findLastWithPosition(tokens)); 7939 node.source.end.offset++; 7940 while(tokens[0][0] !== 'word'){ 7941 if (tokens.length === 1) this.unknownWord(tokens); 7942 node.raws.before += tokens.shift()[1]; 7943 } 7944 node.source.start = this.getPosition(tokens[0][2]); 7945 node.prop = ''; 7946 while(tokens.length){ 7947 let type = tokens[0][0]; 7948 if (type === ':' || type === 'space' || type === 'comment') { 7949 break; 7950 } 7951 node.prop += tokens.shift()[1]; 7952 } 7953 node.raws.between = ''; 7954 let token; 7955 while(tokens.length){ 7956 token = tokens.shift(); 7957 if (token[0] === ':') { 7958 node.raws.between += token[1]; 7959 break; 7960 } else { 7961 if (token[0] === 'word' && /\w/.test(token[1])) { 7962 this.unknownWord([ 7963 token 7964 ]); 7965 } 7966 node.raws.between += token[1]; 7967 } 7968 } 7969 if (node.prop[0] === '_' || node.prop[0] === '*') { 7970 node.raws.before += node.prop[0]; 7971 node.prop = node.prop.slice(1); 7972 } 7973 let firstSpaces = []; 7974 let next; 7975 while(tokens.length){ 7976 next = tokens[0][0]; 7977 if (next !== 'space' && next !== 'comment') break; 7978 firstSpaces.push(tokens.shift()); 7979 } 7980 this.precheckMissedSemicolon(tokens); 7981 for(let i = tokens.length - 1; i >= 0; i--){ 7982 token = tokens[i]; 7983 if (token[1].toLowerCase() === '!important') { 7984 node.important = true; 7985 let string = this.stringFrom(tokens, i); 7986 string = this.spacesFromEnd(tokens) + string; 7987 if (string !== ' !important') node.raws.important = string; 7988 break; 7989 } else if (token[1].toLowerCase() === 'important') { 7990 let cache = tokens.slice(0); 7991 let str = ''; 7992 for(let j = i; j > 0; j--){ 7993 let type = cache[j][0]; 7994 if (str.trim().startsWith('!') && type !== 'space') { 7995 break; 7996 } 7997 str = cache.pop()[1] + str; 7998 } 7999 if (str.trim().startsWith('!')) { 8000 node.important = true; 8001 node.raws.important = str; 8002 tokens = cache; 8003 } 8004 } 8005 if (token[0] !== 'space' && token[0] !== 'comment') { 8006 break; 8007 } 8008 } 8009 let hasWord = tokens.some((i)=>i[0] !== 'space' && i[0] !== 'comment'); 8010 if (hasWord) { 8011 node.raws.between += firstSpaces.map((i)=>i[1]).join(''); 8012 firstSpaces = []; 8013 } 8014 this.raw(node, 'value', firstSpaces.concat(tokens), customProperty); 8015 if (node.value.includes(':') && !customProperty) { 8016 this.checkMissedSemicolon(tokens); 8017 } 8018 } 8019 doubleColon(token) { 8020 throw this.input.error('Double colon', { 8021 offset: token[2] 8022 }, { 8023 offset: token[2] + token[1].length 8024 }); 8025 } 8026 emptyRule(token) { 8027 let node = new Rule(); 8028 this.init(node, token[2]); 8029 node.selector = ''; 8030 node.raws.between = ''; 8031 this.current = node; 8032 } 8033 end(token) { 8034 if (this.current.nodes && this.current.nodes.length) { 8035 this.current.raws.semicolon = this.semicolon; 8036 } 8037 this.semicolon = false; 8038 this.current.raws.after = (this.current.raws.after || '') + this.spaces; 8039 this.spaces = ''; 8040 if (this.current.parent) { 8041 this.current.source.end = this.getPosition(token[2]); 8042 this.current.source.end.offset++; 8043 this.current = this.current.parent; 8044 } else { 8045 this.unexpectedClose(token); 8046 } 8047 } 8048 endFile() { 8049 if (this.current.parent) this.unclosedBlock(); 8050 if (this.current.nodes && this.current.nodes.length) { 8051 this.current.raws.semicolon = this.semicolon; 8052 } 8053 this.current.raws.after = (this.current.raws.after || '') + this.spaces; 8054 this.root.source.end = this.getPosition(this.tokenizer.position()); 8055 } 8056 freeSemicolon(token) { 8057 this.spaces += token[1]; 8058 if (this.current.nodes) { 8059 let prev = this.current.nodes[this.current.nodes.length - 1]; 8060 if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) { 8061 prev.raws.ownSemicolon = this.spaces; 8062 this.spaces = ''; 8063 prev.source.end = this.getPosition(token[2]); 8064 prev.source.end.offset += prev.raws.ownSemicolon.length; 8065 } 8066 } 8067 } 8068 // Helpers 8069 getPosition(offset) { 8070 let pos = this.input.fromOffset(offset); 8071 return { 8072 column: pos.col, 8073 line: pos.line, 8074 offset 8075 }; 8076 } 8077 init(node, offset) { 8078 this.current.push(node); 8079 node.source = { 8080 input: this.input, 8081 start: this.getPosition(offset) 8082 }; 8083 node.raws.before = this.spaces; 8084 this.spaces = ''; 8085 if (node.type !== 'comment') this.semicolon = false; 8086 } 8087 other(start) { 8088 let end = false; 8089 let type = null; 8090 let colon = false; 8091 let bracket = null; 8092 let brackets = []; 8093 let customProperty = start[1].startsWith('--'); 8094 let tokens = []; 8095 let token = start; 8096 while(token){ 8097 type = token[0]; 8098 tokens.push(token); 8099 if (type === '(' || type === '[') { 8100 if (!bracket) bracket = token; 8101 brackets.push(type === '(' ? ')' : ']'); 8102 } else if (customProperty && colon && type === '{') { 8103 if (!bracket) bracket = token; 8104 brackets.push('}'); 8105 } else if (brackets.length === 0) { 8106 if (type === ';') { 8107 if (colon) { 8108 this.decl(tokens, customProperty); 8109 return; 8110 } else { 8111 break; 8112 } 8113 } else if (type === '{') { 8114 this.rule(tokens); 8115 return; 8116 } else if (type === '}') { 8117 this.tokenizer.back(tokens.pop()); 8118 end = true; 8119 break; 8120 } else if (type === ':') { 8121 colon = true; 8122 } 8123 } else if (type === brackets[brackets.length - 1]) { 8124 brackets.pop(); 8125 if (brackets.length === 0) bracket = null; 8126 } 8127 token = this.tokenizer.nextToken(); 8128 } 8129 if (this.tokenizer.endOfFile()) end = true; 8130 if (brackets.length > 0) this.unclosedBracket(bracket); 8131 if (end && colon) { 8132 if (!customProperty) { 8133 while(tokens.length){ 8134 token = tokens[tokens.length - 1][0]; 8135 if (token !== 'space' && token !== 'comment') break; 8136 this.tokenizer.back(tokens.pop()); 8137 } 8138 } 8139 this.decl(tokens, customProperty); 8140 } else { 8141 this.unknownWord(tokens); 8142 } 8143 } 8144 parse() { 8145 let token; 8146 while(!this.tokenizer.endOfFile()){ 8147 token = this.tokenizer.nextToken(); 8148 switch(token[0]){ 8149 case 'space': 8150 this.spaces += token[1]; 8151 break; 8152 case ';': 8153 this.freeSemicolon(token); 8154 break; 8155 case '}': 8156 this.end(token); 8157 break; 8158 case 'comment': 8159 this.comment(token); 8160 break; 8161 case 'at-word': 8162 this.atrule(token); 8163 break; 8164 case '{': 8165 this.emptyRule(token); 8166 break; 8167 default: 8168 this.other(token); 8169 break; 8170 } 8171 } 8172 this.endFile(); 8173 } 8174 precheckMissedSemicolon() { 8175 // Hook for Safe Parser 8176 } 8177 raw(node, prop, tokens, customProperty) { 8178 let token, type; 8179 let length = tokens.length; 8180 let value = ''; 8181 let clean = true; 8182 let next, prev; 8183 for(let i = 0; i < length; i += 1){ 8184 token = tokens[i]; 8185 type = token[0]; 8186 if (type === 'space' && i === length - 1 && !customProperty) { 8187 clean = false;
8188 } else if (type === 'comment') { 8189 prev = tokens[i - 1] ? tokens[i - 1][0] : 'empty'; 8190 next = tokens[i + 1] ? tokens[i + 1][0] : 'empty'; 8191 if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) { 8192 if (value.slice(-1) === ',') { 8193 clean = false; 8194 } else { 8195 value += token[1]; 8196 } 8197 } else { 8198 clean = false; 8199 } 8200 } else { 8201 value += token[1]; 8202 } 8203 } 8204 if (!clean) { 8205 let raw = tokens.reduce((all, i)=>all + i[1], ''); 8206 node.raws[prop] = { 8207 raw, 8208 value 8209 }; 8210 } 8211 node[prop] = value; 8212 } 8213 rule(tokens) { 8214 tokens.pop(); 8215 let node = new Rule(); 8216 this.init(node, tokens[0][2]); 8217 node.raws.between = this.spacesAndCommentsFromEnd(tokens); 8218 this.raw(node, 'selector', tokens); 8219 this.current = node; 8220 } 8221 spacesAndCommentsFromEnd(tokens) { 8222 let lastTokenType; 8223 let spaces = ''; 8224 while(tokens.length){ 8225 lastTokenType = tokens[tokens.length - 1][0]; 8226 if (lastTokenType !== 'space' && lastTokenType !== 'comment') break; 8227 spaces = tokens.pop()[1] + spaces; 8228 } 8229 return spaces; 8230 } 8231 // Errors 8232 spacesAndCommentsFromStart(tokens) { 8233 let next; 8234 let spaces = ''; 8235 while(tokens.length){ 8236 next = tokens[0][0]; 8237 if (next !== 'space' && next !== 'comment') break; 8238 spaces += tokens.shift()[1]; 8239 } 8240 return spaces; 8241 } 8242 spacesFromEnd(tokens) { 8243 let lastTokenType; 8244 let spaces = ''; 8245 while(tokens.length){ 8246 lastTokenType = tokens[tokens.length - 1][0]; 8247 if (lastTokenType !== 'space') break; 8248 spaces = tokens.pop()[1] + spaces; 8249 } 8250 return spaces; 8251 } 8252 stringFrom(tokens, from) { 8253 let result = ''; 8254 for(let i = from; i < tokens.length; i++){ 8255 result += tokens[i][1]; 8256 } 8257 tokens.splice(from, tokens.length - from); 8258 return result; 8259 } 8260 unclosedBlock() { 8261 let pos = this.current.source.start; 8262 throw this.input.error('Unclosed block', pos.line, pos.column); 8263 } 8264 unclosedBracket(bracket) { 8265 throw this.input.error('Unclosed bracket', { 8266 offset: bracket[2] 8267 }, { 8268 offset: bracket[2] + 1 8269 }); 8270 } 8271 unexpectedClose(token) { 8272 throw this.input.error('Unexpected }', { 8273 offset: token[2] 8274 }, { 8275 offset: token[2] + 1 8276 }); 8277 } 8278 unknownWord(tokens) { 8279 throw this.input.error('Unknown word ' + tokens[0][1], { 8280 offset: tokens[0][2] 8281 }, { 8282 offset: tokens[0][2] + tokens[0][1].length 8283 }); 8284 } 8285 unnamedAtrule(node, token) { 8286 throw this.input.error('At-rule without name', { 8287 offset: token[2] 8288 }, { 8289 offset: token[2] + token[1].length 8290 }); 8291 } 8292} 8293module.exports = Parser; 8294}), 8295357373, ((__turbopack_context__, module, exports) => { 8296"use strict"; 8297 8298var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 8299'use strict'; 8300let Container = __turbopack_context__.r(296045); 8301let Input = __turbopack_context__.r(2278); 8302let Parser = __turbopack_context__.r(552371); 8303function parse(css, opts) { 8304 let input = new Input(css, opts); 8305 let parser = new Parser(input); 8306 try { 8307 parser.parse(); 8308 } catch (e) { 8309 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8310 ; 8311 throw e; 8312 } 8313 return parser.root; 8314} 8315module.exports = parse; 8316parse.default = parse; 8317Container.registerParse(parse); 8318}), 8319683078, ((__turbopack_context__, module, exports) => { 8320"use strict"; 8321 8322class Warning { 8323 constructor(text, opts = {}){ 8324 this.type = 'warning'; 8325 this.text = text; 8326 if (opts.node && opts.node.source) { 8327 let range = opts.node.rangeBy(opts); 8328 this.line = range.start.line; 8329 this.column = range.start.column; 8330 this.endLine = range.end.line; 8331 this.endColumn = range.end.column; 8332 } 8333 for(let opt in opts)this[opt] = opts[opt]; 8334 } 8335 toString() { 8336 if (this.node) { 8337 return this.node.error(this.text, { 8338 index: this.index, 8339 plugin: this.plugin, 8340 word: this.word 8341 }).message; 8342 } 8343 if (this.plugin) { 8344 return this.plugin + ': ' + this.text; 8345 } 8346 return this.text; 8347 } 8348} 8349module.exports = Warning; 8350Warning.default = Warning; 8351}),
8352148665, ((__turbopack_context__, module, exports) => { 8353"use strict"; 8354 8355let Warning = __turbopack_context__.r(683078); 8356class Result { 8357 get content() { 8358 return this.css; 8359 } 8360 constructor(processor, root, opts){ 8361 this.processor = processor; 8362 this.messages = []; 8363 this.root = root; 8364 this.opts = opts; 8365 this.css = ''; 8366 this.map = undefined; 8367 } 8368 toString() { 8369 return this.css; 8370 } 8371 warn(text, opts = {}) { 8372 if (!opts.plugin) { 8373 if (this.lastPlugin && this.lastPlugin.postcssPlugin) { 8374 opts.plugin = this.lastPlugin.postcssPlugin; 8375 } 8376 } 8377 let warning = new Warning(text, opts); 8378 this.messages.push(warning); 8379 return warning; 8380 } 8381 warnings() { 8382 return this.messages.filter((i)=>i.type === 'warning'); 8383 } 8384} 8385module.exports = Result; 8386Result.default = Result; 8387}), 8388680698, ((__turbopack_context__, module, exports) => { 8389"use strict"; 8390 8391/* eslint-disable no-console */ let printed = {}; 8392module.exports = function warnOnce(message) { 8393 if (printed[message]) return; 8394 printed[message] = true; 8395 if (typeof console !== 'undefined' && console.warn) { 8396 console.warn(message); 8397 } 8398}; 8399}), 8400409249, ((__turbopack_context__, module, exports) => { 8401"use strict"; 8402 8403var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 8404'use strict'; 8405let Container = __turbopack_context__.r(296045); 8406let Document = __turbopack_context__.r(698475); 8407let MapGenerator = __turbopack_context__.r(320194); 8408let parse = __turbopack_context__.r(357373); 8409let Result = __turbopack_context__.r(148665); 8410let Root = __turbopack_context__.r(551517); 8411let stringify = __turbopack_context__.r(140293); 8412let { isClean, my } = __turbopack_context__.r(322302); 8413let warnOnce = __turbopack_context__.r(680698); 8414const TYPE_TO_CLASS_NAME = { 8415 atrule: 'AtRule', 8416 comment: 'Comment', 8417 decl: 'Declaration', 8418 document: 'Document', 8419 root: 'Root', 8420 rule: 'Rule' 8421}; 8422const PLUGIN_PROPS = { 8423 AtRule: true, 8424 AtRuleExit: true, 8425 Comment: true, 8426 CommentExit: true, 8427 Declaration: true, 8428 DeclarationExit: true, 8429 Document: true, 8430 DocumentExit: true, 8431 Once: true, 8432 OnceExit: true, 8433 postcssPlugin: true, 8434 prepare: true, 8435 Root: true, 8436 RootExit: true, 8437 Rule: true, 8438 RuleExit: true 8439}; 8440const NOT_VISITORS = { 8441 Once: true, 8442 postcssPlugin: true, 8443 prepare: true 8444}; 8445const CHILDREN = 0; 8446function isPromise(obj) { 8447 return typeof obj === 'object' && typeof obj.then === 'function'; 8448} 8449function getEvents(node) { 8450 let key = false; 8451 let type = TYPE_TO_CLASS_NAME[node.type]; 8452 if (node.type === 'decl') { 8453 key = node.prop.toLowerCase(); 8454 } else if (node.type === 'atrule') { 8455 key = node.name.toLowerCase(); 8456 } 8457 if (key && node.append) { 8458 return [ 8459 type, 8460 type + '-' + key, 8461 CHILDREN, 8462 type + 'Exit', 8463 type + 'Exit-' + key 8464 ]; 8465 } else if (key) { 8466 return [ 8467 type, 8468 type + '-' + key, 8469 type + 'Exit', 8470 type + 'Exit-' + key 8471 ]; 8472 } else if (node.append) { 8473 return [ 8474 type, 8475 CHILDREN, 8476 type + 'Exit' 8477 ]; 8478 } else { 8479 return [ 8480 type, 8481 type + 'Exit' 8482 ]; 8483 } 8484} 8485function toStack(node) { 8486 let events; 8487 if (node.type === 'document') { 8488 events = [ 8489 'Document', 8490 CHILDREN, 8491 'DocumentExit' 8492 ]; 8493 } else if (node.type === 'root') { 8494 events = [ 8495 'Root', 8496 CHILDREN, 8497 'RootExit' 8498 ]; 8499 } else { 8500 events = getEvents(node); 8501 } 8502 return { 8503 eventIndex: 0, 8504 events, 8505 iterator: 0, 8506 node, 8507 visitorIndex: 0, 8508 visitors: [] 8509 }; 8510} 8511function cleanMarks(node) { 8512 node[isClean] = false; 8513 if (node.nodes) node.nodes.forEach((i)=>cleanMarks(i)); 8514 return node; 8515} 8516let postcss = {}; 8517class LazyResult { 8518 get content() { 8519 return this.stringify().content; 8520 } 8521 get css() { 8522 return this.stringify().css; 8523 } 8524 get map() { 8525 return this.stringify().map; 8526 } 8527 get messages() { 8528 return this.sync().messages; 8529 } 8530 get opts() { 8531 return this.result.opts; 8532 } 8533 get processor() { 8534 return this.result.processor; 8535 } 8536 get root() { 8537 return this.sync().root; 8538 } 8539 get [Symbol.toStringTag]() { 8540 return 'LazyResult'; 8541 } 8542 constructor(processor, css, opts){ 8543 this.stringified = false;
vendor: 9,202 bytes, lines 8544-8793
8544 this.processed = false; 8545 let root; 8546 if (typeof css === 'object' && css !== null && (css.type === 'root' || css.type === 'document')) { 8547 root = cleanMarks(css); 8548 } else if (css instanceof LazyResult || css instanceof Result) { 8549 root = cleanMarks(css.root); 8550 if (css.map) { 8551 if (typeof opts.map === 'undefined') opts.map = {}; 8552 if (!opts.map.inline) opts.map.inline = false; 8553 opts.map.prev = css.map; 8554 } 8555 } else { 8556 let parser = parse; 8557 if (opts.syntax) parser = opts.syntax.parse; 8558 if (opts.parser) parser = opts.parser; 8559 if (parser.parse) parser = parser.parse; 8560 try { 8561 root = parser(css, opts); 8562 } catch (error) { 8563 this.processed = true; 8564 this.error = error; 8565 } 8566 if (root && !root[my]) { 8567 /* c8 ignore next 2 */ Container.rebuild(root); 8568 } 8569 } 8570 this.result = new Result(processor, root, opts); 8571 this.helpers = { 8572 ...postcss, 8573 postcss, 8574 result: this.result 8575 }; 8576 this.plugins = this.processor.plugins.map((plugin)=>{ 8577 if (typeof plugin === 'object' && plugin.prepare) { 8578 return { 8579 ...plugin, 8580 ...plugin.prepare(this.result) 8581 }; 8582 } else { 8583 return plugin; 8584 } 8585 }); 8586 } 8587 async() { 8588 if (this.error) return Promise.reject(this.error); 8589 if (this.processed) return Promise.resolve(this.result); 8590 if (!this.processing) { 8591 this.processing = this.runAsync(); 8592 } 8593 return this.processing; 8594 } 8595 catch(onRejected) { 8596 return this.async().catch(onRejected); 8597 } 8598 finally(onFinally) { 8599 return this.async().then(onFinally, onFinally); 8600 } 8601 getAsyncError() { 8602 throw new Error('Use process(css).then(cb) to work with async plugins'); 8603 } 8604 handleError(error, node) { 8605 let plugin = this.result.lastPlugin; 8606 try { 8607 if (node) node.addToError(error); 8608 this.error = error; 8609 if (error.name === 'CssSyntaxError' && !error.plugin) { 8610 error.plugin = plugin.postcssPlugin; 8611 error.setMessage(); 8612 } else if (plugin.postcssVersion) { 8613 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8614 ; 8615 } 8616 } catch (err) { 8617 /* c8 ignore next 3 */ // eslint-disable-next-line no-console 8618 if (console && console.error) console.error(err); 8619 } 8620 return error; 8621 } 8622 prepareVisitors() { 8623 this.listeners = {}; 8624 let add = (plugin, type, cb)=>{ 8625 if (!this.listeners[type]) this.listeners[type] = []; 8626 this.listeners[type].push([ 8627 plugin, 8628 cb 8629 ]); 8630 }; 8631 for (let plugin of this.plugins){ 8632 if (typeof plugin === 'object') { 8633 for(let event in plugin){ 8634 if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) { 8635 throw new Error(`Unknown event ${event} in ${plugin.postcssPlugin}. ` + `Try to update PostCSS (${this.processor.version} now).`); 8636 } 8637 if (!NOT_VISITORS[event]) { 8638 if (typeof plugin[event] === 'object') { 8639 for(let filter in plugin[event]){ 8640 if (filter === '*') { 8641 add(plugin, event, plugin[event][filter]); 8642 } else { 8643 add(plugin, event + '-' + filter.toLowerCase(), plugin[event][filter]); 8644 } 8645 } 8646 } else if (typeof plugin[event] === 'function') { 8647 add(plugin, event, plugin[event]); 8648 } 8649 } 8650 } 8651 } 8652 } 8653 this.hasListener = Object.keys(this.listeners).length > 0; 8654 } 8655 async runAsync() { 8656 this.plugin = 0; 8657 for(let i = 0; i < this.plugins.length; i++){ 8658 let plugin = this.plugins[i]; 8659 let promise = this.runOnRoot(plugin); 8660 if (isPromise(promise)) { 8661 try { 8662 await promise; 8663 } catch (error) { 8664 throw this.handleError(error); 8665 } 8666 } 8667 } 8668 this.prepareVisitors(); 8669 if (this.hasListener) { 8670 let root = this.result.root; 8671 while(!root[isClean]){ 8672 root[isClean] = true; 8673 let stack = [ 8674 toStack(root) 8675 ]; 8676 while(stack.length > 0){ 8677 let promise = this.visitTick(stack); 8678 if (isPromise(promise)) { 8679 try { 8680 await promise; 8681 } catch (e) { 8682 let node = stack[stack.length - 1].node; 8683 throw this.handleError(e, node); 8684 } 8685 } 8686 } 8687 } 8688 if (this.listeners.OnceExit) { 8689 for (let [plugin, visitor] of this.listeners.OnceExit){ 8690 this.result.lastPlugin = plugin; 8691 try { 8692 if (root.type === 'document') { 8693 let roots = root.nodes.map((subRoot)=>visitor(subRoot, this.helpers)); 8694 await Promise.all(roots); 8695 } else { 8696 await visitor(root, this.helpers); 8697 } 8698 } catch (e) { 8699 throw this.handleError(e); 8700 } 8701 } 8702 } 8703 } 8704 this.processed = true; 8705 return this.stringify(); 8706 } 8707 runOnRoot(plugin) { 8708 this.result.lastPlugin = plugin; 8709 try { 8710 if (typeof plugin === 'object' && plugin.Once) { 8711 if (this.result.root.type === 'document') { 8712 let roots = this.result.root.nodes.map((root)=>plugin.Once(root, this.helpers)); 8713 if (isPromise(roots[0])) { 8714 return Promise.all(roots); 8715 } 8716 return roots; 8717 } 8718 return plugin.Once(this.result.root, this.helpers); 8719 } else if (typeof plugin === 'function') { 8720 return plugin(this.result.root, this.result); 8721 } 8722 } catch (error) { 8723 throw this.handleError(error); 8724 } 8725 } 8726 stringify() { 8727 if (this.error) throw this.error; 8728 if (this.stringified) return this.result; 8729 this.stringified = true; 8730 this.sync(); 8731 let opts = this.result.opts; 8732 let str = stringify; 8733 if (opts.syntax) str = opts.syntax.stringify; 8734 if (opts.stringifier) str = opts.stringifier; 8735 if (str.stringify) str = str.stringify; 8736 let map = new MapGenerator(str, this.result.root, this.result.opts); 8737 let data = map.generate(); 8738 this.result.css = data[0]; 8739 this.result.map = data[1]; 8740 return this.result; 8741 } 8742 sync() { 8743 if (this.error) throw this.error; 8744 if (this.processed) return this.result; 8745 this.processed = true; 8746 if (this.processing) { 8747 throw this.getAsyncError(); 8748 } 8749 for (let plugin of this.plugins){ 8750 let promise = this.runOnRoot(plugin); 8751 if (isPromise(promise)) { 8752 throw this.getAsyncError(); 8753 } 8754 } 8755 this.prepareVisitors(); 8756 if (this.hasListener) { 8757 let root = this.result.root; 8758 while(!root[isClean]){ 8759 root[isClean] = true; 8760 this.walkSync(root); 8761 } 8762 if (this.listeners.OnceExit) { 8763 if (root.type === 'document') { 8764 for (let subRoot of root.nodes){ 8765 this.visitSync(this.listeners.OnceExit, subRoot); 8766 } 8767 } else { 8768 this.visitSync(this.listeners.OnceExit, root); 8769 } 8770 } 8771 } 8772 return this.result; 8773 } 8774 then(onFulfilled, onRejected) { 8775 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8776 ; 8777 return this.async().then(onFulfilled, onRejected); 8778 } 8779 toString() { 8780 return this.css; 8781 } 8782 visitSync(visitors, node) { 8783 for (let [plugin, visitor] of visitors){ 8784 this.result.lastPlugin = plugin; 8785 let promise; 8786 try { 8787 promise = visitor(node, this.helpers); 8788 } catch (e) { 8789 throw this.handleError(e, node.proxyOf); 8790 } 8791 if (node.type !== 'root' && node.type !== 'document' && !node.parent) { 8792 return true; 8793 }
8794 if (isPromise(promise)) { 8795 throw this.getAsyncError(); 8796 } 8797 } 8798 } 8799 visitTick(stack) { 8800 let visit = stack[stack.length - 1]; 8801 let { node, visitors } = visit; 8802 if (node.type !== 'root' && node.type !== 'document' && !node.parent) { 8803 stack.pop(); 8804 return; 8805 } 8806 if (visitors.length > 0 && visit.visitorIndex < visitors.length) { 8807 let [plugin, visitor] = visitors[visit.visitorIndex]; 8808 visit.visitorIndex += 1; 8809 if (visit.visitorIndex === visitors.length) { 8810 visit.visitors = []; 8811 visit.visitorIndex = 0; 8812 } 8813 this.result.lastPlugin = plugin; 8814 try { 8815 return visitor(node.toProxy(), this.helpers); 8816 } catch (e) { 8817 throw this.handleError(e, node); 8818 } 8819 } 8820 if (visit.iterator !== 0) { 8821 let iterator = visit.iterator; 8822 let child; 8823 while(child = node.nodes[node.indexes[iterator]]){ 8824 node.indexes[iterator] += 1; 8825 if (!child[isClean]) { 8826 child[isClean] = true; 8827 stack.push(toStack(child)); 8828 return; 8829 } 8830 } 8831 visit.iterator = 0; 8832 delete node.indexes[iterator]; 8833 } 8834 let events = visit.events; 8835 while(visit.eventIndex < events.length){ 8836 let event = events[visit.eventIndex]; 8837 visit.eventIndex += 1; 8838 if (event === CHILDREN) { 8839 if (node.nodes && node.nodes.length) { 8840 node[isClean] = true; 8841 visit.iterator = node.getIterator(); 8842 } 8843 return; 8844 } else if (this.listeners[event]) { 8845 visit.visitors = this.listeners[event]; 8846 return; 8847 } 8848 } 8849 stack.pop(); 8850 } 8851 walkSync(node) { 8852 node[isClean] = true; 8853 let events = getEvents(node); 8854 for (let event of events){ 8855 if (event === CHILDREN) { 8856 if (node.nodes) { 8857 node.each((child)=>{ 8858 if (!child[isClean]) this.walkSync(child); 8859 }); 8860 } 8861 } else { 8862 let visitors = this.listeners[event]; 8863 if (visitors) { 8864 if (this.visitSync(visitors, node.toProxy())) return; 8865 } 8866 } 8867 } 8868 } 8869 warnings() { 8870 return this.sync().warnings(); 8871 } 8872} 8873LazyResult.registerPostcss = (dependant)=>{ 8874 postcss = dependant; 8875}; 8876module.exports = LazyResult; 8877LazyResult.default = LazyResult; 8878Root.registerLazyResult(LazyResult); 8879Document.registerLazyResult(LazyResult); 8880}), 8881611589, ((__turbopack_context__, module, exports) => { 8882"use strict"; 8883 8884var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 8885'use strict'; 8886let MapGenerator = __turbopack_context__.r(320194); 8887let parse = __turbopack_context__.r(357373); 8888let Result = __turbopack_context__.r(148665); 8889let stringify = __turbopack_context__.r(140293); 8890let warnOnce = __turbopack_context__.r(680698); 8891class NoWorkResult { 8892 get content() { 8893 return this.result.css; 8894 } 8895 get css() { 8896 return this.result.css; 8897 } 8898 get map() { 8899 return this.result.map; 8900 } 8901 get messages() { 8902 return []; 8903 } 8904 get opts() { 8905 return this.result.opts; 8906 } 8907 get processor() { 8908 return this.result.processor; 8909 } 8910 get root() { 8911 if (this._root) { 8912 return this._root; 8913 } 8914 let root; 8915 let parser = parse; 8916 try { 8917 root = parser(this._css, this._opts); 8918 } catch (error) { 8919 this.error = error; 8920 } 8921 if (this.error) { 8922 throw this.error; 8923 } else { 8924 this._root = root; 8925 return root; 8926 } 8927 } 8928 get [Symbol.toStringTag]() { 8929 return 'NoWorkResult'; 8930 } 8931 constructor(processor, css, opts){ 8932 css = css.toString(); 8933 this.stringified = false;
8934 this._processor = processor; 8935 this._css = css; 8936 this._opts = opts; 8937 this._map = undefined; 8938 let str = stringify; 8939 this.result = new Result(this._processor, undefined, this._opts); 8940 this.result.css = css; 8941 let self = this; 8942 Object.defineProperty(this.result, 'root', { 8943 get () { 8944 return self.root; 8945 } 8946 }); 8947 let map = new MapGenerator(str, undefined, this._opts, css); 8948 if (map.isMap()) { 8949 let [generatedCSS, generatedMap] = map.generate(); 8950 if (generatedCSS) { 8951 this.result.css = generatedCSS; 8952 } 8953 if (generatedMap) { 8954 this.result.map = generatedMap; 8955 } 8956 } else { 8957 map.clearAnnotation(); 8958 this.result.css = map.css; 8959 } 8960 } 8961 async() { 8962 if (this.error) return Promise.reject(this.error); 8963 return Promise.resolve(this.result); 8964 } 8965 catch(onRejected) { 8966 return this.async().catch(onRejected); 8967 } 8968 finally(onFinally) { 8969 return this.async().then(onFinally, onFinally); 8970 } 8971 sync() { 8972 if (this.error) throw this.error; 8973 return this.result; 8974 } 8975 then(onFulfilled, onRejected) { 8976 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8977 ; 8978 return this.async().then(onFulfilled, onRejected); 8979 } 8980 toString() { 8981 return this._css; 8982 } 8983 warnings() { 8984 return []; 8985 } 8986} 8987module.exports = NoWorkResult; 8988NoWorkResult.default = NoWorkResult; 8989}), 8990111902, ((__turbopack_context__, module, exports) => { 8991"use strict"; 8992 8993var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 8994'use strict'; 8995let Document = __turbopack_context__.r(698475); 8996let LazyResult = __turbopack_context__.r(409249); 8997let NoWorkResult = __turbopack_context__.r(611589); 8998let Root = __turbopack_context__.r(551517); 8999class Processor { 9000 constructor(plugins = []){ 9001 this.version = '8.5.10'; 9002 this.plugins = this.normalize(plugins); 9003 } 9004 normalize(plugins) { 9005 let normalized = []; 9006 for (let i of plugins){ 9007 if (i.postcss === true) { 9008 i = i(); 9009 } else if (i.postcss) { 9010 i = i.postcss; 9011 } 9012 if (typeof i === 'object' && Array.isArray(i.plugins)) { 9013 normalized = normalized.concat(i.plugins); 9014 } else if (typeof i === 'object' && i.postcssPlugin) { 9015 normalized.push(i); 9016 } else if (typeof i === 'function') { 9017 normalized.push(i); 9018 } else if (typeof i === 'object' && (i.parse || i.stringify)) { 9019 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 9020 ; 9021 } else { 9022 throw new Error(i + ' is not a PostCSS plugin'); 9023 } 9024 } 9025 return normalized; 9026 } 9027 process(css, opts = {}) { 9028 if (!this.plugins.length && !opts.parser && !opts.stringifier && !opts.syntax) { 9029 return new NoWorkResult(this, css, opts); 9030 } else { 9031 return new LazyResult(this, css, opts); 9032 } 9033 } 9034 use(plugin) { 9035 this.plugins = this.plugins.concat(this.normalize([ 9036 plugin 9037 ])); 9038 return this; 9039 } 9040} 9041module.exports = Processor; 9042Processor.default = Processor; 9043Root.registerProcessor(Processor); 9044Document.registerProcessor(Processor); 9045}), 9046485243, ((__turbopack_context__, module, exports) => { 9047"use strict"; 9048 9049var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 9050'use strict'; 9051let AtRule = __turbopack_context__.r(670255); 9052let Comment = __turbopack_context__.r(877906); 9053let Container = __turbopack_context__.r(296045); 9054let CssSyntaxError = __turbopack_context__.r(71528); 9055let Declaration = __turbopack_context__.r(721772); 9056let Document = __turbopack_context__.r(698475); 9057let fromJSON = __turbopack_context__.r(498729); 9058let Input = __turbopack_context__.r(2278); 9059let LazyResult = __turbopack_context__.r(409249); 9060let list = __turbopack_context__.r(350215); 9061let Node = __turbopack_context__.r(657612); 9062let parse = __turbopack_context__.r(357373); 9063let Processor = __turbopack_context__.r(111902); 9064let Result = __turbopack_context__.r(148665); 9065let Root = __turbopack_context__.r(551517); 9066let Rule = __turbopack_context__.r(893894); 9067let stringify = __turbopack_context__.r(140293); 9068let Warning = __turbopack_context__.r(683078); 9069function postcss(...plugins) { 9070 if (plugins.length === 1 && Array.isArray(plugins[0])) { 9071 plugins = plugins[0]; 9072 } 9073 return new Processor(plugins); 9074} 9075postcss.plugin = function plugin(name, initializer) { 9076 let warningPrinted = false;
vendor: 15,132 bytes, lines 9077-9448
9077 function creator(...args) { 9078 // eslint-disable-next-line no-console 9079 if (console && console.warn && !warningPrinted) { 9080 warningPrinted = true; 9081 // eslint-disable-next-line no-console 9082 console.warn(name + ': postcss.plugin was deprecated. Migration guide:\n' + 'https://evilmartians.com/chronicles/postcss-8-plugin-migration'); 9083 if (__TURBOPACK__imported__module__247167__["default"].env.LANG && __TURBOPACK__imported__module__247167__["default"].env.LANG.startsWith('cn')) { 9084 /* c8 ignore next 7 */ // eslint-disable-next-line no-console 9085 console.warn(name + ': éé¢ postcss.plugin 被å¼ç¨. è¿ç§»æå:\n' + 'https://www.w3ctech.com/topic/2226'); 9086 } 9087 } 9088 let transformer = initializer(...args); 9089 transformer.postcssPlugin = name; 9090 transformer.postcssVersion = new Processor().version; 9091 return transformer; 9092 } 9093 let cache; 9094 Object.defineProperty(creator, 'postcss', { 9095 get () { 9096 if (!cache) cache = creator(); 9097 return cache; 9098 } 9099 }); 9100 creator.process = function(css, processOpts, pluginOpts) { 9101 return postcss([ 9102 creator(pluginOpts) 9103 ]).process(css, processOpts); 9104 }; 9105 return creator; 9106}; 9107postcss.stringify = stringify; 9108postcss.parse = parse; 9109postcss.fromJSON = fromJSON; 9110postcss.list = list; 9111postcss.comment = (defaults)=>new Comment(defaults); 9112postcss.atRule = (defaults)=>new AtRule(defaults); 9113postcss.decl = (defaults)=>new Declaration(defaults); 9114postcss.rule = (defaults)=>new Rule(defaults); 9115postcss.root = (defaults)=>new Root(defaults); 9116postcss.document = (defaults)=>new Document(defaults); 9117postcss.CssSyntaxError = CssSyntaxError; 9118postcss.Declaration = Declaration; 9119postcss.Container = Container; 9120postcss.Processor = Processor; 9121postcss.Document = Document; 9122postcss.Comment = Comment; 9123postcss.Warning = Warning; 9124postcss.AtRule = AtRule; 9125postcss.Result = Result; 9126postcss.Input = Input; 9127postcss.Rule = Rule; 9128postcss.Root = Root; 9129postcss.Node = Node; 9130LazyResult.registerPostcss(postcss); 9131module.exports = postcss; 9132postcss.default = postcss; 9133}), 9134822315, ((__turbopack_context__, module, exports) => { 9135 9136!function(t, e) { 9137 ("TURBOPACK compile-time truthy", 1) ? module.exports = e() : "TURBOPACK unreachable"; 9138}(/*TURBOPACK member replacement*/ __turbopack_context__.e, function() { 9139 "use strict"; 9140 var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { 9141 name: "en", 9142 weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), 9143 months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), 9144 ordinal: function(t) { 9145 var e = [ 9146 "th", 9147 "st", 9148 "nd", 9149 "rd" 9150 ], n = t % 100; 9151 return "[" + t + (e[(n - 20) % 10] || e[n] || e[0]) + "]"; 9152 } 9153 }, m = function(t, e, n) { 9154 var r = String(t); 9155 return !r || r.length >= e ? t : "" + Array(e + 1 - r.length).join(n) + t; 9156 }, v = { 9157 s: m, 9158 z: function(t) { 9159 var e = -t.utcOffset(), n = Math.abs(e), r = Math.floor(n / 60), i = n % 60; 9160 return (e <= 0 ? "+" : "-") + m(r, 2, "0") + ":" + m(i, 2, "0"); 9161 }, 9162 m: function t(e, n) { 9163 if (e.date() < n.date()) return -t(n, e); 9164 var r = 12 * (n.year() - e.year()) + (n.month() - e.month()), i = e.clone().add(r, c), s = n - i < 0, u = e.clone().add(r + (s ? -1 : 1), c); 9165 return +(-(r + (n - i) / (s ? i - u : u - i)) || 0); 9166 }, 9167 a: function(t) { 9168 return t < 0 ? Math.ceil(t) || 0 : Math.floor(t); 9169 }, 9170 p: function(t) { 9171 return ({ 9172 M: c, 9173 y: h, 9174 w: o, 9175 d: a, 9176 D: d, 9177 h: u, 9178 m: s, 9179 s: i, 9180 ms: r, 9181 Q: f 9182 })[t] || String(t || "").toLowerCase().replace(/s$/, ""); 9183 }, 9184 u: function(t) { 9185 return void 0 === t; 9186 } 9187 }, g = "en", D = {}; 9188 D[g] = M; 9189 var p = "$isDayjsObject", S = function(t) { 9190 return t instanceof _ || !(!t || !t[p]); 9191 }, w = function t(e, n, r) { 9192 var i; 9193 if (!e) return g; 9194 if ("string" == typeof e) { 9195 var s = e.toLowerCase(); 9196 D[s] && (i = s), n && (D[s] = n, i = s); 9197 var u = e.split("-"); 9198 if (!i && u.length > 1) return t(u[0]); 9199 } else { 9200 var a = e.name; 9201 D[a] = e, i = a; 9202 } 9203 return !r && i && (g = i), i || !r && g; 9204 }, O = function(t, e) { 9205 if (S(t)) return t.clone(); 9206 var n = "object" == typeof e ? e : {}; 9207 return n.date = t, n.args = arguments, new _(n); 9208 }, b = v; 9209 b.l = w, b.i = S, b.w = function(t, e) { 9210 return O(t, { 9211 locale: e.$L, 9212 utc: e.$u, 9213 x: e.$x, 9214 $offset: e.$offset 9215 }); 9216 }; 9217 var _ = function() { 9218 function M(t) { 9219 this.$L = w(t.locale, null, !0), this.parse(t), this.$x = this.$x || t.x || {}, this[p] = !0; 9220 } 9221 var m = M.prototype; 9222 return m.parse = function(t) { 9223 this.$d = function(t) { 9224 var e = t.date, n = t.utc; 9225 if (null === e) return new Date(NaN); 9226 if (b.u(e)) return new Date; 9227 if (e instanceof Date) return new Date(e); 9228 if ("string" == typeof e && !/Z$/i.test(e)) { 9229 var r = e.match($); 9230 if (r) { 9231 var i = r[2] - 1 || 0, s = (r[7] || "0").substring(0, 3); 9232 return n ? new Date(Date.UTC(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s)) : new Date(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s); 9233 } 9234 } 9235 return new Date(e); 9236 }(t), this.init(); 9237 }, m.init = function() { 9238 var t = this.$d; 9239 this.$y = t.getFullYear(), this.$M = t.getMonth(), this.$D = t.getDate(), this.$W = t.getDay(), this.$H = t.getHours(), this.$m = t.getMinutes(), this.$s = t.getSeconds(), this.$ms = t.getMilliseconds(); 9240 }, m.$utils = function() { 9241 return b; 9242 }, m.isValid = function() { 9243 return !(this.$d.toString() === l); 9244 }, m.isSame = function(t, e) { 9245 var n = O(t); 9246 return this.startOf(e) <= n && n <= this.endOf(e); 9247 }, m.isAfter = function(t, e) { 9248 return O(t) < this.startOf(e); 9249 }, m.isBefore = function(t, e) { 9250 return this.endOf(e) < O(t); 9251 }, m.$g = function(t, e, n) { 9252 return b.u(t) ? this[e] : this.set(n, t); 9253 }, m.unix = function() { 9254 return Math.floor(this.valueOf() / 1e3); 9255 }, m.valueOf = function() { 9256 return this.$d.getTime(); 9257 }, m.startOf = function(t, e) { 9258 var n = this, r = !!b.u(e) || e, f = b.p(t), l = function(t, e) { 9259 var i = b.w(n.$u ? Date.UTC(n.$y, e, t) : new Date(n.$y, e, t), n); 9260 return r ? i : i.endOf(a); 9261 }, $ = function(t, e) { 9262 return b.w(n.toDate()[t].apply(n.toDate("s"), (r ? [ 9263 0, 9264 0, 9265 0, 9266 0 9267 ] : [ 9268 23, 9269 59, 9270 59, 9271 999 9272 ]).slice(e)), n); 9273 }, y = this.$W, M = this.$M, m = this.$D, v = "set" + (this.$u ? "UTC" : ""); 9274 switch(f){ 9275 case h: 9276 return r ? l(1, 0) : l(31, 11); 9277 case c: 9278 return r ? l(1, M) : l(0, M + 1); 9279 case o: 9280 var g = this.$locale().weekStart || 0, D = (y < g ? y + 7 : y) - g; 9281 return l(r ? m - D : m + (6 - D), M); 9282 case a: 9283 case d: 9284 return $(v + "Hours", 0); 9285 case u: 9286 return $(v + "Minutes", 1); 9287 case s: 9288 return $(v + "Seconds", 2); 9289 case i: 9290 return $(v + "Milliseconds", 3); 9291 default: 9292 return this.clone(); 9293 } 9294 }, m.endOf = function(t) { 9295 return this.startOf(t, !1); 9296 }, m.$set = function(t, e) { 9297 var n, o = b.p(t), f = "set" + (this.$u ? "UTC" : ""), l = (n = {}, n[a] = f + "Date", n[d] = f + "Date", n[c] = f + "Month", n[h] = f + "FullYear", n[u] = f + "Hours", n[s] = f + "Minutes", n[i] = f + "Seconds", n[r] = f + "Milliseconds", n)[o], $ = o === a ? this.$D + (e - this.$W) : e; 9298 if (o === c || o === h) { 9299 var y = this.clone().set(d, 1); 9300 y.$d[l]($), y.init(), this.$d = y.set(d, Math.min(this.$D, y.daysInMonth())).$d; 9301 } else l && this.$d[l]($); 9302 return this.init(), this; 9303 }, m.set = function(t, e) { 9304 return this.clone().$set(t, e); 9305 }, m.get = function(t) { 9306 return this[b.p(t)](); 9307 }, m.add = function(r, f) { 9308 var d, l = this; 9309 r = Number(r); 9310 var $ = b.p(f), y = function(t) { 9311 var e = O(l); 9312 return b.w(e.date(e.date() + Math.round(t * r)), l); 9313 }; 9314 if ($ === c) return this.set(c, this.$M + r); 9315 if ($ === h) return this.set(h, this.$y + r); 9316 if ($ === a) return y(1); 9317 if ($ === o) return y(7); 9318 var M = (d = {}, d[s] = e, d[u] = n, d[i] = t, d)[$] || 1, m = this.$d.getTime() + r * M; 9319 return b.w(m, this); 9320 }, m.subtract = function(t, e) { 9321 return this.add(-1 * t, e); 9322 }, m.format = function(t) { 9323 var e = this, n = this.$locale(); 9324 if (!this.isValid()) return n.invalidDate || l; 9325 var r = t || "YYYY-MM-DDTHH:mm:ssZ", i = b.z(this), s = this.$H, u = this.$m, a = this.$M, o = n.weekdays, c = n.months, f = n.meridiem, h = function(t, n, i, s) { 9326 return t && (t[n] || t(e, r)) || i[n].slice(0, s); 9327 }, d = function(t) { 9328 return b.s(s % 12 || 12, t, "0"); 9329 }, $ = f || function(t, e, n) { 9330 var r = t < 12 ? "AM" : "PM"; 9331 return n ? r.toLowerCase() : r; 9332 }; 9333 return r.replace(y, function(t, r) { 9334 return r || function(t) { 9335 switch(t){ 9336 case "YY": 9337 return String(e.$y).slice(-2); 9338 case "YYYY": 9339 return b.s(e.$y, 4, "0"); 9340 case "M": 9341 return a + 1; 9342 case "MM": 9343 return b.s(a + 1, 2, "0"); 9344 case "MMM": 9345 return h(n.monthsShort, a, c, 3); 9346 case "MMMM": 9347 return h(c, a); 9348 case "D": 9349 return e.$D; 9350 case "DD": 9351 return b.s(e.$D, 2, "0"); 9352 case "d": 9353 return String(e.$W); 9354 case "dd": 9355 return h(n.weekdaysMin, e.$W, o, 2); 9356 case "ddd": 9357 return h(n.weekdaysShort, e.$W, o, 3); 9358 case "dddd": 9359 return o[e.$W]; 9360 case "H": 9361 return String(s); 9362 case "HH": 9363 return b.s(s, 2, "0"); 9364 case "h": 9365 return d(1); 9366 case "hh": 9367 return d(2); 9368 case "a": 9369 return $(s, u, !0); 9370 case "A": 9371 return $(s, u, !1); 9372 case "m": 9373 return String(u); 9374 case "mm": 9375 return b.s(u, 2, "0"); 9376 case "s": 9377 return String(e.$s); 9378 case "ss": 9379 return b.s(e.$s, 2, "0"); 9380 case "SSS": 9381 return b.s(e.$ms, 3, "0"); 9382 case "Z": 9383 return i; 9384 } 9385 return null; 9386 }(t) || i.replace(":", ""); 9387 }); 9388 }, m.utcOffset = function() { 9389 return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); 9390 }, m.diff = function(r, d, l) { 9391 var $, y = this, M = b.p(d), m = O(r), v = (m.utcOffset() - this.utcOffset()) * e, g = this - m, D = function() { 9392 return b.m(y, m); 9393 }; 9394 switch(M){ 9395 case h: 9396 $ = D() / 12; 9397 break; 9398 case c: 9399 $ = D(); 9400 break; 9401 case f: 9402 $ = D() / 3; 9403 break; 9404 case o: 9405 $ = (g - v) / 6048e5; 9406 break; 9407 case a: 9408 $ = (g - v) / 864e5; 9409 break; 9410 case u: 9411 $ = g / n; 9412 break; 9413 case s: 9414 $ = g / e; 9415 break; 9416 case i: 9417 $ = g / t; 9418 break; 9419 default: 9420 $ = g; 9421 } 9422 return l ? $ : b.a($); 9423 }, m.daysInMonth = function() { 9424 return this.endOf(c).$D; 9425 }, m.$locale = function() { 9426 return D[this.$L]; 9427 }, m.locale = function(t, e) { 9428 if (!t) return this.$L; 9429 var n = this.clone(), r = w(t, e, !0); 9430 return r && (n.$L = r), n; 9431 }, m.clone = function() { 9432 return b.w(this.$d, this); 9433 }, m.toDate = function() { 9434 return new Date(this.valueOf()); 9435 }, m.toJSON = function() { 9436 return this.isValid() ? this.toISOString() : null; 9437 }, m.toISOString = function() { 9438 return this.$d.toISOString(); 9439 }, m.toString = function() { 9440 return this.$d.toUTCString(); 9441 }, M; 9442 }(), k = _.prototype; 9443 return O.prototype = k, [ 9444 [ 9445 "$ms", 9446 r 9447 ], 9448 [
9449 "$s", 9450 i 9451 ], 9452 [ 9453 "$m", 9454 s 9455 ], 9456 [ 9457 "$H", 9458 u 9459 ], 9460 [ 9461 "$W", 9462 a 9463 ], 9464 [ 9465 "$M", 9466 c 9467 ], 9468 [ 9469 "$y", 9470 h 9471 ], 9472 [ 9473 "$D", 9474 d 9475 ] 9476 ].forEach(function(t) { 9477 k[t[1]] = function(e) { 9478 return this.$g(e, t[0], t[1]); 9479 }; 9480 }), O.extend = function(t, e) { 9481 return t.$i || (t(e, _, O), t.$i = !0), O; 9482 }, O.locale = w, O.isDayjs = S, O.unix = function(t) { 9483 return O(1e3 * t); 9484 }, O.en = D[g], O.Ls = D, O.p = {}, O; 9485}); 9486}), 948782004, ((__turbopack_context__, module, exports) => { 9488 9489const dayjs = __turbopack_context__.r(822315); 9490// Strip characters browsers ignore inside URLs (control chars and 9491// embedded HTML comments) that are commonly used to sneak XSS 9492// payloads past simple scheme checks. 9493function cleanHref(href) { 9494 // Browsers ignore character codes of 32 (space) and below in a surprising 9495 // number of situations. Start reading here: 9496 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Embedded_tab 9497 // eslint-disable-next-line no-control-regex 9498 href = href.replace(/[\x00-\x20]+/g, ''); 9499 // Clobber any comments in URLs, which the browser might 9500 // interpret inside an XML data island, allowing 9501 // a javascript: URL to be snuck through 9502 while(true){ 9503 const firstIndex = href.indexOf('<!--'); 9504 if (firstIndex === -1) { 9505 break; 9506 } 9507 const lastIndex = href.indexOf('-->', firstIndex + 4); 9508 if (lastIndex === -1) { 9509 break; 9510 } 9511 href = href.substring(0, firstIndex) + href.substring(lastIndex + 3); 9512 } 9513 return href; 9514} 9515// Returns true if `href` should be rejected as unsafe. Used to block 9516// `javascript:`, `data:` and other dangerous schemes both when 9517// validating URL fields and when sanitizing HTML attribute values. 9518// 9519// `options.allowedSchemes` is an array of permitted URL schemes 9520// (defaults to the schemes long permitted by `launder().url`). 9521// `options.allowProtocolRelative` controls whether protocol-relative 9522// URLs (e.g. `//example.com`) are permitted. Defaults to true. 9523function naughtyHref(href, options) { 9524 options = options || {}; 9525 const allowedSchemes = options.allowedSchemes || [ 9526 'http', 9527 'https', 9528 'ftp', 9529 'mailto', 9530 'tel', 9531 'sms' 9532 ]; 9533 const allowProtocolRelative = options.allowProtocolRelative !== false; 9534 if (typeof href !== 'string') { 9535 return false; 9536 } 9537 href = cleanHref(href); 9538 // Case insensitive so we don't get faked out by JAVASCRIPT #1 9539 // Allow more characters after the first so we don't get faked 9540 // out by certain schemes browsers accept 9541 const matches = href.match(/^([a-zA-Z][a-zA-Z0-9.\-+]*):/); 9542 if (!matches) { 9543 // Protocol-relative URL starting with any combination of '/' and '\' 9544 if (href.match(/^[/\\]{2}/)) { 9545 return !allowProtocolRelative; 9546 } 9547 // No scheme 9548 return false; 9549 } 9550 const scheme = matches[1].toLowerCase(); 9551 return allowedSchemes.indexOf(scheme) === -1; 9552} 9553module.exports = function(options) { 9554 const self = {}; 9555 self.options = options || {}; 9556 self.filterTag = self.options.filterTag || function(tag) { 9557 tag = tag.trim(); 9558 return tag.toLowerCase(); 9559 }; 9560 self.string = function(s, def) { 9561 if (typeof s !== 'string') { 9562 if (typeof s === 'number' || typeof s === 'boolean') { 9563 s += ''; 9564 } else { 9565 s = ''; 9566 } 9567 } 9568 s = s.trim(); 9569 if (def !== undefined) { 9570 if (s === '') { 9571 s = def; 9572 } 9573 } 9574 return s; 9575 }; 9576 self.strings = function(strings) { 9577 if (!Array.isArray(strings)) { 9578 return []; 9579 } 9580 return strings.map(function(s) { 9581 return self.string(s); 9582 }); 9583 }; 9584 self.integer = function(i, def, min, max) { 9585 if (def === undefined) { 9586 def = 0; 9587 } 9588 if (typeof i === 'number') { 9589 i = Math.floor(i); 9590 } else { 9591 try { 9592 i = parseInt(i, 10); 9593 if (isNaN(i)) { 9594 i = def; 9595 } 9596 } catch (e) { 9597 i = def; 9598 } 9599 } 9600 if (typeof min === 'number' && i < min) { 9601 i = min; 9602 } 9603 if (typeof max === 'number' && i > max) { 9604 i = max; 9605 } 9606 return i; 9607 }; 9608 self.padInteger = function(i, places) { 9609 let s = i + ''; 9610 while(s.length < places){ 9611 s = '0' + s; 9612 } 9613 return s; 9614 }; 9615 self.float = function(i, def, min, max) { 9616 if (def === undefined) { 9617 def = 0; 9618 } 9619 if (!(typeof i === 'number')) { 9620 try { 9621 i = parseFloat(i, 10); 9622 if (isNaN(i)) { 9623 i = def; 9624 } 9625 } catch (e) { 9626 i = def; 9627 } 9628 } 9629 if (typeof min === 'number' && i < min) { 9630 i = min; 9631 } 9632 if (typeof max === 'number' && i > max) { 9633 i = max; 9634 } 9635 return i; 9636 }; 9637 self.naughtyHref = naughtyHref; 9638 self.url = function(s, def, httpsFix) { 9639 s = self.string(s, def); 9640 // Allow the default to be undefined, null, false, etc. 9641 if (s === def) { 9642 return s; 9643 } 9644 // Strip characters browsers ignore that are commonly used to 9645 // smuggle dangerous schemes past validation. 9646 s = cleanHref(s); 9647 // Reject naughty URLs (e.g. `javascript:`, `data:`) before fixUrl 9648 // runs. Otherwise fixUrl could mask such schemes by prepending 9649 // `https://` to anything containing a `.`, turning 9650 // `javascript:alert(document.domain)` into a syntactically odd 9651 // but accepted `https://...` URL. 9652 if (naughtyHref(s)) { 9653 return def; 9654 } 9655 s = fixUrl(s); 9656 if (s === null) { 9657 return def; 9658 } 9659 return s; 9660 //TURBOPACK unreachable 9661 ; 9662 function fixUrl(href) { 9663 if (href.match(/^(((https?|ftp):\/\/)|((mailto|tel|sms
9663):)|#|([^/.]+)?\/|[^/.]+$)/)) { 9664 // All good - no change required 9665 return href; 9666 } else if (href.match(/^[^/.]+\.[^/.]+/)) { 9667 // Smells like a domain name. Educated guess: they left off http:// 9668 const protocol = httpsFix ? 'https://' : 'http://'; 9669 return protocol + href; 9670 } else { 9671 return null; 9672 } 9673 } 9674 }; 9675 self.select = function(s, choices, def) { 9676 s = self.string(s); 9677 if (!choices || !choices.length) { 9678 return def; 9679 } 9680 let choice; 9681 if (typeof choices[0] === 'object') { 9682 choice = choices.find(function(choice) { 9683 if (choice.value === null || choice.value === undefined) { 9684 // Don't crash on invalid choices 9685 return false; 9686 } 9687 return choice.value.toString() === s; 9688 }); 9689 if (choice != null) { 9690 return choice.value; 9691 } 9692 return def; 9693 } 9694 choice = choices.find(function(choice) { 9695 if (choice === null || choice === undefined) { 9696 // Don't crash on invalid choices 9697 return false; 9698 } 9699 return choice.toString() === s; 9700 }); 9701 if (choice !== undefined) { 9702 return choice; 9703 } 9704 return def; 9705 }; 9706 self.boolean = function(b, def) { 9707 if (b === true) { 9708 return true; 9709 } 9710 if (b === false) { 9711 return false; 9712 } 9713 b = self.string(b, def); 9714 if (b === def) { 9715 if (b === undefined) { 9716 return false; 9717 } 9718 return b; 9719 } 9720 b = b.toLowerCase().charAt(0); 9721 if (b === '' || b === 'n' || b === '0' || b === 'f') { 9722 return false; 9723 } 9724 if (b === 't' || b === 'y' || b === '1') { 9725 return true; 9726 } 9727 return false; 9728 }; 9729 // Given an `options` object in which options[name] is a string 9730 // set to '0', '1', or 'any', this method adds mongodb criteria 9731 // to the `criteria` object. 9732 // 9733 // '0' or false means "the property must be false or absent," '1' or true 9734 // means "the property must be true," and 'any' or null means "we don't care 9735 // what the property is." 9736 // 9737 // See `booleanOrNull` for additional synonyms accepted for the 9738 // three possible values. 9739 // 9740 // An empty string is considered equivalent to '0'. 9741 // 9742 // This is not the same as apos.sanitizeBoolean which is concerned only with 9743 // true or false and does not address "any." 9744 // 9745 // `def` defaults to `any`. 9746 // 9747 // This method is most often used with REST API parameters and forms. 9748 self.addBooleanFilterToCriteria = function(options, name, criteria, def) { 9749 // if any or null, we aren't changing criteria 9750 if (def === undefined) { 9751 def = null; 9752 } 9753 // allow object or boolean 9754 let value = typeof options === 'object' && options !== null ? options[name] : options; 9755 value = value === undefined ? def : value; 9756 value = self.booleanOrNull(value); 9757 if (value === null) { 9758 // Don't care, show all 9759 } else if (!value) { 9760 // Must be absent or false. Hooray for $ne 9761 criteria[name] = { 9762 $ne: true 9763 }; 9764 } else { 9765 // Must be true 9766 criteria[name] = true; 9767 } 9768 }; 9769 // This method is used for tristate filters, i.e. "published," 9770 // "unpublished", and "show me both". 9771 // 9772 // Accepts `true`, `false`, or `null` and returns them exactly 9773 // as such; if the parameter is none of those or their synonyms 9774 // below, returns `def`. 9775 // 9776 // Also accepts the strings `'yes'` (or starting with y), `'no'` (or 9777 // starting with n), `'true'` (or starting with t), `'false'` 9778 // (or starting with f), `'1'`, `'0'` and the strings `'any'` and 9779 // `'null'`. The string `'null'` must be an exact match, anything 9780 // else starting with `n` is taken as `no` (false). 9781 // 9782 // These various synonyms are useful for string input, such as from 9783 // a user friendly query string. 9784 self.booleanOrNull = function(b, def) { 9785 if (b === true) { 9786 return b; 9787 } 9788 if (b === false) { 9789 return b; 9790 } 9791 if (b === null) { 9792 return b; 9793 } 9794 b = self.string(b, def); 9795 if (b === def) { 9796 if (def === undefined) { 9797 return null; 9798 } 9799 return b; 9800 } 9801 // String 'null' must match as a full string to disambiguate from string 'n' for 'no' 9802 if (b === 'null') { 9803 return null; 9804 } 9805 b = b.toLowerCase().charAt(0); 9806 if (b === '' || b === 'n' || b === '0' || b === 'f') { 9807 return false;
9808 } 9809 if (b === 't' || b === 'y' || b === '1') { 9810 return true; 9811 } 9812 if (b === 'a') { 9813 return null; 9814 } 9815 return def; 9816 }; 9817 // Accept a user-entered string in YYYY-MM-DD, MM/DD, MM/DD/YY, or MM/DD/YYYY format 9818 // (tolerates missing leading zeroes on MM and DD). Also accepts a Date object. 9819 // Returns YYYY-MM-DD. 9820 // 9821 // The current year is assumed when MM/DD is used. If there is no explicit default 9822 // any unparseable date is returned as today's date. 9823 // 9824 // If the default is explicitly `null` (not `undefined`) then `null` is returned for 9825 // any unparseable date. 9826 // 9827 // The `now` argument can be passed for performance if you prefer to call 9828 // `new Date()` just once before many calls to this method and pass that single 9829 // value to all of them. 9830 self.date = function(date, def, now) { 9831 let components; 9832 function returnDefault() { 9833 if (def === undefined) { 9834 def = dayjs().format('YYYY-MM-DD'); 9835 } 9836 return def; 9837 } 9838 if (typeof date === 'string') { 9839 if (date.match(/\//)) { 9840 components = date.split('/'); 9841 if (components.length === 2) { 9842 // Convert mm/dd to yyyy-mm-dd 9843 return (now || new Date()).getFullYear() + '-' + self.padInteger(components[0], 2) + '-' + self.padInteger(components[1], 2); 9844 } else if (components.length === 3) { 9845 // Convert mm/dd/yy to mm/dd/yyyy 9846 if (components[2] < 100) { 9847 // Add the current century. If the result is more than 9848 // 50 years in the future, assume they meant the 9849 // previous century. Thus in 2015, we find that 9850 // we get the intuitive result for both 1/1/75, 9851 // 1/1/99 and 1/1/25. It's a nasty habit among 9852 // us imprecise humans. -Tom 9853 const d = now || new Date(); 9854 const nowYear = d.getFullYear() % 100; 9855 const nowCentury = d.getFullYear() - nowYear; 9856 let theirYear = parseInt(components[2]) + nowCentury; 9857 if (theirYear - d.getFullYear() > 50) { 9858 theirYear -= 100; 9859 } 9860 components[2] = theirYear; 9861 } 9862 // Convert mm/dd/yyyy to yyyy-mm-dd 9863 return self.padInteger(components[2], 4) + '-' + self.padInteger(components[0], 2) + '-' + self.padInteger(components[1], 2); 9864 } else { 9865 return returnDefault(); 9866 } 9867 } else if (date.match(/-/)) { 9868 components = date.split('-'); 9869 if (components.length === 2) { 9870 // Convert mm-dd to yyyy-mm-dd 9871 return (now || new Date()).getFullYear() + '-' + self.padInteger(components[0], 2) + '-' + self.padInteger(components[1], 2); 9872 } else if (components.length === 3) { 9873 // Convert yyyy-mm-dd (with questionable padding) to yyyy-mm-dd 9874 return self.padInteger(components[0], 4) + '-' + self.padInteger(components[1], 2) + '-' + self.padInteger(components[2], 2); 9875 } else { 9876 return returnDefault(); 9877 } 9878 } 9879 } 9880 try { 9881 if (date === null) { 9882 return returnDefault(); 9883 } 9884 date = now || new Date(date); 9885 if (isNaN(date.getTime())) { 9886 return returnDefault(); 9887 } 9888 return date.getFullYear() + '-' + self.padInteger(date.getMonth() + 1, 2) + '-' + self.padInteger(date.getDate(), 2); 9889 } catch (e) { 9890 return returnDefault(); 9891 } 9892 }; 9893 // This is likely not relevent to you unless you're using Apostrophe 9894 // Given a date object, return a date string in Apostrophe's preferred sortable, 9895 // comparable, JSON-able format, which is YYYY-MM-DD. If `date` is undefined 9896 // the current date is used. 9897 self.formatDate = function(date) { 9898 return dayjs(date).format('YYYY-MM-DD'); 9899 }; 9900 // Accepts a user-entered string in 12-hour or 24-hour time and returns a string 9901 // in 24-hour time. This method is tolerant of syntax such as `4pm`; minutes and 9902 // seconds are optional. 9903 // 9904 // If `def` is not set the default is the current time. 9905 self.time = function(time, def) { 9906 time = self.string(time).toLowerCase(); 9907 time = time.trim(); 9908 const components = time.match(/^(\d+)([:|.](\d+))?([:|.](\d+))?\s*(am|pm|AM|PM|a|p|A|M)?$/); 9909 if (components) { 9910 let hours = parseInt(components[1], 10); 9911 const minutes = components[3] !== undefined ? parseInt(components[3], 10) : 0; 9912 const seconds = components[5] !== undefined ? parseInt(components[5], 10) : 0; 9913 let ampm = components[6] ? components[6].toLowerCase() : components[6]; 9914 ampm = ampm && ampm.charAt(0); 9915 if (hours === 12 && ampm === 'a') { 9916 hours -= 12; 9917 } else if (hours === 12 && ampm === 'p') { 9918 // Leave it be 9919 } else if (ampm === 'p') { 9920 hours += 12; 9921 } 9922 if (hours === 24 || hours === '24') { 9923 hours = 0; 9924 } 9925 return self.padInteger(hours, 2) + ':' + self.padInteger(minutes, 2) + ':' + self.padInteger(seconds, 2); 9926 } else { 9927 if (def !== undefined) { 9928 return def; 9929 } 9930 return dayjs().format('HH:mm'); 9931 } 9932 }; 9933 // This is likely not relevent to you unless you're using Apostrophe 9934 // Given a JavaScript Date object, return a time string in 9935 // Apostrophe's preferred sortable, comparable, JSON-able format: 9936 // 24-hour time, with seconds. 9937 // 9938 // If `date` is missing the current time is used. 9939 self.formatTime = function(date) { 9940 return dayjs(date).format('HH:mm:ss'); 9941 }; 9942 // Sanitize tags. Tags should be submitted as an array of str
9942ings, 9943 // or a comma-separated string. 9944 // 9945 // This method ensures the input is an array or string and, if 9946 // an array, that the elements of the array are strings. 9947 // 9948 // If a filterTag function is passed as an option when initializing 9949 // Launder, then all tags are passed through it (as individual 9950 // strings, one per call) and the return value is used instead. You 9951 // may also pass a filterTag when calling this function 9952 self.tags = function(tags, filter) { 9953 if (typeof tags === 'string') { 9954 tags = tags.split(/,\s*/); 9955 } 9956 if (!Array.isArray(tags)) { 9957 return []; 9958 } 9959 const strings = tags.map((tag)=>self.string(tag)); 9960 const rewritten = strings.map(filter || self.filterTag); 9961 const filtered = rewritten.filter((tag)=>tag.length > 0); 9962 return filtered; 9963 }; 9964 // Sanitize an id. IDs must consist solely of upper and lower case 9965 // letters, numbers, and digits unless options.idRegExp is set. 9966 self.idRegExp = self.options.idRegExp || /^[A-Za-z0-9_]+$/; 9967 self.id = function(s, def) { 9968 const id = self.string(s, def); 9969 if (id === def) { 9970 return id; 9971 } 9972 if (!id.match(self.idRegExp)) { 9973 return def; 9974 } 9975 return id; 9976 }; 9977 // Sanitize an array of IDs. IDs must consist solely of upper and lower case 9978 // letters and numbers, digits, and underscores. Any elements that are not 9979 // IDs are omitted from the final array. 9980 self.ids = function(ids) { 9981 if (!Array.isArray(ids)) { 9982 return []; 9983 } 9984 const result = ids.filter(function(id) { 9985 return self.id(id) !== undefined; 9986 }); 9987 return result; 9988 }; 9989 return self; 9990}; 9991// Expose `naughtyHref` statically so callers (notably sanitize-html) 9992// can use it without instantiating a launder. 9993module.exports.naughtyHref = naughtyHref; 9994}), 9995544821, ((__turbopack_context__, module, exports) => { 9996 9997const htmlparser = __turbopack_context__.r(132109); 9998const escapeStringRegexp = __turbopack_context__.r(64873); 9999const { isPlainObject } = __turbopack_context__.r(875654); 10000const deepmerge = __turbopack_context__.r(130860); 10001const parseSrcset = __turbopack_context__.r(661840); 10002const { parse: postcssParse } = __turbopack_context__.r(485243); 10003const { naughtyHref: launderNaughtyHref } = __turbopack_context__.r(82004); 10004// Tags that can conceivably represent stand-alone media. 10005const mediaTags = [ 10006 'img', 10007 'audio', 10008 'video', 10009 'picture', 10010 'svg', 10011 'object', 10012 'map', 10013 'iframe', 10014 'embed' 10015]; 10016// Tags that are inherently vulnerable to being used in XSS attacks. 10017const vulnerableTags = [ 10018 'script', 10019 'style' 10020]; 10021// SVG SMIL animation elements. These do not carry a URL themselves: they 10022// retarget an attribute of another element, naming it with `attributeName` 10023// and supplying the new value(s) in `values`, `from`, `to` and `by`. 10024const svgAnimationTags = [ 10025 'animate', 10026 'animatecolor', 10027 'animatemotion', 10028 'animatetransform', 10029 'set' 10030]; 10031// Attribute names that always name a URL sink, whatever 10032// `allowedSchemesAppliedToAttributes` has been narrowed to. A namespace prefix 10033// is ignored when matching, so `xlink:href` and any other prefixed spelling of 10034// `href` are covered. 10035const alwaysUrlAttributes = [ 10036 'href' 10037]; 10038function each(obj, cb) { 10039 if (obj) { 10040 Object.keys(obj).forEach(function(key) { 10041 cb(obj[key], key); 10042 }); 10043 } 10044} 10045// Avoid false positives with .__proto__, .hasOwnProperty, etc. 10046function has(obj, key) { 10047 return ({}).hasOwnProperty.call(obj, key); 10048} 10049// Returns those elements of `a` for which `cb(a)` returns truthy 10050function filter(a, cb) { 10051 const n = []; 10052 each(a, function(v) { 10053 if (cb(v)) { 10054 n.push(v); 10055 } 10056 }); 10057 return n; 10058} 10059function isEmptyObject(obj) { 10060 for(const key in obj){ 10061 if (has(obj, key)) { 10062 return false; 10063 } 10064 } 10065 return true; 10066} 10067function stringifySrcset(parsedSrcset) { 10068 return parsedSrcset.map(function(part) { 10069 if (!part.url) { 10070 throw new Error('URL missing'); 10071 } 10072 return part.url + (part.w ? ` ${part.w}w` : '') + (part.h ? ` ${part.h}h` : '') + (part.d ? ` ${part.d}x` : ''); 10073 }).join(', '); 10074} 10075module.exports = sanitizeHtml; 10076// A valid attribute name. 10077// We use a tolerant definition based on the set of strings defined by 10078// html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state 10079// and html.spec.whatwg.org/multipage/parsing.html#attribute-name-state . 10080// The characters accepted are ones which can be appended to the attribute 10081// name buffer without triggering a parse error: 10082// * unexpected-equals-sign-before-attribute-name 10083// * unexpected-null-character 10084// * unexpected-character-in-attribute-name 10085// We exclude the empty string because it's impossible to get to the after 10086// attribute name state with an empty attribute name buffer. 10087const VALID_HTML_ATTRIBUTE_NAME = /^[^\0\t\n\f\r /<=>]+$/; 10088// Ignore the _recursing flag; it's there for recursive 10089// invocation as a guard against this exploit: 10090// https://github.com/fb55/htmlparser2/issues/105 10091function sanitizeHtml(html, options, _recursing) { 10092 if (html == null) { 10093 return ''; 10094 } 10095 if (typeof html === 'number') { 10096 html = html.toString(); 10097 } 10098 let result = ''; 10099 // Used for hot swapping the result variable with an empty string 10100 // in order to "capture" the text written to it. 10101 let tempResult = ''; 10102 function Frame(tag, attribs) { 10103 const that = this; 10104 this.tag = tag; 10105 this.attribs = attribs || {}; 10106 this.tagPosition = result.length; 10107 this.text = ''; // Node inner text 10108 this.openingTagLength = 0; 10109 this.mediaChildren = []; 10110 this.updateParentNodeText = function() { 10111 if (stack.length) { 10112 const parentFrame = stack[stack.length - 1]; 10113 parentFrame.text += that.text; 10114 } 10115 }; 10116 this.updateParentNodeMediaChildren = function() { 10117 if (stack.length && mediaTags.includes(this.tag)) { 10118 const parentFrame = stack[stack.length - 1]; 10119 parentFrame.mediaChildren.push(this.tag); 10120 } 10121 }; 10122 } 10123 options = Object.assign({}, sanitizeHtml.defaults, options); 10124 options.parser = Object.assign({}, htmlParserDefaults, options.parser); 10125 const tagAllowed = function(name) { 10126 return options.allowedTags === false || (options.allowedTags || []).indexOf(name) > -1; 10127 }; 10128 // vulnerableTags
vendor: 8,919 bytes, lines 10129-10319
10129 vulnerableTags.forEach(function(tag) { 10130 if (tagAllowed(tag) && !options.allowVulnerableTags) { 10131 console.warn(`\n\nâ ï¸ Your \`allowedTags\` option includes, \`${tag}\`, which is inherently\nvulnerable to XSS attacks. Please remove it from \`allowedTags\`.\nOr, to disable this warning, add the \`allowVulnerableTags\` option\nand ensure you are accounting for this risk.\n\n`); 10132 } 10133 }); 10134 // Tags that contain something other than HTML, or where discarding 10135 // the text when the tag is disallowed makes sense for other reasons. 10136 // If we are not allowing these tags, we should drop their content too. 10137 // For other tags you would drop the tag but keep its content. 10138 // `xmp` is included because htmlparser2 treats it as a raw-text element, 10139 // so markup inside is parsed as text on input but would otherwise be 10140 // re-emitted unescaped via the `ontext` branch below, allowing XSS bypass 10141 // when `xmp` is disallowed (which is the default). 10142 const nonTextTagsArray = options.nonTextTags || [ 10143 'script', 10144 'style', 10145 'textarea', 10146 'option', 10147 'xmp' 10148 ]; 10149 let allowedAttributesMap; 10150 let allowedAttributesGlobMap; 10151 if (options.allowedAttributes) { 10152 allowedAttributesMap = {}; 10153 allowedAttributesGlobMap = {}; 10154 each(options.allowedAttributes, function(attributes, tag) { 10155 allowedAttributesMap[tag] = []; 10156 const globRegex = []; 10157 attributes.forEach(function(obj) { 10158 if (typeof obj === 'string' && obj.indexOf('*') >= 0) { 10159 globRegex.push(escapeStringRegexp(obj).replace(/\\\*/g, '.*')); 10160 } else { 10161 allowedAttributesMap[tag].push(obj); 10162 } 10163 }); 10164 if (globRegex.length) { 10165 allowedAttributesGlobMap[tag] = new RegExp('^(' + globRegex.join('|') + ')$'); 10166 } 10167 }); 10168 } 10169 const allowedClassesMap = {}; 10170 const allowedClassesGlobMap = {}; 10171 const allowedClassesRegexMap = {}; 10172 each(options.allowedClasses, function(classes, tag) { 10173 // Implicitly allows the class attribute 10174 if (allowedAttributesMap) { 10175 if (!has(allowedAttributesMap, tag)) { 10176 allowedAttributesMap[tag] = []; 10177 } 10178 allowedAttributesMap[tag].push('class'); 10179 } 10180 allowedClassesMap[tag] = classes; 10181 if (Array.isArray(classes)) { 10182 const globRegex = []; 10183 allowedClassesMap[tag] = []; 10184 allowedClassesRegexMap[tag] = []; 10185 classes.forEach(function(obj) { 10186 if (typeof obj === 'string' && obj.indexOf('*') >= 0) { 10187 globRegex.push(escapeStringRegexp(obj).replace(/\\\*/g, '.*')); 10188 } else if (obj instanceof RegExp) { 10189 allowedClassesRegexMap[tag].push(obj); 10190 } else { 10191 allowedClassesMap[tag].push(obj); 10192 } 10193 }); 10194 if (globRegex.length) { 10195 allowedClassesGlobMap[tag] = new RegExp('^(' + globRegex.join('|') + ')$'); 10196 } 10197 } 10198 }); 10199 const transformTagsMap = {}; 10200 let transformTagsAll; 10201 each(options.transformTags, function(transform, tag) { 10202 let transFun; 10203 if (typeof transform === 'function') { 10204 transFun = transform; 10205 } else if (typeof transform === 'string') { 10206 transFun = sanitizeHtml.simpleTransform(transform); 10207 } 10208 if (tag === '*') { 10209 transformTagsAll = transFun; 10210 } else { 10211 transformTagsMap[tag] = transFun; 10212 } 10213 }); 10214 let depth; 10215 let stack; 10216 let skipMap; 10217 let transformMap; 10218 let skipText; 10219 let skipTextDepth; 10220 let addedText = false; 10221 initializeState(); 10222 const parser = new htmlparser.Parser({ 10223 onopentag: function(name, attribs) { 10224 if (options.onOpenTag) { 10225 options.onOpenTag(name, attribs); 10226 } 10227 // If `enforceHtmlBoundary` is `true` and this has found the opening 10228 // `html` tag, reset the state. 10229 if (options.enforceHtmlBoundary && name === 'html') { 10230 initializeState(); 10231 } 10232 if (skipText) { 10233 skipTextDepth++; 10234 return; 10235 } 10236 const frame = new Frame(name, attribs); 10237 stack.push(frame); 10238 let skip = false; 10239 const hasText = !!frame.text; 10240 let transformedTag; 10241 if (has(transformTagsMap, name)) { 10242 transformedTag = transformTagsMap[name](name, attribs); 10243 frame.attribs = attribs = transformedTag.attribs; 10244 if (transformedTag.text !== undefined) { 10245 frame.innerText = transformedTag.text; 10246 } 10247 if (name !== transformedTag.tagName) { 10248 frame.name = name = transformedTag.tagName; 10249 transformMap[depth] = transformedTag.tagName; 10250 } 10251 } 10252 if (transformTagsAll) { 10253 transformedTag = transformTagsAll(name, attribs); 10254 frame.attribs = attribs = transformedTag.attribs; 10255 if (name !== transformedTag.tagName) { 10256 frame.name = name = transformedTag.tagName; 10257 transformMap[depth] = transformedTag.tagName; 10258 } 10259 } 10260 if (!tagAllowed(name) || animatesUrlAttribute(name, attribs) || options.disallowedTagsMode === 'recursiveEscape' && !isEmptyObject(skipMap) || options.nestingLimit != null && depth >= options.nestingLimit) { 10261 skip = true; 10262 skipMap[depth] = true; 10263 if (options.disallowedTagsMode === 'discard' || options.disallowedTagsMode === 'completelyDiscard') { 10264 if (nonTextTagsArray.indexOf(name) !== -1) { 10265 skipText = true; 10266 skipTextDepth = 1; 10267 } 10268 } 10269 } 10270 depth++; 10271 if (skip) { 10272 if (options.disallowedTagsMode === 'discard' || options.disallowedTagsMode === 'completelyDiscard') { 10273 // We want the contents but not this tag 10274 if (frame.innerText && !hasText) { 10275 const escaped = escapeHtml(frame.innerText); 10276 if (options.textFilter) { 10277 result += options.textFilter(escaped, name); 10278 } else { 10279 result += escaped; 10280 } 10281 addedText = true; 10282 } 10283 return; 10284 } 10285 tempResult = result; 10286 result = ''; 10287 } 10288 result += '<' + name; 10289 if (name === 'script') { 10290 if (options.allowedScriptHostnames || options.allowedScriptDomains) { 10291 frame.innerText = ''; 10292 } 10293 } 10294 const isBeingEscaped = skip && (options.disallowedTagsMode === 'escape' || options.disallowedTagsMode === 'recursiveEscape'); 10295 const shouldPreserveEscapedAttributes = isBeingEscaped && options.preserveEscapedAttributes; 10296 if (shouldPreserveEscapedAttributes) { 10297 each(attribs, function(value, a) { 10298 result += ' ' + a + '="' + escapeHtml(value || '', true) + '"'; 10299 }); 10300 } else if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) { 10301 each(attribs, function(value, a) { 10302 if (!VALID_HTML_ATTRIBUTE_NAME.test(a)) { 10303 // This prevents part of an attribute name in the output from being 10304 // interpreted as the end of an attribute, or end of a tag. 10305 delete frame.attribs[a]; 10306 return; 10307 } 10308 // If the value is empty, check if the attribute is 10309 // in the allowedEmptyAttributes array. 10310 // If it is not in the allowedEmptyAttributes array, 10311 // and it is a known non-boolean attribute, delete it 10312 // List taken from https://html.spec.whatwg.org/multipage/indices.html#attributes-3 10313 if (value === '' && !options.allowedEmptyAttributes.includes(a) && (options.nonBooleanAttributes.includes(a) || options.nonBooleanAttributes.includes('*'))) { 10314 delete frame.attribs[a]; 10315 return; 10316 } 10317 // check allowedAttributesMap for the element and attribute and modify the value 10318 // as necessary if there are specific values defined. 10319 let passedAllowedAttributesMapCheck = false;
10320 if (!allowedAttributesMap || has(allowedAttributesMap, name) && allowedAttributesMap[name].indexOf(a) !== -1 || allowedAttributesMap['*'] && allowedAttributesMap['*'].indexOf(a) !== -1 || has(allowedAttributesGlobMap, name) && allowedAttributesGlobMap[name].test(a) || allowedAttributesGlobMap['*'] && allowedAttributesGlobMap['*'].test(a)) { 10321 passedAllowedAttributesMapCheck = true; 10322 } else if (allowedAttributesMap && allowedAttributesMap[name]) { 10323 for (const o of allowedAttributesMap[name]){ 10324 if (isPlainObject(o) && o.name && o.name === a) { 10325 passedAllowedAttributesMapCheck = true; 10326 let newValue = ''; 10327 if (o.multiple === true) { 10328 // verify the values that are allowed 10329 const splitStrArray = value.split(' '); 10330 for (const s of splitStrArray){ 10331 if (o.values.indexOf(s) !== -1) { 10332 if (newValue === '') { 10333 newValue = s; 10334 } else { 10335 newValue += ' ' + s; 10336 } 10337 } 10338 } 10339 } else if (o.values.indexOf(value) >= 0) { 10340 // verified an allowed value matches the entire attribute value 10341 newValue = value; 10342 } 10343 value = newValue; 10344 } 10345 } 10346 } 10347 if (passedAllowedAttributesMapCheck) { 10348 if (options.allowedSchemesAppliedToAttributes.indexOf(a) !== -1) { 10349 if (naughtyHref(name, value)) { 10350 delete frame.attribs[a]; 10351 return; 10352 } 10353 } 10354 if (name === 'script' && a === 'src') { 10355 let allowed = true; 10356 try { 10357 const parsed = parseUrl(value); 10358 if (options.allowedScriptHostnames || options.allowedScriptDomains) { 10359 const allowedHostname = (options.allowedScriptHostnames || []).find(function(hostname) { 10360 return hostname === parsed.url.hostname; 10361 }); 10362 const allowedDomain = (options.allowedScriptDomains || []).find(function(domain) { 10363 return parsed.url.hostname === domain || parsed.url.hostname.endsWith(`.${domain}`); 10364 }); 10365 allowed = allowedHostname || allowedDomain; 10366 } 10367 } catch (e) { 10368 allowed = false; 10369 } 10370 if (!allowed) { 10371 delete frame.attribs[a]; 10372 return; 10373 } 10374 } 10375 if (name === 'iframe' && a === 'src') { 10376 let allowed = true; 10377 try { 10378 const parsed = parseUrl(value); 10379 if (parsed.isRelativeUrl) { 10380 // default value of allowIframeRelativeUrls is true 10381 // unless allowedIframeHostnames or allowedIframeDomains specified 10382 allowed = has(options, 'allowIframeRelativeUrls') ? options.allowIframeRelativeUrls : !options.allowedIframeHostnames && !options.allowedIframeDomains; 10383 } else if (options.allowedIframeHostnames || options.allowedIframeDomains) { 10384 const allowedHostname = (options.allowedIframeHostnames || []).find(function(hostname) { 10385 return hostname === parsed.url.hostname; 10386 }); 10387 const allowedDomain = (options.allowedIframeDomains || []).find(function(domain) { 10388 return parsed.url.hostname === domain || parsed.url.hostname.endsWith(`.${domain}`); 10389 }); 10390 allowed = allowedHostname || allowedDomain; 10391 } 10392 } catch (e) { 10393 // Unparseable iframe src 10394 allowed = false;
vendor: 13,157 bytes, lines 10395-10643
10395 } 10396 if (!allowed) { 10397 delete frame.attribs[a]; 10398 return; 10399 } 10400 } 10401 if (a === 'srcset' || a === 'imagesrcset') { 10402 try { 10403 let parsed = parseSrcset(value); 10404 parsed.forEach(function(value) { 10405 if (naughtyHref(a, value.url)) { 10406 value.evil = true; 10407 } 10408 }); 10409 parsed = filter(parsed, function(v) { 10410 return !v.evil; 10411 }); 10412 if (!parsed.length) { 10413 delete frame.attribs[a]; 10414 return; 10415 } else { 10416 value = stringifySrcset(filter(parsed, function(v) { 10417 return !v.evil; 10418 })); 10419 frame.attribs[a] = value; 10420 } 10421 } catch (e) { 10422 // Unparseable srcset 10423 delete frame.attribs[a]; 10424 return; 10425 } 10426 } 10427 if (a === 'class') { 10428 const allowedSpecificClasses = allowedClassesMap[name]; 10429 const allowedWildcardClasses = allowedClassesMap['*']; 10430 const allowedSpecificClassesGlob = allowedClassesGlobMap[name]; 10431 const allowedSpecificClassesRegex = allowedClassesRegexMap[name]; 10432 const allowedWildcardClassesRegex = allowedClassesRegexMap['*']; 10433 const allowedWildcardClassesGlob = allowedClassesGlobMap['*']; 10434 const allowedClassesGlobs = [ 10435 allowedSpecificClassesGlob, 10436 allowedWildcardClassesGlob 10437 ].concat(allowedSpecificClassesRegex, allowedWildcardClassesRegex).filter(function(t) { 10438 return t; 10439 }); 10440 if (allowedSpecificClasses && allowedWildcardClasses) { 10441 value = filterClasses(value, deepmerge(allowedSpecificClasses, allowedWildcardClasses), allowedClassesGlobs); 10442 } else { 10443 value = filterClasses(value, allowedSpecificClasses || allowedWildcardClasses, allowedClassesGlobs); 10444 } 10445 if (!value.length) { 10446 delete frame.attribs[a]; 10447 return; 10448 } 10449 } 10450 if (a === 'style') { 10451 if (options.parseStyleAttributes) { 10452 try { 10453 const abstractSyntaxTree = postcssParse(name + ' {' + value + '}', { 10454 map: false 10455 }); 10456 const filteredAST = filterCss(abstractSyntaxTree, options.allowedStyles); 10457 value = stringifyStyleAttributes(filteredAST); 10458 if (value.length === 0) { 10459 delete frame.attribs[a]; 10460 return; 10461 } 10462 } catch (e) { 10463 if (typeof window !== 'undefined') { 10464 console.warn('Failed to parse "' + name + ' {' + value + '}' + '", If you\'re running this in a browser, we recommend to disable style parsing: options.parseStyleAttributes: false, since this only works in a node environment due to a postcss dependency, More info: https://github.com/apostrophecms/sanitize-html/issues/547'); 10465 } 10466 delete frame.attribs[a]; 10467 return; 10468 } 10469 } else if (options.allowedStyles) { 10470 throw new Error('allowedStyles option cannot be used together with parseStyleAttributes: false.'); 10471 } 10472 } 10473 result += ' ' + a; 10474 if (value && value.length) { 10475 result += '="' + escapeHtml(value, true) + '"'; 10476 } else if (options.allowedEmptyAttributes.includes(a)) { 10477 result += '=""'; 10478 } 10479 } else { 10480 delete frame.attribs[a]; 10481 } 10482 }); 10483 } 10484 if (options.selfClosing.indexOf(name) !== -1) { 10485 result += ' />'; 10486 } else { 10487 result += '>'; 10488 if (frame.innerText && !hasText) { 10489 const escaped = escapeHtml(frame.innerText); 10490 if (options.textFilter) { 10491 result += options.textFilter(escaped, name); 10492 } else { 10493 result += escaped; 10494 } 10495 addedText = true; 10496 } 10497 } 10498 if (skip) { 10499 result = tempResult + escapeHtml(result); 10500 tempResult = ''; 10501 } 10502 frame.openingTagLength = result.length - frame.tagPosition; 10503 }, 10504 ontext: function(text) { 10505 if (skipText) { 10506 return; 10507 } 10508 const lastFrame = stack[stack.length - 1]; 10509 let tag; 10510 if (lastFrame) { 10511 tag = lastFrame.tag; 10512 // If inner text was set by transform function then let's use it 10513 text = lastFrame.innerText !== undefined ? lastFrame.innerText : text; 10514 } 10515 if (options.disallowedTagsMode === 'completelyDiscard' && !tagAllowed(tag)) { 10516 text = ''; 10517 } else if (tag && tagAllowed(tag) && (options.disallowedTagsMode === 'discard' || options.disallowedTagsMode === 'completelyDiscard') && (tag === 'script' || tag === 'style')) { 10518 // htmlparser2 gives us these as-is. Escaping them ruins the content. Allowing 10519 // script tags is, by definition, game over for XSS protection, so if that's 10520 // your concern, don't allow them. The same is essentially true for style tags 10521 // which have their own collection of XSS vectors. 10522 result += text; 10523 } else if (tag && tagAllowed(tag) && (options.disallowedTagsMode === 'discard' || options.disallowedTagsMode === 'completelyDiscard') && (tag === 'textarea' || tag === 'xmp')) { 10524 // <textarea> and <xmp> hold text that must not be re-emitted verbatim: 10525 // if a raw `<` survives into the output it can reopen a tag when the 10526 // result is re-parsed by a browser, smuggling non-allowlisted markup 10527 // through the allowlist (mutation-XSS, GHSA-jxwj-j7wr-gfrw â e.g. the 10528 // `</textarea/>` solidus mis-close). We therefore ALWAYS escape this 10529 // content rather than passing it through. Escaping unconditionally also 10530 // closes the related SVG/MathML foreign-content bypass (where the HTML5 10531 // parser treats <textarea>/<xmp> as ordinary foreign elements and a 10532 // browser re-parses their contents as live markup, e.g. 10533 // `<svg><textarea><img src=x onerror=alert(1)></textarea></svg>`): since 10534 // we never re-emit raw text for these tags, no namespace check is 10535 // needed. The two tags need different escaping because htmlparser2 10536 // tokenizes them differently: 10537 if (tag === 'xmp') { 10538 // <xmp> is a raw-text (CDATA) element: entities are NOT decoded, so 10539 // its content reaches us as raw source that is already entity-encoded. 10540 // Escape only the angle brackets so a literal `<` cannot reopen a tag, 10541 // while leaving `&` untouched to avoid double-encoding entities that 10542 // are already encoded in the source. 10543 result += text.replace(/</g, '<').replace(/>/g, '>'); 10544 } else { 10545 // <textarea> is an RCDATA element: htmlparser2 (>= 11) decodes 10546 // entities inside it, so its content reaches us as plain decoded text. 10547 // It must therefore be fully escaped like any other text â escaping 10548 // `&` as well as `<`/`>` â so entities round-trip faithfully (no 10549 // double-encoding, see the CVE-2026-40186 regression tests) and no 10550 // `<` can reopen a tag. 10551 result += escapeHtml(text, false); 10552 } 10553 // Other "nonTextTags" like <option> are not raw text elements in 10554 // htmlparser2, so their contents are decoded and must be escaped below 10555 // like any other text (important to prevent XSS via entity-encoded 10556 // payloads such as <option><script>...</script></option>). 10557 } else if (!addedText) { 10558 const escaped = escapeHtml(text, false); 10559 if (options.textFilter) { 10560 result += options.textFilter(escaped, tag); 10561 } else { 10562 result += escaped; 10563 } 10564 } 10565 if (stack.length) { 10566 const frame = stack[stack.length - 1]; 10567 frame.text += text; 10568 } 10569 }, 10570 onclosetag: function(name, isImplied) { 10571 if (options.onCloseTag) { 10572 options.onCloseTag(name, isImplied); 10573 } 10574 if (skipText) { 10575 skipTextDepth--; 10576 if (!skipTextDepth) { 10577 skipText = false; 10578 } else { 10579 return; 10580 } 10581 } 10582 const frame = stack.pop(); 10583 if (!frame) { 10584 // Do not crash on bad markup 10585 return; 10586 } 10587 if (frame.tag !== name) { 10588 // Another case of bad markup. 10589 // Push to stack, so that it will be used in future closing tags. 10590 stack.push(frame); 10591 return; 10592 } 10593 skipText = options.enforceHtmlBoundary ? name === 'html' : false; 10594 depth--; 10595 const skip = skipMap[depth]; 10596 if (skip) { 10597 delete skipMap[depth]; 10598 if (options.disallowedTagsMode === 'discard' || options.disallowedTagsMode === 'completelyDiscard') { 10599 frame.updateParentNodeText(); 10600 return; 10601 } 10602 tempResult = result; 10603 result = ''; 10604 } 10605 if (transformMap[depth]) { 10606 name = transformMap[depth]; 10607 delete transformMap[depth]; 10608 } 10609 if (options.exclusiveFilter) { 10610 const filterResult = options.exclusiveFilter(frame); 10611 if (filterResult === 'excludeTag') { 10612 if (skip) { 10613 // no longer escaping the tag since it's not added at all 10614 result = tempResult; 10615 tempResult = ''; 10616 } 10617 // remove the opening tag from the result 10618 result = result.substring(0, frame.tagPosition) + result.substring(frame.tagPosition + frame.openingTagLength); 10619 return; 10620 } else if (filterResult) { 10621 result = result.substring(0, frame.tagPosition); 10622 return; 10623 } 10624 } 10625 frame.updateParentNodeMediaChildren(); 10626 frame.updateParentNodeText(); 10627 if (// Already output /> 10628 options.selfClosing.indexOf(name) !== -1 || isImplied && !tagAllowed(name) && [ 10629 'escape', 10630 'recursiveEscape' 10631 ].indexOf(options.disallowedTagsMode) >= 0) { 10632 if (skip) { 10633 result = tempResult; 10634 tempResult = ''; 10635 } 10636 return; 10637 } 10638 result += '</' + name + '>'; 10639 if (skip) { 10640 result = tempResult + escapeHtml(result); 10641 tempResult = ''; 10642 } 10643 addedText = false;
10644 } 10645 }, options.parser); 10646 parser.write(html); 10647 parser.end(); 10648 if (options.disallowedTagsMode === 'escape' || options.disallowedTagsMode === 'recursiveEscape') { 10649 const lastParsedIndex = parser.endIndex; 10650 if (lastParsedIndex != null && lastParsedIndex >= 0 && lastParsedIndex < html.length) { 10651 const unparsed = html.substring(lastParsedIndex); 10652 result += escapeHtml(unparsed); 10653 } else if ((lastParsedIndex == null || lastParsedIndex < 0) && html.length > 0 && result === '') { 10654 result = escapeHtml(html); 10655 } 10656 } 10657 return result; 10658 //TURBOPACK unreachable 10659 ; 10660 function initializeState() { 10661 result = ''; 10662 depth = 0; 10663 stack = []; 10664 skipMap = {}; 10665 transformMap = {}; 10666 skipText = false; 10667 skipTextDepth = 0; 10668 } 10669 function escapeHtml(s, quote) { 10670 if (typeof s !== 'string') { 10671 s = s + ''; 10672 } 10673 if (options.parser.decodeEntities) { 10674 s = s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); 10675 if (quote) { 10676 s = s.replace(/"/g, '"'); 10677 } 10678 } 10679 // TODO: this is inadequate because it will pass `&0;`. This approach 10680 // will not work, each & must be considered with regard to whether it 10681 // is followed by a 100% syntactically valid entity or not, and escaped 10682 // if it is not. If this bothers you, don't set parser.decodeEntities 10683 // to false. (The default is true.) 10684 s = s.replace(/&(?![a-zA-Z0-9#]{1,20};)/g, '&') // Match ampersands not part of existing HTML entity 10685 .replace(/</g, '<').replace(/>/g, '>'); 10686 if (quote) { 10687 s = s.replace(/"/g, '"'); 10688 } 10689 return s; 10690 } 10691 function naughtyHref(name, href) { 10692 // Resolve the per-tag scheme allowlist if one is configured for 10693 // this tag, otherwise fall back to the global allowedSchemes. 10694 const allowedSchemes = has(options.allowedSchemesByTag, name) ? options.allowedSchemesByTag[name] : options.allowedSchemes || []; 10695 return launderNaughtyHref(href, { 10696 allowedSchemes, 10697 allowProtocolRelative: options.allowProtocolRelative 10698 }); 10699 } 10700 // True if this is an SVG SMIL animation element that animates a URL-bearing 10701 // attribute, e.g. `<animate attributeName="href" values="#safe;javascript:...">`. 10702 // 10703 // Such an element carries no URL of its own: the browser copies the animation 10704 // values into the target attribute *after* sanitization, so a `javascript:` 10705 // destination reaches a live link sink without ever being scheme checked. 10706 // `values` compounds this, because it is a semicolon-separated LIST of 10707 // destinations: checking it as one flat URL only validates its first entry, so 10708 // a leading `#safe` fragment carries the rest of the list past the policy. 10709 // 10710 // Re-checking each entry of each value attribute would leave the safety of the 10711 // output resting on our imitation of SMIL list parsing, so we reject the 10712 // animation on the strength of its target instead. Animations of attributes 10713 // that are not URL sinks, such as `fill` or `opacity`, are unaffected. 10714 function animatesUrlAttribute(name, attribs) { 10715 if (svgAnimationTags.indexOf(name.toLowerCase()) === -1) { 10716 return false; 10717 } 10718 const schemeCheckedAttributes = options.allowedSchemesAppliedToAttributes || []; 10719 return Object.keys(attribs || {}).some(function(attributeName) { 10720 if (attributeName.toLowerCase() !== 'attributename') { 10721 return false; 10722 } 10723 const target = (attribs[attributeName] || '').trim().toLowerCase(); 10724 // The target may be namespace prefixed (`xlink:href`). Which prefixes are 10725 // in scope depends on the document, so consider the local name too. 10726 const localName = target.slice(target.lastIndexOf(':') + 1); 10727 return alwaysUrlAttributes.indexOf(localName) !== -1 || schemeCheckedAttributes.indexOf(target) !== -1 || schemeCheckedAttributes.indexOf(localName) !== -1; 10728 }); 10729 } 10730 function parseUrl(value) { 10731 value = value.replace(/^(\w+:)?\s*[\\/]\s*[\\/]/, '$1//'); 10732 if (value.startsWith('relative:')) { 10733 // An attempt to exploit our workaround for base URLs being 10734 // mandatory for relative URL validation in the WHATWG 10735 // URL parser, reject it 10736 throw new Error('relative: exploit attempt'); 10737 }
vendor: 4,418 bytes, lines 10738-10830
10738 // naughtyHref is in charge of whether protocol relative URLs 10739 // are cool. Here we are concerned just with allowed hostnames and 10740 // whether to allow relative URLs. 10741 // 10742 // Build a placeholder "base URL" against which any reasonable 10743 // relative URL may be parsed successfully 10744 let base = 'relative://relative-site'; 10745 for(let i = 0; i < 100; i++){ 10746 base += `/${i}`; 10747 } 10748 const parsed = new URL(value, base); 10749 const isRelativeUrl = parsed && parsed.hostname === 'relative-site' && parsed.protocol === 'relative:'; 10750 return { 10751 isRelativeUrl, 10752 url: parsed 10753 }; 10754 } 10755 /** 10756 * Filters user input css properties by allowlisted regex attributes. 10757 * Modifies the abstractSyntaxTree object. 10758 * 10759 * @param {object} abstractSyntaxTree - Object representation of CSS attributes. 10760 * @property {array[Declaration]} abstractSyntaxTree.nodes[0] - 10761 * Each object contains prop and value key, i.e { prop: 'color', value: 'red' }. 10762 * @param {object} allowedStyles - Keys are properties (i.e color), 10763 * value is list of permitted regex rules (i.e /green/i). 10764 * @return {object} - The modified tree. 10765 */ function filterCss(abstractSyntaxTree, allowedStyles) { 10766 if (!allowedStyles) { 10767 return abstractSyntaxTree; 10768 } 10769 const astRules = abstractSyntaxTree.nodes[0]; 10770 let selectedRule; 10771 // Merge global and tag-specific styles into new AST. 10772 if (allowedStyles[astRules.selector] && allowedStyles['*']) { 10773 selectedRule = deepmerge(allowedStyles[astRules.selector], allowedStyles['*']); 10774 } else { 10775 selectedRule = allowedStyles[astRules.selector] || allowedStyles['*']; 10776 } 10777 if (selectedRule) { 10778 abstractSyntaxTree.nodes[0].nodes = astRules.nodes.reduce(filterDeclarations(selectedRule), []); 10779 } 10780 return abstractSyntaxTree; 10781 } 10782 /** 10783 * Extracts the style attributes from an AbstractSyntaxTree and formats those 10784 * values in the inline style attribute format. 10785 * 10786 * @param {AbstractSyntaxTree} filteredAST 10787 * @return {string} - Example: 10788 * "color:yellow;text-align:center !important;font-family:helvetica;" 10789 */ function stringifyStyleAttributes(filteredAST) { 10790 return filteredAST.nodes[0].nodes.reduce(function(extractedAttributes, attrObject) { 10791 extractedAttributes.push(`${attrObject.prop}:${attrObject.value}${attrObject.important ? ' !important' : ''}`); 10792 return extractedAttributes; 10793 }, []).join(';'); 10794 } 10795 /** 10796 * Filters the existing attributes for the given property. Discards any attributes 10797 * which don't match the allowlist. 10798 * 10799 * @param {object} selectedRule - Example: { color: red, font-family: helvetica } 10800 * @param {array} allowedDeclarationsList - List of declarations 10801 * which pass the allowlist. 10802 * @param {object} attributeObject - Object representing the current css property. 10803 * @property {string} attributeObject.type - Typically 'declaration'. 10804 * @property {string} attributeObject.prop - The CSS property, i.e 'color'. 10805 * @property {string} attributeObject.value - The corresponding value to 10806 * the css property, i.e 'red'. 10807 * @return {function} - When used in Array.reduce, 10808 * will return an array of Declaration objects 10809 */ function filterDeclarations(selectedRule) { 10810 return function(allowedDeclarationsList, attributeObject) { 10811 // If this property is allowlisted... 10812 if (has(selectedRule, attributeObject.prop)) { 10813 const matchesRegex = selectedRule[attributeObject.prop].some(function(regularExpression) { 10814 return regularExpression.test(attributeObject.value); 10815 }); 10816 if (matchesRegex) { 10817 allowedDeclarationsList.push(attributeObject); 10818 } 10819 } 10820 return allowedDeclarationsList; 10821 }; 10822 } 10823 function filterClasses(classes, allowed, allowedGlobs) { 10824 if (!allowed) { 10825 // The class attribute is allowed without filtering on this tag 10826 return classes; 10827 } 10828 classes = classes.split(/\s+/); 10829 return classes.filter(function(clss) { 10830 return allowed.indexOf(clss) !== -1 || allowedGlobs.some(function(glob) {
vendor: 7,628 bytes, lines 10831-11205
10831 return glob.test(clss); 10832 }); 10833 }).join(' '); 10834 } 10835} 10836// Defaults are accessible to you so that you can use them as a starting point 10837// programmatically if you wish 10838const htmlParserDefaults = { 10839 decodeEntities: true 10840}; 10841sanitizeHtml.defaults = { 10842 allowedTags: [ 10843 // Sections derived from MDN element categories and limited to the more 10844 // benign categories. 10845 // https://developer.mozilla.org/en-US/docs/Web/HTML/Element 10846 // Content sectioning 10847 'address', 10848 'article', 10849 'aside', 10850 'footer', 10851 'header', 10852 'h1', 10853 'h2', 10854 'h3', 10855 'h4', 10856 'h5', 10857 'h6', 10858 'hgroup', 10859 'main', 10860 'nav', 10861 'section', 10862 // Text content 10863 'blockquote', 10864 'dd', 10865 'div', 10866 'dl', 10867 'dt', 10868 'figcaption', 10869 'figure', 10870 'hr', 10871 'li', 10872 'menu', 10873 'ol', 10874 'p', 10875 'pre', 10876 'ul', 10877 // Inline text semantics 10878 'a', 10879 'abbr', 10880 'b', 10881 'bdi', 10882 'bdo', 10883 'br', 10884 'cite', 10885 'code', 10886 'data', 10887 'dfn', 10888 'em', 10889 'i', 10890 'kbd', 10891 'mark', 10892 'q', 10893 'rb', 10894 'rp', 10895 'rt', 10896 'rtc', 10897 'ruby', 10898 's', 10899 'samp', 10900 'small', 10901 'span', 10902 'strong', 10903 'sub', 10904 'sup', 10905 'time', 10906 'u', 10907 'var', 10908 'wbr', 10909 // Table content 10910 'caption', 10911 'col', 10912 'colgroup', 10913 'table', 10914 'tbody', 10915 'td', 10916 'tfoot', 10917 'th', 10918 'thead', 10919 'tr' 10920 ], 10921 // Tags that cannot be boolean 10922 nonBooleanAttributes: [ 10923 'abbr', 10924 'accept', 10925 'accept-charset', 10926 'accesskey', 10927 'action', 10928 'allow', 10929 'alt', 10930 'as', 10931 'autocapitalize', 10932 'autocomplete', 10933 'blocking', 10934 'charset', 10935 'cite', 10936 'class', 10937 'color', 10938 'cols', 10939 'colspan', 10940 'content', 10941 'contenteditable', 10942 'coords', 10943 'crossorigin', 10944 'data', 10945 'datetime', 10946 'decoding', 10947 'dir', 10948 'dirname', 10949 'download', 10950 'draggable', 10951 'enctype', 10952 'enterkeyhint', 10953 'fetchpriority', 10954 'for', 10955 'form', 10956 'formaction', 10957 'formenctype', 10958 'formmethod', 10959 'formtarget', 10960 'headers', 10961 'height', 10962 'hidden', 10963 'high', 10964 'href', 10965 'hreflang', 10966 'http-equiv', 10967 'id', 10968 'imagesizes', 10969 'imagesrcset', 10970 'inputmode', 10971 'integrity', 10972 'is', 10973 'itemid', 10974 'itemprop', 10975 'itemref', 10976 'itemtype', 10977 'kind', 10978 'label', 10979 'lang', 10980 'list', 10981 'loading', 10982 'low', 10983 'max', 10984 'maxlength', 10985 'media', 10986 'method', 10987 'min', 10988 'minlength', 10989 'name', 10990 'nonce', 10991 'optimum', 10992 'pattern', 10993 'ping', 10994 'placeholder', 10995 'popover', 10996 'popovertarget', 10997 'popovertargetaction', 10998 'poster', 10999 'preload', 11000 'referrerpolicy', 11001 'rel', 11002 'rows', 11003 'rowspan', 11004 'sandbox', 11005 'scope', 11006 'shape', 11007 'size', 11008 'sizes', 11009 'slot', 11010 'span', 11011 'spellcheck', 11012 'src', 11013 'srcdoc', 11014 'srclang', 11015 'srcset', 11016 'start', 11017 'step', 11018 'style', 11019 'tabindex', 11020 'target', 11021 'title', 11022 'translate', 11023 'type', 11024 'usemap', 11025 'value', 11026 'width', 11027 'wrap', 11028 // Event handlers 11029 'onauxclick', 11030 'onafterprint', 11031 'onbeforematch', 11032 'onbeforeprint', 11033 'onbeforeunload', 11034 'onbeforetoggle', 11035 'onblur', 11036 'oncancel', 11037 'oncanplay', 11038 'oncanplaythrough', 11039 'onchange', 11040 'onclick', 11041 'onclose', 11042 'oncontextlost', 11043 'oncontextmenu', 11044 'oncontextrestored', 11045 'oncopy', 11046 'oncuechange', 11047 'oncut', 11048 'ondblclick', 11049 'ondrag', 11050 'ondragend', 11051 'ondragenter', 11052 'ondragleave', 11053 'ondragover', 11054 'ondragstart', 11055 'ondrop', 11056 'ondurationchange', 11057 'onemptied', 11058 'onended', 11059 'onerror', 11060 'onfocus', 11061 'onformdata', 11062 'onhashchange', 11063 'oninput', 11064 'oninvalid', 11065 'onkeydown', 11066 'onkeypress', 11067 'onkeyup', 11068 'onlanguagechange', 11069 'onload', 11070 'onloadeddata', 11071 'onloadedmetadata', 11072 'onloadstart', 11073 'onmessage', 11074 'onmessageerror', 11075 'onmousedown', 11076 'onmouseenter', 11077 'onmouseleave', 11078 'onmousemove', 11079 'onmouseout', 11080 'onmouseover', 11081 'onmouseup', 11082 'onoffline', 11083 'ononline', 11084 'onpagehide', 11085 'onpageshow', 11086 'onpaste', 11087 'onpause', 11088 'onplay', 11089 'onplaying', 11090 'onpopstate', 11091 'onprogress', 11092 'onratechange', 11093 'onreset', 11094 'onresize', 11095 'onrejectionhandled', 11096 'onscroll', 11097 'onscrollend', 11098 'onsecuritypolicyviolation', 11099 'onseeked', 11100 'onseeking', 11101 'onselect', 11102 'onslotchange', 11103 'onstalled', 11104 'onstorage', 11105 'onsubmit', 11106 'onsuspend', 11107 'ontimeupdate', 11108 'ontoggle', 11109 'onunhandledrejection', 11110 'onunload', 11111 'onvolumechange', 11112 'onwaiting', 11113 'onwheel' 11114 ], 11115 disallowedTagsMode: 'discard', 11116 allowedAttributes: { 11117 a: [ 11118 'href', 11119 'name', 11120 'target' 11121 ], 11122 // We don't currently allow img itself by default, but 11123 // these attributes would make sense if we did. 11124 img: [ 11125 'src', 11126 'srcset', 11127 'alt', 11128 'title', 11129 'width', 11130 'height', 11131 'loading' 11132 ] 11133 }, 11134 allowedEmptyAttributes: [ 11135 'alt' 11136 ], 11137 // Lots of these won't come up by default because we don't allow them 11138 selfClosing: [ 11139 'img', 11140 'br', 11141 'hr', 11142 'area', 11143 'base', 11144 'basefont', 11145 'input', 11146 'link', 11147 'meta', 11148 'col' 11149 ], 11150 // URL schemes we permit 11151 allowedSchemes: [ 11152 'http', 11153 'https', 11154 'ftp', 11155 'mailto', 11156 'tel' 11157 ], 11158 allowedSchemesByTag: {}, 11159 allowedSchemesAppliedToAttributes: [ 11160 'href', 11161 'src', 11162 'cite', 11163 'action', 11164 'formaction', 11165 'data', 11166 'xlink:href', 11167 'poster', 11168 'background', 11169 'ping', 11170 'longdesc', 11171 'usemap', 11172 'codebase', 11173 'classid', 11174 'archive', 11175 'profile', 11176 'manifest', 11177 'itemid', 11178 'dynsrc', 11179 'lowsrc' 11180 ], 11181 allowProtocolRelative: true, 11182 enforceHtmlBoundary: false, 11183 parseStyleAttributes: true, 11184 preserveEscapedAttributes: false 11185}; 11186sanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) { 11187 merge = merge === undefined ? true : merge; 11188 newAttribs = newAttribs || {}; 11189 return function(tagName, attribs) { 11190 let attrib; 11191 if (merge) { 11192 for(attrib in newAttribs){ 11193 attribs[attrib] = newAttribs[attrib]; 11194 } 11195 } else { 11196 attribs = newAttribs; 11197 } 11198 return { 11199 tagName: newTagName, 11200 attribs 11201 }; 11202 }; 11203}; 11204}), 1120533477, 898894,
11206783157, 11207356417, 11208952676, 11209426612, 11210((__turbopack_context__) => { 11211"use strict"; 11212 11213// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/CrudForm.js [app-client] (ecmascript) 11214; 11215var __TURBOPACK__imported__module__247167__ = __turbopack_context__.i(247167); 11216var __TURBOPACK__imported__module__843476__ = __turbopack_context__.i(843476); 11217var __TURBOPACK__imported__module__271645__ = __turbopack_context__.i(271645); 11218var __TURBOPACK__imported__module__522016__ = __turbopack_context__.i(522016); 11219var __TURBOPACK__imported__module__618566__ = __turbopack_context__.i(618566); 11220var __TURBOPACK__imported__module__477183__ = __turbopack_context__.i(477183); 11221var __TURBOPACK__imported__module__76590__ = __turbopack_context__.i(76590); 11222var __TURBOPACK__imported__module__807311__ = __turbopack_context__.i(807311); 11223var __TURBOPACK__imported__module__542969__ = __turbopack_context__.i(542969); 11224var __TURBOPACK__imported__module__848476__ = __turbopack_context__.i(848476); 11225var __TURBOPACK__imported__module__987030__ = __turbopack_context__.i(987030); 11226var __TURBOPACK__imported__module__949915__ = __turbopack_context__.i(949915); 11227var __TURBOPACK__imported__module__268153__ = __turbopack_context__.i(268153); 11228var __TURBOPACK__imported__module__262524__ = __turbopack_context__.i(262524); 11229var __TURBOPACK__imported__module__484973__ = __turbopack_context__.i(484973); 11230var __TURBOPACK__imported__module__871241__ = __turbopack_context__.i(871241); 11231var __TURBOPACK__imported__module__754114__ = __turbopack_context__.i(754114); 11232var __TURBOPACK__imported__module__110035__ = __turbopack_context__.i(110035); 11233var __TURBOPACK__imported__module__741870__ = __turbopack_context__.i(741870); 11234var __TURBOPACK__imported__module__643531__ = __turbopack_context__.i(643531); 11235var __TURBOPACK__imported__module__239616__ = __turbopack_context__.i(239616); 11236var __TURBOPACK__imported__module__852008__ = __turbopack_context__.i(852008); 11237var __TURBOPACK__imported__module__751975__ = __turbopack_context__.i(751975); 11238var __TURBOPACK__imported__module__283086__ = __turbopack_context__.i(283086); 11239var __TURBOPACK__imported__module__488844__ = __turbopack_context__.i(488844); 11240var __TURBOPACK__imported__module__390519__ = __turbopack_context__.i(390519); 11241var __TURBOPACK__imported__module__954922__ = __turbopack_context__.i(954922); 11242var __TURBOPACK__imported__module__150965__ = __turbopack_context__.i(150965); 11243var __TURBOPACK__imported__module__201928__ = __turbopack_context__.i(201928); 11244var __TURBOPACK__imported__module__223945__ = __turbopack_context__.i(223945); 11245var __TURBOPACK__imported__module__761911__ = __turbopack_context__.i(761911); 11246var __TURBOPACK__imported__module__63727__ = __turbopack_context__.i(63727); 11247var __TURBOPACK__imported__module__342920__ = __turbopack_context__.i(342920); 11248var __TURBOPACK__imported__module__810980__ = __turbopack_context__.i(810980); 11249var __TURBOPACK__imported__module__571930__ = __turbopack_context__.i(571930); 11250var __TURBOPACK__imported__module__968553__ = __turbopack_context__.i(968553); 11251var __TURBOPACK__imported__module__205125__ = __turbopack_context__.i(205125); 11252var __TURBOPACK__imported__module__503116__ = __turbopack_context__.i(503116); 11253var __TURBOPACK__imported__module__727927__ = __turbopack_context__.i(727927); 11254var __TURBOPACK__imported__module__394908__ = __turbopack_context__.i(394908); 11255var __TURBOPACK__imported__module__561659__ = __turbopack_context__.i(561659); 11256var __TURBOPACK__imported__module__658041__ = __turbopack_context__.i(658041); 11257var __TURBOPACK__imported__module__958377__ = __turbopack_context__.i(958377); 11258var __TURBOPACK__imported__module__730699__ = __turbopack_context__.i(730699); 11259var __TURBOPACK__imported__module__248256__ = __turbopack_context__.i(248256); 11260var __TURBOPACK__imported__module__790597__ = __turbopack_context__.i(790597); 11261var __TURBOPACK__imported__module__952571__ = __turbopack_context__.i(952571); 11262var __TURBOPACK__imported__module__834161__ = __turbopack_context__.i(834161); 11263var __TURBOPACK__imported__module__73526__ = __turbopack_context__.i(73526); 11264var __TURBOPACK__imported__module__647780__ = __turbopack_context__.i(647780); 11265var __TURBOPACK__imported__module__98919__ = __turbopack_context__.i(98919); 11266var __TURBOPACK__imported__module__870273__ = __turbopack_context__.i(870273); 11267var __TURBOPACK__imported__module__715788__ = __turbopack_context__.i(715788); 11268var __TURBOPACK__imported__module__39312__ = __turbopack_context__.i(39312); 11269var __TURBOPACK__imported__module__575822__ = __turbopack_context__.i(575822); 11270var __TURBOPACK__imported__module__127308__ = __turbopack_context__.i(127308); 11271var __TURBOPACK__imported__module__221019__ = __turbopack_context__.i(221019); 11272var __TURBOPACK__imported__module__861172__ = __turbopack_context__.i(861172); 11273var __TURBOPACK__imported__module__928441__ = __turbopack_context__.i(928441); 11274var __TURBOPACK__imported__module__276583__ = __turbopack_context__.i(276583); 11275var __TURBOPACK__imported__module__341881__ = __turbopack_context__.i(341881); 11276var __TURBOPACK__imported__module__401851__ = __turbopack_context__.i(401851); 11277var __TURBOPACK__imported__module__826514__ = __turbopack_context__.i(826514); 11278var __TURBOPACK__imported__module__129474__ = __turbopack_context__.i(129474); 11279var __TURBOPACK__imported__module__637688__ = __turbopack_context__.i(637688); 11280var __TURBOPACK__imported__module__283531__ = __turbopack_context__.i(283531); 11281var __TURBOPACK__imported__module__685008__ = __turbopack_context__.i(685008); 11282var __TURBOPACK__imported__module__490746__ = __turbopack_context__.i(490746); 11283var __TURBOPACK__imported__module__977896__ = __turbopack_context__.i(977896); 11284var __TURBOPACK__imported__module__372790__ = __turbopack_context__.i(372790); 11285var __TURBOPACK__imported__module__644149__ = __turbopack_context__.i(644149); 11286// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/custom-fields/FieldDefinitionsManager.js [app-client] (ecmascript) 11287; 11288var __TURBOPACK__imported__module__843476__1 = __TURBOPACK__imported__module__843476__; 11289var __TURBOPACK__imported__module__271645__1 = __TURBOPACK__imported__module__271645__; 11290var __TURBOPACK__imported__module__912598__ = __turbopack_context__.i(912598); 11291var __TURBOPACK__imported__module__110035__1 = __TURBOPACK__imported__module__110035__; 11292var __TURBOPACK__imported__module__306994__ = __turbopack_context__.i(306994); 11293var __TURBOPACK__imported__module__975215__ = __turbopack_context__.i(975215); 11294var __TURBOPACK__imported__module__484973__1 = __TURBOPACK__imported__module__484973__; 11295var __TURBOPACK__imported__module__490746__1 = __TURBOPACK__imported__module__490746__; 11296var __TURBOPACK__imported__module__685008__1 = __TURBOPACK__imported__module__685008__; 11297var __TURBOPACK__imported__module__221019__1 = __TURBOPACK__imported__module__221019__; 11298// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/custom-fields/FieldDefinitionsEditor.js [app-client] (ecmascript) 11299; 11300var __TURBOPACK__imported__module__843476__2 = __TURBOPACK__imported__module__843476__; 11301var __TURBOPACK__imported__module__271645__2 = __TURBOPACK__imported__module__271645__; 11302var __TURBOPACK__imported__module__514306__ = __turbopack_context__.i(514306); 11303var __TURBOPACK__imported__module__750570__ = __turbopack_context__.i(750570); 11304var __TURBOPACK__imported__module__763639__ = __turbopack_context__.i(763639); 11305var __TURBOPACK__imported__module__788699__ = __turbopack_context__.i(788699); 11306var __TURBOPACK__imported__module__107233__ = __turbopack_context__.i(107233); 11307var __TURBOPACK__imported__module__727612__ = __turbopack_context__.i(727612); 11308var __TURBOPACK__imported__module__110035__2 = __TURBOPACK__imported__module__110035__; 11309// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/primitives/checkbox-field.js [app-client] (ecmascript) 11310; 11311var __TURBOPACK__imported__module__843476__3 = __TURBOPACK__imported__module__843476__; 11312var __TURBOPACK__imported__module__271645__3 = __TURBOPACK__imported__module__271645__; 11313var __TURBOPACK__imported__module__406911__ = __turbopack_context__.i(406911); 11314var __TURBOPACK__imported__module__848476__1 = __TURBOPACK__imported__module__848476__; 11315; 11316; 11317; 11318; 11319const CheckboxField = /*#__PURE__*/ __TURBOPACK__imported__module__271645__3["forwardRef"](({ id: idProp, label, sublabel, description, badge, link, flip = false, containerClassName, contentClassName, size = "md", className, disabled, ...checkboxProps }, ref)=>{ 11320 const reactId = __TURBOPACK__imported__module__271645__3["useId"](); 11321 const id = idProp ?? `checkbox-field-${reactId}`; 11322 const hasMultiLine = Boolean(description || sublabel || link); 11323 const checkbox = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])(__TURBOPACK__imported__module__848476__1["Checkbox"], { 11324 ref, 11325 id, 11326 size, 11327 disabled, 11328 className: (0, __TURBOPACK__imported__module__406911__["cn"])(hasMultiLine && "mt-0.5", className), 11329 ...checkboxProps 11330 }); 11331 const content = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsxs"])("div", { 11332 className: (0, __TURBOPACK__imported__module__406911__["cn"])("flex flex-1 min-w-0 flex-col gap-2.5", contentClassName), 11333 children: [
11334 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsxs"])("div", { 11335 className: "flex flex-col gap-1", 11336 children: [ 11337 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsxs"])("div", { 11338 className: "flex flex-wrap items-center gap-1", 11339 children: [ 11340 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])("label", { 11341 htmlFor: id, 11342 className: (0, __TURBOPACK__imported__module__406911__["cn"])("text-sm font-medium leading-5 text-foreground select-none", disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer"), 11343 children: label 11344 }), 11345 sublabel ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])("span", { 11346 className: "text-xs leading-4 text-muted-foreground select-none", 11347 children: sublabel 11348 }) : null,
11349 badge ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])("span", { 11350 className: "inline-flex shrink-0", 11351 children: badge 11352 }) : null 11353 ] 11354 }), 11355 description ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])("p", { 11356 className: "text-xs leading-4 text-muted-foreground", 11357 children: description 11358 }) : null 11359 ] 11360 }), 11361 link ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsx"])("div", { 11362 className: "flex", 11363 children: link 11364 }) : null 11365 ] 11366 }); 11367 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__3["jsxs"])("div", { 11368 className: (0, __TURBOPACK__imported__module__406911__["cn"])("flex gap-2", hasMultiLine ? "items-start" : "items-center", flip && "flex-row-reverse", containerClassName), 11369 children: [ 11370 flip ? content : checkbox, 11371 flip ? checkbox : content 11372 ] 11373 }); 11374}); 11375CheckboxField.displayName = "CheckboxField"; 11376; 11377__turbopack_context__.s([ 11378 "CheckboxField", 11379 0, 11380 CheckboxField 11381], 898894); 11382var __TURBOPACK__imported__module__828151__ = __turbopack_context__.i(828151); 11383var __TURBOPACK__imported__module__741870__1 = __TURBOPACK__imported__module__741870__; 11384var __TURBOPACK__imported__module__987030__1 = __TURBOPACK__imported__module__987030__; 11385var __TURBOPACK__imported__module__262524__1 = __TURBOPACK__imported__module__262524__; 11386var __TURBOPACK__imported__module__130133__ = __turbopack_context__.i(130133); 11387var __TURBOPACK__imported__module__928441__1 = __TURBOPACK__imported__module__928441__; 11388var __TURBOPACK__imported__module__127308__1 = __TURBOPACK__imported__module__127308__; 11389var __TURBOPACK__imported__module__84884__ = __turbopack_context__.i(84884); 11390var __TURBOPACK__imported__module__488573__ = __turbopack_context__.i(488573); 11391var __TURBOPACK__imported__module__486775__ = __turbopack_context__.i(486775); 11392var __TURBOPACK__imported__module__644149__1 = __TURBOPACK__imported__module__644149__; 11393var __TURBOPACK__imported__module__602810__ = __turbopack_context__.i(602810); 11394"use client"; 11395; 11396; 11397; 11398; 11399; 11400; 11401; 11402; 11403; 11404; 11405; 11406; 11407; 11408; 11409; 11410; 11411function formatFallback(template, params) { 11412 if (!params) return template; 11413 return template.replace(/\{\{(\w+)\}\}|\{(\w+)\}/g, (match, doubleKey, singleKey)=>{ 11414 const key = doubleKey ?? singleKey; 11415 if (!key) return match; 11416 const value = params[key]; 11417 return value === void 0 ? match : String(value); 11418 }); 11419} 11420const DEFAULT_VALUE_NONE = "__open_mercato_no_default__"; 11421function getDefaultValueNoneOptionValue(options) { 11422 const optionValues = new Set(options.map((option)=>String(option.value))); 11423 let candidate = DEFAULT_VALUE_NONE; 11424 while(optionValues.has(candidate)){ 11425 candidate = `${candidate}_`; 11426 } 11427 return candidate; 11428} 11429const FIELDSET_ICON_OPTIONS = [ 11430 { 11431 value: "layers", 11432 label: "Layers" 11433 }, 11434 { 11435 value: "tag", 11436 label: "Tag" 11437 }, 11438 { 11439 value: "sparkles", 11440 label: "Sparkles" 11441 }, 11442 { 11443 value: "package", 11444 label: "Package" 11445 }, 11446 { 11447 value: "shirt", 11448 label: "Shirt" 11449 }, 11450 { 11451 value: "grid", 11452 label: "Grid" 11453 }, 11454 { 11455 value: "shoppingBag", 11456 label: "Shopping bag" 11457 }, 11458 { 11459 value: "shoppingCart", 11460 label: "Shopping cart" 11461 }, 11462 { 11463 value: "store", 11464 label: "Store" 11465 }, 11466 { 11467 value: "users", 11468 label: "Users" 11469 }, 11470 { 11471 value: "briefcase", 11472 label: "Briefcase" 11473 }, 11474 { 11475 value: "building", 11476 label: "Building" 11477 }, 11478 { 11479 value: "bookOpen", 11480 label: "Book open" 11481 }, 11482 { 11483 value: "bookmark", 11484 label: "Bookmark" 11485 }, 11486 { 11487 value: "camera", 11488 label: "Camera" 11489 }, 11490 { 11491 value: "car", 11492 label: "Car" 11493 }, 11494 { 11495 value: "clock", 11496 label: "Clock" 11497 }, 11498 { 11499 value: "cloud", 11500 label: "Cloud" 11501 }, 11502 { 11503 value: "compass", 11504 label: "Compass" 11505 }, 11506 {
11507 value: "creditCard", 11508 label: "Credit card" 11509 }, 11510 { 11511 value: "database", 11512 label: "Database" 11513 }, 11514 { 11515 value: "flame", 11516 label: "Flame" 11517 }, 11518 { 11519 value: "gift", 11520 label: "Gift" 11521 }, 11522 { 11523 value: "globe", 11524 label: "Globe" 11525 }, 11526 { 11527 value: "heart", 11528 label: "Heart" 11529 }, 11530 { 11531 value: "key", 11532 label: "Key" 11533 }, 11534 { 11535 value: "map", 11536 label: "Map" 11537 }, 11538 { 11539 value: "palette", 11540 label: "Palette" 11541 }, 11542 { 11543 value: "shield", 11544 label: "Shield" 11545 }, 11546 { 11547 value: "star", 11548 label: "Star" 11549 }, 11550 { 11551 value: "truck", 11552 label: "Truck" 11553 }, 11554 { 11555 value: "zap", 11556 label: "Zap" 11557 }, 11558 { 11559 value: "coins", 11560 label: "Coins" 11561 } 11562]; 11563function slugifyFieldsetCode(value) { 11564 return (0, __TURBOPACK__imported__module__84884__["slugify"])(value, { 11565 replacement: "", 11566 allowedChars: "_-" 11567 }); 11568} 11569function ensureUniqueFieldsetCode(base, existing) { 11570 const sanitizedBase = slugifyFieldsetCode(base) || "fieldset"; 11571 let candidate = sanitizedBase; 11572 let counter = 1; 11573 const existingCodes = new Set(existing.map((fs)=>fs.code)); 11574 while(existingCodes.has(candidate)){ 11575 counter += 1; 11576 candidate = `${sanitizedBase}_${counter}`; 11577 } 11578 return candidate; 11579} 11580function normalizeGroupValue(raw) { 11581 if (!raw) return null; 11582 if (typeof raw === "string") { 11583 const code2 = raw.trim(); 11584 return code2 ? { 11585 code: code2 11586 } : null; 11587 } 11588 if (typeof raw !== "object") return null; 11589 const entry = raw; 11590 const code = typeof entry.code === "string" ? entry.code.trim() : ""; 11591 if (!code) return null; 11592 const group = { 11593 code 11594 }; 11595 if (typeof entry.title === "string" && entry.title.trim()) group.title = entry.title.trim(); 11596 if (typeof entry.hint === "string" && entry.hint.trim()) group.hint = entry.hint.trim(); 11597 return group; 11598} 11599function FieldDefinitionsEditor({ definitions, errors, deletedKeys, kindOptions, orderNotice, infoNote, addButtonLabel, fieldsets = [], activeFieldset = null, onActiveFieldsetChange, onFieldsetsChange, onFieldsetCodeChange, onFieldsetRemoved, singleFieldsetPerRecord, onSingleFieldsetPerRecordChange, onAddField, onRemoveField, onDefinitionChange, onRestoreField, onReorder, onTranslate, listRef, listProps, translate }) { 11600 const { confirm, ConfirmDialogElement } = (0, __TURBOPACK__imported__module__486775__["useConfirmDialog"])(); 11601 const dragIndex = __TURBOPACK__imported__module__271645__2["useRef"](null); 11602 const hasFieldsets = fieldsets.length > 0; 11603 const contextT = (0, __TURBOPACK__imported__module__928441__1["useOptionalT"])(); 11604 const t = __TURBOPACK__imported__module__271645__2["useCallback"]((key, fallbackOrParams, params)=>{ 11605 if (translate) return translate(key, fallbackOrParams, params); 11606 if (contextT) return contextT(key, fallbackOrParams, params); 11607 return typeof fallbackOrParams === "string" ? formatFallback(fallbackOrParams, params) : key; 11608 }, [ 11609 translate, 11610 contextT 11611 ]); 11612 const resolvedKindOptions = __TURBOPACK__imported__module__271645__2["useMemo"](()=>kindOptions ?? __TURBOPACK__imported__module__130133__["CUSTOM_FIELD_KINDS"].map((kind)=>({ 11613 value: kind, 11614 label: t(`entities.customFields.editor.kindOption.${kind}`, kind.charAt(0).toUpperCase() + kind.slice(1)) 11615 })), [ 11616 kindOptions, 11617 t 11618 ]); 11619 const resolvedInfoNote = infoNote !== void 0 ? infoNote : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 11620 className: "text-xs text-muted-foreground mt-2", 11621 children: t("entities.customFields.editor.supportedKindsNote", "Supported kinds: text, multiline, integer, float, boolean, select (with options/optionsUrl), currency (fixed currencies list), relation (with related entity and options URL).") 11622 }); 11623 const resolvedAddButtonLabel = addButtonLabel ?? t("entities.customFields.editor.addField", "Add Field"); 11624 const resolvedActiveFieldset = __TURBOPACK__imported__module__271645__2["useMemo"](()=>{ 11625 if (!hasFieldsets) return activeFieldset ?? null; 11626 if (activeFieldset === null) return null; 11627 return fieldsets.some((fs)=>fs.code === activeFieldset) ? activeFieldset : fieldsets[0]?.code ?? null; 11628 }, [ 11629 activeFieldset, 11630 fieldsets, 11631 hasFieldsets 11632 ]); 11633 const filteredDefinitions = __TURBOPACK__imported__module__271645__2["useMemo"](()=>definitions.map((definition, index)=>({ 11634 definition, 11635 index 11636 })).filter(({ definition })=>{ 11637 if (!hasFieldsets) return true; 11638 const assigned = typeof definition.configJson?.fieldset === "string" ? definition.configJson.fieldset : void 0; 11639 if (!resolvedActiveFieldset) return !assigned; 11640 return assigned === resolvedActiveFieldset; 11641 }), [ 11642 definitions, 11643 hasFieldsets, 11644 resolvedActiveFieldset 11645 ]); 11646 const activeFieldsetConfig = hasFieldsets && resolvedActiveFieldset ? fieldsets.find((fs)=>fs.code === resolvedActiveFieldset) ?? null : null; 11647 const handleActiveFieldsetChange = (value)=>{ 11648 if (!onActiveFieldsetChange) return; 11649 onActiveFieldsetChange(value ? value : null); 11650 }; 11651 const handleFieldsetPatch = (code, patch)=>{ 11652 if (!onFieldsetsChange) return; 11653 const next = fieldsets.map((fs)=>fs.code === code ? { 11654 ...fs, 11655 ...patch 11656 } : fs); 11657 onFieldsetsChange(next); 11658 }; 11659 const handleFieldsetCodeInput = (code, nextValue)=>{ 11660 if (!onFieldsetsChange) return; 11661 const target = fieldsets.find((fs)=>fs.code === code); 11662 if (!target) return; 11663 const sanitized = slugifyFieldsetCode(nextValue); 11664 if (!sanitized) return; 11665 const next = fieldsets.map((fs)=>fs.code === code ? { 11666 ...fs, 11667 code: sanitized 11668 } : fs); 11669 onFieldsetsChange(next); 11670 onFieldsetCodeChange?.(code, sanitized); 11671 onActiveFieldsetChange?.(sanitized); 11672 }; 11673 const handleAddFieldset = ()=>{ 11674 if (!onFieldsetsChange) return; 11675 const code = ensureUniqueFieldsetCode(`fieldset_${fieldsets.length + 1}`, fieldsets); 11676 const nextFieldsets = [ 11677 ...fieldsets, 11678 { 11679 code, 11680 label: t("entities.customFields.editor.newFieldsetLabel", "New fieldset"), 11681 icon: "layers" 11682 } 11683 ]; 11684 onFieldsetsChange(nextFieldsets); 11685 onActiveFieldsetChange?.(code); 11686 }; 11687 const handleRemoveFieldset = async ()=>{ 11688 if (!onFieldsetsChange) return; 11689 if (!resolvedActiveFieldset) return; 11690 const confirmed = await confirm({ 11691 title: t("entities.customFields.editor.deleteFieldsetTitle", 'Delete fieldset "{code}"?', { 11692 code: resolvedActiveFieldset 11693 }), 11694 text: t("entities.customFields.editor.deleteFieldsetText", "This will move its fields to Unassigned."), 11695 variant: "destructive" 11696 }); 11697 if (!confirmed) return; 11698 const next = fieldsets.filter((fs)=>fs.code !== resolvedActiveFieldset); 11699 onFieldsetsChange(next); 11700 onFieldsetRemoved?.(resolvedActiveFieldset); 11701 const fallback = next[0]?.code ?? null; 11702 onActiveFieldsetChange?.(fallback); 11703 }; 11704 const registerGroup = __TURBOPACK__imported__module__271645__2["useCallback"]((fieldsetCode, group)=>{ 11705 if (!onFieldsetsChange || !fieldsetCode) return; 11706 const next = fieldsets.map((fs)=>{ 11707 if (fs.code !== fieldsetCode) return fs; 11708 const list = Array.isArray(fs.groups) ? fs.groups : []; 11709 const existingIndex = list.findIndex((entry)=>entry.code === group.code); 11710 if (existingIndex >= 0) { 11711 const updated = [ 11712 ...list 11713 ]; 11714 updated[existingIndex] = { 11715 ...list[existingIndex], 11716 ...group 11717 }; 11718 return { 11719 ...fs, 11720 groups: updated 11721 }; 11722 } 11723 return { 11724 ...fs, 11725 groups: [ 11726 ...list, 11727 group 11728 ] 11729 }; 11730 }); 11731 onFieldsetsChange(next); 11732 }, [ 11733 fieldsets, 11734 onFieldsetsChange 11735 ]); 11736 const removeGroup = __TURBOPACK__imported__module__271645__2["useCallback"]((fieldsetCode, groupCode)=>{ 11737 if (!onFieldsetsChange || !fieldsetCode || !groupCode) return; 11738 const next = fieldsets.map((fs)=>{ 11739 if (fs.code !== fieldsetCode) return fs; 11740 const list = Array.isArray(fs.groups) ? fs.groups : []; 11741 return { 11742 ...fs, 11743 groups: list.filter((entry)=>entry.code !== groupCode) 11744 }; 11745 }); 11746 onFieldsetsChange(next); 11747 }, [ 11748 fieldsets, 11749 onFieldsetsChange 11750 ]); 11751 const availableGroups = activeFieldsetConfig?.groups ?? []; 11752 const canToggleSingleFieldset = hasFieldsets && fieldsets.length > 1; 11753 const singleFieldsetChecked = singleFieldsetPerRecord !== false; 11754 const handleReorder = __TURBOPACK__imported__module__271645__2["useCallback"]((from, to)=>{ 11755 if (from === to) return; 11756 onReorder?.(from, to); 11757 }, [ 11758 onReorder 11759 ]); 11760 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 11761 ref: listRef, 11762 className: "space-y-3", 11763 ...listProps, 11764 children: [
11765 hasFieldsets ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 11766 className: "rounded border bg-card p-3 space-y-3", 11767 children: [ 11768 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 11769 className: "flex flex-wrap items-center gap-2", 11770 children: [ 11771 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("label", { 11772 className: "text-xs font-medium text-muted-foreground", 11773 children: t("entities.customFields.fieldsetSelectorLabel", "Fieldset") 11774 }), 11775 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 11776 value: resolvedActiveFieldset || void 0, 11777 onValueChange: (value)=>handleActiveFieldsetChange(value ?? ""), 11778 children: [
11779 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 11780 size: "sm", 11781 className: "w-auto min-w-[10rem]", 11782 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], { 11783 placeholder: t("entities.customFields.editor.unassignedFields", "Unassigned fields") 11784 }) 11785 }), 11786 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 11787 children: fieldsets.map((fs)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 11788 value: fs.code, 11789 children: fs.label || fs.code 11790 }, fs.code)) 11791 }) 11792 ] 11793 }),
11794 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__110035__2["Button"], { 11795 variant: "outline", 11796 size: "sm", 11797 onClick: handleAddFieldset, 11798 className: "text-xs", 11799 children: [ 11800 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__107233__["Plus"], { 11801 className: "h-3.5 w-3.5" 11802 }), 11803 " ", 11804 t("entities.customFields.editor.add", "Add") 11805 ] 11806 }), 11807 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__110035__2["Button"], { 11808 variant: "outline", 11809 size: "sm", 11810 onClick: handleRemoveFieldset, 11811 disabled: !resolvedActiveFieldset, 11812 className: "text-xs", 11813 children: [
11814 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__727612__["Trash2"], { 11815 className: "h-3.5 w-3.5" 11816 }), 11817 " ", 11818 t("entities.customFields.editor.delete", "Delete") 11819 ] 11820 }) 11821 ] 11822 }), 11823 resolvedActiveFieldset && activeFieldsetConfig ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 11824 className: "grid grid-cols-1 md:grid-cols-4 gap-3", 11825 children: [ 11826 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 11827 label: t("entities.customFields.editor.code", "Code"), 11828 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 11829 size: "sm", 11830 inputClassName: "font-mono", 11831 value: activeFieldsetConfig.code, 11832 onChange: (event)=>handleFieldsetCodeInput(activeFieldsetConfig.code, event.target.value) 11833 }) 11834 }),
11835 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 11836 label: t("entities.customFields.editor.label", "Label"), 11837 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 11838 size: "sm", 11839 value: activeFieldsetConfig.label, 11840 onChange: (event)=>handleFieldsetPatch(activeFieldsetConfig.code, { 11841 label: event.target.value 11842 }) 11843 }) 11844 }), 11845 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 11846 label: t("entities.customFields.editor.icon", "Icon"), 11847 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 11848 value: activeFieldsetConfig.icon || void 0, 11849 onValueChange: (value)=>handleFieldsetPatch(activeFieldsetConfig.code, { 11850 icon: value || void 0 11851 }), 11852 children: [
11853 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 11854 size: "sm", 11855 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], { 11856 placeholder: t("entities.customFields.editor.defaultOption", "Default") 11857 }) 11858 }), 11859 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 11860 children: FIELDSET_ICON_OPTIONS.map((option)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 11861 value: option.value, 11862 children: t(`entities.customFields.editor.iconOption.${option.value}`, option.label) 11863 }, option.value)) 11864 }) 11865 ] 11866 }) 11867 }),
11868 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 11869 label: t("entities.customFields.editor.description", "Description"), 11870 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 11871 size: "sm", 11872 value: activeFieldsetConfig.description ?? "", 11873 onChange: (event)=>handleFieldsetPatch(activeFieldsetConfig.code, { 11874 description: event.target.value 11875 }) 11876 }) 11877 }) 11878 ] 11879 }) : null, 11880 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 11881 className: "flex items-center gap-2", 11882 children: [
11883 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(CheckboxField, { 11884 size: "sm", 11885 disabled: !canToggleSingleFieldset, 11886 checked: singleFieldsetChecked, 11887 onCheckedChange: (checked)=>onSingleFieldsetPerRecordChange?.(checked === true), 11888 label: t("entities.customFields.editor.singleFieldsetPerEntity", "Single fieldset per entity"), 11889 containerClassName: "text-xs", 11890 contentClassName: "gap-1 [&_label]:text-xs [&_label]:font-normal" 11891 }), 11892 !canToggleSingleFieldset ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("span", { 11893 className: "text-xs text-muted-foreground", 11894 children: t("entities.customFields.editor.singleFieldsetToggleHint", "(add at least two fieldsets to toggle)") 11895 }) : null 11896 ] 11897 }) 11898 ] 11899 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 11900 className: "rounded border border-dashed bg-muted/30 p-4 text-sm text-muted-foreground flex flex-col gap-3", 11901 children: [
11902 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 11903 children: t("entities.customFields.editor.noFieldsets", "No fieldsets defined yet. Fieldsets let you group custom fields for different variants of the same entity (e.g., Fashion vs. Sport products).") 11904 }), 11905 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 11906 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__110035__2["Button"], { 11907 variant: "outline", 11908 size: "sm", 11909 onClick: handleAddFieldset, 11910 children: [ 11911 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__107233__["Plus"], { 11912 className: "h-4 w-4" 11913 }), 11914 t("entities.customFields.editor.addFirstFieldset", "Add first fieldset") 11915 ] 11916 }) 11917 }) 11918 ] 11919 }), 11920 orderNotice?.dirty && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 11921 className: "sticky top-0 z-sticky -mt-1 -mb-1", 11922 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 11923 className: "inline-flex items-center gap-2 text-xs px-2 py-1 rounded border border-status-warning-border bg-status-warning-bg text-status-warning-text shadow-sm", 11924 children: orderNotice?.saving ? t("entities.customFields.editor.savingOrder", "Saving order\u2026") : orderNotice?.message ?? t("entities.customFields.editor.reorderedSavingSoon", "Reordered \u2014 saving soon") 11925 }) 11926 }), 11927 filteredDefinitions.map(({ definition, index })=>{ 11928 const assignedFieldset = typeof definition.configJson?.fieldset === "string" ? definition.configJson.fieldset : null; 11929 const groupOptions = assignedFieldset ? fieldsets.find((fs)=>fs.code === assignedFieldset)?.groups ?? [] : availableGroups; 11930 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 11931 className: "group", 11932 draggable: true, 11933 onDragStart: ()=>{ 11934 dragIndex.current = index; 11935 }, 11936 onDragOver: (event)=>{ 11937 event.preventDefault(); 11938 }, 11939 onDrop: ()=>{ 11940 const from = dragIndex.current; 11941 if (from == null) return; 11942 dragIndex.current = null; 11943 handleReorder(from, index); 11944 }, 11945 onDragEnd: ()=>{ 11946 dragIndex.current = null; 11947 }, 11948 tabIndex: 0, 11949 onKeyDown: (event)=>{ 11950 if (!event.altKey) return; 11951 if (event.key === "ArrowUp" || event.key === "Up") { 11952 event.preventDefault(); 11953 handleReorder(index, Math.max(0, index - 1)); 11954 } 11955 if (event.key === "ArrowDown" || event.key === "Down") { 11956 event.preventDefault(); 11957 handleReorder(index, Math.min(definitions.length - 1, index + 1)); 11958 } 11959 }, 11960 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(FieldDefinitionCard, { 11961 definition, 11962 error: errors?.[index], 11963 kindOptions: resolvedKindOptions, 11964 onChange: (next)=>onDefinitionChange(index, next), 11965 onRemove: ()=>onRemoveField(index), 11966 allowFieldsetSelection: hasFieldsets, 11967 fieldsets, 11968 activeFieldset: resolvedActiveFieldset, 11969 availableGroups: groupOptions, 11970 onRegisterGroup: registerGroup, 11971 onRemoveGroup: removeGroup, 11972 onTranslate: onTranslate ? ()=>onTranslate(definition, index) : void 0, 11973 translate: t 11974 }) 11975 }, definition.key || `def-${index}`); 11976 }),
11977 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 11978 children: [ 11979 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__110035__2["Button"], { 11980 variant: "outline", 11981 size: "sm", 11982 onClick: onAddField, 11983 children: [ 11984 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__107233__["Plus"], { 11985 className: "h-4 w-4" 11986 }), 11987 " ", 11988 resolvedAddButtonLabel 11989 ] 11990 }), 11991 resolvedInfoNote, 11992 deletedKeys && deletedKeys.length > 0 && onRestoreField ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 11993 className: "text-xs text-muted-foreground mt-2", 11994 children: [ 11995 t("entities.customFields.editor.restoreDeletedFields", "Restore deleted fields:"), 11996 " ", 11997 deletedKeys.map((key, idx)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("span", { 11998 children: [
11999 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__110035__2["Button"], { 12000 variant: "link", 12001 className: "h-auto p-0", 12002 onClick: ()=>onRestoreField(key), 12003 children: key 12004 }), 12005 idx < deletedKeys.length - 1 ? ", " : "" 12006 ] 12007 }, key)) 12008 ] 12009 }) : null 12010 ] 12011 }), 12012 ConfirmDialogElement 12013 ] 12014 }); 12015} 12016const FieldDefinitionCard = /*#__PURE__*/ __TURBOPACK__imported__module__271645__2["memo"](function FieldDefinitionCard2({ definition, error, kindOptions, onChange, onRemove, allowFieldsetSelection = false, fieldsets = [], activeFieldset, availableGroups = [], onRegisterGroup, onRemoveGroup, onTranslate, translate }) { 12017 const [local, setLocal] = __TURBOPACK__imported__module__271645__2["useState"](definition); 12018 const localRef = __TURBOPACK__imported__module__271645__2["useRef"](definition); 12019 const [optionValueDraft, setOptionValueDraft] = __TURBOPACK__imported__module__271645__2["useState"](""); 12020 const [optionLabelDraft, setOptionLabelDraft] = __TURBOPACK__imported__module__271645__2["useState"](""); 12021 const [optionDialogOpen, setOptionDialogOpen] = __TURBOPACK__imported__module__271645__2["useState"](false); 12022 const [optionFormError, setOptionFormError] = __TURBOPACK__imported__module__271645__2["useState"](null); 12023 const [groupDialogOpen, setGroupDialogOpen] = __TURBOPACK__imported__module__271645__2["useState"](false); 12024 const [groupDraft, setGroupDraft] = __TURBOPACK__imported__module__271645__2["useState"]({ 12025 code: "", 12026 title: "", 12027 hint: "" 12028 }); 12029 const [editingGroupCode, setEditingGroupCode] = __TURBOPACK__imported__module__271645__2["useState"](null); 12030 const [groupError, setGroupError] = __TURBOPACK__imported__module__271645__2["useState"](null); 12031 const currentFieldsetValue = __TURBOPACK__imported__module__271645__2["useMemo"](()=>typeof local.configJson?.fieldset === "string" ? local.configJson.fieldset : "", [ 12032 local.configJson?.fieldset 12033 ]); 12034 const t = __TURBOPACK__imported__module__271645__2["useCallback"]((key, fallbackOrParams, params)=>{ 12035 if (translate) return translate(key, fallbackOrParams, params); 12036 return typeof fallbackOrParams === "string" ? formatFallback(fallbackOrParams, params) : key; 12037 }, [ 12038 translate 12039 ]); 12040 __TURBOPACK__imported__module__271645__2["useEffect"](()=>{ 12041 localRef.current = definition; 12042 setLocal(definition); 12043 }, [ 12044 definition.key 12045 ]); 12046 __TURBOPACK__imported__module__271645__2["useEffect"](()=>{ 12047 setOptionValueDraft(""); 12048 setOptionLabelDraft(""); 12049 setGroupDialogOpen(false); 12050 setGroupDraft({ 12051 code: "", 12052 title: "", 12053 hint: "" 12054 }); 12055 setEditingGroupCode(null); 12056 setGroupError(null); 12057 }, [ 12058 definition.key 12059 ]); 12060 __TURBOPACK__imported__module__271645__2["useEffect"](()=>{ 12061 if (!currentFieldsetValue) { 12062 setGroupDialogOpen(false); 12063 setGroupDraft({ 12064 code: "", 12065 title: "", 12066 hint: "" 12067 }); 12068 setEditingGroupCode(null); 12069 setGroupError(null); 12070 } 12071 }, [ 12072 currentFieldsetValue 12073 ]); 12074 const currentGroup = __TURBOPACK__imported__module__271645__2["useMemo"](()=>normalizeGroupValue(local.configJson?.group), [ 12075 local 12076 ]); 12077 const groupOptions = __TURBOPACK__imported__module__271645__2["useMemo"](()=>{ 12078 const list = Array.isArray(availableGroups) ? [ 12079 ...availableGroups 12080 ] : []; 12081 if (currentGroup && !list.some((entry)=>entry.code === currentGroup.code)) { 12082 list.push(currentGroup); 12083 } 12084 return list; 12085 }, [ 12086 availableGroups, 12087 currentGroup 12088 ]); 12089 const resolvedOptions = __TURBOPACK__imported__module__271645__2["useMemo"](()=>(0, __TURBOPACK__imported__module__602810__["normalizeCustomFieldOptions"])(local.configJson?.options), [ 12090 local.configJson?.options 12091 ]); 12092 const sanitize = (def)=>{ 12093 if (!def.configJson || !Array.isArray(def.configJson.options)) return def; 12094 const normalizedOptions = (0, __TURBOPACK__imported__module__602810__["normalizeCustomFieldOptions"])(def.configJson.options); 12095 return { 12096 ...def, 12097 configJson: { 12098 ...def.configJson, 12099 options: normalizedOptions 12100 } 12101 }; 12102 }; 12103 const replaceLocal = __TURBOPACK__imported__module__271645__2["useCallback"]((next)=>{ 12104 localRef.current = next; 12105 setLocal(next); 12106 return next; 12107 }, []); 12108 const apply = (patch, propagateNow = false)=>{ 12109 const current = localRef.current; 12110 const resolvedPatch = typeof patch === "function" ? patch(current) : patch; 12111 const next = { 12112 ...current, 12113 ...resolvedPatch 12114 }; 12115 const resolvedNext = propagateNow ? sanitize(next) : next; 12116 replaceLocal(resolvedNext); 12117 if (propagateNow) { 12118 onChange(resolvedNext); 12119 } 12120 }; 12121 const commit = ()=>{ 12122 const sanitized = sanitize(localRef.current); 12123 replaceLocal(sanitized); 12124 onChange(sanitized); 12125 }; 12126 const handleFieldsetSelect = (value)=>{ 12127 const nextConfig = { 12128 ...localRef.current.configJson || {} 12129 }; 12130 if (value) nextConfig.fieldset = value; 12131 else delete nextConfig.fieldset; 12132 delete nextConfig.group; 12133 const next = { 12134 ...localRef.current, 12135 configJson: nextConfig 12136 }; 12137 replaceLocal(next); 12138 onChange(next); 12139 }; 12140 const handleGroupSelect = (value)=>{ 12141 if (!currentFieldsetValue) return; 12142 if (!value) { 12143 const nextConfig2 = { 12144 ...local.configJson || {} 12145 }; 12146 delete nextConfig2.group; 12147 apply({ 12148 configJson: nextConfig2 12149 }, true); 12150 return; 12151 } 12152 const match = groupOptions.find((group)=>group.code === value); 12153 const nextGroup = match ?? { 12154 code: value 12155 }; 12156 const nextConfig = { 12157 ...local.configJson || {} 12158 }; 12159 nextConfig.group = nextGroup; 12160 apply({ 12161 configJson: nextConfig 12162 }, true); 12163 onRegisterGroup?.(currentFieldsetValue, nextGroup); 12164 }; 12165 const handleOpenGroupDialog = (group)=>{ 12166 if (!currentFieldsetValue) return; 12167 if (group) { 12168 setGroupDraft({ 12169 code: group.code, 12170 title: group.title ?? "", 12171 hint: group.hint ?? "" 12172 }); 12173 setEditingGroupCode(group.code); 12174 } else { 12175 setGroupDraft({ 12176 code: "", 12177 title: "", 12178 hint: "" 12179 }); 12180 setEditingGroupCode(null); 12181 } 12182 setGroupError(null); 12183 setGroupDialogOpen(true); 12184 }; 12185 const handleGroupDialogSubmit = ()=>{ 12186 if (!currentFieldsetValue) return; 12187 const code = slugifyFieldsetCode(groupDraft.code || ""); 12188 if (!code) { 12189 setGroupError(t("entities.customFields.editor.groupCodeRequired", "Group code is required.")); 12190 return; 12191 } 12192 const group = { 12193 code, 12194 title: groupDraft.title.trim() || void 0, 12195 hint: groupDraft.hint.trim() || void 0 12196 }; 12197 onRegisterGroup?.(currentFieldsetValue, group); 12198 const shouldAttachToField = !editingGroupCode || currentGroup?.code === editingGroupCode; 12199 if (shouldAttachToField) { 12200 const nextConfig = { 12201 ...local.configJson || {} 12202 }; 12203 nextConfig.group = group; 12204 apply({ 12205 configJson: nextConfig 12206 }, true); 12207 } 12208 setGroupDraft({ 12209 code: "", 12210 title: "", 12211 hint: "" 12212 }); 12213 setEditingGroupCode(null); 12214 setGroupDialogOpen(false); 12215 }; 12216 const handleRemoveGroupEntry = (code)=>{ 12217 if (!currentFieldsetValue) return; 12218 onRemoveGroup?.(currentFieldsetValue, code); 12219 if (currentGroup?.code === code) { 12220 handleGroupSelect(""); 12221 } 12222 if (editingGroupCode === code) { 12223 setGroupDraft({ 12224 code: "", 12225 title: "", 12226 hint: "" 12227 }); 12228 setEditingGroupCode(null); 12229 } 12230 }; 12231 const handleEditGroupEntry = (group)=>{ 12232 handleOpenGroupDialog(group); 12233 }; 12234 const resetOptionDialog = ()=>{ 12235 setOptionValueDraft(""); 12236 setOptionLabelDraft(""); 12237 setOptionFormError(null); 12238 }; 12239 const handleOpenOptionDialog = ()=>{ 12240 resetOptionDialog(); 12241 setOptionDialogOpen(true); 12242 }; 12243 const handleCloseOptionDialog = ()=>{ 12244 resetOptionDialog(); 12245 setOptionDialogOpen(false); 12246 }; 12247 const handleAddOption = ()=>{ 12248 const value = optionValueDraft.trim(); 12249 const label = optionLabelDraft.trim(); 12250 if (!value) { 12251 setOptionFormError(t("entities.customFields.editor.valueRequired", "Value is required")); 12252 return; 12253 } 12254 setOptionFormError(null); 12255 const nextOptions = Array.isArray(local.configJson?.options) ? [ 12256 ...local.configJson.options 12257 ] : []; 12258 nextOptions.push({ 12259 value, 12260 label: label || value 12261 }); 12262 apply({ 12263 configJson: { 12264 ...local.configJson || {}, 12265 options: nextOptions 12266 } 12267 }, true); 12268 handleCloseOptionDialog(); 12269 }; 12270 const handleRemoveOption = (index)=>{ 12271 const nextOptions = Array.isArray(local.configJson?.options) ? [ 12272 ...local.configJson.options 12273 ] : []; 12274 nextOptions.splice(index, 1); 12275 apply({ 12276 configJson: { 12277 ...local.configJson || {}, 12278 options: nextOptions 12279 } 12280 }, true); 12281 }; 12282 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__843476__2["Fragment"], { 12283 children: [
12284 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12285 className: "rounded border p-3 bg-card transition-colors hover:border-muted-foreground/60", 12286 children: [ 12287 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12288 className: "flex items-center justify-between", 12289 children: [ 12290 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12291 className: "flex items-center gap-2 text-xs text-muted-foreground", 12292 children: [ 12293 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("span", { 12294 className: "inline-flex items-center justify-center h-5 w-5 rounded hover:bg-muted cursor-grab active:cursor-grabbing", 12295 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__750570__["GripVertical"], { 12296 className: "h-4 w-4 opacity-70" 12297 }) 12298 }), 12299 t("entities.customFields.editor.dragToReorder", "Drag to reorder") 12300 ] 12301 }),
12302 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12303 className: "flex items-center gap-3", 12304 children: [ 12305 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(CheckboxField, { 12306 size: "sm", 12307 checked: local.isActive !== false, 12308 onCheckedChange: (checked)=>{ 12309 apply({ 12310 isActive: checked === true 12311 }, true); 12312 }, 12313 label: t("entities.customFields.editor.active", "Active"), 12314 containerClassName: "text-sm", 12315 contentClassName: "gap-1 [&_label]:text-sm [&_label]:font-normal" 12316 }), 12317 onTranslate && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__741870__1["IconButton"], { 12318 variant: "outline", 12319 size: "sm", 12320 onClick: onTranslate, 12321 "aria-label": t("entities.customFields.editor.translateField", "Translate field"), 12322 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__763639__["Languages"], { 12323 className: "h-4 w-4" 12324 }) 12325 }),
12326 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__741870__1["IconButton"], { 12327 variant: "outline", 12328 size: "sm", 12329 onClick: onRemove, 12330 "aria-label": t("entities.customFields.editor.removeField", "Remove field"), 12331 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__727612__["Trash2"], { 12332 className: "h-4 w-4" 12333 }) 12334 }) 12335 ] 12336 }) 12337 ] 12338 }), 12339 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12340 className: "mt-3 grid grid-cols-1 md:grid-cols-12 gap-3 items-center", 12341 children: [
12342 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 12343 label: t("entities.customFields.editor.key", "Key"), 12344 error: error?.key, 12345 className: "md:col-span-6", 12346 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 12347 inputClassName: "font-mono", 12348 placeholder: "snake_case", 12349 value: local.key, 12350 onChange: (event)=>apply({ 12351 key: event.target.value 12352 }), 12353 onBlur: commit 12354 }) 12355 }), 12356 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 12357 label: t("entities.customFields.editor.kind", "Kind"), 12358 error: error?.kind, 12359 className: "md:col-span-6", 12360 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 12361 value: local.kind || void 0, 12362 onValueChange: (value)=>{ 12363 apply({ 12364 kind: value ?? "" 12365 }, true); 12366 }, 12367 children: [
12368 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 12369 "aria-invalid": !!error?.kind, 12370 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], {}) 12371 }), 12372 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 12373 children: kindOptions.map((option)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12374 value: option.value, 12375 children: option.label 12376 }, option.value)) 12377 }) 12378 ] 12379 }) 12380 }) 12381 ] 12382 }), 12383 allowFieldsetSelection ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12384 className: "mt-3 grid grid-cols-1 md:grid-cols-2 gap-3", 12385 children: [
12386 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12387 children: [ 12388 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("label", { 12389 className: "text-xs", 12390 children: t("entities.customFields.editor.assignToFieldset", "Assign to fieldset") 12391 }), 12392 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 12393 value: currentFieldsetValue || void 0, 12394 onValueChange: (value)=>handleFieldsetSelect(value ?? ""), 12395 children: [ 12396 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 12397 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], { 12398 placeholder: t("entities.customFields.editor.unassigned", "Unassigned") 12399 }) 12400 }),
12401 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 12402 children: (fieldsets || []).map((fs)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12403 value: fs.code, 12404 children: fs.label || fs.code 12405 }, fs.code)) 12406 }) 12407 ] 12408 }) 12409 ] 12410 }), 12411 currentFieldsetValue ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12412 children: [ 12413 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12414 className: "flex items-center justify-between", 12415 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("label", { 12416 className: "text-xs", 12417 children: t("entities.customFields.editor.group", "Group") 12418 }) 12419 }),
12420 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12421 className: "flex items-center gap-2 mt-1", 12422 children: [ 12423 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 12424 value: currentGroup?.code || void 0, 12425 onValueChange: (value)=>handleGroupSelect(value ?? ""), 12426 children: [ 12427 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 12428 className: "flex-1", 12429 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], { 12430 placeholder: t("entities.customFields.editor.noGroup", "No group") 12431 }) 12432 }),
12433 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 12434 children: groupOptions.map((group)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12435 value: group.code, 12436 children: group.title || group.code 12437 }, group.code)) 12438 }) 12439 ] 12440 }), 12441 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__741870__1["IconButton"], { 12442 variant: "outline", 12443 className: "text-muted-foreground", 12444 onClick: ()=>handleOpenGroupDialog(), 12445 "aria-label": t("entities.customFields.editor.createGroup", "Create group"), 12446 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__107233__["Plus"], { 12447 className: "h-4 w-4" 12448 }) 12449 }),
12450 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__741870__1["IconButton"], { 12451 variant: "outline", 12452 className: "text-muted-foreground", 12453 onClick: ()=>handleOpenGroupDialog(), 12454 "aria-label": t("entities.customFields.editor.editGroups", "Edit groups"), 12455 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__514306__["Cog"], { 12456 className: "h-4 w-4" 12457 }) 12458 }) 12459 ] 12460 }) 12461 ] 12462 }) : null 12463 ] 12464 }) : null,
12465 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12466 className: "mt-3 grid grid-cols-1 md:grid-cols-2 gap-3", 12467 children: [ 12468 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 12469 label: t("entities.customFields.editor.label", "Label"), 12470 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 12471 value: typeof local.configJson?.label === "string" ? local.configJson.label : "", 12472 onChange: (event)=>apply({ 12473 configJson: { 12474 ...local.configJson || {}, 12475 label: event.target.value 12476 } 12477 }), 12478 onBlur: commit 12479 }) 12480 }),
12481 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 12482 label: t("entities.customFields.editor.description", "Description"), 12483 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 12484 value: typeof local.configJson?.description === "string" ? local.configJson.description : "", 12485 onChange: (event)=>apply({ 12486 configJson: { 12487 ...local.configJson || {}, 12488 description: event.target.value 12489 } 12490 }), 12491 onBlur: commit 12492 }) 12493 }), 12494 (local.kind === "text" || local.kind === "multiline") && /* @__P
12494URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__843476__2["Fragment"], { 12495 children: [ 12496 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12497 children: [ 12498 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("label", { 12499 className: "text-xs", 12500 children: t("entities.customFields.editor.editor", "Editor") 12501 }), 12502 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 12503 value: typeof local.configJson?.editor === "string" && local.configJson.editor ? local.configJson.editor : void 0, 12504 onValueChange: (value)=>{ 12505 apply({ 12506 configJson: { 12507 ...local.configJson || {}, 12508 editor: value || void 0 12509 } 12510 }, true); 12511 }, 12512 children: [
12513 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 12514 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], { 12515 placeholder: t("entities.customFields.editor.defaultOption", "Default") 12516 }) 12517 }), 12518 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 12519 children: [ 12520 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12521 value: "markdown", 12522 children: t("entities.customFields.editor.editorMarkdown", "Markdown (UIW)") 12523 }), 12524 /* @__P
12524URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12525 value: "simpleMarkdown", 12526 children: t("entities.customFields.editor.editorSimpleMarkdown", "Simple Markdown") 12527 }), 12528 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12529 value: "htmlRichText", 12530 children: t("entities.customFields.editor.editorHtmlRichText", "HTML Rich Text") 12531 }), 12532 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12533 value: "plain", 12534 children: t("entities.customFields.editor.editorPlain", "Plain textarea") 12535 }) 12536 ] 12537 }) 12538 ] 12539 }) 12540 ] 12541 }), 12542 local.kind === "text" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__843476__2["Fragment"], { 12543 children: [
12544 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(CheckboxField, { 12545 size: "sm", 12546 checked: !!local.configJson?.multi, 12547 onCheckedChange: (checked)=>{ 12548 apply({ 12549 configJson: { 12550 ...local.configJson || {}, 12551 multi: checked === true 12552 } 12553 }, true); 12554 }, 12555 label: t("entities.customFields.editor.multiple", "Multiple"), 12556 containerClassName: "md:col-span-2", 12557 contentClassName: "gap-1 [&_label]:text-xs [&_label]:font-normal" 12558 }), 12559 !!local.configJson?.multi && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12560 className: "md:col-span-2", 12561 children: [
12562 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("label", { 12563 className: "text-xs", 12564 children: t("entities.customFields.editor.multiSelectInputStyle", "Multi-select input style") 12565 }), 12566 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 12567 value: local.configJson?.input === "listbox" ? "listbox" : "default", 12568 onValueChange: (value)=>{ 12569 const nextConfig = { 12570 ...local.configJson || {} 12571 }; 12572 if (value === "listbox") nextConfig.input = "listbox"; 12573 else delete nextConfig.input; 12574 apply({ 12575 configJson: nextConfig 12576 }, true); 12577 }, 12578 children: [ 12579 /* @__P
12579URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 12580 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], {}) 12581 }), 12582 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 12583 children: [ 12584 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12585 value: "default", 12586 children: t("entities.customFields.editor.defaultOption", "Default") 12587 }), 12588 /* @__P
12588URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12589 value: "listbox", 12590 children: t("entities.customFields.editor.listboxSearchable", "Listbox (searchable)") 12591 }) 12592 ] 12593 }) 12594 ] 12595 }) 12596 ] 12597 }) 12598 ] 12599 }) 12600 ] 12601 }), 12602 local.kind === "select" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12603 className: "md:col-span-6 space-y-3", 12604 children: [
12605 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("label", { 12606 className: "text-xs", 12607 children: t("entities.customFields.editor.options", "Options") 12608 }), 12609 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12610 className: "space-y-2", 12611 children: resolvedOptions.length > 0 ? resolvedOptions.map((option, idx)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12612 className: "flex items-center justify-between rounded border px-3 py-2 text-xs bg-muted", 12613 children: [ 12614 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12615 children: [ 12616 /* @__P
12616URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12617 className: "font-medium text-foreground", 12618 children: option.label 12619 }), 12620 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12621 className: "text-muted-foreground font-mono text-overline", 12622 children: option.value 12623 }) 12624 ] 12625 }), 12626 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__741870__1["IconButton"], { 12627 variant: "ghost", 12628 size: "xs", 12629 className: "text-destructive hover:text-destructive/80", 12630 onClick: ()=>handleRemoveOption(idx), 12631 "aria-label": t("entities.customFields.editor.removeOption", "Remove option"), 12632 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__727612__["Trash2"], { 12633 className: "h-3.5 w-3.5" 12634 }) 12635 }) 12636 ] 12637 }, `${option.value}-${idx}`)) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("span", { 12638 className: "text-xs text-muted-foreground", 12639 children: t("entities.customFields.editor.noOptionsDefined", "No options defined.") 12640 }) 12641 }),
12642 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12643 className: "flex justify-end", 12644 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__110035__2["Button"], { 12645 variant: "outline", 12646 size: "sm", 12647 className: "text-xs", 12648 onClick: handleOpenOptionDialog, 12649 children: [ 12650 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__107233__["Plus"], { 12651 className: "h-3.5 w-3.5" 12652 }), 12653 t("entities.customFields.editor.addOption", "Add option") 12654 ] 12655 }) 12656 }) 12657 ] 12658 }), 12659 (local.kind === "select" || local.kind === "relation") && /* @__P
12659URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__843476__2["Fragment"], { 12660 children: [ 12661 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 12662 label: t("entities.customFields.editor.optionsUrl", "Options URL"), 12663 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 12664 placeholder: "/api/...", 12665 value: typeof local.configJson?.optionsUrl === "string" ? local.configJson.optionsUrl : "", 12666 onChange: (event)=>apply({ 12667 configJson: { 12668 ...local.configJson || {}, 12669 optionsUrl: event.target.value 12670 } 12671 }), 12672 onBlur: commit 12673 }) 12674 }), 12675 local.kind === "relation" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 12676 label: t("entities.customFields.editor.relatedEntityId", "Related Entity ID"), 12677 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 12678 inputClassName: "font-mono", 12679 placeholder: "module:entity", 12680 value: typeof local.configJson?.relatedEntityId === "string" ? local.configJson.relatedEntityId : "", 12681 onChange: (event)=>{ 12682 const relatedEntityId = event.target.value; 12683 const defOptionsUrl = relatedEntityId ? `/api/entities/relations/options?entityId=${encodeURIComponent(relatedEntityId)}` : ""; 12684 apply({ 12685 configJson: { 12686 ...local.configJson || {}, 12687 relatedEntityId, 12688 optionsUrl: local.configJson?.optionsUrl || defOptionsUrl 12689 } 12690 }); 12691 }, 12692 onBlur: commit 12693 }) 12694 }) 12695 ] 12696 }), 12697 local.kind === "currency" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12698 className: "md:col-span-2", 12699 children: [
12700 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("label", { 12701 className: "text-xs", 12702 children: t("entities.customFields.editor.optionsSource", "Options source") 12703 }), 12704 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12705 className: "rounded border bg-muted px-2 py-1 text-xs text-muted-foreground", 12706 children: "/api/currencies/options" 12707 }) 12708 ] 12709 }), 12710 (local.kind === "integer" || local.kind === "float") && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 12711 label: t("entities.customFields.editor.unitsOptional", "Units (optional)"), 12712 className: "md:col-span-2", 12713 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 12714 placeholder: t("entities.customFields.editor.unitsPlaceholder", "kg, cm, etc."), 12715 value: typeof local.configJson?.unit === "string" ? local.configJson.unit : "", 12716 onChange: (event)=>apply({ 12717 configJson: { 12718 ...local.configJson || {}, 12719 unit: event.target.value 12720 } 12721 }), 12722 onBlur: commit 12723 }) 12724 }) 12725 ] 12726 }),
12727 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12728 className: "mt-3 pt-3 border-t", 12729 children: [ 12730 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12731 className: "flex items-center justify-between mb-2", 12732 children: [ 12733 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("label", { 12734 className: "text-sm font-medium", 12735 children: t("entities.customFields.editor.validationRules", "Validation rules") 12736 }), 12737 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__110035__2["Button"], { 12738 variant: "outline", 12739 size: "sm", 12740 className: "text-xs", 12741 onClick: ()=>{ 12742 apply((current)=>{ 12743 const list = Array.isArray(current.configJson?.validation) ? [ 12744 ...current.configJson.validation 12745 ] : []; 12746 list.push({ 12747 rule: "required", 12748 message: t("entities.customFields.editor.ruleRequiredMessage", "This field is required") 12749 }); 12750 return { 12751 configJson: { 12752 ...current.configJson || {}, 12753 validation: list 12754 } 12755 }; 12756 }, true); 12757 }, 12758 children: [
12759 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__107233__["Plus"], { 12760 className: "h-3.5 w-3.5" 12761 }), 12762 t("entities.customFields.editor.addRule", "Add rule") 12763 ] 12764 }) 12765 ] 12766 }), 12767 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12768 className: "space-y-2", 12769 children: [ 12770 (Array.isArray(local.configJson?.validation) ? local.configJson.validation : []).map((rule, index)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 12771 className: "grid grid-cols-1 md:grid-cols-12 gap-2 items-center", 12772 children: [
12773 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12774 className: "md:col-span-3", 12775 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 12776 value: rule?.rule || "required", 12777 onValueChange: (value)=>{ 12778 const nextRule = value; 12779 apply((current)=>{ 12780 const list = Array.isArray(current.configJson?.validation) ? [ 12781 ...current.configJson.validation 12782 ] : []; 12783 const existing = list[index] || {}; 12784 list[index] = { 12785 ...existing, 12786 rule: nextRule, 12787 message: existing.message || rule?.message || "" 12788 }; 12789 return { 12790 configJson: { 12791 ...current.configJson || {}, 12792 validation: list 12793 } 12794 }; 12795 }, true); 12796 }, 12797 children: [ 12798 /* @__P
12798URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 12799 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], {}) 12800 }), 12801 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 12802 children: [ 12803 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12804 value: "required", 12805 children: t("entities.customFields.editor.validation.required", "required") 12806 }), 12807 /* @__P
12807URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12808 value: "date", 12809 children: t("entities.customFields.editor.validation.date", "date") 12810 }), 12811 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12812 value: "integer", 12813 children: t("entities.customFields.editor.validation.integer", "integer") 12814 }), 12815 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12816 value: "float", 12817 children: t("entities.customFields.editor.validation.float", "float") 12818 }), 12819 /* @__P
12819URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12820 value: "lt", 12821 children: t("entities.customFields.editor.validation.lt", "lt") 12822 }), 12823 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12824 value: "lte", 12825 children: t("entities.customFields.editor.validation.lte", "lte") 12826 }), 12827 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12828 value: "gt", 12829 children: t("entities.customFields.editor.validation.gt", "gt") 12830 }), 12831 /* @__P
12831URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12832 value: "gte", 12833 children: t("entities.customFields.editor.validation.gte", "gte") 12834 }), 12835 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12836 value: "eq", 12837 children: t("entities.customFields.editor.validation.eq", "eq") 12838 }), 12839 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12840 value: "ne", 12841 children: t("entities.customFields.editor.validation.ne", "ne") 12842 }), 12843 /* @__P
12843URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 12844 value: "regex", 12845 children: t("entities.customFields.editor.validation.regex", "regex") 12846 }) 12847 ] 12848 }) 12849 ] 12850 }) 12851 }), 12852 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12853 className: "md:col-span-4", 12854 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 12855 placeholder: rule?.rule === "regex" ? t("entities.customFields.editor.rulePatternPlaceholder", "Pattern (e.g. ^[a-z]+$)") : [ 12856 "lt", 12857 "lte", 12858 "gt", 12859 "gte" 12860 ].includes(rule?.rule) ? t("entities.customFields.editor.ruleNumberPlaceholder", "Number") : t("entities.customFields.editor.noParameterPlaceholder", "\u2014"), 12861 value: rule?.param ?? "", 12862 onChange: (event)=>{ 12863 const value = [ 12864 "lt", 12865 "lte", 12866 "gt", 12867 "gte" 12868 ].includes(rule?.rule) ? Number(event.target.value) : event.target.value; 12869 apply((current)=>{ 12870 const list = Array.isArray(current.configJson?.validation) ? [ 12871 ...current.configJson.validation 12872 ] : []; 12873 const existing = list[index] || {}; 12874 list[index] = { 12875 ...existing, 12876 ...rule, 12877 param: value 12878 }; 12879 return { 12880 configJson: { 12881 ...current.configJson || {}, 12882 validation: list 12883 } 12884 }; 12885 }); 12886 }, 12887 onBlur: commit, 12888 disabled: rule?.rule === "required" || rule?.rule === "date" || rule?.rule === "integer" || rule?.rule === "float" 12889 }) 12890 }),
12891 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12892 className: "md:col-span-4", 12893 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 12894 placeholder: t("entities.customFields.editor.ruleErrorMessagePlaceholder", "Error message"), 12895 value: rule?.message || "", 12896 onChange: (event)=>{ 12897 const message = event.target.value; 12898 apply((current)=>{ 12899 const list = Array.isArray(current.configJson?.validation) ? [ 12900 ...current.configJson.validation 12901 ] : []; 12902 const existing = list[index] || {}; 12903 list[index] = { 12904 ...existing, 12905 ...rule, 12906 message 12907 }; 12908 return { 12909 configJson: { 12910 ...current.configJson || {}, 12911 validation: list 12912 } 12913 }; 12914 }); 12915 }, 12916 onBlur: commit 12917 }) 12918 }),
12919 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12920 className: "md:col-span-1 flex justify-end", 12921 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__741870__1["IconButton"], { 12922 variant: "outline", 12923 size: "sm", 12924 "aria-label": t("entities.customFields.editor.removeRule", "Remove rule"), 12925 onClick: ()=>{ 12926 apply((current)=>{ 12927 const list = Array.isArray(current.configJson?.validation) ? [ 12928 ...current.configJson.validation 12929 ] : []; 12930 list.splice(index, 1); 12931 return { 12932 configJson: { 12933 ...current.configJson || {}, 12934 validation: list 12935 } 12936 }; 12937 }, true); 12938 }, 12939 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__727612__["Trash2"], { 12940 className: "h-4 w-4" 12941 }) 12942 }) 12943 }) 12944 ] 12945 }, index)), 12946 (!Array.isArray(local.configJson?.validation) || local.configJson.validation.length === 0) && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12947 className: "text-xs text-muted-foreground", 12948 children: t("entities.customFields.editor.noValidationRules", "No validation rules defined.") 12949 }) 12950 ] 12951 }) 12952 ] 12953 }),
12954 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 12955 className: "mt-3", 12956 children: (()=>{ 12957 const Editor = __TURBOPACK__imported__module__127308__1["FieldRegistry"].getDefEditor(local.kind); 12958 if (!Editor) return null; 12959 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(Editor, { 12960 def: { 12961 key: local.key, 12962 kind: local.kind, 12963 configJson: local.configJson 12964 }, 12965 onChange: (patch)=>apply({ 12966 configJson: { 12967 ...local.configJson || {}, 12968 ...patch || {} 12969 } 12970 }, true) 12971 }); 12972 })() 12973 }), 12974 (()=>{ 12975 if (local.kind === "dictionary") return null; 12976 if (local.kind === "relation" || local.kind === "attachment") return null; 12977 const currentDefault = local.configJson?.defaultValue; 12978 if (local.kind === "boolean") { 12979 const boolDefault = currentDefault === true ? "true" : currentDefault === false ? "false" : ""; 12980 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 12981 label: t("entities.customFields.fields.defaultValue", "Default value"), 12982 className: "mt-3", 12983 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 12984 value: boolDefault || DEFAULT_VALUE_NONE, 12985 onValueChange: (raw)=>{ 12986 const value = raw === "true" ? true : raw === "false" ? false : void 0; 12987 apply({ 12988 configJson: { 12989 ...local.configJson || {}, 12990 defaultValue: value 12991 } 12992 }, true); 12993 }, 12994 children: [
12995 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 12996 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], {}) 12997 }), 12998 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 12999 children: [ 13000 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 13001 value: DEFAULT_VALUE_NONE, 13002 children: t("entities.customFields.fields.defaultValueNone", "No default") 13003 }),
13004 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 13005 value: "true", 13006 children: t("entities.customFields.fields.defaultValueTrue", "Checked (true)") 13007 }), 13008 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 13009 value: "false", 13010 children: t("entities.customFields.fields.defaultValueFalse", "Unchecked (false)") 13011 }) 13012 ] 13013 }) 13014 ] 13015 }) 13016 }); 13017 } 13018 if (local.kind === "select" && !local.configJson?.multi) { 13019 const opts = (0, __TURBOPACK__imported__module__602810__["normalizeCustomFieldOptions"])(local.configJson?.options || []); 13020 if (opts.length > 0) { 13021 const noneValue = getDefaultValueNoneOptionValue(opts); 13022 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 13023 label: t("entities.customFields.fields.defaultValue", "Default value"), 13024 className: "mt-3", 13025 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["Select"], { 13026 value: typeof currentDefault === "string" || typeof currentDefault === "number" ? String(currentDefault) : "", 13027 onValueChange: (raw)=>{ 13028 if (raw === noneValue) { 13029 apply({ 13030 configJson: { 13031 ...local.configJson || {}, 13032 defaultValue: void 0 13033 } 13034 }, true); 13035 return; 13036 } 13037 const matched = opts.find((o)=>String(o.value) === raw); 13038 const typed = matched ? matched.value : raw; 13039 apply({ 13040 configJson: { 13041 ...local.configJson || {}, 13042 defaultValue: typed 13043 } 13044 }, true); 13045 }, 13046 children: [
13047 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectTrigger"], { 13048 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectValue"], { 13049 placeholder: t("entities.customFields.fields.defaultValueNone", "No default") 13050 }) 13051 }), 13052 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__262524__1["SelectContent"], { 13053 children: [ 13054 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 13055 value: noneValue, 13056 children: t("entities.customFields.fields.defaultValueNone", "No default") 13057 }), 13058 opts.map((option)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__262524__1["SelectItem"], { 13059 value: String(option.value), 13060 children: option.label 13061 }, String(option.value))) 13062 ] 13063 }) 13064 ] 13065 }) 13066 }); 13067 } 13068 } 13069 if (local.kind === "integer" || local.kind === "float") { 13070 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 13071 label: t("entities.customFields.fields.defaultValue", "Default value"), 13072 className: "mt-3", 13073 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 13074 type: "number", 13075 step: local.kind === "integer" ? "1" : "any", 13076 value: typeof currentDefault === "number" ? String(currentDefault) : "", 13077 onChange: (event)=>{ 13078 const raw = event.target.value; 13079 const parsed = raw === "" ? void 0 : local.kind === "integer" ? parseInt(raw, 10) : parseFloat(raw); 13080 const value = parsed !== void 0 && !isNaN(parsed) ? parsed : void 0; 13081 apply({ 13082 configJson: { 13083 ...local.configJson || {}, 13084 defaultValue: value 13085 } 13086 }); 13087 }, 13088 onBlur: commit, 13089 placeholder: t("entities.customFields.fields.defaultValuePlaceholder", "No default") 13090 }) 13091 }); 13092 } 13093 if ([ 13094 "text", 13095 "multiline", 13096 "date", 13097 "datetime", 13098 "currency" 13099 ].includes(local.kind)) { 13100 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 13101 label: t("entities.customFields.fields.defaultValue", "Default value"), 13102 className: "mt-3", 13103 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 13104 value: typeof currentDefault === "string" ? currentDefault : "", 13105 onChange: (event)=>{ 13106 const value = event.target.value; 13107 apply({ 13108 configJson: { 13109 ...local.configJson || {}, 13110 defaultValue: value || void 0 13111 } 13112 }); 13113 }, 13114 onBlur: commit, 13115 placeholder: t("entities.customFields.fields.defaultValuePlaceholder", "No default") 13116 }) 13117 }); 13118 } 13119 return null; 13120 })(),
13121 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 13122 className: "mt-3 pt-2 border-t flex flex-wrap items-center gap-4", 13123 children: [ 13124 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("span", { 13125 className: "text-xs text-muted-foreground", 13126 children: t("entities.customFields.fields.visibility", "Visibility:") 13127 }), 13128 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(CheckboxField, { 13129 size: "sm", 13130 checked: local.configJson?.listVisible !== false, 13131 onCheckedChange: (checked)=>{ 13132 apply({ 13133 configJson: { 13134 ...local.configJson || {}, 13135 listVisible: checked === true 13136 } 13137 }, true); 13138 }, 13139 label: t("entities.customFields.fields.listVisible", "List"), 13140 contentClassName: "gap-1 [&_label]:text-xs [&_label]:font-normal" 13141 }),
13142 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(CheckboxField, { 13143 size: "sm", 13144 checked: !!local.configJson?.filterable, 13145 onCheckedChange: (checked)=>{ 13146 apply({ 13147 configJson: { 13148 ...local.configJson || {}, 13149 filterable: checked === true 13150 } 13151 }, true); 13152 }, 13153 label: t("entities.customFields.fields.filterable", "Filter"), 13154 contentClassName: "gap-1 [&_label]:text-xs [&_label]:font-normal" 13155 }), 13156 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(CheckboxField, { 13157 size: "sm", 13158 checked: local.configJson?.formEditable !== false, 13159 onCheckedChange: (checked)=>{ 13160 apply({ 13161 configJson: { 13162 ...local.configJson || {}, 13163 formEditable: checked === true 13164 } 13165 }, true); 13166 }, 13167 label: t("entities.customFields.fields.formEditable", "Form"), 13168 contentClassName: "gap-1 [&_label]:text-xs [&_label]:font-normal" 13169 }),
13170 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(CheckboxField, { 13171 size: "sm", 13172 checked: !!local.configJson?.encrypted, 13173 onCheckedChange: (checked)=>{ 13174 apply({ 13175 configJson: { 13176 ...local.configJson || {}, 13177 encrypted: checked === true 13178 } 13179 }, true); 13180 }, 13181 label: t("entities.customFields.fields.encrypted", "Encrypted"), 13182 contentClassName: "gap-1 [&_label]:text-xs [&_label]:font-normal" 13183 }) 13184 ] 13185 }) 13186 ] 13187 }), 13188 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__644149__1["Dialog"], { 13189 open: optionDialogOpen, 13190 onOpenChange: (open)=>{ 13191 setOptionDialogOpen(open); 13192 if (!open) resetOptionDialog(); 13193 }, 13194 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__644149__1["DialogContent"], { 13195 className: "max-w-sm", 13196 children: [
13197 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__644149__1["DialogHeader"], { 13198 children: [ 13199 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__644149__1["DialogTitle"], { 13200 children: t("entities.customFields.editor.addOption", "Add option") 13201 }), 13202 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__644149__1["DialogDescription"], { 13203 children: t("entities.customFields.editor.addOptionDescription", "Provide the stored value and optional label shown to users.") 13204 }) 13205 ] 13206 }), 13207 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 13208 className: "space-y-4 py-2", 13209 children: [
13210 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 13211 label: t("entities.customFields.editor.value", "Value"), 13212 error: optionFormError ?? void 0, 13213 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 13214 inputClassName: "font-mono", 13215 placeholder: "unique_value", 13216 value: optionValueDraft, 13217 onChange: (event)=>{ 13218 setOptionFormError(null); 13219 setOptionValueDraft(event.target.value); 13220 } 13221 }) 13222 }), 13223 /* @__P
13223URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 13224 label: t("entities.customFields.editor.label", "Label"), 13225 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 13226 placeholder: t("entities.customFields.editor.optionLabelPlaceholder", "Label shown to users (optional)"), 13227 value: optionLabelDraft, 13228 onChange: (event)=>setOptionLabelDraft(event.target.value) 13229 }) 13230 }) 13231 ] 13232 }), 13233 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__644149__1["DialogFooter"], { 13234 children: [ 13235 /* @__P
13235URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__110035__2["Button"], { 13236 variant: "outline", 13237 size: "sm", 13238 onClick: handleCloseOptionDialog, 13239 children: t("entities.customFields.editor.cancel", "Cancel") 13240 }), 13241 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__110035__2["Button"], { 13242 size: "sm", 13243 onClick: handleAddOption, 13244 children: t("entities.customFields.editor.addOption", "Add option") 13245 }) 13246 ] 13247 }) 13248 ] 13249 }) 13250 }), 13251 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__644149__1["Dialog"], { 13252 open: groupDialogOpen, 13253 onOpenChange: (open)=>{ 13254 setGroupDialogOpen(open); 13255 if (!open) { 13256 setGroupError(null); 13257 setEditingGroupCode(null); 13258 setGroupDraft({ 13259 code: "", 13260 title: "", 13261 hint: "" 13262 }); 13263 } 13264 }, 13265 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__644149__1["DialogContent"], { 13266 className: "max-w-md", 13267 children: [
13268 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__644149__1["DialogHeader"], { 13269 children: [ 13270 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__644149__1["DialogTitle"], { 13271 children: editingGroupCode ? t("entities.customFields.editor.editGroup", "Edit group") : t("entities.customFields.editor.newGroup", "New group") 13272 }), 13273 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__644149__1["DialogDescription"], { 13274 children: editingGroupCode ? t("entities.customFields.editor.editGroupDescription", "Update the selected group for this fieldset.") : t("entities.customFields.editor.newGroupDescription", "Add a reusable group for this fieldset.") 13275 }) 13276 ] 13277 }),
13278 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 13279 className: "space-y-3", 13280 children: [ 13281 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 13282 label: t("entities.customFields.editor.groupCode", "Group code"), 13283 error: groupError ?? void 0, 13284 disabled: !!editingGroupCode, 13285 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 13286 inputClassName: "font-mono", 13287 value: groupDraft.code, 13288 onChange: (event)=>{ 13289 setGroupDraft((prev)=>({ 13290 ...prev, 13291 code: event.target.value 13292 })); 13293 if (groupError) setGroupError(null); 13294 }, 13295 disabled: !!editingGroupCode, 13296 placeholder: t("entities.customFields.editor.groupCodePlaceholder", "e.g. buying_committee") 13297 }) 13298 }),
13299 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 13300 label: t("entities.customFields.editor.label", "Label"), 13301 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 13302 value: groupDraft.title, 13303 onChange: (event)=>setGroupDraft((prev)=>({ 13304 ...prev, 13305 title: event.target.value 13306 })), 13307 placeholder: t("entities.customFields.editor.groupLabelPlaceholder", "Buying committee") 13308 }) 13309 }), 13310 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__828151__["FormField"], { 13311 label: t("entities.customFields.editor.hint", "Hint"), 13312 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__987030__1["Input"], { 13313 value: groupDraft.hint, 13314 onChange: (event)=>setGroupDraft((prev)=>({ 13315 ...prev, 13316 hint: event.target.value 13317 })), 13318 placeholder: t("entities.customFields.editor.groupHintPlaceholder", "Visible to merchandisers") 13319 }) 13320 }), 13321 currentFieldsetValue && groupOptions.length > 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 13322 children: [
13323 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 13324 className: "text-xs font-medium mb-1", 13325 children: t("entities.customFields.editor.existingGroups", "Existing groups") 13326 }), 13327 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 13328 className: "space-y-2 max-h-40 overflow-y-auto", 13329 children: groupOptions.map((group)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 13330 className: "flex items-center justify-between rounded border px-3 py-2 text-sm", 13331 children: [ 13332 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 13333 children: [ 13334 /* @__P
13334URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 13335 className: "font-medium", 13336 children: group.title || group.code 13337 }), 13338 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 13339 className: "text-xs text-muted-foreground font-mono", 13340 children: group.code 13341 }), 13342 group.hint ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])("div", { 13343 className: "text-xs text-muted-foreground", 13344 children: group.hint 13345 }) : null 13346 ] 13347 }),
13348 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])("div", { 13349 className: "flex items-center gap-2", 13350 children: [ 13351 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__741870__1["IconButton"], { 13352 variant: "ghost", 13353 size: "xs", 13354 className: "text-muted-foreground hover:text-foreground", 13355 onClick: ()=>handleEditGroupEntry(group), 13356 "aria-label": t("entities.customFields.editor.editGroupAria", "Edit {code}", { 13357 code: group.code 13358 }), 13359 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__788699__["Pencil"], { 13360 className: "h-4 w-4" 13361 }) 13362 }), 13363 /* @__P
13363URE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__741870__1["IconButton"], { 13364 variant: "ghost", 13365 size: "xs", 13366 className: "text-destructive hover:text-destructive/80", 13367 onClick: ()=>handleRemoveGroupEntry(group.code), 13368 "aria-label": t("entities.customFields.editor.deleteGroupAria", "Delete {code}", { 13369 code: group.code 13370 }), 13371 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__727612__["Trash2"], { 13372 className: "h-4 w-4" 13373 }) 13374 }) 13375 ] 13376 }) 13377 ] 13378 }, group.code)) 13379 }) 13380 ] 13381 }) : null 13382 ] 13383 }),
13384 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsxs"])(__TURBOPACK__imported__module__644149__1["DialogFooter"], { 13385 children: [ 13386 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__110035__2["Button"], { 13387 variant: "outline", 13388 size: "sm", 13389 onClick: ()=>setGroupDialogOpen(false), 13390 children: t("entities.customFields.editor.cancel", "Cancel") 13391 }), 13392 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__2["jsx"])(__TURBOPACK__imported__module__110035__2["Button"], { 13393 size: "sm", 13394 onClick: handleGroupDialogSubmit, 13395 children: t("entities.customFields.editor.saveGroup", "Save group") 13396 }) 13397 ] 13398 }) 13399 ] 13400 }) 13401 }) 13402 ] 13403 }); 13404}); 13405FieldDefinitionCard.displayName = "FieldDefinitionCard"; 13406; 13407__turbopack_context__.s([ 13408 "FieldDefinitionsEditor", 13409 0, 13410 FieldDefinitionsEditor 13411], 783157); 13412// MERGED MODULE: [project]/node_modules/@open-mercato/shared/dist/modules/entities/validators.js [app-client] (ecmascript) 13413; 13414var __TURBOPACK__imported__module__681307__ = __turbopack_context__.i(681307); 13415var __TURBOPACK__imported__module__130133__1 = __TURBOPACK__imported__module__130133__; 13416var __TURBOPACK__imported__module__714428__ = __turbopack_context__.i(714428); 13417; 13418; 13419; 13420const entityIdRegex = /^[a-z0-9_]+:[a-z0-9_]+$/; 13421const fieldsetCodeRegex = /^[a-z0-9_\-]+$/; 13422const upsertCustomEntitySchema = __TURBOPACK__imported__module__681307__["z"].object({ 13423 entityId: __TURBOPACK__imported__module__681307__["z"].string().regex(entityIdRegex, "Enter the entity id in the format: module_name:entity_id with your prefered entity and module names"), 13424 label: __TURBOPACK__imported__module__681307__["z"].string().min(1).max(200), 13425 description: __TURBOPACK__imported__module__681307__["z"].string().max(2e3).optional().nullable(), 13426 labelField: __TURBOPACK__imported__module__681307__["z"].string().min(1).max(100).regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/).optional(), 13427 defaultEditor: __TURBOPACK__imported__module__681307__["z"].enum([ 13428 "markdown", 13429 "simpleMarkdown", 13430 "htmlRichText", 13431 "plain" 13432 ]).optional(), 13433 showInSidebar: __TURBOPACK__imported__module__681307__["z"].boolean().default(false), 13434 accessRestricted: __TURBOPACK__imported__module__681307__["z"].boolean().default(false), 13435 isActive: __TURBOPACK__imported__module__681307__["z"].boolean().optional() 13436}); 13437const upsertCustomFieldDefSchema = __TURBOPACK__imported__module__681307__["z"].object({ 13438 entityId: __TURBOPACK__imported__module__681307__["z"].string().regex(entityIdRegex), 13439 key: __TURBOPACK__imported__module__681307__["z"].string().min(1).max(100).regex(/^[a-z0-9_]+$/, "snake_case only"), 13440 kind: __TURBOPACK__imported__module__681307__["z"].enum(__TURBOPACK__imported__module__130133__1["CUSTOM_FIELD_KINDS"]), 13441 configJson: __TURBOPACK__imported__module__681307__["z"].object({ 13442 // optional UI/behavioral hints 13443 label: __TURBOPACK__imported__module__681307__["z"].string().max(200).optional(), 13444 description: __TURBOPACK__imported__module__681307__["z"].string().max(2e3).optional(), 13445 options: __TURBOPACK__imported__module__681307__["z"].array(__TURBOPACK__imported__module__681307__["z"].union([ 13446 __TURBOPACK__imported__module__681307__["z"].string(), 13447 __TURBOPACK__imported__module__681307__["z"].number() 13448 ])).optional(), 13449 optionsUrl: __TURBOPACK__imported__module__681307__["z"].string().url().optional(), 13450 multi: __TURBOPACK__imported__module__681307__["z"].boolean().optional(), 13451 editor: __TURBOPACK__imported__module__681307__["z"].string().optional(), 13452 input: __TURBOPACK__imported__module__681307__["z"].string().optional(), 13453 filterable: __TURBOPACK__imported__module__681307__["z"].boolean().optional(), 13454 formEditable: __TURBOPACK__imported__module__681307__["z"].boolean().optional(), 13455 listVisible: __TURBOPACK__imported__module__681307__["z"].boolean().optional(), 13456 priority: __TURBOPACK__imported__module__681307__["z"].number().optional(), 13457 encrypted: __TURBOPACK__imported__module__681307__["z"].boolean().optional(), 13458 relatedEntityId: __TURBOPACK__imported__module__681307__["z"].string().optional(), 13459 dictionaryId: __TURBOPACK__imported__module__681307__["z"].string().uuid().optional(), 13460 dictionaryInlineCreate: __TURBOPACK__imported__module__681307__["z"].boolean().optional(), 13461 // validation rules 13462 validation: __TURBOPACK__imported__module__714428__["validationRulesArraySchema"].optional(), 13463 fieldset: __TURBOPACK__imported__module__681307__["z"].string().regex(fieldsetCodeRegex).optional(), 13464 group: __TURBOPACK__imported__module__681307__["z"].object({ 13465 code: __TURBOPACK__imported__module__681307__["z"].string().regex(fieldsetCodeRegex), 13466 title: __TURBOPACK__imported__module__681307__["z"].string().max(200).optional(), 13467 hint: __TURBOPACK__imported__module__681307__["z"].string().max(500).optional() 13468 }).optional() 13469 }).passthrough().optional(), 13470 isActive: __TURBOPACK__imported__module__681307__["z"].boolean().optional() 13471}); 13472const customFieldsetGroupSchema = __TURBOPACK__imported__module__681307__["z"].object({ 13473 code: __TURBOPACK__imported__module__681307__["z"].string().regex(fieldsetCodeRegex), 13474 title: __TURBOPACK__imported__module__681307__["z"].string().max(200).optional(), 13475 hint: __TURBOPACK__imported__module__681307__["z"].string().max(500).optional() 13476});
13477const customFieldsetSchema = __TURBOPACK__imported__module__681307__["z"].object({ 13478 code: __TURBOPACK__imported__module__681307__["z"].string().regex(fieldsetCodeRegex), 13479 label: __TURBOPACK__imported__module__681307__["z"].string().min(1).max(255), 13480 icon: __TURBOPACK__imported__module__681307__["z"].string().max(100).optional(), 13481 description: __TURBOPACK__imported__module__681307__["z"].string().max(2e3).optional(), 13482 groups: __TURBOPACK__imported__module__681307__["z"].array(customFieldsetGroupSchema).optional() 13483}); 13484const customFieldEntityConfigSchema = __TURBOPACK__imported__module__681307__["z"].object({ 13485 fieldsets: __TURBOPACK__imported__module__681307__["z"].array(customFieldsetSchema).max(20).optional(), 13486 singleFieldsetPerRecord: __TURBOPACK__imported__module__681307__["z"].boolean().optional() 13487}); 13488const encryptionFieldRuleSchema = __TURBOPACK__imported__module__681307__["z"].object({ 13489 field: __TURBOPACK__imported__module__681307__["z"].string().min(1).max(200), 13490 hashField: __TURBOPACK__imported__module__681307__["z"].string().min(1).max(200).optional().nullable() 13491}); 13492const upsertEncryptionMapSchema = __TURBOPACK__imported__module__681307__["z"].object({ 13493 entityId: __TURBOPACK__imported__module__681307__["z"].string().regex(entityIdRegex), 13494 tenantId: __TURBOPACK__imported__module__681307__["z"].string().uuid().nullable().optional(), 13495 organizationId: __TURBOPACK__imported__module__681307__["z"].string().uuid().nullable().optional(), 13496 fields: __TURBOPACK__imported__module__681307__["z"].array(encryptionFieldRuleSchema).min(1), 13497 isActive: __TURBOPACK__imported__module__681307__["z"].boolean().optional() 13498}); 13499; 13500__turbopack_context__.s([ 13501 "customFieldEntityConfigSchema", 13502 0, 13503 customFieldEntityConfigSchema, 13504 "customFieldsetGroupSchema", 13505 0, 13506 customFieldsetGroupSchema, 13507 "customFieldsetSchema", 13508 0, 13509 customFieldsetSchema, 13510 "encryptionFieldRuleSchema", 13511 0, 13512 encryptionFieldRuleSchema, 13513 "entityIdRegex", 13514 0, 13515 entityIdRegex, 13516 "fieldsetCodeRegex", 13517 0, 13518 fieldsetCodeRegex, 13519 "upsertCustomEntitySchema", 13520 0, 13521 upsertCustomEntitySchema, 13522 "upsertCustomFieldDefSchema", 13523 0, 13524 upsertCustomFieldDefSchema, 13525 "upsertEncryptionMapSchema", 13526 0, 13527 upsertEncryptionMapSchema 13528], 356417); 13529var __TURBOPACK__imported__module__928441__2 = __TURBOPACK__imported__module__928441__; 13530"use client"; 13531; 13532; 13533; 13534; 13535; 13536; 13537; 13538; 13539; 13540; 13541; 13542; 13543; 13544function normalizeGroupPayload(value) { 13545 if (!value) return null; 13546 if (typeof value === "string") { 13547 const code2 = value.trim(); 13548 return code2 ? { 13549 code: code2 13550 } : null; 13551 } 13552 if (typeof value !== "object") return null; 13553 const entry = value; 13554 const code = typeof entry.code === "string" ? entry.code.trim() : ""; 13555 if (!code) return null; 13556 const group = { 13557 code 13558 }; 13559 if (typeof entry.title === "string" && entry.title.trim()) group.title = entry.title.trim(); 13560 if (typeof entry.hint === "string" && entry.hint.trim()) group.hint = entry.hint.trim(); 13561 return group; 13562} 13563const FieldDefinitionsManager = /*#__PURE__*/ __TURBOPACK__imported__module__271645__1["forwardRef"](function FieldDefinitionsManager2({ entityId, initialFieldset = null, onClose, onSaved, fullEditorHref }, ref) { 13564 const t = (0, __TURBOPACK__imported__module__928441__2["useT"])(); 13565 const queryClient = (0, __TURBOPACK__imported__module__912598__["useQueryClient"])(); 13566 const [loading, setLoading] = __TURBOPACK__imported__module__271645__1["useState"](true); 13567 const [saving, setSaving] = __TURBOPACK__imported__module__271645__1["useState"](false); 13568 const [statusError, setStatusError] = __TURBOPACK__imported__module__271645__1["useState"](null); 13569 const [defs, setDefs] = __TURBOPACK__imported__module__271645__1["useState"]([]); 13570 const [deletedKeys, setDeletedKeys] = __TURBOPACK__imported__module__271645__1["useState"]([]); 13571 const [defErrors, setDefErrors] = __TURBOPACK__imported__module__271645__1["useState"]({}); 13572 const [fieldsets, setFieldsets] = __TURBOPACK__imported__module__271645__1["useState"]([]); 13573 const [activeFieldset, setActiveFieldset] = __TURBOPACK__imported__module__271645__1["useState"](initialFieldset); 13574 const [singleFieldsetPerRecord, setSingleFieldsetPerRecord] = __TURBOPACK__imported__module__271645__1["useState"](true); 13575 const [isDirty, setIsDirty] = __TURBOPACK__imported__module__271645__1["useState"](false); 13576 const [orderDirty, setOrderDirty] = __TURBOPACK__imported__module__271645__1["useState"](false); 13577 const loadDefinitions = __TURBOPACK__imported__module__271645__1["useCallback"](async ()=>{ 13578 if (!entityId) return;
13579 setLoading(true); 13580 setStatusError(null); 13581 try { 13582 const json = await (0, __TURBOPACK__imported__module__490746__1["readApiResultOrThrow"])(`/api/entities/definitions.manage?entityId=${encodeURIComponent(entityId)}`, void 0, { 13583 errorMessage: t("entities.customFields.errors.loadFailed", "Failed to load field definitions"), 13584 fallback: { 13585 items: [], 13586 deletedKeys: [] 13587 } 13588 }); 13589 const loaded = (json.items || []).map((d)=>({ 13590 key: d.key, 13591 kind: d.kind, 13592 configJson: d.configJson || {}, 13593 isActive: d.isActive !== false 13594 })); 13595 loaded.sort((a, b)=>Number(a.configJson?.priority ?? 0) - Number(b.configJson?.priority ?? 0)); 13596 setDefs(loaded); 13597 setDeletedKeys(Array.isArray(json.deletedKeys) ? json.deletedKeys : []); 13598 const loadedFieldsets = Array.isArray(json.fieldsets) ? json.fieldsets : []; 13599 setFieldsets(loadedFieldsets);
13600 setActiveFieldset((current)=>{ 13601 if (initialFieldset && loadedFieldsets.some((fs)=>fs.code === initialFieldset)) { 13602 return initialFieldset; 13603 } 13604 if (current && loadedFieldsets.some((fs)=>fs.code === current)) return current; 13605 return loadedFieldsets[0]?.code ?? null; 13606 }); 13607 setSingleFieldsetPerRecord(json.settings?.singleFieldsetPerRecord !== false); 13608 setDefErrors({}); 13609 setIsDirty(false); 13610 setOrderDirty(false); 13611 } catch (err) { 13612 const message = err instanceof Error ? err.message : t("entities.customFields.errors.loadFailed", "Failed to load field definitions"); 13613 setStatusError(message); 13614 } finally{ 13615 setLoading(false); 13616 } 13617 }, [ 13618 entityId, 13619 initialFieldset, 13620 t 13621 ]); 13622 __TURBOPACK__imported__module__271645__1["useEffect"](()=>{ 13623 loadDefinitions().catch(()=>{}); 13624 }, [ 13625 loadDefinitions 13626 ]); 13627 const buildFieldsetPayload = __TURBOPACK__imported__module__271645__1["useCallback"](()=>{ 13628 const groupMap = /* @__PURE__ */ new Map(); 13629 defs.forEach((definition)=>{ 13630 const code = typeof definition.configJson?.fieldset === "string" ? definition.configJson.fieldset : null; 13631 if (!code) return; 13632 const normalized = normalizeGroupPayload(definition.configJson?.group); 13633 if (!normalized) return; 13634 const list = groupMap.get(code) ?? []; 13635 if (!list.some((entry)=>entry.code === normalized.code)) { 13636 list.push(normalized); 13637 groupMap.set(code, list); 13638 } 13639 }); 13640 return fieldsets.map((fs)=>({ 13641 ...fs, 13642 groups: groupMap.get(fs.code) ?? [] 13643 })); 13644 }, [ 13645 defs, 13646 fieldsets 13647 ]); 13648 const validateDef = __TURBOPACK__imported__module__271645__1["useCallback"]((definition)=>{ 13649 const parsed = upsertCustomFieldDefSchema.safeParse({ 13650 entityId, 13651 key: definition.key, 13652 kind: definition.kind, 13653 configJson: definition.configJson, 13654 isActive: definition.isActive 13655 }); 13656 if (parsed.success) return {}; 13657 const errs = {}; 13658 for (const issue of parsed.error.issues){ 13659 if (issue.path.includes("key")) errs.key = issue.message; 13660 if (issue.path.includes("kind")) errs.kind = issue.message; 13661 } 13662 return errs; 13663 }, [ 13664 entityId 13665 ]); 13666 const validateAll = __TURBOPACK__imported__module__271645__1["useCallback"](()=>{ 13667 const nextErrors = {}; 13668 defs.forEach((definition, index)=>{ 13669 nextErrors[index] = validateDef(definition); 13670 }); 13671 setDefErrors(nextErrors); 13672 return Object.values(nextErrors).every((entry)=>!entry.key && !entry.kind); 13673 }, [ 13674 defs, 13675 validateDef 13676 ]); 13677 const handleDefinitionChange = __TURBOPACK__imported__module__271645__1["useCallback"]((index, nextDef)=>{ 13678 setDefs((arr)=>
13678arr.map((entry, idx)=>idx === index ? nextDef : entry)); 13679 setDefErrors((prev)=>({ 13680 ...prev, 13681 [index]: validateDef(nextDef) 13682 })); 13683 setIsDirty(true); 13684 }, [ 13685 validateDef 13686 ]); 13687 const handleAddField = __TURBOPACK__imported__module__271645__1["useCallback"](()=>{ 13688 setDefs((arr)=>[ 13689 ...arr, 13690 { 13691 key: "", 13692 kind: "text", 13693 configJson: activeFieldset ? { 13694 fieldset: activeFieldset 13695 } : {}, 13696 isActive: true 13697 } 13698 ]); 13699 setIsDirty(true); 13700 }, [ 13701 activeFieldset 13702 ]); 13703 const handleRemoveField = __TURBOPACK__imported__module__271645__1["useCallback"](async (index)=>{ 13704 const def = defs[index]; 13705 if (!def) return; 13706 if (def.key) { 13707 try { 13708 const call = await (0, __TURBOPACK__imported__module__490746__1["apiCall"])("/api/entities/definitions", { 13709 method: "DELETE", 13710 headers: { 13711 "content-type": "application/json" 13712 }, 13713 body: JSON.stringify({ 13714 entityId, 13715 key: def.key 13716 }) 13717 }); 13718 if (!call.ok) { 13719 await (0, __TURBOPACK__imported__module__685008__1["raiseCrudError"])(call.response, t("entities.customFields.errors.deleteFailed", "Failed to delete field")); 13720 } 13721 } catch (error) { 13722 const message = error instanceof Error ? error.message : t("entities.customFields.errors.deleteFailed", "Failed to delete field"); 13723 (0, __TURBOPACK__imported__module__484973__1["flash"])(message, "error"); 13724 return; 13725 } 13726 } 13727 setDefs((arr)=>
13727arr.filter((_, idx)=>idx !== index)); 13728 setIsDirty(true); 13729 }, [ 13730 defs, 13731 entityId, 13732 t 13733 ]); 13734 const handleRestoreField = __TURBOPACK__imported__module__271645__1["useCallback"](async (key)=>{ 13735 try { 13736 const call = await (0, __TURBOPACK__imported__module__490746__1["apiCall"])("/api/entities/definitions.restore", { 13737 method: "POST", 13738 headers: { 13739 "content-type": "application/json" 13740 }, 13741 body: JSON.stringify({ 13742 entityId, 13743 key 13744 }) 13745 }); 13746 if (!call.ok) { 13747 await (0, __TURBOPACK__imported__module__685008__1["raiseCrudError"])(call.response, t("entities.customFields.errors.restoreFailed", "Failed to restore field")); 13748 } 13749 (0, __TURBOPACK__imported__module__484973__1["flash"])(t("entities.customFields.flash.restored", "Field restored"), "success"); 13750 await loadDefinitions(); 13751 } catch (error) { 13752 const message = error instanceof Error ? error.message : t("entities.customFields.errors.restoreFailed", "Failed to restore field"); 13753 (0, __TURBOPACK__imported__module__484973__1["flash"])(message, "error"); 13754 } 13755 }, [ 13756 entityId, 13757 loadDefinitions, 13758 t 13759 ]); 13760 const handleReorder = __TURBOPACK__imported__module__271645__1["useCallback"]((from, to)=>{ 13761 setDefs((arr)=>
13761{ 13762 const next = [ 13763 ...arr 13764 ]; 13765 const [moved] = next.splice(from, 1); 13766 next.splice(to, 0, moved); 13767 return next; 13768 }); 13769 setIsDirty(true); 13770 setOrderDirty(true); 13771 }, []); 13772 const handleFieldsetsChange = __TURBOPACK__imported__module__271645__1["useCallback"]((next)=>{ 13773 setFieldsets(next); 13774 if (!next.some((fs)=>fs.code === activeFieldset)) { 13775 setActiveFieldset(next[0]?.code ?? null); 13776 } 13777 setIsDirty(true); 13778 }, [ 13779 activeFieldset 13780 ]); 13781 const handleFieldsetCodeChange = __TURBOPACK__imported__module__271645__1["useCallback"]((previousCode, nextCode)=>{ 13782 if (!previousCode || !nextCode || previousCode === nextCode) return; 13783 setDefs((arr)=>arr.map((entry)=>{ 13784 const current = typeof entry.configJson?.fieldset === "string" ? entry.configJson.fieldset : void 0; 13785 if (current !== previousCode) return entry; 13786 const nextConfig = { 13787 ...entry.configJson || {} 13788 }; 13789 nextConfig.fieldset = nextCode; 13790 return { 13791 ...entry, 13792 configJson: nextConfig 13793 }; 13794 })); 13795 setActiveFieldset((current)=>current === previousCode ? nextCode : current); 13796 setIsDirty(true); 13797 }, []); 13798 const handleFieldsetRemoved = __TURBOPACK__imported__module__271645__1["useCallback"]((code)=>{ 13799 if (!code) return; 13800 setDefs((arr)=>
13800arr.map((entry)=>{ 13801 const current = typeof entry.configJson?.fieldset === "string" ? entry.configJson.fieldset : void 0; 13802 if (current !== code) return entry; 13803 const nextConfig = { 13804 ...entry.configJson || {} 13805 }; 13806 delete nextConfig.fieldset; 13807 delete nextConfig.group; 13808 return { 13809 ...entry, 13810 configJson: nextConfig 13811 }; 13812 })); 13813 setIsDirty(true); 13814 }, []); 13815 const submit = __TURBOPACK__imported__module__271645__1["useCallback"](async ()=>{ 13816 if (!entityId) return; 13817 setSaving(true); 13818 setStatusError(null); 13819 try { 13820 if (!validateAll()) { 13821 (0, __TURBOPACK__imported__module__484973__1["flash"])(t("entities.customFields.errors.validation", "Please fix validation errors"), "error"); 13822 throw new Error(t("entities.customFields.errors.validation", "Validation failed")); 13823 } 13824 const payload = { 13825 entityId, 13826 definitions: defs.filter((d)=>!!d.key).map((d)=>({ 13827 key: d.key, 13828 kind: d.kind, 13829 configJson: d.configJson, 13830 isActive: d.isActive !== false 13831 })), 13832 fieldsets: buildFieldsetPayload(), 13833 singleFieldsetPerRecord 13834 }; 13835 const call = await (0, __TURBOPACK__imported__module__490746__1["apiCall"])("/api/entities/definitions.batch", { 13836 method: "POST", 13837 headers: { 13838 "content-type": "application/json" 13839 }, 13840 body: JSON.stringify(payload) 13841 }); 13842 if (!call.ok) { 13843 await (0, __TURBOPACK__imported__module__685008__1["raiseCrudError"])(call.response, t("entities.customFields.errors.saveFailed", "Failed to save definitions")); 13844 } 13845 await (0, __TURBOPACK__imported__module__221019__1["invalidateCustomFieldDefs"])(queryClient, entity
13845Id); 13846 (0, __TURBOPACK__imported__module__484973__1["flash"])(t("entities.customFields.flash.saved", "Definitions saved"), "success"); 13847 setIsDirty(false); 13848 setOrderDirty(false); 13849 if (onSaved) await onSaved(); 13850 onClose(); 13851 } catch (err) { 13852 const message = err instanceof Error ? err.message : t("entities.customFields.errors.saveFailed", "Failed to save definitions"); 13853 setStatusError(message); 13854 } finally{ 13855 setSaving(false); 13856 } 13857 }, [ 13858 buildFieldsetPayload, 13859 defs, 13860 entityId, 13861 onClose, 13862 onSaved, 13863 queryClient, 13864 singleFieldsetPerRecord, 13865 t, 13866 validateAll 13867 ]); 13868 __TURBOPACK__imported__module__271645__1["useImperativeHandle"](ref, ()=>({ 13869 submit 13870 }), [ 13871 submit 13872 ]); 13873 const cancelLabel = t("ui.forms.actions.cancel", "Cancel"); 13874 const saveLabel = saving ? t("ui.forms.status.saving", "Saving...") : t("ui.forms.actions.save", "Save"); 13875 const openFullLabel = t("entities.customFields.openInNewTab", "Open full editor"); 13876 const handleOpenFullEditor = __TURBOPACK__imported__module__271645__1["useCallback"](()=>{ 13877 if (!fullEditorHref || ("TURBOPACK compile-time value", "object") === "undefined") return; 13878 window.open(fullEditorHref, "_blank", "noopener,noreferrer"); 13879 }, [ 13880 fullEditorHref 13881 ]);
13882 const content = loading ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])("div", { 13883 className: "flex h-64 items-center justify-center", 13884 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__306994__["Spinner"], { 13885 size: "lg" 13886 }) 13887 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(FieldDefinitionsEditor, { 13888 definitions: defs, 13889 errors: defErrors, 13890 deletedKeys, 13891 fieldsets, 13892 activeFieldset, 13893 onActiveFieldsetChange: setActiveFieldset, 13894 onFieldsetsChange: handleFieldsetsChange, 13895 onFieldsetCodeChange: handleFieldsetCodeChange, 13896 onFieldsetRemoved: handleFieldsetRemoved, 13897 singleFieldsetPerRecord, 13898 onSingleFieldsetPerRecordChange: (value)=>{ 13899 setSingleFieldsetPerRecord(value); 13900 setIsDirty(true); 13901 }, 13902 onAddField: handleAddField, 13903 onRemoveField: (index)=>{ 13904 void handleRemoveField(index); 13905 }, 13906 onDefinitionChange: handleDefinitionChange, 13907 onRestoreField: (key)=>{ 13908 void handleRestoreField(key); 13909 }, 13910 onReorder: handleReorder, 13911 orderNotice: orderDirty ? { 13912 dirty: true, 13913 message: t("entities.customFields.orderNotice", "Reordered \u2014 remember to save") 13914 } : void 0, 13915 translate: t 13916 }); 13917 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])("div", { 13918 className: "flex flex-col gap-3 sm:gap-4", 13919 children: [ 13920 statusError ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])(__TURBOPACK__imported__module__975215__["Alert"], { 13921 variant: "destructive", 13922 children: [
13923 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__975215__["AlertTitle"], { 13924 children: t("entities.customFields.errors.title", "Something went wrong") 13925 }), 13926 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__975215__["AlertDescription"], { 13927 children: statusError 13928 }) 13929 ] 13930 }) : null, 13931 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])("div", { 13932 className: "rounded-lg border bg-card p-3 sm:p-4 max-h-[70vh] overflow-y-auto", 13933 children: content 13934 }), 13935 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsxs"])("div", { 13936 className: "flex justify-end gap-2", 13937 children: [ 13938 fullEditorHref ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__110035__1["Button"], { 13939 type: "button", 13940 variant: "ghost", 13941 onClick: handleOpenFullEditor, 13942 children: openFullLabel 13943 }) : null,
13944 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__110035__1["Button"], { 13945 type: "button", 13946 variant: "outline", 13947 onClick: onClose, 13948 disabled: saving, 13949 children: cancelLabel 13950 }), 13951 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__1["jsx"])(__TURBOPACK__imported__module__110035__1["Button"], { 13952 type: "button", 13953 onClick: ()=>{ 13954 void submit(); 13955 }, 13956 disabled: saving || !isDirty, 13957 children: saveLabel 13958 }) 13959 ] 13960 }) 13961 ] 13962 }); 13963}); 13964FieldDefinitionsManager.displayName = "FieldDefinitionsManager"; 13965; 13966var __TURBOPACK__imported__module__488573__1 = __TURBOPACK__imported__module__488573__; 13967var __TURBOPACK__imported__module__486775__1 = __TURBOPACK__imported__module__486775__; 13968var __TURBOPACK__imported__module__862013__ = __turbopack_context__.i(862013); 13969var __TURBOPACK__imported__module__781167__ = __turbopack_context__.i(781167); 13970var __TURBOPACK__imported__module__157467__ = __turbopack_context__.i(157467); 13971var __TURBOPACK__imported__module__170768__ = __turbopack_context__.i(170768); 13972var __TURBOPACK__imported__module__406911__1 = __TURBOPACK__imported__module__406911__; 13973var __TURBOPACK__imported__module__488166__ = __turbopack_context__.i(488166); 13974var __TURBOPACK__imported__module__753861__ = __turbopack_context__.i(753861); 13975// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/crud/CollapsibleGroup.js [app-client] (ecmascript) 13976; 13977var __TURBOPACK__imported__module__843476__4 = __TURBOPACK__imported__module__843476__; 13978var __TURBOPACK__imported__module__271645__4 = __TURBOPACK__imported__module__271645__; 13979var __TURBOPACK__imported__module__664659__ = __turbopack_context__.i(664659); 13980var __TURBOPACK__imported__module__406911__2 = __TURBOPACK__imported__module__406911__; 13981var __TURBOPACK__imported__module__928441__3 = __TURBOPACK__imported__module__928441__; 13982var __TURBOPACK__imported__module__110035__3 = __TURBOPACK__imported__module__110035__; 13983// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/crud/useGroupCollapse.js [app-client] (ecmascript) 13984; 13985var __TURBOPACK__imported__module__271645__5 = __TURBOPACK__imported__module__271645__; 13986// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/crud/usePersistedBooleanFlag.js [app-client] (ecmascript) 13987; 13988var __TURBOPACK__imported__module__271645__6 = __TURBOPACK__imported__module__271645__; 13989var __TURBOPACK__imported__module__246256__ = __turbopack_context__.i(246256); 13990"use client"; 13991; 13992; 13993const LOCAL_BROADCAST_EVENT = "om:persisted-boolean-flag:change"; 13994const localEmitter = ("TURBOPACK compile-time truthy", 1) ? new EventTarget() : "TURBOPACK unreachable"; 13995function readCurrentValue(storageKey, defaultValue) { 13996 const saved = (0, __TURBOPACK__imported__module__246256__["readJsonFromLocalStorage"])(storageKey, null); 13997 if (saved === "1") return true; 13998 if (saved === "0") return false; 13999 return defaultValue; 14000} 14001function persistValue(storageKey, next) { 14002 (0, __TURBOPACK__imported__module__246256__["writeJsonToLocalStorage"])(storageKey, next ? "1" : "0"); 14003 localEmitter?.dispatchEvent(new CustomEvent(LOCAL_BROADCAST_EVENT, { 14004 detail: storageKey 14005 })); 14006} 14007function subscribe(storageKey, onChange) { 14008 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 14009 ; 14010 const handleStorage = (event)=>{ 14011 if (event.key === storageKey) onChange(); 14012 }; 14013 const handleLocal = (event)=>{ 14014 const detail = event.detail; 14015 if (detail === storageKey) onChange(); 14016 }; 14017 window.addEventListener("storage", handleStorage); 14018 localEmitter?.addEventListener(LOCAL_BROADCAST_EVENT, handleLocal); 14019 return ()=>{ 14020 window.removeEventListener("storage", handleStorage); 14021 localEmitter?.removeEventListener(LOCAL_BROADCAST_EVENT, handleLocal); 14022 }; 14023} 14024function usePersistedBooleanFlag(storageKey, defaultValue) { 14025 const [isHydrated, setIsHydrated] = (0, __TURBOPACK__imported__module__271645__6["useState"])(false); 14026 const getSnapshot = (0, __TURBOPACK__imported__module__271645__6["useCallback"])(()=>readCurrentValue(storageKey, defaultValue), [ 14027 storageKey, 14028 defaultValue 14029 ]); 14030 const getServerSnapshot = (0, __TURBOPACK__imported__module__271645__6["useCallback"])(()=>defaultValue, [ 14031 defaultValue 14032 ]); 14033 const subscribeKey = (0, __TURBOPACK__imported__module__271645__6["useCallback"])((onChange)=>
14033subscribe(storageKey, onChange), [ 14034 storageKey 14035 ]); 14036 const value = (0, __TURBOPACK__imported__module__271645__6["useSyncExternalStore"])(subscribeKey, getSnapshot, getServerSnapshot); 14037 (0, __TURBOPACK__imported__module__271645__6["useEffect"])(()=>{ 14038 setIsHydrated(true); 14039 }, []); 14040 const setValue = (0, __TURBOPACK__imported__module__271645__6["useCallback"])((next)=>{ 14041 const current = readCurrentValue(storageKey, defaultValue); 14042 const nextValue = typeof next === "function" ? next(current) : next; 14043 persistValue(storageKey, nextValue); 14044 }, [ 14045 storageKey, 14046 defaultValue 14047 ]); 14048 const toggle = (0, __TURBOPACK__imported__module__271645__6["useCallback"])(()=>{ 14049 const current = readCurrentValue(storageKey, defaultValue); 14050 persistValue(storageKey, !current); 14051 }, [ 14052 storageKey, 14053 defaultValue 14054 ]); 14055 return { 14056 value, 14057 toggle, 14058 setValue, 14059 isHydrated 14060 }; 14061} 14062; 14063__turbopack_context__.s([ 14064 "usePersistedBooleanFlag", 14065 0, 14066 usePersistedBooleanFlag 14067], 952676); 14068"use client"; 14069; 14070; 14071function getStorageKey(pageType, groupId) { 14072 return `om:collapsible:${pageType}:${groupId}`; 14073} 14074function useGroupCollapse(pageType, groupId, defaultExpanded = true) { 14075 const { value: expanded, toggle, setValue, isHydrated } = usePersistedBooleanFlag(getStorageKey(pageType, groupId), defaultExpanded); 14076 const setExpanded = (0, __TURBOPACK__imported__module__271645__5["useCallback"])((next)=>{ 14077 if (typeof next === "function") { 14078 setValue((prev)=>next(prev)); 14079 } else { 14080 setValue(next); 14081 } 14082 }, [ 14083 setValue 14084 ]); 14085 return { 14086 expanded, 14087 toggle, 14088 setExpanded, 14089 isHydrated 14090 }; 14091} 14092; 14093// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/crud/SortableGroupHandle.js [app-client] (ecmascript) 14094; 14095var __TURBOPACK__imported__module__843476__5 = __TURBOPACK__imported__module__843476__; 14096var __TURBOPACK__imported__module__271645__7 = __TURBOPACK__imported__module__271645__; 14097var __TURBOPACK__imported__module__750570__1 = __TURBOPACK__imported__module__750570__; 14098var __TURBOPACK__imported__module__406911__3 = __TURBOPACK__imported__module__406911__; 14099var __TURBOPACK__imported__module__741870__2 = __TURBOPACK__imported__module__741870__; 14100"use client"; 14101; 14102; 14103; 14104; 14105; 14106const SortableGroupHandleContext = /*#__PURE__*/ __TURBOPACK__imported__module__271645__7["createContext"](null); 14107const SortableGroupHandleProvider = SortableGroupHandleContext.Provider; 14108function useSortableGroupHandle() { 14109 return __TURBOPACK__imported__module__271645__7["useContext"](SortableGroupHandleContext); 14110} 14111function SortableGroupHandle({ ariaLabel, className }) { 14112 const handle = useSortableGroupHandle(); 14113 if (!handle) return null; 14114 const { ref, attributes, listeners, disabled } = handle; 14115 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__5["jsx"])(__TURBOPACK__imported__module__741870__2["IconButton"], { 14116 type: "button", 14117 variant: "ghost", 14118 size: "xs", 14119 ref, 14120 "aria-label": ariaLabel, 14121 disabled, 14122 className: (0, __TURBOPACK__imported__module__406911__3["cn"])("cursor-grab text-muted-foreground hover:text-foreground active:cursor-grabbing focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-sm", className), 14123 ...attributes, 14124 ...listeners ?? {}, 14125 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__5["jsx"])(__TURBOPACK__imported__module__750570__1["GripVertical"], { 14126 className: "size-4" 14127 }) 14128 }); 14129} 14130; 14131"use client"; 14132; 14133; 14134; 14135; 14136; 14137; 14138; 14139; 14140const CollapsibleGroup = /*#__PURE__*/ __TURBOPACK__imported__module__271645__4["forwardRef"](function CollapsibleGroup2({ groupId, title, pageType, defaultExpanded = true, errorCount = 0, fieldCount, chevronPosition = "right", icon, children }, ref) { 14141 const t = (0, __TURBOPACK__imported__module__928441__3["useT"])(); 14142 const { expanded, toggle, setExpanded, isHydrated } = useGroupCollapse(pageType, groupId, defaultExpanded); 14143 const contentId = `collapsible-group-${groupId}`; 14144 const sortableHandle = useSortableGroupHandle(); 14145 const showDragHandle = sortableHandle !== null; 14146 __TURBOPACK__imported__module__271645__4["useImperativeHandle"](ref, ()=>({ 14147 expand: ()=>setExpanded(true) 14148 }), [ 14149 setExpanded 14150 ]); 14151 const chevronIcon = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])(__TURBOPACK__imported__module__664659__["ChevronDown"], { 14152 className: (0, __TURBOPACK__imported__module__406911__2["cn"])("size-4 shrink-0 motion-safe:transition-transform motion-safe:duration-200", expanded && "rotate-180") 14153 }); 14154 const fieldCountLabel = typeof fieldCount === "number" && fieldCount >
14154 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])("span", { 14155 className: "text-xs font-normal text-muted-foreground", 14156 children: [ 14157 "\xB7 ", 14158 fieldCount, 14159 " ", 14160 fieldCount === 1 ? t("ui.collapsible.fieldSingular", "field") : t("ui.collapsible.fieldPlural", "fields") 14161 ] 14162 }) : null; 14163 const errorBadge = errorCount > 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])("span", { 14164 className: "inline-flex items-center rounded-full bg-destructive/10 px-2 py-0.5 text-xs font-medium text-destructive", 14165 children: errorCount === 1 ? t("ui.collapsible.errorSingular", "{{count}} error", { 14166 count: errorCount 14167 }) : t("ui.collapsible.errorPlural", "{{count}} errors", { 14168 count: errorCount 14169 }) 14170 }) : null; 14171 const dragHandle = showDragHandle ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])("span", { 14172 className: "inline-flex shrink-0 items-center", 14173 onClick: (event)=>event.stopPropagation(), 14174 onPointerDown: (event)=>event.stopPropagation(), 14175 onKeyDown: (event)=>event.stopPropagation(), 14176 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])(SortableGroupHandle, { 14177 ariaLabel: t("ui.crud.dragHandle.aria", "Drag to reorder") 14178 }) 14179 }) : null; 14180 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])("div", { 14181 id: `collapsible-group-wrapper-${groupId}`, 14182 className: (0, __TURBOPACK__imported__module__406911__2["cn"])(// Aligned with Figma Accordion `210:4022`: rounded-10, three visual 14183 // states (closed = white card + soft border + x-small shadow, 14184 // hover-while-closed = bg-muted + no border + no shadow, 14185 // open = bg-muted + no border + no shadow). Destructive border 14186 // wins over the Figma states when the group has validation errors. 14187 "rounded-[10px] border bg-card transition-colors", !isHydrated && "invisible", errorCount > 0 ? "border-destructive" : expanded ? "border-transparent bg-muted shadow-none" : "border-border shadow-xs hover:border-transparent hover:bg-muted hover:shadow-none"), 14188 "data-collapsible-group-id": groupId, 14189 "data-state": expanded ? "open" : "closed", 14190 "data-persistence-hydrated": isHydrated ? "true" : "false", 14191 "aria-hidden": isHydrated ? void 0 : true, 14192 children: [ 14193 title && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])("div", { 14194 className: (0, __TURBOPACK__imported__module__406911__2["cn"])("flex items-center gap-2 px-2 py-2", chevronPosition === "left" ? "flex-row" : "flex-row"), 14195 children: [ 14196 dragHandle,
14197 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])(__TURBOPACK__imported__module__110035__3["Button"], { 14198 type: "button", 14199 variant: "muted", 14200 onClick: toggle, 14201 className: (0, __TURBOPACK__imported__module__406911__2["cn"])(// Defer hover styling to the surrounding wrapper so the whole 14202 // row toggles to `bg-muted` together (Figma Accordion behaviour) 14203 // instead of stacking a second hover layer over the trigger 14204 // button. 14205 "flex-1 rounded-md px-2 py-1 text-sm font-medium hover:bg-transparent dark:hover:bg-transparent", chevronPosition === "left" ? "justify-start gap-2" : "justify-between"), 14206 "aria-expanded": expanded, 14207 "aria-controls": contentId, 14208 children: chevronPosition === "left" ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])(__TURBOPACK__imported__module__843476__4["Fragment"], { 14209 children: [ 14210 chevronIcon,
14211 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])("span", { 14212 className: "flex items-center gap-2", 14213 children: [ 14214 icon && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])("span", { 14215 className: "relative shrink-0 text-muted-foreground", 14216 children: [ 14217 icon, 14218 !expanded && errorCount > 0 && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])("span", { 14219 className: "absolute -right-0.5 -top-0.5 size-2 rounded-full bg-destructive" 14220 }) 14221 ] 14222 }), 14223 /* @__P
14223URE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])("span", { 14224 children: title 14225 }), 14226 fieldCountLabel, 14227 errorBadge 14228 ] 14229 }) 14230 ] 14231 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])(__TURBOPACK__imported__module__843476__4["Fragment"], { 14232 children: [ 14233 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])("span", { 14234 className: "flex items-center gap-2", 14235 children: [ 14236 icon && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsxs"])("span", { 14237 className: "relative shrink-0 text-muted-foreground", 14238 children: [ 14239 icon, 14240 !expanded && errorCount > 0 && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])("span", { 14241 className: "absolute -right-0.5 -top-0.5 size-2 rounded-full bg-destructive" 14242 }) 14243 ] 14244 }),
14245 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])("span", { 14246 children: title 14247 }), 14248 fieldCountLabel, 14249 errorBadge 14250 ] 14251 }), 14252 chevronIcon 14253 ] 14254 }) 14255 }) 14256 ] 14257 }), 14258 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])("div", { 14259 id: contentId, 14260 className: (0, __TURBOPACK__imported__module__406911__2["cn"])("motion-safe:transition-all motion-safe:duration-200 overflow-hidden", expanded ? "max-h-[5000px] opacity-100" : "max-h-0 opacity-0"), 14261 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__4["jsx"])("div", { 14262 className: "px-4 py-3", 14263 children 14264 }) 14265 }) 14266 ] 14267 }); 14268}); 14269; 14270// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/crud/useGroupOrder.js [app-client] (ecmascript) 14271; 14272var __TURBOPACK__imported__module__271645__8 = __TURBOPACK__imported__module__271645__; 14273var __TURBOPACK__imported__module__246256__1 = __TURBOPACK__imported__module__246256__; 14274"use client"; 14275; 14276; 14277const STORAGE_PREFIX = "om:group-order:"; 14278function getStorageKey1(pageType) { 14279 return `${STORAGE_PREFIX}${pageType}`; 14280} 14281function mergeOrder(saved, defaults) { 14282 const known = new Set(defaults); 14283 const result = saved.filter((id)=>known.has(id)); 14284 for (const id of defaults){ 14285 if (!result.includes(id)) result.push(id); 14286 } 14287 return result; 14288} 14289function arraysEqual(a, b) { 14290 if (a.length !== b.length) return false; 14291 for(let i = 0; i < a.length; i += 1){ 14292 if (a[i] !== b[i]) return false; 14293 } 14294 return true; 14295} 14296function useGroupOrder(pageType, defaultGroupIds) { 14297 const [orderedIds, setOrderedIds] = __TURBOPACK__imported__module__271645__8["useState"](defaultGroupIds); 14298 const mounted = __TURBOPACK__imported__module__271645__8["useRef"](false); 14299 __TURBOPACK__imported__module__271645__8["useEffect"](()=>{ 14300 mounted.current = true; 14301 const saved = (0, __TURBOPACK__imported__module__246256__1["readJsonFromLocalStorage"])(getStorageKey1(pageType), null); 14302 if (Array.isArray(saved)) { 14303 setOrderedIds(mergeOrder(saved, defaultGroupIds)); 14304 } 14305 }, [ 14306 pageType 14307 ]); 14308 __TURBOPACK__imported__module__271645__8["useEffect"](()=>{ 14309 setOrderedIds((prev)=>{ 14310 const merged = mergeOrder(prev, defaultGroupIds); 14311 return arraysEqual(prev, merged) ? prev : merged; 14312 }); 14313 }, [ 14314 defaultGroupIds 14315 ]); 14316 const reorder = __TURBOPACK__imported__module__271645__8["useCallback"]((fromIndex, toIndex)=>{ 14317 setOrderedIds((prev)=>{ 14318 const next = [ 14319 ...prev 14320 ]; 14321 const [moved] = next.splice(fromIndex, 1); 14322 next.splice(toIndex, 0, moved); 14323 if (mounted.current) { 14324 (0, __TURBOPACK__imported__module__246256__1["writeJsonToLocalStorage"])(getStorageKey1(pageType), next); 14325 } 14326 return next; 14327 }); 14328 }, [ 14329 pageType 14330 ]); 14331 return { 14332 orderedIds, 14333 reorder 14334 }; 14335} 14336; 14337// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/injection/InjectedField.js [app-client] (ecmascript) 14338;
14339var __TURBOPACK__imported__module__843476__6 = __TURBOPACK__imported__module__843476__; 14340var __TURBOPACK__imported__module__271645__9 = __TURBOPACK__imported__module__271645__; 14341// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/backend/injection/visibility-utils.js [app-client] (ecmascript) 14342; 14343function evaluateVisibilityRule(rule, formData) { 14344 const current = formData[rule.field]; 14345 switch(rule.operator){ 14346 case "eq": 14347 return current === rule.value; 14348 case "neq": 14349 return current !== rule.value; 14350 case "in": 14351 return Array.isArray(rule.value) ? rule.value.includes(current) : false; 14352 case "notIn": 14353 return Array.isArray(rule.value) ? !rule.value.includes(current) : true; 14354 case "truthy": 14355 return Boolean(current); 14356 case "falsy": 14357 return !current; 14358 default: 14359 return true; 14360 } 14361} 14362function evaluateInjectedVisibility(condition, values, context) { 14363 if (!condition) return true; 14364 if (typeof condition === "function") return condition(values, context); 14365 return evaluateVisibilityRule(condition, values); 14366} 14367; 14368var __TURBOPACK__imported__module__928441__4 = __TURBOPACK__imported__module__928441__; 14369var __TURBOPACK__imported__module__987030__2 = __TURBOPACK__imported__module__987030__; 14370var __TURBOPACK__imported__module__848476__2 = __TURBOPACK__imported__module__848476__; 14371var __TURBOPACK__imported__module__268153__1 = __TURBOPACK__imported__module__268153__; 14372var __TURBOPACK__imported__module__948473__ = __turbopack_context__.i(948473); 14373var __TURBOPACK__imported__module__262524__2 = __TURBOPACK__imported__module__262524__; 14374var __TURBOPACK__imported__module__306994__1 = __TURBOPACK__imported__module__306994__; 14375"use client"; 14376; 14377; 14378; 14379; 14380; 14381; 14382; 14383; 14384; 14385; 14386const MAX_CACHE_ENTRIES = 100; 14387const optionsCache = /* @__PURE__ */ new Map(); 14388function evictExpiredCacheEntries() { 14389 if (optionsCache.size <= MAX_CACHE_ENTRIES) return; 14390 const now = Date.now(); 14391 for (const [key, entry] of optionsCache){ 14392 if (entry.expiresAt < now) optionsCache.delete(key); 14393 } 14394} 14395function SelectField({ field, value, onChange, disabled, options, optionsError, label }) { 14396 const t = (0, __TURBOPACK__imported__module__928441__4["useT"])(); 14397 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__
143976["jsxs"])("div", { 14398 className: "space-y-2", 14399 "data-crud-field-id": field.id, 14400 children: [ 14401 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__948473__["Label"], { 14402 htmlFor: field.id, 14403 children: label 14404 }), 14405 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsxs"])(__TURBOPACK__imported__module__262524__2["Select"], { 14406 value: typeof value === "string" && value ? value : void 0, 14407 onValueChange: (next)=>onChange(field.id, next || void 0), 14408 disabled: disabled || options.length === 0 && !field.options?.length, 14409 children: [ 14410 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__262524__2["SelectTrigger"], { 14411 id: field.id, 14412 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__262524__2["SelectValue"], { 14413 placeholder: t("ui.filters.select.placeholder", "Select...") 14414 }) 14415 }),
14416 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__262524__2["SelectContent"], { 14417 children: options.map((option)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__262524__2["SelectItem"], { 14418 value: option.value, 14419 children: option.labelKey ? t(option.labelKey, option.label) : option.label 14420 }, option.value)) 14421 }) 14422 ] 14423 }), 14424 optionsError ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])("div", { 14425 className: "text-xs text-muted-foreground", 14426 children: t("ui.forms.optionsUnavailable", "Options unavailable") 14427 }) : null 14428 ] 14429 }); 14430} 14431function InjectedField({ field, value, onChange, context, formData, readOnly = false }) { 14432 const t = (0, __TURBOPACK__imported__module__928441__4["useT"])(); 14433 const [dynamicOptions, setDynamicOptions] = __TURBOPACK__imported__module__271645__9["useState"](null); 14434 const [optionsError, setOptionsError] = __TURBOPACK__imported__module__271645__9["useState"](false); 14435 __TURBOPACK__imported__module__271645__9["useEffect"](()=>{ 14436 let cancelled = false; 14437 const loadOptions = async ()=>{ 14438 if (typeof field.optionsLoader !== "function") return; 14439 const ttl = Math.max(1, field.optionsCacheTtl ?? 60); 14440 const cacheKey = `${field.id}:${context.organizationId ?? ""}:${context.tenantId ?? ""}`; 14441 const cached = optionsCache.get(cacheKey); 14442 if (cached && cached.expiresAt > Date.now()) { 14443 setDynamicOptions(cached.options); 14444 return; 14445 } 14446 try { 14447 const loaded = await field.optionsLoader(context); 14448 if (cancelled) return; 14449 const normalized = Array.isArray(loaded) ? loaded : []; 14450 setDynamicOptions(normalized); 14451 setOptionsError(false); 14452 evictExpiredCacheEntries(); 14453 optionsCache.set(cacheKey, { 14454 options: normalized, 14455 expiresAt: Date.now() + ttl * 1e3 14456 }); 14457 } catch { 14458 if (cancelled) return; 14459 setDynamicOptions(Array.isArray(field.options) ? field.options : null); 14460 setOptionsError(true); 14461 } 14462 }; 14463 void loadOptions(); 14464 return ()=>{ 14465 cancelled = true; 14466 }; 14467 }, [ 14468 context, 14469 field.id, 14470 field.options, 14471 field.optionsCacheTtl, 14472 field.optionsLoader 14473 ]); 14474 if (!evaluateInjectedVisibility(field.visibleWhen, formData, context)) return null; 14475 const label = field.labelKey ? t(field.labelKey, field.label) : t(field.label, field.label); 14476 const disabled = readOnly || field.readOnly; 14477 const options = dynamicOptions ?? field.options ?? []; 14478 if (field.type === "custom" && field.customComponent) { 14479 const CustomComponent = field.customComponent; 14480 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__
144806["jsx"])(__TURBOPACK__imported__module__271645__9["Suspense"], { 14481 fallback: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__306994__1["Spinner"], { 14482 size: "sm" 14483 }), 14484 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(CustomComponent, { 14485 value, 14486 onChange: (next)=>onChange(field.id, next), 14487 context, 14488 disabled 14489 }) 14490 }); 14491 } 14492 if (field.type === "textarea") { 14493 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsxs"])("div", { 14494 className: "space-y-2", 14495 "data-crud-field-id": field.id, 14496 children: [ 14497 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__948473__["Label"], { 14498 htmlFor: field.id, 14499 children: label 14500 }), 14501 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__
145016["jsx"])(__TURBOPACK__imported__module__268153__1["Textarea"], { 14502 id: field.id, 14503 className: "min-h-[96px]", 14504 value: typeof value === "string" ? value : "", 14505 disabled, 14506 onChange: (event)=>onChange(field.id, event.target.value) 14507 }) 14508 ] 14509 }); 14510 } 14511 if (field.type === "select") { 14512 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(SelectField, { 14513 field, 14514 value, 14515 onChange, 14516 disabled, 14517 options, 14518 optionsError, 14519 label 14520 }); 14521 } 14522 if (field.type === "boolean") { 14523 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsxs"])("label", { 14524 className: "flex items-center gap-2 text-sm", 14525 "data-crud-field-id": field.id, 14526 children: [ 14527 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__848476__2["Checkbox"], { 14528 checked: value === true, 14529 disabled, 14530 onCheckedChange: (checked)=>onChange(field.id, checked === true) 14531 }),
14532 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])("span", { 14533 children: label 14534 }) 14535 ] 14536 }); 14537 } 14538 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsxs"])("div", { 14539 className: "space-y-2", 14540 "data-crud-field-id": field.id, 14541 children: [ 14542 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__948473__["Label"], { 14543 htmlFor: field.id, 14544 children: label 14545 }), 14546 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__6["jsx"])(__TURBOPACK__imported__module__987030__2["Input"], { 14547 id: field.id, 14548 type: field.type === "number" ? "number" : field.type === "date" ? "date" : "text", 14549 value: typeof value === "string" || typeof value === "number" ? String(value) : "", 14550 disabled, 14551 onChange: (event)=>{ 14552 if (field.type === "number") { 14553 onChange(field.id, event.target.value === "" ? void 0 : Number(event.target.value)); 14554 return; 14555 } 14556 onChange(field.id, event.target.value); 14557 } 14558 }) 14559 ] 14560 }); 14561} 14562var InjectedField_default = InjectedField; 14563; 14564var __TURBOPACK__imported__module__238232__ = __turbopack_context__.i(238232); 14565var __TURBOPACK__imported__module__486257__ = __turbopack_context__.i(486257); 14566// MERGED MODULE: [project]/node_modules/@open-mercato/ui/dist/primitives/rich-editor.js [app-client] (ecmascript) 14567; 14568var __TURBOPACK__imported__module__843476__7 = __TURBOPACK__imported__module__843476__; 14569var __TURBOPACK__imported__module__271645__10 = __TURBOPACK__imported__module__271645__; 14570// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/text-align-center.js [app-client] (ecmascript) <export default as AlignCenter> 14571; 14572var __TURBOPACK__imported__module__393392__ = __turbopack_context__.i(393392); 14573var __TURBOPACK__imported__module__393392__ = __TURBOPACK__imported__module__393392__; 14574// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/text-align-justify.js [app-client] (ecmascript) <export default as AlignJustify> 14575; 14576var __TURBOPACK__imported__module__778835__ = __turbopack_context__.i(778835); 14577var __TURBOPACK__imported__module__778835__ = __TURBOPACK__imported__module__778835__; 14578// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/text-align-start.js [app-client] (ecmascript) <export default as AlignLeft> 14579; 14580var __TURBOPACK__imported__module__634558__ = __turbopack_context__.i(634558); 14581__turbopack_context__.s([ 14582 "AlignLeft", 14583 ()=>__TURBOPACK__imported__module__634558__["default"] 14584], 426612); 14585var __TURBOPACK__imported__module__634558__ = __TURBOPACK__imported__module__634558__; 14586// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/text-align-end.js [app-client] (ecmascript) <export default as AlignRight> 14587; 14588var __TURBOPACK__imported__module__57522__ = __turbopack_context__.i(57522); 14589var __TURBOPACK__imported__module__57522__ = __TURBOPACK__imported__module__57522__; 14590var __TURBOPACK__imported__module__257995__ = __turbopack_context__.i(257995); 14591// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/bold.js [app-client] (ecmascript) <export default as Bold> 14592; 14593var __TURBOPACK__imported__module__582894__ = __turbopack_context__.i(582894); 14594var __TURBOPACK__imported__module__582894__ = __TURBOPACK__imported__module__582894__; 14595var __TURBOPACK__imported__module__664659__1 = __TURBOPACK__imported__module__664659__; 14596var __TURBOPACK__imported__module__758472__ = __turbopack_context__.i(758472); 14597var __TURBOPACK__imported__module__741929__ = __turbopack_context__.i(741929); 14598var __TURBOPACK__imported__module__974875__ = __turbopack_context__.i(974875); 14599var __TURBOPACK__imported__module__473708__ = __turbopack_context__.i(473708); 14600// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/italic.js [app-client] (ecmascript) <export default as Italic> 14601; 14602var __TURBOPACK__imported__module__192986__ = __turbopack_context__.i(192986
14602); 14603var __TURBOPACK__imported__module__192986__ = __TURBOPACK__imported__module__192986__; 14604var __TURBOPACK__imported__module__221345__ = __turbopack_context__.i(221345); 14605var __TURBOPACK__imported__module__370956__ = __turbopack_context__.i(370956); 14606var __TURBOPACK__imported__module__63804__ = __turbopack_context__.i(63804); 14607// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/list-ordered.js [app-client] (ecmascript) <export default as ListOrdered> 14608; 14609var __TURBOPACK__imported__module__57489__ = __turbopack_context__.i(57489); 14610var __TURBOPACK__imported__module__57489__ = __TURBOPACK__imported__module__57489__; 14611var __TURBOPACK__imported__module__398361__ = __turbopack_context__.i(398361); 14612var __TURBOPACK__imported__module__194983__ = __turbopack_context__.i(194983); 14613var __TURBOPACK__imported__module__299023__ = __turbopack_context__.i(299023); 14614var __TURBOPACK__imported__module__323585__ = __turbopack_context__.i(323585); 14615// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/quote.js [app-client] (ecmascript) <export default as Quote> 14616; 14617var __TURBOPACK__imported__module__947875__ = __turbopack_context__.i(947875); 14618var __TURBOPACK__imported__module__947875__ = __TURBOPACK__imported__module__947875__; 14619// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/strikethrough.js [app-client] (ecmascript) <export default as Strikethrough> 14620; 14621var __TURBOPACK__imported__module__406940__ = __turbopack_context__.i(406940); 14622var __TURBOPACK__imported__module__406940__ = __TURBOPACK__imported__module__406940__; 14623// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/table.js [app-client] (ecmascript) <export default as Table> 14624; 14625var __TURBOPACK__imported__module__608719__ = __turbopack_context__.i(608719); 14626var __TURBOPACK__imported__module__608719__ = __TURBOPACK__imported__module__608719__; 14627// MERGED MODULE: [project]/node_modules/lucide-react/dist/esm/icons/underline.js [app-client] (ecmascript) <export default as Underline> 14628; 14629var __TURBOPACK__imported__module__20623__ = __turbopack_context__.i(20623); 14630var __TURBOPACK__imported__module__20623__ = __TURBOPACK__imported__module__20623__; 14631var __TURBOPACK__imported__module__225913__ = __turbopack_context__.i(225913); 14632var __TURBOPACK__imported__module__406911__4 = __TURBOPACK__imported__module__406911__; 14633// MERGED MODULE: [project]/node_modules/@open-mercato/shared/dist/lib/html/sanitizeRichText.js [app-client] (ecmascript) <export sanitizeRichTextHtml as sanitizeHtmlRichText> 14634; 14635// MERGED MODULE: [project]/node_modules/@open-mercato/shared/dist/lib/html/sanitizeRichText.js [app-client] (ecmascript) 14636; 14637var __TURBOPACK__imported__module__544821__ = __turbopack_context__.i(544821); 14638; 14639const RICH_TEXT_ALLOWED_TAGS = [ 14640 "a", 14641 "b", 14642 "blockquote", 14643 "br", 14644 "code", 14645 "div", 14646 "em", 14647 "h1", 14648 "h2", 14649 "h3", 14650 "h4", 14651 "h5", 14652 "h6", 14653 "hr", 14654 "i", 14655 "img", 14656 "input", 14657 "label", 14658 "li", 14659 "ol", 14660 "p", 14661 "pre", 14662 "s", 14663 "span", 14664 "strong", 14665 "table", 14666 "tbody", 14667 "td", 14668 "th", 14669 "thead", 14670 "tr", 14671 "u", 14672 "ul" 14673]; 14674const RICH_TEXT_DROP_WITH_CONTENT_TAGS = [ 14675 "button", 14676 "embed", 14677 "form", 14678 "iframe", 14679 "link", 14680 "math", 14681 "meta", 14682 "object", 14683 "option", 14684 "script", 14685 "select", 14686 "style", 14687 "svg", 14688 "textarea" 14689]; 14690const HTML_LIKE_PATTERN = /<\/?[a-z][\s\S]*>/i; 14691function escapeAttribute(value) { 14692 return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">"); 14693} 14694function sanitizeRichTextHtml(value) { 14695 if (typeof value !== "string" || value.length === 0) return ""; 14696 return (0, __TURBOPACK__imported__module__544821__["default"])(value, { 14697 allowedTags: [ 14698 ...RICH_TEXT_ALLOWED_TAGS 14699 ], 14700 allowedAttributes: { 14701 a: [ 14702 "href", 14703 "title" 14704 ], 14705 img: [ 14706 "src", 14707 "alt", 14708 "width", 14709 "height" 14710 ], 14711 table: [ 14712 "style" 14713 ], 14714 tr: [], 14715 td: [ 14716 "colspan", 14717 "rowspan", 14718 "style" 14719 ], 14720 th: [ 14721 "colspan", 14722 "rowspan", 14723 "style" 14724 ], 14725 input: [ 14726 "type", 14727 "checked", 14728 "disabled" 14729 ], 14730 label: [], 14731 span: [ 14732 "style" 14733 ], 14734 p: [ 14735 "style" 14736 ], 14737 div: [ 14738 "style" 14739 ], 14740 ul: [ 14741 "data-task-list", 14742 "style" 14743 ], 14744 ol: [ 14745 "style" 14746 ], 14747 li: [ 14748 "style" 14749 ], 14750 h1: [ 14751 "style" 14752 ], 14753 h2: [ 14754 "style" 14755 ], 14756 h3: [ 14757 "style" 14758 ], 14759 h4: [ 14760 "style" 14761 ], 14762 h5: [ 14763 "style" 14764 ], 14765 h6: [ 14766 "style" 14767 ] 14768 }, 14769 allowedSchemes: [ 14770 "http", 14771 "https", 14772 "mailto", 14773 "tel" 14774 ], 14775 allowedSchemesAppliedToAttributes: [ 14776 "href", 14777 "src" 14778 ], 14779 allowProtocolRelative: false, 14780 nonTextTags: [ 14781 ...RICH_TEXT_DROP_WITH_CONTENT_TAGS 14782 ], 14783 allowedStyles: { 14784 "*": { 14785 "color": [ 14786 /^#(?:[0-9a-f]{3}){1,2}$/i, 14787 /^rgb\([\d,\s]+\)$/i, 14788 /^rgba\([\d.,\s]+\)$/i 14789 ], 14790 "background-color": [ 14791 /^#(?:[0-9a-f]{3}){1,2}$/i, 14792 /^rgb\([\d,\s]+\)$/i, 14793 /^rgba\([\d.,\s]+\)$/i 14794 ], 14795 "font-size": [ 14796 /^\d+(?:\.\d+)?(?:px|em|rem|%)$/ 14797 ], 14798 "font-weight": [ 14799 /^(?:normal|bold|\d{3})$/ 14800 ], 14801 "font-style": [ 14802 /^(?:normal|italic|oblique)$/ 14803 ], 14804 "text-align": [ 14805 /^(?:left|right|center|justify)$/ 14806 ], 14807 "text-decoration": [ 14808 /^(?:none|underline|line-through)$/ 14809 ], 14810 "width": [ 14811 /^\d+(?:\.\d+)?(?:px|em|rem|%)$/ 14812 ], 14813 "height": [ 14814 /^\d+(?:\.\d+)?(?:px|em|rem|%)$/ 14815 ], 14816 "border": [ 14817 /^[\w\-:#.,\s()]+$/ 14818 ], 14819 "border-collapse": [ 14820 /^(?:collapse|separate)$/ 14821 ], 14822 "padding": [ 14823 /^[\d.\spxemr%]+$/ 14824 ], 14825 "list-style": [ 14826 /^(?:none|disc|circle|square|decimal)$/ 14827 ], 14828 "padding-left": [ 14829 /^\d+(?:\.\d+)?(?:px|em|rem|%)?$/ 14830 ] 14831 } 14832 }, 14833 transformTags: { 14834 // Restrict <input> to checkbox toggles only â strip any other `type` so 14835 // text/file/etc. inputs don't slip through the rich text channel. 14836 "input": (tagName, attribs)=>{ 14837 if (attribs.type === "checkbox") { 14838 return { 14839 tagName: "input", 14840 attribs 14841 }; 14842 } 14843 return { 14844 tagName: "", 14845 attribs: {}, 14846 text: "" 14847 }; 14848 } 14849 } 14850 }); 14851} 14852function sanitizeRichTextHref(value) { 14853 if (typeof value !== "string") return null; 14854 const trimmed = value.trim(); 14855 if (!trimmed) return null; 14856 const html = sanitizeRichTextHtml(`<a href="${escapeAttribute(trimmed)}">x</a>`); 14857 const match = /\shref="([^"]+)"/.exec(html); 14858 return match ? trimmed : null; 14859} 14860function sanitizeRichTextPasteContent(html, text) { 14861 if (html) { 14862 return { 14863 command: "insertHTML", 14864 value: sanitizeRichTextHtml(html) 14865 }; 14866 } 14867 if (!text) return null; 14868 if (HTML_LIKE_PATTERN.test(text)) { 14869 return { 14870 command: "insertHTML", 14871 value: sanitizeRichTextHtml(text) 14872 }; 14873 } 14874 return { 14875 command: "insertText", 14876 value: text 14877 }; 14878} 14879; 14880var __TURBOPACK__imported__module__388528__ = __turbopack_context__.i(388528); 14881var __TURBOPACK__imported__module__220339__ = __turbopack_context__.i(220339); 14882var __TURBOPACK__imported__module__644149__2 = __TURBOPACK__imported__module__644149__; 14883var __TURBOPACK__imported__module__987030__3 = __TURBOPACK__imported__module__987030__; 14884var __TURBOPACK__imported__module__110035__4 = __TURBOPACK__imported__module__110035__; 14885"use client"; 14886; 14887; 14888; 14889; 14890; 14891; 14892; 14893; 14894; 14895; 14896; 14897const RICH_EDITOR_COLOR_PALETTE = { 14898 gray: "#7b7b7b", 14899 black: "#171717", 14900 white: "#ffffff", 14901 blue: "#6366f1", 14902 orange: "#f59e0b", 14903 red: "#ef4444", 14904 green: "#22c55e", 14905 yellow: "#f6b51e", 14906 purple: "#7d52f4", 14907 sky: "#47c2ff", 14908 pink: "#fb4ba3", 14909 teal: "#22d3bb" 14910}; 14911const COLOR_KEYS = [ 14912 "gray", 14913 "black", 14914 "white", 14915 "blue", 14916 "orange", 14917 "red", 14918 "green", 14919 "yellow", 14920 "purple", 14921 "sky", 14922 "pink", 14923 "teal" 14924]; 14925const COLOR_LABELS_EN = { 14926 gray: "Gray", 14927 black: "Black", 14928 white: "White", 14929 blue: "Blue", 14930 orange: "Orange", 14931 red: "Red", 14932 green: "Green", 14933 yellow: "Yellow", 14934 purple: "Purple", 14935 sky: "Sky", 14936 pink: "Pink", 14937 teal: "Teal" 14938}; 14939const ALIGN_ICONS = { 14940 left: __TURBOPACK__imported__module__634558__["default"], 14941 center: __TURBOPACK__imported__module__393392__["default"], 14942 right: __TURBOPACK__imported__module__57522__["default"],
14943 justify: __TURBOPACK__imported__module__778835__["default"] 14944}; 14945const FONT_SIZE_OPTIONS = [ 14946 "12px", 14947 "14px", 14948 "16px", 14949 "18px", 14950 "20px", 14951 "24px" 14952]; 14953const EMPTY_SELECTION_STATE = { 14954 bold: false, 14955 italic: false, 14956 underline: false, 14957 strikethrough: false, 14958 unorderedList: false, 14959 orderedList: false, 14960 blockquote: false, 14961 code: false, 14962 heading: "", 14963 align: "left" 14964}; 14965const RichEditorContext = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["createContext"](null); 14966function useRichEditorContext(component) { 14967 const ctx = __TURBOPACK__imported__module__271645__10["useContext"](RichEditorContext); 14968 if (!ctx) { 14969 throw new Error(`${component} must be rendered inside <RichEditor>`); 14970 } 14971 return ctx; 14972} 14973const DEFAULT_LABELS = { 14974 bold: "Bold", 14975 italic: "Italic", 14976 underline: "Underline", 14977 strikethrough: "Strikethrough", 14978 unorderedList: "Bullet list", 14979 orderedList: "Numbered list", 14980 checklist: "Checklist", 14981 blockquote: "Quote", 14982 code: "Code", 14983 inlineCode: "Inline code", 14984 codeBlock: "Code block", 14985 horizontalRule: "Horizontal rule", 14986 image: "Image", 14987 imageUrlPrompt: "Enter image URL", 14988 table: "Table", 14989 heading: "Header", 14990 heading1: "Heading 1", 14991 heading2: "Heading 2", 14992 heading3: "Heading 3", 14993 paragraph: "Paragraph", 14994 link: "Link", 14995 linkUrlPrompt: "Enter URL", 14996 color: "Text color", 14997 textColor: "Color", 14998 fontSize: "Font size", 14999 align: "Align", 15000 alignLeft: "Align left", 15001 alignCenter: "Align center", 15002 alignRight: "Align right", 15003 alignJustify: "Justify", 15004 comment: "Add comment", 15005 mention: "Mention", 15006 more: "More", 15007 help: "Help", 15008 fullscreen: "Toggle fullscreen", 15009 placeholder: "Placeholder text...", 15010 colors: COLOR_LABELS_EN 15011}; 15012function deriveSelectionState() { 15013 if (typeof document === "undefined" || !document.queryCommandState) { 15014 return EMPTY_SELECTION_STATE; 15015 } 15016 try { 15017 const block = document.queryCommandValue?.("formatBlock") ?? ""; 15018 const lower = String(block).toLowerCase().replace(/[<>]/g, ""); 15019 const heading = lower === "h1" || lower === "h2" || lower === "h3" ? lower : ""; 15020 const align = document.queryCommandState("justifyCenter") ? "center" : document.queryCommandState("justifyRight") ? "right" : document.queryCommandState("justifyFull") ? "justify" : "left"; 15021 return { 15022 bold: document.queryCommandState("bold"), 15023 italic: document.queryCommandState("italic"), 15024 underline: document.queryCommandState("underline"), 15025 strikethrough: document.queryCommandState("strikeThrough"), 15026 unorderedList: document.queryCommandState("insertUnorderedList"), 15027 orderedList: document.queryCommandState("insertOrderedList"), 15028 blockquote: lower === "blockquote", 15029 code: lower === "pre", 15030 heading, 15031 align 15032 }; 15033 } catch { 15034 return EMPTY_SELECTION_STATE; 15035 } 15036} 15037const RichEditor = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["memo"](function RichEditor2({ value = "", onChange, variant = "standard", placeholder, minRows = 4, disabled = false, className, contentClassName, labels: labelsProp, onComment, onMention, moreMenu, onFullscreen, onImageInsert, maxLength, children, id, name, "aria-invalid": ariaInvalid }) { 15038 const labels = __TURBOPACK__imported__module__271645__10["useMemo"](()=>({ 15039 ...DEFAULT_LABELS, 15040 ...labelsProp ?? {}, 15041 colors: { 15042 ...DEFAULT_LABELS.colors, 15043 ...labelsProp?.colors ?? {} 15044 } 15045 }), [ 15046 labelsProp 15047 ]); 15048 const editorRef = __TURBOPACK__imported__module__271645__10["useRef"](null); 15049 const applyingExternal = __TURBOPACK__imported__module__271645__10["useRef"](false); 15050 const typingRef = __TURBOPACK__imported__module__271645__10["useRef"](false); 15051 const savedSelectionRef = __TURBOPACK__imported__module__271645__10["useRef"](null); 15052 const [selection, setSelection] = __TURBOPACK__imported__module__271645__10["useState"](EMPTY_SELECTION_STATE);
15053 const [promptDialog, setPromptDialog] = __TURBOPACK__imported__module__271645__10["useState"](null); 15054 __TURBOPACK__imported__module__271645__10["useEffect"](()=>{ 15055 const el = editorRef.current; 15056 if (!el) return; 15057 const sanitizedValue = sanitizeRichTextHtml(value); 15058 if (!typingRef.current && el.innerHTML !== sanitizedValue) { 15059 applyingExternal.current = true; 15060 el.innerHTML = sanitizedValue; 15061 requestAnimationFrame(()=>{ 15062 applyingExternal.current = false; 15063 }); 15064 } 15065 }, [ 15066 value 15067 ]); 15068 const refreshSelectionState = __TURBOPACK__imported__module__271645__10["useCallback"](()=>{ 15069 setSelection(deriveSelectionState()); 15070 }, []); 15071 const exec = __TURBOPACK__imported__module__271645__10["useCallback"]((command, arg)=>{ 15072 const el = editorRef.current; 15073 if (!el || disabled) return; 15074 el.focus(); 15075 try { 15076 document.execCommand("styleWithCSS", false, "true"); 15077 } catch {} 15078 try { 15079 document.execCommand(command, false, arg); 15080 } catch {} 15081 refreshSelectionState(); 15082 }, [ 15083 disabled, 15084 refreshSelectionState 15085 ]); 15086 const requestUrlPrompt = __TURBOPACK__imported__module__271645__10["useCallback"]((request)=>{ 15087 if ("TURBOPACK compile-time truthy", 1) { 15088 const sel = window.getSelection(); 15089 if (sel && sel.rangeCount > 0 && editorRef.current?.contains(sel.anchorNode)) { 15090 savedSelectionRef.current = sel.getRangeAt(0).cloneRange(); 15091 } else { 15092 savedSelectionRef.current = null; 15093 } 15094 } 15095 setPromptDialog({ 15096 ...request, 15097 value: "" 15098 }); 15099 }, []); 15100 const ctx = __TURBOPACK__imported__module__271645__10["useMemo"](()=>({ 15101 exec, 15102 selection, 15103 disabled, 15104 requestUrlPrompt 15105 }), [ 15106 exec, 15107 selection, 15108 disabled, 15109 requestUrlPrompt 15110 ]); 15111 __TURBOPACK__imported__module__271645__10["useEffect"](()=>{ 15112 if (typeof document === "undefined") return; 15113 const onSelectionChange = ()=>{ 15114 if (!editorRef.current) return; 15115 const sel = window.getSelection(); 15116 if (!sel || !sel.anchorNode) return; 15117 if (!editorRef.current.contains(sel.anchorNode)) return; 15118 refreshSelectionState(); 15119 }; 15120 document.addEventListener("selectionchange", onSelectionChange); 15121 return ()=>{ 15122 document.removeEventListener("selectionchange", onSelectionChange); 15123 }; 15124 }, [ 15125 refreshSelectionState 15126 ]); 15127 const onKeyDown = __TURBOPACK__imported__module__271645__10["useCallback"]((e)=>{ 15128 const isMod = e.metaKey || e.ctrlKey; 15129 if (!isMod) return; 15130 const k = e.key.toLowerCase(); 15131 if (k === "b") { 15132 e.preventDefault(); 15133 exec("bold"); 15134 } else if (k === "i") { 15135 e.preventDefault(); 15136 exec("italic"); 15137 } else if (k === "u") { 15138 e.preventDefault(); 15139 exec("underline"); 15140 } 15141 }, [ 15142 exec 15143 ]); 15144 const onPaste = __TURBOPACK__imported__module__271645__10["useCallback"]((e)=>{ 15145 const html = e.clipboardData.getData("text/html"); 15146 const text = e.clipboardData.getData("text/plain"); 15147 const sanitizedPaste = sanitizeRichTextPasteContent(html, text); 15148 if (!sanitizedPaste) return; 15149 e.preventDefault(); 15150 exec(sanitizedPaste.command, sanitizedPaste.value); 15151 }, [ 15152 exec 15153 ]); 15154 const onBlur = __TURBOPACK__imported__module__271645__10["useCallback"](()=>{ 15155 const el = editorRef.current; 15156 if (!el) return; 15157 typingRef.current = false; 15158 const sanitized = sanitizeRichTextHtml(el.innerHTML); 15159 if (el.innerHTML !== sanitized) { 15160 applyingExternal.current = true; 15161 el.innerHTML = sanitized; 15162 requestAnimationFrame(()=>{ 15163 applyingExternal.current = false; 15164 }); 15165 } 15166 onChange(sanitized); 15167 }, [ 15168 onChange 15169 ]); 15170 const presetItems = usePresetToolbarItems({ 15171 variant, 15172 labels, 15173 onComment, 15174 onMention, 15175 onFullscreen, 15176 onImageInsert, 15177 exec, 15178 selection, 15179 requestUrlPrompt 15180 }); 15181 const plaintextLength = __TURBOPACK__imported__module__271645__10["useMemo"](()=>{ 15182 if (!maxLength) return 0; 15183 if (typeof document === "undefined") return 0; 15184 const tmp = document.createElement("div"); 15185 tmp.innerHTML = sanitizeRichTextHtml(value); 15186 return (tmp.textContent ?? "").length; 15187 }, [ 15188 value, 15189 maxLength 15190 ]); 15191 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorContext.Provider, { 15192 value: ctx, 15193 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__220339__["TooltipProvider"], { 15194 delayDuration: 400, 15195 children: [
15196 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 15197 className: (0, __TURBOPACK__imported__module__406911__4["cn"])("w-full space-y-2", disabled && "opacity-60", className), 15198 "data-slot": "rich-editor", 15199 "data-disabled": disabled ? "true" : "false", 15200 "aria-invalid": ariaInvalid, 15201 children: variant === "custom" ? children : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__843476__7["Fragment"], { 15202 children: [ 15203 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorAutoToolbar, { 15204 items: presetItems, 15205 labels, 15206 moreMenu 15207 }), 15208 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 15209 className: "relative", 15210 children: [
15211 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorContent, { 15212 ref: editorRef, 15213 placeholder: placeholder ?? labels.placeholder, 15214 minRows, 15215 disabled, 15216 className: contentClassName, 15217 onKeyDown, 15218 onPaste, 15219 onBlur, 15220 onInput: ()=>{ 15221 if (!applyingExternal.current) typingRef.current = true; 15222 }, 15223 id, 15224 name 15225 }), 15226 maxLength ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("span", { 15227 className: (0, __TURBOPACK__imported__module__406911__4["cn"])("pointer-events-none absolute bottom-2 right-3 select-none text-xs leading-4 text-muted-foreground", plaintextLength > maxLength && "text-destructive"), 15228 "data-slot": "rich-editor-counter", 15229 "aria-live": "polite", 15230 children: [ 15231 plaintextLength, 15232 "/", 15233 maxLength 15234 ] 15235 }) : null 15236 ] 15237 }) 15238 ] 15239 }) 15240 }),
15241 promptDialog !== null ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__644149__2["Dialog"], { 15242 open: true, 15243 onOpenChange: (open)=>{ 15244 if (!open) setPromptDialog(null); 15245 }, 15246 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__644149__2["DialogContent"], { 15247 className: "sm:max-w-md", 15248 onKeyDown: (e)=>{ 15249 if (e.key === "Enter" && promptDialog) { 15250 e.preventDefault(); 15251 const url = sanitizeRichTextHref(promptDialog.value); 15252 const onConfirm = promptDialog.onConfirm; 15253 setPromptDialog(null); 15254 if (!url) return; 15255 const el = editorRef.current; 15256 const range = savedSelectionRef.current; 15257 if (el) { 15258 el.focus(); 15259 if (range) { 15260 const sel = window.getSelection(); 15261 sel?.removeAllRanges(); 15262 sel?.addRange(range); 15263 } 15264 } 15265 onConfirm(url); 15266 } 15267 }, 15268 children: [
15269 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__644149__2["DialogHeader"], { 15270 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__644149__2["DialogTitle"], { 15271 children: promptDialog?.title ?? "" 15272 }) 15273 }), 15274 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__987030__3["Input"], { 15275 autoFocus: true, 15276 type: "url", 15277 value: promptDialog?.value ?? "", 15278 placeholder: promptDialog?.placeholder ?? "https://\u2026", 15279 onChange: (e)=>{ 15280 const next = e.target.value; 15281 setPromptDialog((prev)=>prev ? { 15282 ...prev, 15283 value: next 15284 } : prev); 15285 } 15286 }),
15287 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__644149__2["DialogFooter"], { 15288 children: [ 15289 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__110035__4["Button"], { 15290 type: "button", 15291 variant: "outline", 15292 onClick: ()=>setPromptDialog(null), 15293 children: "Cancel" 15294 }), 15295 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__110035__4["Button"], { 15296 type: "button", 15297 onClick: ()=>{ 15298 if (!promptDialog) return; 15299 const url = sanitizeRichTextHref(promptDialog.value); 15300 const onConfirm = promptDialog.onConfirm; 15301 setPromptDialog(null); 15302 if (!url) return; 15303 const el = editorRef.current; 15304 const range = savedSelectionRef.current; 15305 if (el) { 15306 el.focus(); 15307 if (range) { 15308 const sel = window.getSelection(); 15309 sel?.removeAllRanges(); 15310 sel?.addRange(range); 15311 } 15312 } 15313 onConfirm(url); 15314 }, 15315 children: "OK" 15316 }) 15317 ] 15318 }) 15319 ] 15320 }) 15321 }) : null 15322 ] 15323 }) 15324 }); 15325}, (prev, next)=>prev.value === next.value && prev.disabled === next.disabled && prev.variant === next.variant && prev.maxLength === next.maxLength); 15326RichEditor.displayName = "RichEditor"; 15327const RichEditorToolbar = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["forwardRef"](({ className, children, ...props }, ref)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 15328 ref, 15329 role: "toolbar", 15330 "aria-label": "Rich text formatting", 15331 className: (0, __TURBOPACK__imported__module__406911__4["cn"])(// Figma 166331:4006 reference: standalone card with rounded-8 + border + shadow-xs. 15332 // 2px outer padding, 2px gap between items. 15333 "flex w-fit max-w-full flex-wrap items-center gap-0.5 overflow-x-auto rounded-lg border border-border bg-card p-0.5 shadow-xs", className), 15334 "data-slot": "rich-editor-toolbar", 15335 ...props, 15336 children 15337 })); 15338RichEditorToolbar.displayName = "RichEditorToolbar"; 15339const richEditorItemVariants = (0, __TURBOPACK__imported__module__225913__["cva"])(// Figma Rich Editor Items (166251 family): 28Ãh, rounded-6, bg-white default, 15340// bg-weak-50 (= bg-muted token) on hover, on toggle-active (data-active=true, 15341// e.g. Bold inside a bold selection), and on dropdown-open 15342// (data-state=open from Radix PopoverTrigger). Text / icon colours move from 15343// sub-600 (= text-muted-foreground, #5c5c5c) in the default state to 15344// strong-950 (= text-foreground, #171717) in the active / open states per 15345// Figma 166261:22214 / 166261:22217 reference cells. 15346"group/rich-editor-item inline-flex h-7 shrink-0 items-center justify-center rounded-md bg-transparent text-sm font-medium leading-5 text-muted-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-40 data-[active=true]:bg-muted data-[active=true]:text-foreground data-[state=open]:bg-muted data-[state=open]:text-foreground", { 15347 variants: { 15348 type: { 15349 // Figma 166251:2698 â pl-[10px] pr-[4px] py-[4px], gap-[2px]. 15350 text: "min-w-0 gap-0.5 pl-2.5 pr-1 py-1 tracking-[-0.084px] [&_svg]:size-4", 15351 // Figma 166251:2700 â square icon button p-[4px]. 15352 icon: "aspect-square p-1 [&_svg]:size-4", 15353 // Figma 166251:3337 â icon + caret p-[4px] gap-[2px]. 15354 dropdown: "gap-0.5 p-1 [&_svg]:size-4", 15355 // Figma 166331:4437 â color swatch + caret pl-[8px] pr-[4px] py-[4px]. 15356 color: "gap-0.5 pl-2 pr-1 py-1 [&_svg]:size-4" 15357 } 15358 }, 15359 defaultVariants: { 15360 type: "icon" 15361 } 15362}); 15363const RichEditorButton = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["forwardRef"](({ className, type, active, tooltipLabel, children, onMouseDown, ...props }, ref)=>{ 15364 const button = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("button", { 15365 ref, 15366 type: "button", 15367 onMouseDown: (e)=>{ 15368 e.preventDefault(); 15369 onMouseDown?.(e); 15370 }, 15371 "data-active": active ? "true" : "false", 15372 "aria-pressed": active, 15373 className: (0, __TURBOPACK__imported__module__406911__4["cn"])(richEditorItemVariants({ 15374 type 15375 }), className), 15376 ...props, 15377 children 15378 }); 15379 if (!tooltipLabel) return button; 15380 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__220339__["Tooltip"], { 15381 children: [
15382 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__220339__["TooltipTrigger"], { 15383 asChild: true, 15384 children: button 15385 }), 15386 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__220339__["TooltipContent"], { 15387 side: "top", 15388 sideOffset: 6, 15389 children: tooltipLabel 15390 }) 15391 ] 15392 }); 15393}); 15394RichEditorButton.displayName = "RichEditorButton"; 15395const RichEditorIconButton = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["forwardRef"](({ icon, ariaLabel, command, commandArg, onActivate, active, onClick, ...props }, ref)=>{ 15396 const { exec, disabled } = useRichEditorContext("RichEditorIconButton"); 15397 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorButton, { 15398 ref, 15399 type: "icon", 15400 active, 15401 "aria-label": ariaLabel, 15402 disabled: disabled || props.disabled, 15403 onClick: (e)=>{ 15404 if (command) exec(command, commandArg); 15405 onActivate?.(); 15406 onClick?.(e); 15407 }, 15408 ...props, 15409 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15410 "data-slot": "rich-editor-item-icon", 15411 "aria-hidden": "true", 15412 children: icon 15413 }) 15414 }); 15415}); 15416RichEditorIconButton.displayName = "RichEditorIconButton"; 15417const RichEditorTextDropdown = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["forwardRef"](({ label, ariaLabel, menu, onActivate, ...props }, ref)=>{ 15418 const { disabled } = useRichEditorContext("RichEditorTextDropdown"); 15419 const button = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(RichEditorButton, { 15420 ref, 15421 type: "text", 15422 "aria-label": ariaLabel, 15423 disabled: disabled || props.disabled, 15424 onClick: onActivate, 15425 ...props, 15426 children: [
15427 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15428 className: "truncate", 15429 children: label 15430 }), 15431 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__664659__1["ChevronDown"], { 15432 className: "opacity-60 transition-transform group-data-[state=open]/rich-editor-item:rotate-180", 15433 "aria-hidden": "true" 15434 }) 15435 ] 15436 }); 15437 if (!menu) return button; 15438 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__388528__["Popover"], { 15439 children: [ 15440 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__388528__["PopoverTrigger"], { 15441 asChild: true, 15442 children: button 15443 }), 15444 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__388528__["PopoverContent"], { 15445 align: "start", 15446 sideOffset: 6, 15447 className: "w-44 p-1", 15448 children: menu 15449 }) 15450 ] 15451 }); 15452}); 15453RichEditorTextDropdown.displayName = "RichEditorTextDropdown"; 15454const RichEditorDropdownButton = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["forwardRef"](({ icon, ariaLabel, menu, showChevron, ...props }, ref)=>{ 15455 const { disabled } = useRichEditorContext("RichEditorDropdownButton"); 15456 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__388528__["Popover"], { 15457 children: [
15458 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__388528__["PopoverTrigger"], { 15459 asChild: true, 15460 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(RichEditorButton, { 15461 ref, 15462 type: "dropdown", 15463 "aria-label": ariaLabel, 15464 disabled: disabled || props.disabled, 15465 ...props, 15466 children: [ 15467 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15468 "data-slot": "rich-editor-item-icon", 15469 "aria-hidden": "true", 15470 children: icon 15471 }), 15472 showChevron === false ? null : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__664659__1["ChevronDown"], { 15473 className: "opacity-60 transition-transform group-data-[state=open]/rich-editor-item:rotate-180", 15474 "aria-hidden": "true" 15475 }) 15476 ] 15477 }) 15478 }),
15479 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__388528__["PopoverContent"], { 15480 align: "start", 15481 sideOffset: 6, 15482 className: "w-44 p-1", 15483 children: menu 15484 }) 15485 ] 15486 }); 15487}); 15488RichEditorDropdownButton.displayName = "RichEditorDropdownButton"; 15489const RichEditorColorButton = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["forwardRef"](({ colorValue, ariaLabel, command = "foreColor", onSelect, colorLabels, palette = COLOR_KEYS, ...props }, ref)=>{ 15490 const { exec, disabled } = useRichEditorContext("RichEditorColorButton"); 15491 const [lastSelected, setLastSelected] = __TURBOPACK__imported__module__271645__10["useState"](null); 15492 const effectiveValue = colorValue ?? lastSelected; 15493 const swatchColor = effectiveValue ? RICH_EDITOR_COLOR_PALETTE[effectiveValue] : RICH_EDITOR_COLOR_PALETTE.blue; 15494 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__388528__["Popover"], { 15495 children: [
15496 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__388528__["PopoverTrigger"], { 15497 asChild: true, 15498 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(RichEditorButton, { 15499 ref, 15500 type: "color", 15501 "aria-label": ariaLabel, 15502 disabled: disabled || props.disabled, 15503 ...props, 15504 children: [ 15505 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15506 className: "inline-block size-4 shrink-0 rounded-full border border-black/10", 15507 style: { 15508 backgroundColor: swatchColor 15509 }, 15510 "data-slot": "rich-editor-color-swatch", 15511 "aria-hidden": "true" 15512 }), 15513 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__664659__1["ChevronDown"], { 15514 className: "opacity-60 transition-transform group-data-[state=open]/rich-editor-item:rotate-180", 15515 "aria-hidden": "true" 15516 }) 15517 ] 15518 }) 15519 }),
15520 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__388528__["PopoverContent"], { 15521 align: "start", 15522 sideOffset: 6, 15523 className: "w-36 p-1", 15524 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorColorPalette, { 15525 value: effectiveValue, 15526 labels: colorLabels, 15527 palette, 15528 onChange: (key)=>{ 15529 if (key) exec(command, RICH_EDITOR_COLOR_PALETTE[key]); 15530 setLastSelected(key); 15531 onSelect?.(key); 15532 } 15533 }) 15534 }) 15535 ] 15536 }); 15537}); 15538RichEditorColorButton.displayName = "RichEditorColorButton"; 15539function RichEditorColorPalette({ value, onChange, labels, palette, className }) { 15540 const resolvedLabels = { 15541 ...COLOR_LABELS_EN, 15542 ...labels ?? {} 15543 }; 15544 const keys = palette && palette.length > 0 ? palette : COLOR_KEYS; 15545 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 15546 className: (0, __TURBOPACK__imported__module__406911__4["cn"])("flex flex-col gap-0.5", className), 15547 "data-slot": "rich-editor-color-palette", 15548 role: "listbox", 15549 "aria-label": "Color palette", 15550 children: keys.map((key)=>{ 15551 const isActive = value === key; 15552 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("button", { 15553 type: "button", 15554 role: "option", 15555 "aria-selected": isActive, 15556 "aria-label": resolvedLabels[key], 15557 onMouseDown: (e)=>e.preventDefault(), 15558 onClick: ()=>onChange?.(key), 15559 className: (0, __TURBOPACK__imported__module__406911__4["cn"])("flex items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/40", isActive && "font-medium text-foreground"), 15560 "data-color-key": key, 15561 children: [
15562 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15563 className: "size-4 shrink-0 rounded-full border border-black/10", 15564 style: { 15565 backgroundColor: RICH_EDITOR_COLOR_PALETTE[key] 15566 }, 15567 "aria-hidden": "true" 15568 }), 15569 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15570 className: "truncate", 15571 children: resolvedLabels[key] 15572 }) 15573 ] 15574 }, key); 15575 }) 15576 }); 15577} 15578const RichEditorMenuItem = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["forwardRef"](({ className, icon, children, destructive, onMouseDown, ...props }, ref)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("button", { 15579 ref, 15580 type: "button", 15581 role: "menuitem", 15582 onMouseDown: (e)=>{ 15583 e.preventDefault(); 15584 onMouseDown?.(e); 15585 }, 15586 className: (0, __TURBOPACK__imported__module__406911__4["cn"])("flex w-full cursor-pointer items-center gap-2 rounded px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50", destructive && "text-destructive hover:bg-destructive/10", className), 15587 "data-slot": "rich-editor-menu-item", 15588 ...props, 15589 children: [ 15590 icon ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15591 className: "inline-flex size-4 shrink-0 items-center justify-center text-muted-foreground [&_svg]:size-4", 15592 "data-slot": "rich-editor-menu-item-icon", 15593 "aria-hidden": "true", 15594 children: icon 15595 }) : null,
15596 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15597 className: "min-w-0 flex-1 truncate", 15598 children 15599 }) 15600 ] 15601 })); 15602RichEditorMenuItem.displayName = "RichEditorMenuItem"; 15603function RichEditorDivider({ className }) { 15604 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15605 role: "separator", 15606 "aria-orientation": "vertical", 15607 className: (0, __TURBOPACK__imported__module__406911__4["cn"])("mx-px inline-block h-4 w-px shrink-0 bg-border", className), 15608 "data-slot": "rich-editor-divider" 15609 }); 15610} 15611const RichEditorContent = /*#__PURE__*/ __TURBOPACK__imported__module__271645__10["forwardRef"](({ className, placeholder, minRows = 4, disabled, onBlur, onInput, onKeyDown, onPaste, id, name, ...props }, ref)=>{ 15612 const minHeight = `${Math.max(1, minRows) * 1.5}rem`; 15613 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 15614 ref, 15615 contentEditable: !disabled, 15616 suppressContentEditableWarning: true, 15617 spellCheck: true, 15618 role: "textbox", 15619 "aria-multiline": "true", 15620 "data-slot": "rich-editor-content", 15621 "data-placeholder": placeholder ?? "", 15622 "data-name": name, 15623 id, 15624 className: (0, __TURBOPACK__imported__module__406911__4["cn"])(// Figma reference: content lives in its own bordered card with rounded-8 + shadow-xs, 15625 // visually separated from the toolbar by the small vertical gap from the parent 15626 // wrapper's `space-y-2`. 15627 "w-full max-w-none rounded-lg border border-border bg-card px-3 py-3 text-sm leading-6 text-foreground shadow-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40", // The project does not include `@tailwindcss/typography`, so we have to 15628 // re-implement the rich text rendering ourselves via descendant-arbitrary 15629 // selectors. Cover every tag the toolbar can produce so the user sees 15630 // the formatting instantly after each execCommand. 15631 "[&_h1]:mt-4 [&_h1]:mb-2 [&_h1]:text-2xl [&_h1]:font-bold", "[&_h2]:mt-3 [&_h2]:mb-2 [&_h2]:text-xl [&_h2]:font-semibold", "[&_h3]:mt-3 [&_h3]:mb-1 [&_h3]:text-lg [&_h3]:font-semibold", "[&_p]:my-1", "[&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-6", "[&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-6", "[&_li]:my-0.5", // Task list checklist override â when <ul data-task-list> we drop the 15632 // disc bullet so the <input type=checkbox> child stands alone. 15633 "[&_ul[data-task-list]]:list-none [&_ul[data-task-list]]:pl-0", "[&_ul[data-task-list]_input[type=checkbox]]:mr-2", "[&_blockquote]:my-2 [&_blockquote]:border-l-4 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:italic [&_blockquote]:text-muted-foreground", "[&_pre]:my-2 [&_pre]:rounded [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:font-mono [&_pre]:text-xs", "[&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:font-mono [&_code]:text-xs", "[&_a]:text-primary [&_a]:underline", "[&_hr]:my-3 [&_hr]:border-border", "[&_img]:my-2 [&_img]:h-auto [&_img]:max-w-full [&_img]:rounded", "[&_table]:my-2 [&_table]:border-collapse", "[&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1", "[&_th]:border [&_th]:border-border [&_th]:bg-muted [&_th]:px-2 [&_th]:py-1", "data-[placeholder]:before:pointer-events-none data-[placeholder]:empty:before:content-[attr(data-placeholder)] data-[placeholder]:empty:before:text-muted-foreground", className), 15634 style: { 15635 minHeight 15636 }, 15637 onBlur, 15638 onInput, 15639 onKeyDown, 15640 onPaste, 15641 ...props 15642 }); 15643}); 15644RichEditorContent.displayName = "RichEditorContent"; 15645function renderToolbarItem(item) { 15646 switch(item.kind){ 15647 case "divider": 15648 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorDivider, {}, item.key); 15649 case "iconButton": 15650 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorIconButton, { 15651 icon: item.icon, 15652 ariaLabel: item.ariaLabel, 15653 tooltipLabel: item.tooltipLabel, 15654 active: item.active, 15655 command: item.command, 15656 commandArg: item.commandArg, 15657 onActivate: item.onActivate 15658 }, item.key); 15659 case "textDropdown": 15660 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorTextDropdown, { 15661 ariaLabel: item.ariaLabel, 15662 label: item.label, 15663 menu: item.menu 15664 }, item.key); 15665 case "dropdownButton": 15666 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorDropdownButton, { 15667 icon: item.icon, 15668 ariaLabel: item.ariaLabel, 15669 menu: item.menu, 15670 showChevron: item.showChevron 15671 }, item.key); 15672 case "colorButton": 15673 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorColorButton, { 15674 ariaLabel: item.ariaLabel, 15675 colorLabels: item.colorLabels 15676 }, item.key); 15677 } 15678} 15679function trimTrailingDividers(items) { 15680 let end = items.length; 15681 while(end > 0 && items[end - 1].kind === "divider")end -= 1; 15682 return items.slice(0, end); 15683} 15684function trimLeadingDividers(items) { 15685 let start = 0; 15686 while(start < items.length && items[start].kind === "divider")start += 1; 15687 return items.slice(start); 15688} 15689function usePresetToolbarItems({ variant, labels, onComment, onMention, onFullscreen, onImageInsert, exec, selection, requestUrlPrompt }) { 15690 const onLink = __TURBOPACK__imported__module__271645__10["useCallback"](()=>{ 15691 requestUrlPrompt({ 15692 kind: "link", 15693 title: labels.linkUrlPrompt, 15694 placeholder: "https://example.com", 15695 onConfirm: (url)=>exec("createLink", url) 15696 }); 15697 }, [ 15698 requestUrlPrompt, 15699 exec, 15700 labels.linkUrlPrompt 15701 ]); 15702 const onImage = __TURBOPACK__imported__module__271645__10["useCallback"](()=>{ 15703 if (onImageInsert) { 15704 onImageInsert(); 15705 return; 15706 } 15707 requestUrlPrompt({ 15708 kind: "image", 15709 title: labels.imageUrlPrompt, 15710 placeholder: "https://example.com/image.png", 15711 onConfirm: (url)=>exec("insertImage", url) 15712 }); 15713 }, [ 15714 requestUrlPrompt, 15715 exec, 15716 labels.imageUrlPrompt, 15717 onImageInsert 15718 ]); 15719 const onInsertTable = __TURBOPACK__imported__module__271645__10["useCallback"](()=>{ 15720 const html = '<table style="border-collapse:collapse;width:100%"><tbody><tr><td style="border:1px solid #ebebeb;padding:8px"> </td><td style="border:1px solid #ebebeb;padding:8px"> </td><td style="border:1px solid #ebebeb;padding:8px"> </td></tr><tr><td style="border:1px solid #ebebeb;padding:8px"> </td><td style="border:1px solid #ebebeb;padding:8px"> </td><td style="border:1px solid #ebebeb;padding:8px"> </td></tr><tr><td style="border:1px solid #ebebeb;padding:8px"> </td><td style="border:1px solid #ebebeb;padding:8px"> </td><td style="border:1px solid #ebebeb;padding:8px"> </td></tr></tbody></table><p> </p>'; 15721 exec("insertHTML", html); 15722 }, [ 15723 exec 15724 ]); 15725 const onInsertChecklist = __TURBOPACK__imported__module__271645__10["useCallback"](()=>{ 15726 const html = '<ul data-task-list="true" style="list-style:none;padding-left:0"><li><label><input type="checkbox" /> </label></li></ul>'; 15727 exec("insertHTML", html); 15728 }, [ 15729 exec 15730 ]); 15731 const onInsertInlineCode = __TURBOPACK__imported__module__271645__10["useCallback"](()=>{ 15732 const selectionText = ("TURBOPACK compile-time truthy", 1) ? window.getSelection()?.toString() ?? "" : "TURBOPACK unreachable"; 15733 if (!selectionText) { 15734 exec("insertHTML", "<code> </code>"); 15735 return; 15736 } 15737 exec("insertHTML", `<code>${selectionText}</code>`); 15738 }, [ 15739 exec 15740 ]); 15741 const showHeading = variant === "full" || variant === "standard"; 15742 const showFontSize = variant === "full"; 15743 const showColor = variant === "full"; 15744 const showStrike = variant === "full"; 15745 const showHr = variant === "full"; 15746 const showQuoteAndCode = variant === "full"; 15747 const showImageTable = variant === "full"; 15748 const showChecklist = variant === "full"; 15749 const showOrdered = variant === "full" || variant === "standard" || variant === "basic"; 15750 const showAlign = variant === "full"; 15751 const showComment = variant === "full"; 15752 const commentHandler = onComment ?? (()=>exec("insertText", "[comment: ]")); 15753 const showMention = variant === "full"; 15754 const mentionHandler = onMention ?? (()=>exec("insertText", "@")); 15755 const showLink = variant === "full" || variant === "standard" || variant === "basic"; 15756 const showLists = variant !== "minimal"; 15757 const showHelp = variant === "full"; 15758 const showFullscreen = variant === "full" && onFullscreen !== void 0;
15759 const keyboardShortcutsHelp = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 15760 className: "flex w-64 flex-col gap-1 p-1 text-sm", 15761 role: "menu", 15762 children: [ 15763 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 15764 className: "px-2 py-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", 15765 children: "Keyboard" 15766 }), 15767 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 15768 className: "flex items-center justify-between rounded px-2 py-1 hover:bg-muted", 15769 children: [ 15770 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15771 children: labels.bold 15772 }), 15773 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("kbd", { 15774 className: "rounded border bg-card px-1.5 py-0.5 text-xs", 15775 children: "\u2318 B" 15776 }) 15777 ] 15778 }),
15779 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 15780 className: "flex items-center justify-between rounded px-2 py-1 hover:bg-muted", 15781 children: [ 15782 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15783 children: labels.italic 15784 }), 15785 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("kbd", { 15786 className: "rounded border bg-card px-1.5 py-0.5 text-xs", 15787 children: "\u2318 I" 15788 }) 15789 ] 15790 }), 15791 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 15792 className: "flex items-center justify-between rounded px-2 py-1 hover:bg-muted", 15793 children: [ 15794 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15795 children: labels.underline 15796 }),
15797 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("kbd", { 15798 className: "rounded border bg-card px-1.5 py-0.5 text-xs", 15799 children: "\u2318 U" 15800 }) 15801 ] 15802 }) 15803 ] 15804 }); 15805 const headingMenu = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 15806 className: "flex flex-col gap-0.5", 15807 role: "menu", 15808 children: [ 15809 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("button", { 15810 type: "button", 15811 role: "menuitem", 15812 className: "cursor-pointer rounded px-2 py-1 text-left text-sm hover:bg-muted", 15813 onMouseDown: (e)=>e.preventDefault(), 15814 onClick: ()=>exec("formatBlock", "<p>"), 15815 children: labels.paragraph 15816 }), 15817 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("button", { 15818 type: "button", 15819 role: "menuitem", 15820 className: "cursor-pointer rounded px-2 py-1 text-left text-lg font-semibold hover:bg-muted", 15821 onMouseDown: (e)=>e.preventDefault(), 15822 onClick: ()=>exec("formatBlock", "<h1>"), 15823 children: labels.heading1 15824 }),
15825 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("button", { 15826 type: "button", 15827 role: "menuitem", 15828 className: "cursor-pointer rounded px-2 py-1 text-left text-base font-semibold hover:bg-muted", 15829 onMouseDown: (e)=>e.preventDefault(), 15830 onClick: ()=>exec("formatBlock", "<h2>"), 15831 children: labels.heading2 15832 }), 15833 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("button", { 15834 type: "button", 15835 role: "menuitem", 15836 className: "cursor-pointer rounded px-2 py-1 text-left text-sm font-semibold hover:bg-muted", 15837 onMouseDown: (e)=>e.preventDefault(), 15838 onClick: ()=>exec("formatBlock", "<h3>"), 15839 children: labels.heading3 15840 }) 15841 ] 15842 }); 15843 const headingLabel = (()=>{ 15844 switch(selection.heading){ 15845 case "h1": 15846 return labels.heading1; 15847 case "h2": 15848 return labels.heading2; 15849 case "h3": 15850 return labels.heading3; 15851 default: 15852 return labels.heading; 15853 } 15854 })(); 15855 const fontSizeMenu = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 15856 className: "flex flex-col gap-0.5", 15857 role: "menu", 15858 children: FONT_SIZE_OPTIONS.map((size)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("button", { 15859 type: "button", 15860 role: "menuitem", 15861 className: "cursor-pointer rounded px-2 py-1 text-left text-sm hover:bg-muted", 15862 onMouseDown: (e)=>e.preventDefault(), 15863 onClick: ()=>{ 15864 exec("removeFormat"); 15865 const px = parseInt(size, 10); 15866 if (px > 0) { 15867 exec("insertHTML", `<span style="font-size:${px}px">${window.getSelection()?.toString() ?? ""}</span>`); 15868 } 15869 }, 15870 children: size 15871 }, size)) 15872 }); 15873 const alignMenu = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 15874 className: "flex flex-col gap-0.5", 15875 role: "menu", 15876 children: [ 15877 "left", 15878 "center", 15879 "right", 15880 "justify" 15881 ].map((option)=>{ 15882 const Icon = ALIGN_ICONS[option]; 15883 const command = option === "justify" ? "justifyFull" : `justify${option[0].toUpperCase()}${option.slice(1)}`; 15884 const label = option === "left" ? labels.alignLeft : option === "center" ? labels.alignCenter : option === "right" ? labels.alignRight : labels.alignJustify; 15885 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("button", { 15886 type: "button", 15887 role: "menuitem", 15888 className: "flex cursor-pointer items-center gap-2 rounded px-2 py-1 text-left text-sm hover:bg-muted", 15889 onMouseDown: (e)=>e.preventDefault(), 15890 onClick: ()=>exec(command), 15891 children: [
15892 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(Icon, { 15893 className: "size-4", 15894 "aria-hidden": "true" 15895 }), 15896 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("span", { 15897 children: label 15898 }) 15899 ] 15900 }, option); 15901 }) 15902 }); 15903 const AlignActiveIcon = ALIGN_ICONS[selection.align]; 15904 if (variant === "custom") return []; 15905 const items = []; 15906 if (showHeading) { 15907 items.push({ 15908 kind: "textDropdown", 15909 key: "heading", 15910 ariaLabel: labels.heading, 15911 label: headingLabel, 15912 menu: headingMenu 15913 }); 15914 items.push({ 15915 kind: "divider", 15916 key: "d-heading" 15917 }); 15918 } 15919 if (showFontSize) { 15920 items.push({ 15921 kind: "textDropdown", 15922 key: "fontSize", 15923 ariaLabel: labels.fontSize, 15924 label: "14px", 15925 menu: fontSizeMenu 15926 }); 15927 items.push({ 15928 kind: "divider", 15929 key: "d-fontSize" 15930 }); 15931 } 15932 if (showColor) { 15933 items.push({ 15934 kind: "colorButton", 15935 key: "color", 15936 ariaLabel: labels.color, 15937 colorLabels: labels.colors 15938 }); 15939 items.push({ 15940 kind: "divider", 15941 key: "d-color" 15942 }); 15943 } 15944 items.push({ 15945 kind: "iconButton", 15946 key: "bold", 15947 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__582894__["default"], {}), 15948 command: "bold", 15949 ariaLabel: labels.bold, 15950 tooltipLabel: labels.bold, 15951 active: selection.bold 15952 }); 15953 items.push({ 15954 kind: "iconButton", 15955 key: "italic", 15956 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__192986__["default"], {}), 15957 command: "italic", 15958 ariaLabel: labels.italic, 15959 tooltipLabel: labels.italic, 15960 active: selection.italic 15961 }); 15962 items.push({ 15963 kind: "iconButton", 15964 key: "underline", 15965 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__20623__["default"], {}), 15966 command: "underline", 15967 ariaLabel: labels.underline, 15968 tooltipLabel: labels.underline, 15969 active: selection.underline 15970 }); 15971 if (showStrike) { 15972 items.push({ 15973 kind: "iconButton", 15974 key: "strike", 15975 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__406940__["default"], {}), 15976 command: "strikeThrough", 15977 ariaLabel: labels.strikethrough, 15978 tooltipLabel: labels.strikethrough, 15979 active: selection.strikethrough 15980 }); 15981 } 15982 if (showLists) { 15983 items.push({ 15984 kind: "divider", 15985 key: "d-lists" 15986 }); 15987 items.push({ 15988 kind: "iconButton", 15989 key: "ul", 15990 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__370956__["List"], {}), 15991 command: "insertUnorderedList", 15992 ariaLabel: labels.unorderedList, 15993 tooltipLabel: labels.unorderedList, 15994 active: selection.unorderedList 15995 }); 15996 if (showOrdered) { 15997 items.push({ 15998 kind: "iconButton", 15999 key: "ol", 16000 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__57489__["default"], {}), 16001 command: "insertOrderedList", 16002 ariaLabel: labels.orderedList, 16003 tooltipLabel: labels.orderedList, 16004 active: selection.orderedList 16005 }); 16006 } 16007 } 16008 if (showHr || showQuoteAndCode) { 16009 items.push({ 16010 kind: "divider", 16011 key: "d-structure" 16012 }); 16013 if (showHr) { 16014 items.push({ 16015 kind: "iconButton", 16016 key: "hr", 16017 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__299023__["Minus"], {}), 16018 ariaLabel: labels.horizontalRule, 16019 tooltipLabel: labels.horizontalRule, 16020 onActivate: ()=>exec("insertHorizontalRule") 16021 }); 16022 } 16023 if (showQuoteAndCode) { 16024 items.push({ 16025 kind: "iconButton", 16026 key: "quote", 16027 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__947875__["default"], {}), 16028 ariaLabel: labels.blockquote, 16029 tooltipLabel: labels.blockquote, 16030 active: selection.blockquote, 16031 onActivate: ()=>exec("formatBlock", selection.blockquote ? "<p>" : "<blockquote>") 16032 }); 16033 items.push({ 16034 kind: "iconButton", 16035 key: "inlineCode", 16036 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__758472__["Code"], {}), 16037 ariaLabel: labels.inlineCode, 16038 tooltipLabel: labels.inlineCode, 16039 onActivate: onInsertInlineCode 16040 }); 16041 items.push({ 16042 kind: "iconButton", 16043 key: "codeBlock", 16044 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__741929__["FileCode"], {}), 16045 ariaLabel: labels.codeBlock, 16046 tooltipLabel: labels.codeBlock, 16047 active: selection.code, 16048 onActivate: ()=>exec("formatBlock", selection.code ? "<p>" : "<pre>") 16049 }); 16050 } 16051 } 16052 if (showImageTable) { 16053 items.push({ 16054 kind: "divider", 16055 key: "d-media" 16056 }); 16057 items.push({ 16058 kind: "iconButton", 16059 key: "image", 16060 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__473708__["Image"], {}), 16061 ariaLabel: labels.image, 16062 tooltipLabel: labels.image, 16063 onActivate: onImage 16064 }); 16065 items.push({ 16066 kind: "iconButton", 16067 key: "table", 16068 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__608719__["default"], {}), 16069 ariaLabel: labels.table, 16070 tooltipLabel: labels.table, 16071 onActivate: onInsertTable 16072 }); 16073 } 16074 if (showChecklist) { 16075 items.push({ 16076 kind: "iconButton", 16077 key: "checklist", 16078 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__63804__["ListChecks"], {}), 16079 ariaLabel: labels.checklist, 16080 tooltipLabel: labels.checklist, 16081 onActivate: onInsertChecklist 16082 }); 16083 } 16084 if (showAlign) { 16085 items.push({ 16086 kind: "divider", 16087 key: "d-align" 16088 }); 16089 items.push({ 16090 kind: "dropdownButton", 16091 key: "align", 16092 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(AlignActiveIcon, {}), 16093 ariaLabel: labels.align, 16094 menu: alignMenu 16095 }); 16096 } 16097 if (showLink || showComment || showMention) { 16098 items.push({ 16099 kind: "divider", 16100 key: "d-anchors" 16101 }); 16102 } 16103 if (showComment) { 16104 items.push({ 16105 kind: "iconButton", 16106 key: "comment", 16107 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__194983__["MessageCircle"], {}), 16108 ariaLabel: labels.comment, 16109 tooltipLabel: labels.comment, 16110 onActivate: commentHandler 16111 }); 16112 } 16113 if (showLink) { 16114 items.push({ 16115 kind: "iconButton", 16116 key: "link", 16117 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__221345__["Link"], {}), 16118 ariaLabel: labels.link, 16119 tooltipLabel: labels.link, 16120 onActivate: onLink 16121 }); 16122 } 16123 if (showMention) { 16124 items.push({ 16125 kind: "iconButton", 16126 key: "mention", 16127 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__257995__["AtSign"], {}), 16128 ariaLabel: labels.mention, 16129 tooltipLabel: labels.mention, 16130 onActivate: mentionHandler 16131 }); 16132 } 16133 if (showHelp || showFullscreen) { 16134 items.push({ 16135 kind: "divider", 16136 key: "d-trailing" 16137 }); 16138 if (showHelp) { 16139 items.push({ 16140 kind: "dropdownButton", 16141 key: "help", 16142 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__974875__["HelpCircle"], {}), 16143 ariaLabel: labels.help, 16144 menu: keyboardShortcutsHelp,
16145 showChevron: false 16146 }); 16147 } 16148 if (showFullscreen && onFullscreen) { 16149 items.push({ 16150 kind: "iconButton", 16151 key: "fullscreen", 16152 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__398361__["Maximize2"], {}), 16153 ariaLabel: labels.fullscreen, 16154 tooltipLabel: labels.fullscreen, 16155 onActivate: onFullscreen 16156 }); 16157 } 16158 } 16159 return trimTrailingDividers(items); 16160} 16161function RichEditorAutoToolbar({ items, labels, moreMenu }) { 16162 const measureRef = __TURBOPACK__imported__module__271645__10["useRef"](null); 16163 const containerRef = __TURBOPACK__imported__module__271645__10["useRef"](null); 16164 const [firstHidden, setFirstHidden] = __TURBOPACK__imported__module__271645__10["useState"](null); 16165 __TURBOPACK__imported__module__271645__10["useLayoutEffect"](()=>{ 16166 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 16167 ; 16168 if (typeof ResizeObserver === "undefined") return; 16169 const container = containerRef.current; 16170 const measureEl = measureRef.current; 16171 if (!container || !measureEl) return; 16172 const measure = ()=>{ 16173 const containerWidth = container.clientWidth; 16174 if (containerWidth === 0) return; 16175 const allEls = Array.from(measureEl.children); 16176 if (allEls.length === 0) return; 16177 const moreEl = allEls[allEls.length - 1]; 16178 const itemEls = allEls.slice(0, -1); 16179 const moreReserved = moreEl.offsetWidth + 4; 16180 const containerPadding = 4; 16181 let totalWidth = 0; 16182 for (const el of itemEls)totalWidth += el.offsetWidth + 2; 16183 if (totalWidth + containerPadding <= containerWidth + 2) { 16184 setFirstHidden(null); 16185 return; 16186 } 16187 let accumulated = 0; 16188 for(let i = 0; i < itemEls.length; i++){ 16189 accumulated += itemEls[i].offsetWidth + 2; 16190 if (accumulated > containerWidth - moreReserved - containerPadding) { 16191 setFirstHidden(i); 16192 return; 16193 } 16194 } 16195 setFirstHidden(null); 16196 }; 16197 measure(); 16198 const ro = new ResizeObserver(measure); 16199 ro.observe(container); 16200 return ()=>ro.disconnect(); 16201 }, [ 16202 items 16203 ]); 16204 const visibleItems = firstHidden === null ? items : trimTrailingDividers(items.slice(0, firstHidden)); 16205 const hiddenItems = firstHidden === null ? [] : trimLeadingDividers(items.slice(firstHidden)); 16206 const hasOverflow = hiddenItems.length > 0; 16207 const showMoreButton = hasOverflow || !!moreMenu; 16208 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 16209 className: "relative w-full", 16210 children: [
16211 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 16212 ref: measureRef, 16213 "aria-hidden": "true", 16214 className: "pointer-events-none invisible absolute left-0 top-0 flex flex-row flex-nowrap items-center gap-0.5", 16215 children: [ 16216 items.map(renderToolbarItem), 16217 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorDropdownButton, { 16218 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__323585__["MoreVertical"], {}), 16219 ariaLabel: labels.more, 16220 showChevron: false, 16221 menu: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", {}) 16222 }) 16223 ] 16224 }), 16225 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(RichEditorToolbar, { 16226 ref: containerRef, 16227 className: "w-full flex-nowrap overflow-hidden", 16228 children: [ 16229 visibleItems.map(renderToolbarItem), 16230 showMoreButton ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(RichEditorDropdownButton, { 16231 icon: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])(__TURBOPACK__imported__module__323585__["MoreVertical"], {}), 16232 ariaLabel: labels.more, 16233 showChevron: false, 16234 menu: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])("div", { 16235 className: "flex max-w-[320px] flex-row flex-wrap items-center gap-0.5 p-1", 16236 children: [ 16237 moreMenu ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsxs"])(__TURBOPACK__imported__module__843476__7["Fragment"], { 16238 children: [
16239 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 16240 className: "w-full", 16241 children: moreMenu 16242 }), 16243 hiddenItems.length > 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__7["jsx"])("div", { 16244 className: "my-1 h-px w-full bg-border" 16245 }) : null 16246 ] 16247 }) : null, 16248 hiddenItems.map(renderToolbarItem) 16249 ] 16250 }) 16251 }) : null 16252 ] 16253 }) 16254 ] 16255 }); 16256} 16257; 16258var __TURBOPACK__imported__module__167556__ = __turbopack_context__.i(167556); 16259"use client"; 16260; 16261; 16262; 16263; 16264; 16265; 16266; 16267; 16268; 16269; 16270; 16271; 16272; 16273; 16274; 16275; 16276; 16277; 16278; 16279; 16280; 16281; 16282; 16283; 16284; 16285; 16286; 16287; 16288; 16289; 16290; 16291; 16292; 16293; 16294; 16295; 16296; 16297; 16298; 16299; 16300; 16301; 16302; 16303; 16304; 16305; 16306; 16307; 16308; 16309; 16310; 16311; 16312; 16313const logger = (0, __TURBOPACK__imported__module__488166__["createLogger"])("ui").child({ 16314 component: "CrudForm" 16315}); 16316const EMPTY_OPTIONS = []; 16317const SELECT_CLEAR_SENTINEL = "__crudform_select_clear__"; 16318const FOCUSABLE_SELECTOR = '[data-crud-focus-target], input:not([type="hidden"]):not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'; 16319const CRUDFORM_EXTENDED_EVENTS_ENABLED = (0, __TURBOPACK__imported__module__170768__["parseBooleanWithDefault"])(__TURBOPACK__imported__module__247167__["default"].env.NEXT_PUBLIC_OM_CRUDFORM_EXTENDED_EVENTS_ENABLED, true); 16320function evaluateFieldVisibility(visibleWhen, values) { 16321 if (!visibleWhen) return true; 16322 return values[visibleWhen.field] === visibleWhen.equals; 16323} 16324function isFormControlTarget(target) { 16325 if (!target || typeof target.tagName !== "string") return false; 16326 const el = target; 16327 const tag = el.tagName; 16328 if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true; 16329 if (el.isContentEditable) return true; 16330 return false; 16331} 16332function resolveActivatorEventTarget(event) { 16333 const native = event.nativeEvent; 16334 if (native && typeof native.target !== "undefined") return native.target; 16335 return event.target ?? null; 16336} 16337class GuardedKeyboardSensor extends __TURBOPACK__imported__module__477183__["KeyboardSensor"] { 16338 static{ 16339 this.activators = __TURBOPACK__imported__module__477183__["KeyboardSensor"].activators.map((activator)=>({ 16340 eventName: activator.eventName, 16341 handler: (event, options, context)=>{ 16342 if (isFormControlTarget(resolveActivatorEventTarget(event))) return false; 16343 return activator.handler(event, options, context); 16344 } 16345 })); 16346 } 16347} 16348function resolveInternalNavigationTarget(target) { 16349 if (("TURBOPACK compile-time value", "object") === "undefined" || target == null) return null; 16350 try { 16351 const url = target instanceof URL ? target : new URL(target, window.location.origin); 16352 if (url.origin !== window.location.origin) return null; 16353 const currentPath = `${window.location.pathname}${window.location.search}`; 16354 const nextPath = `${url.pathname}${url.search}`; 16355 if (nextPath === currentPath) return null; 16356 return `${url.pathname}${url.search}${url.hash}`; 16357 } catch { 16358 return null; 16359 } 16360}
16361function buildResolvedEntityIdsKey(entityId, entityIds) { 16362 const dedup = /* @__PURE__ */ new Set(); 16363 const list = []; 16364 if (Array.isArray(entityIds) && entityIds.length) { 16365 entityIds.forEach((id)=>{ 16366 const trimmed = typeof id === "string" ? id.trim() : ""; 16367 if (!trimmed || dedup.has(trimmed)) return; 16368 dedup.add(trimmed); 16369 list.push(trimmed); 16370 }); 16371 } else if (typeof entityId === "string" && entityId.trim().length > 0) { 16372 list.push(entityId.trim()); 16373 } 16374 return list.join("\0"); 16375} 16376function readByDotPath(source, path) { 16377 if (!source || !path) return void 0; 16378 if (Object.prototype.hasOwnProperty.call(source, path)) return source[path]; 16379 const segments = path.split(".").filter(Boolean); 16380 let current = source; 16381 for (const segment of segments){ 16382 if (!current || typeof current !== "object" || Array.isArray(current)) return void 0; 16383 current = current[segment]; 16384 } 16385 return current; 16386} 16387const PROTO_POLLUTING_KEYS = /* @__PURE__ */ new Set([ 16388 "__proto__", 16389 "prototype", 16390 "constructor" 16391]); 16392function isProtoPollutingKey(key) { 16393 return PROTO_POLLUTING_KEYS.has(key); 16394} 16395function writeByDotPath(target, path, value) { 16396 const segments = path.split(".").filter(Boolean); 16397 if (segments.length === 0) return; 16398 if (segments.some(isProtoPollutingKey)) return; 16399 let current = target; 16400 for(let index = 0; index < segments.length - 1; index++){ 16401 const segment = segments[index]; 16402 const existing = current[segment]; 16403 const isSafeObject = !!existing && typeof existing === "object" && !Array.isArray(existing) && (Object.getPrototypeOf(existing) === Object.prototype || Object.getPrototypeOf(existing) === null); 16404 if (!isSafeObject) { 16405 const created = /* @__PURE__ */ Object.create(null); 16406 current[segment] = created; 16407 current = created; 16408 } else { 16409 current = existing; 16410 } 16411 } 16412 const finalSegment = segments[segments.length - 1]; 16413 if (isProtoPollutingKey(finalSegment)) return; 16414 current[finalSegment] = value; 16415} 16416function collapseDotPathFields(source, dotPathFieldIds) { 16417 if (!dotPathFieldIds.size) return source; 16418 let result = null; 16419 for (const fieldId of dotPathFieldIds){ 16420 if (!Object.prototype.hasOwnProperty.call(source, fieldId)) continue; 16421 if (!result) result = { 16422 ...source 16423 }; 16424 writeByDotPath(result, fieldId, source[fieldId]); 16425 } 16426 return result ?? source; 16427} 16428function readInitialCustomFieldValue(source, key) { 16429 if (!source || !key) return void 0; 16430 const candidates = [ 16431 `cf_${key}`, 16432 `cf:${key}`, 16433 key 16434 ]; 16435 for (const candidate of candidates){ 16436 if (Object.prototype.hasOwnProperty.call(source, candidate)) { 16437 return source[candidate]; 16438 } 16439 } 16440 return void 0; 16441} 16442function readRenderedFieldValue(source, fieldId) { 16443 if (Object.prototype.hasOwnProperty.call(source, fieldId)) { 16444 return source[fieldId]; 16445 } 16446 if (fieldId.startsWith("cf_")) { 16447 return readInitialCustomFieldValue(source, fieldId.slice(3)); 16448 } 16449 if (fieldId.startsWith("cf:")) { 16450 return readInitialCustomFieldValue(source, fieldId.slice(3)); 16451 } 16452 return void 0; 16453} 16454function serializeIssuePath(path) { 16455 if (!Array.isArray(path) || path.length === 0) return null; 16456 const segments = path.map((segment)=>{ 16457 if (typeof segment === "string" || typeof segment === "number") { 16458 const normalized = String(segment).trim(); 16459 return normalized.length > 0 ? normalized : null; 16460 } 16461 return null; 16462 }).filter((segment)=>segment !== null); 16463 return segments.length > 0 ? segments.join(".") : null; 16464} 16465function normalizeDirtySnapshotValue(value) { 16466 if (value === void 0 || value === null || value === "") return void 0; 16467 if (Array.isArray(value)) { 16468 const normalized2 = value.map((entry)=>normalizeDirtySnapshotValue(entry)).filter((entry)=>entry !== void 0); 16469 return normalized2.length ? normalized2 : void 0; 16470 } 16471 if (typeof value !== "object") return value; 16472 const prototype = Object.getPrototypeOf(value); 16473 if (prototype !== Object.prototype && prototype !== null) return value; 16474 const normalized = {}; 16475 const record = value; 16476 for (const key of Object.keys(record).sort((a, b)=>a < b ? -1 : a > b ? 1 : 0)){
16477 const nextValue = normalizeDirtySnapshotValue(record[key]); 16478 if (nextValue !== void 0) normalized[key] = nextValue; 16479 } 16480 return Object.keys(normalized).length ? normalized : void 0; 16481} 16482function createDirtySnapshot(source) { 16483 return JSON.stringify(normalizeDirtySnapshotValue(source) ?? {}); 16484} 16485function createDirtyValueSnapshot(value) { 16486 return JSON.stringify(normalizeDirtySnapshotValue(value) ?? null); 16487} 16488const FIELDSET_ICON_COMPONENTS = { 16489 layers: __TURBOPACK__imported__module__852008__["Layers"], 16490 tag: __TURBOPACK__imported__module__751975__["Tag"], 16491 sparkles: __TURBOPACK__imported__module__283086__["Sparkles"], 16492 package: __TURBOPACK__imported__module__488844__["Package"], 16493 shirt: __TURBOPACK__imported__module__390519__["Shirt"], 16494 grid: __TURBOPACK__imported__module__954922__["Grid"], 16495 shoppingBag: __TURBOPACK__imported__module__150965__["ShoppingBag"], 16496 shoppingCart: __TURBOPACK__imported__module__201928__["ShoppingCart"], 16497 store: __TURBOPACK__imported__module__223945__["Store"], 16498 users: __TURBOPACK__imported__module__761911__["Users"], 16499 briefcase: __TURBOPACK__imported__module__63727__["Briefcase"], 16500 building: __TURBOPACK__imported__module__342920__["Building"], 16501 bookOpen: __TURBOPACK__imported__module__810980__["BookOpen"], 16502 bookmark: __TURBOPACK__imported__module__571930__["Bookmark"], 16503 camera: __TURBOPACK__imported__module__968553__["Camera"], 16504 car: __TURBOPACK__imported__module__205125__["Car"], 16505 clock: __TURBOPACK__imported__module__503116__["Clock"], 16506 cloud: __TURBOPACK__imported__module__727927__["Cloud"], 16507 compass: __TURBOPACK__imported__module__394908__["Compass"], 16508 creditCard: __TURBOPACK__imported__module__561659__["CreditCard"], 16509 database: __TURBOPACK__imported__module__658041__["Database"], 16510 flame: __TURBOPACK__imported__module__958377__["Flame"], 16511 gift: __TURBOPACK__imported__module__730699__["Gift"], 16512 globe: __TURBOPACK__imported__module__248256__["Globe"], 16513 heart: __TURBOPACK__imported__module__790597__["Heart"], 16514 key: __TURBOPACK__imported__module__834161__["Key"], 16515 map: __TURBOPACK__imported__module__73526__["Map"], 16516 palette: __TURBOPACK__imported__module__647780__["Palette"], 16517 shield: __TURBOPACK__imported__module__98919__["Shield"], 16518 star: __TURBOPACK__imported__module__870273__["Star"], 16519 truck: __TURBOPACK__imported__module__715788__["Truck"], 16520 zap: __TURBOPACK__imported__module__39312__["Zap"], 16521 coins: __TURBOPACK__imported__module__575822__["Coins"] 16522}; 16523class FieldDefinitionsManagerErrorBoundary extends __TURBOPACK__imported__module__271645__["Component"] { 16524 constructor(props){ 16525 super(props); 16526 this.state = { 16527 hasError: false 16528 }; 16529 } 16530 static getDerivedStateFromError() { 16531 return { 16532 hasError: true 16533 }; 16534 } 16535 render() { 16536 if (this.state.hasError) { 16537 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 16538 className: "flex flex-col items-center justify-center gap-3 p-6 text-sm text-muted-foreground", 16539 children: [
16540 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("p", { 16541 children: this.props.unavailableMessage 16542 }), 16543 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 16544 type: "button", 16545 variant: "outline", 16546 size: "sm", 16547 onClick: this.props.onClose, 16548 children: "Close" 16549 }) 16550 ] 16551 }); 16552 } 16553 return this.props.children; 16554 } 16555} 16556function SortableGroupItem({ id, children, disabled }) { 16557 const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = (0, __TURBOPACK__imported__module__76590__["useSortable"])({ 16558 id, 16559 disabled 16560 }); 16561 const style = { 16562 transform: __TURBOPACK__imported__module__807311__["CSS"].Transform.toString(transform), 16563 transition, 16564 opacity: isDragging ? 0.5 : 1, 16565 position: "relative" 16566 }; 16567 const handleProps = __TURBOPACK__imported__module__271645__["useMemo"](()=>({ 16568 ref: setActivatorNodeRef, 16569 attributes, 16570 listeners, 16571 isDragging, 16572 disabled: !!disabled 16573 }), [ 16574 setActivatorNodeRef, 16575 attributes, 16576 listeners, 16577 isDragging, 16578 disabled 16579 ]); 16580 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 16581 ref: setNodeRef, 16582 style, 16583 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(SortableGroupHandleProvider, { 16584 value: handleProps, 16585 children 16586 }) 16587 }); 16588} 16589function CrudForm({ schema, fields, initialValues, disableInitialFocus = false, submitLabel, submitIcon, formId: providedFormId, customFieldsLoadingMessage, cancelHref, successRedirect, deleteRedirect, onSubmit, onDelete, deleteVisible, optimisticLockUpdatedAt, disableOptimisticLock = false, twoColumn = false, title, backHref, entityId, entityIds, groups, isLoading = false, loadingMessage, customEntity = false, embedded = false, hideFooterActions = false, trackDirtyWhenEmbedded = false, onDirtyChange, extraActions, versionHistory, contentHeader, readOnly = false, readOnlyOverlay, customFieldsetBindings, customFieldsManageMode = "inline", injectionSpotId, replacementHandle, collapsibleGroups, sortableGroups, shouldBypassUnsavedChangesGuard }) { 16590 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 16591 (0, __TURBOPACK__imported__module__127308__["loadGeneratedFieldRegistrations"])().catch(()=>{}); 16592 }, []); 16593 const { confirm, ConfirmDialogElement } = (0, __TURBOPACK__imported__module__486775__1["useConfirmDialog"])(); 16594 const router = (0, __TURBOPACK__imported__module__618566__["useRouter"])(); 16595 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 16596 const resolvedSubmitLabel = submitLabel ?? t("ui.forms.actions.save"); 16597 const resolvedLoadingMessage = loadingMessage ?? t("ui.forms.loading"); 16598 const resolvedCustomFieldsLoadingMessage = customFieldsLoadingMessage ?? resolvedLoadingMessage; 16599 const cancelLabel = t("ui.forms.actions.cancel"); 16600 const deleteLabel = t("ui.forms.actions.delete"); 16601 const savingLabel = t("ui.forms.status.saving"); 16602 const backLabel = t("ui.navigation.back"); 16603 const customFieldsLabel = t("entities.customFields.title"); 16604 const fieldsetSelectorLabel = t("entities.customFields.fieldsetSelectorLabel", "Fieldset"); 16605 const emptyFieldsetMessage = t("entities.customFields.emptyFieldset", "No fields defined for this fieldset."); 16606 const defaultFieldsetLabel = t("entities.customFields.defaultFieldset", "Default"); 16607 const manageFieldsetLabel = t("entities.customFields.manageFieldset", "Manage fields"); 16608 const fieldsetDialogTitle = t("entities.customFields.manageDialogTitle", "Edit custom fields"); 16609 const fieldsetDialogUnavailable = t("entities.customFields.manageDialogUnavailable", "Field definitions page is unavailable."); 16610 const hasVersionHistory = Boolean(versionHistory?.resourceKind); 16611 const deleteConfirmMessage = hasVersionHistory ? t("ui.forms.confirmDeleteWithUndo", "Delete this record? You can restore it using version history.") : t("ui.forms.confirmDelete"); 16612 const deleteSuccessMessage = t("ui.forms.flash.deleteSuccess"); 16613 const deleteErrorMessage = t("ui.forms.flash.deleteError"); 16614 const saveErrorMessage = t("ui.forms.flash.saveError"); 16615 const internalFormId = __TURBOPACK__imported__module__271645__["useId"](); 16616 const formId = providedFormId ?? internalFormId; 16617 const formReadOnly = Boolean(readOnly); 16618 const [values, setValues] = __TURBOPACK__imported__module__271645__["useState"](()=>({ 16619 ...initialValues ?? {} 16620 })); 16621 const valuesRef = __TURBOPACK__imported__module__271645__["useRef"](values); 16622 const [errors, setErrors] = __TURBOPACK__imported__module__271645__["useState"]({});
16623 const [pending, setPending] = __TURBOPACK__imported__module__271645__["useState"](false); 16624 const submittingRef = __TURBOPACK__imported__module__271645__["useRef"](false); 16625 const deletingRef = __TURBOPACK__imported__module__271645__["useRef"](false); 16626 const [formError, setFormError] = __TURBOPACK__imported__module__271645__["useState"](null); 16627 const [dynamicOptions, setDynamicOptions] = __TURBOPACK__imported__module__271645__["useState"]({}); 16628 const [cfDefinitions, setCfDefinitions] = __TURBOPACK__imported__module__271645__["useState"]([]); 16629 const [cfMetadata, setCfMetadata] = __TURBOPACK__imported__module__271645__["useState"](null); 16630 const [cfFieldsetSelections, setCfFieldsetSelections] = __TURBOPACK__imported__module__271645__["useState"]({}); 16631 const [isLoadingCustomFields, setIsLoadingCustomFields] = __TURBOPACK__imported__module__271645__["useState"](false); 16632 const [customFieldDefsVersion, setCustomFieldDefsVersion] = __TURBOPACK__imported__module__271645__["useState"](0); 16633 const [fieldsetEditorTarget, setFieldsetEditorTarget] = __TURBOPACK__imported__module__271645__["useState"](null); 16634 const [isInDialog, setIsInDialog] = __TURBOPACK__imported__module__271645__["useState"](false); 16635 const rootRef = __TURBOPACK__imported__module__271645__["useRef"](null); 16636 const collapsibleGroupsEnabled = Boolean(collapsibleGroups); 16637 const collapsiblePageType = typeof collapsibleGroups === "object" ? collapsibleGroups.pageType : formId; 16638 const collapsibleChevronPosition = typeof collapsibleGroups === "object" ? collapsibleGroups.chevronPosition : void 0; 16639 const groupCollapseRefs = __TURBOPACK__imported__module__271645__["useRef"](/* @__PURE__ */ new Map()); 16640 const sortableGroupsEnabled = Boolean(sortableGroups); 16641 const sortablePageType = typeof sortableGroups === "object" ? sortableGroups.pageType : formId; 16642 const fieldsetManagerRef = __TURBOPACK__imported__module__271645__["useRef"](null); 16643 const resolvedEntityIdsKey = __TURBOPACK__imported__module__271645__["useMemo"](()=>buildResolvedEntityIdsKey(entityId, entityIds), [ 16644 entityId, 16645 entityIds 16646 ]); 16647 const resolvedEntityIds = __TURBOPACK__imported__module__271645__["useMemo"](()=>resolvedEntityIdsKey ? resolvedEntityIdsKey.split("\0") : [], [ 16648 resolvedEntityIdsKey 16649 ]); 16650 const primaryEntityId = resolvedEntityIds.length ? resolvedEntityIds[0] : null; 16651 const resolvedInjectionSpotId = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 16652 if (injectionSpotId) return injectionSpotId; 16653 if (resolvedEntityIds.length) { 16654 const normalized = resolvedEntityIds[0].replace(/[:]+/g, "."); 16655 return `crud-form:${normalized}`; 16656 } 16657 return void 0; 16658 }, [ 16659 injectionSpotId, 16660 resolvedEntityIds 16661 ]); 16662 const resolvedReplacementHandle = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 16663 if (replacementHandle) return replacementHandle; 16664 if (resolvedEntityIds.length) return __TURBOPACK__imported__module__486257__["ComponentReplacementHandles"].crudForm(resolvedEntityIds[0].replace(/[:]+/g, ".")); 16665 return __TURBOPACK__imported__module__486257__["ComponentReplacementHandles"].crudForm("unknown"); 16666 }, [ 16667 replacementHandle, 16668 resolvedEntityIds 16669 ]); 16670 const headerInjectionSpotId = resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:header` : void 0; 16671 const recordId = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 16672 const raw = values.id; 16673 if (typeof raw === "string") return raw; 16674 if (typeof raw === "number") return String(raw); 16675 return void 0; 16676 }, [ 16677 values 16678 ]); 16679 const fallbackRecordId = recordId || (versionHistory?.resourceId === void 0 || versionHistory.resourceId === null ? void 0 : String(versionHistory.resourceId).trim() || void 0); 16680 const operation = recordId ? "update" : "create"; 16681 const resolvedOptimisticLockUpdatedAt = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 16682 if (disableOptimisticLock) return null; 16683 if (optimisticLockUpdatedAt !== void 0) return optimisticLockUpdatedAt; 16684 const source = initialValues; 16685 const camel = source?.updatedAt; 16686 if (typeof camel === "string" && camel.length > 0) return camel; 16687 const snake = source?.updated_at; 16688 if (typeof snake === "string" && snake.length > 0) return snake; 16689 return null; 16690 }, [ 16691 disableOptimisticLock, 16692 optimisticLockUpdatedAt, 16693 initialValues 16694 ]); 16695 const injectionContext = __TURBOPACK__imported__module__271645__["useMemo"](()=>({ 16696 formId, 16697 entityId: primaryEntityId,
16698 resourceKind: versionHistory?.resourceKind, 16699 resourceId: recordId ?? versionHistory?.resourceId, 16700 recordId: fallbackRecordId, 16701 isLoading, 16702 pending, 16703 operation 16704 }), [ 16705 formId, 16706 primaryEntityId, 16707 versionHistory?.resourceKind, 16708 versionHistory?.resourceId, 16709 recordId, 16710 fallbackRecordId, 16711 isLoading, 16712 pending, 16713 operation 16714 ]); 16715 const injectionContextRef = __TURBOPACK__imported__module__271645__["useRef"](injectionContext); 16716 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 16717 injectionContextRef.current = injectionContext; 16718 }, [ 16719 injectionContext 16720 ]); 16721 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 16722 valuesRef.current = values; 16723 }, [ 16724 values 16725 ]); 16726 const isDirtyRef = __TURBOPACK__imported__module__271645__["useRef"](false); 16727 const navigationPromptBypassRef = __TURBOPACK__imported__module__271645__["useRef"](false); 16728 const navigationConfirmPendingRef = __TURBOPACK__imported__module__271645__["useRef"](false); 16729 const submitNavigationBypassRef = __TURBOPACK__imported__module__271645__["useRef"](false); 16730 const submitNavigationBypassTimeoutRef = __TURBOPACK__imported__module__271645__["useRef"](null); 16731 const [hasUnsavedChanges, setHasUnsavedChanges] = __TURBOPACK__imported__module__271645__["useState"](false); 16732 const popStateRollbackRef = __TURBOPACK__imported__module__271645__["useRef"](false); 16733 const shouldBypassUnsavedChangesGuardRef = __TURBOPACK__imported__module__271645__["useRef"](shouldBypassUnsavedChangesGuard); 16734 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 16735 shouldBypassUnsavedChangesGuardRef.current = shouldBypassUnsavedChangesGuard; 16736 }, [ 16737 shouldBypassUnsavedChangesGuard 16738 ]); 16739 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 16740 if (embedded && !trackDirtyWhenEmbedded) { 16741 isDirtyRef.current = false; 16742 setHasUnsavedChanges(false); 16743 return; 16744 } 16745 const snapshot = dirtyBaselineSnapshotRef.current; 16746 if (!snapshot) { 16747 isDirtyRef.current = false; 16748 setHasUnsavedChanges(false); 16749 return; 16750 } 16751 const currentSnapshot = createDirtySnapshot(values); 16752 const dirty = currentSnapshot !== snapshot; 16753 isDirtyRef.current = dirty; 16754 setHasUnsavedChanges(dirty); 16755 }, [ 16756 embedded, 16757 trackDirtyWhenEmbedded, 16758 values 16759 ]); 16760 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 16761 onDirtyChange?.(hasUnsavedChanges); 16762 }, [ 16763 hasUnsavedChanges, 16764 onDirtyChange 16765 ]); 16766 const allowNextNavigation = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 16767 navigationPromptBypassRef.current = true; 16768 if ("TURBOPACK compile-time truthy", 1) { 16769 window.setTimeout(()=>{ 16770 navigationPromptBypassRef.current = false; 16771 }, 0); 16772 } 16773 }, []); 16774 const clearSubmitNavigationBypass = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 16775 submitNavigationBypassRef.current = false; 16776 if (("TURBOPACK compile-time value", "object") !== "undefined" && submitNavigationBypassTimeoutRef.current !== null) { 16777 window.clearTimeout(submitNavigationBypassTimeoutRef.current); 16778 submitNavigationBypassTimeoutRef.current = null; 16779 } 16780 }, []); 16781 const keepSubmitNavigationBypassAlive = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 16782 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 16783 ; 16784 submitNavigationBypassRef.current = true; 16785 if (submitNavigationBypassTimeoutRef.current !== null) { 16786 window.clearTimeout(submitNavigationBypassTimeoutRef.current); 16787 } 16788 submitNavigationBypassTimeoutRef.current = window.setTimeout(()=>{ 16789 submitNavigationBypassRef.current = false; 16790 submitNavigationBypassTimeoutRef.current = null; 16791 }, 1500); 16792 }, []); 16793 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 16794 return ()=>{ 16795 clearSubmitNavigationBypass(); 16796 }; 16797 }, [ 16798 clearSubmitNavigationBypass 16799 ]); 16800 const clearDirtyState = __TURBOPACK__imported__module__271645__["useCallback"]((snapshotSource)=>{ 16801 const source = snapshotSource ?? valuesRef.current;
16802 dirtyBaselineSnapshotRef.current = createDirtySnapshot(source); 16803 dirtyBaselineValuesRef.current = { 16804 ...source 16805 }; 16806 userEditedFieldIdsRef.current.clear(); 16807 isDirtyRef.current = false; 16808 setHasUnsavedChanges(false); 16809 }, []); 16810 const confirmUnsavedChanges = __TURBOPACK__imported__module__271645__["useCallback"](async ()=>{ 16811 if (!isDirtyRef.current || ("TURBOPACK compile-time value", "object") === "undefined") return true; 16812 if (navigationPromptBypassRef.current || submitNavigationBypassRef.current) return true; 16813 if (navigationConfirmPendingRef.current) return false; 16814 navigationConfirmPendingRef.current = true; 16815 try { 16816 const confirmed = await confirm({ 16817 title: t("ui.forms.confirmUnsavedChanges", "You have unsaved changes. Are you sure you want to leave?") 16818 }); 16819 if (confirmed) allowNextNavigation(); 16820 return confirmed; 16821 } finally{ 16822 navigationConfirmPendingRef.current = false; 16823 } 16824 }, [ 16825 allowNextNavigation, 16826 confirm, 16827 t 16828 ]); 16829 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 16830 if (embedded && !trackDirtyWhenEmbedded || !hasUnsavedChanges) return; 16831 const beforeUnloadHandler = (event)=>{ 16832 if (!isDirtyRef.current || submitNavigationBypassRef.current) return; 16833 event.preventDefault(); 16834 event.returnValue = ""; 16835 }; 16836 window.addEventListener("beforeunload", beforeUnloadHandler); 16837 const clickHandler = (event)=>{ 16838 if (event.defaultPrevented) return; 16839 if (!isDirtyRef.current) return; 16840 const anchor = event.target?.closest?.("a[href]"); 16841 if (!anchor) return; 16842 const href = anchor.getAttribute("href"); 16843 if (!href || href.startsWith("#") || href.startsWith("mailto:") || href.startsWith("tel:")) return; 16844 if (anchor.target === "_blank" || event.metaKey || event.ctrlKey || event.shiftKey) return; 16845 const target = resolveInternalNavigationTarget(href); 16846 if (!target) return; 16847 if (shouldBypassUnsavedChangesGuardRef.current?.(target)) return; 16848 const baselineSnapshot = dirtyBaselineSnapshotRef.current; 16849 if (baselineSnapshot && createDirtySnapshot(valuesRef.current) === baselineSnapshot) { 16850 isDirtyRef.current = false; 16851 setHasUnsavedChanges(false); 16852 return; 16853 } 16854 event.preventDefault(); 16855 event.stopPropagation(); 16856 if (navigationConfirmPendingRef.current) return; 16857 void confirmUnsavedChanges().then((confirmed)=>{ 16858 if (!confirmed) return; 16859 clearDirtyState(); 16860 router.push(target); 16861 }); 16862 }; 16863 document.addEventListener("click", clickHandler, true); 16864 const originalPushState = window.history.pushState.bind(window.history); 16865 const originalReplaceState = window.history.replaceState.bind(window.history); 16866 const createHistoryInterceptor = (original)=>(data, unused, url)=>{ 16867 const target = resolveInternalNavigationTarget(url ?? null); 16868 if (!target || navigationPromptBypassRef.current || submitNavigationBypassRef.current) { 16869 return original(data, unused, url); 16870 } 16871 if (!isDirtyRef.current) { 16872 return original(data, unused, url); 16873 } 16874 if (shouldBypassUnsavedChangesGuardRef.current?.(target)) { 16875 return original(data, unused, url); 16876 } 16877 const baselineSnapshot = dirtyBaselineSnapshotRef.current; 16878 if (baselineSnapshot && createDirtySnapshot(valuesRef.current) === baselineSnapshot) { 16879 isDirtyRef.current = false; 16880 setHasUnsavedChanges(false); 16881 return original(data, unused, url); 16882 } 16883 if (navigationConfirmPendingRef.current) { 16884 return void 0; 16885 } 16886 void confirmUnsavedChanges().then((confirmed)=>{ 16887 if (!confirmed) return; 16888 clearDirtyState(); 16889 original(data, unused, url); 16890 }); 16891 return void 0; 16892 }; 16893 const popStateHandler = ()=>{ 16894 if (popStateRollbackRef.current) { 16895 popStateRollbackRef.current = false;
16896 return; 16897 } 16898 if (!isDirtyRef.current || navigationPromptBypassRef.current || submitNavigationBypassRef.current) return; 16899 popStateRollbackRef.current = true; 16900 window.history.go(1); 16901 if (navigationConfirmPendingRef.current) return; 16902 void confirmUnsavedChanges().then((confirmed)=>{ 16903 if (!confirmed) return; 16904 clearDirtyState(); 16905 allowNextNavigation(); 16906 window.history.back(); 16907 }); 16908 }; 16909 window.history.pushState = createHistoryInterceptor(originalPushState); 16910 window.history.replaceState = createHistoryInterceptor(originalReplaceState); 16911 window.addEventListener("popstate", popStateHandler); 16912 return ()=>{ 16913 window.removeEventListener("beforeunload", beforeUnloadHandler); 16914 document.removeEventListener("click", clickHandler, true); 16915 window.removeEventListener("popstate", popStateHandler); 16916 window.history.pushState = originalPushState; 16917 window.history.replaceState = originalReplaceState; 16918 }; 16919 }, [ 16920 allowNextNavigation, 16921 clearDirtyState, 16922 confirmUnsavedChanges, 16923 embedded, 16924 hasUnsavedChanges, 16925 router, 16926 trackDirtyWhenEmbedded 16927 ]); 16928 const { widgets: injectionWidgets } = (0, __TURBOPACK__imported__module__862013__["useInjectionWidgets"])(resolvedInjectionSpotId, { 16929 context: injectionContext, 16930 triggerOnLoad: true 16931 }); 16932 const { widgets: injectedFieldWidgets } = (0, __TURBOPACK__imported__module__753861__["useInjectionDataWidgets"])(resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:fields` : "__disabled__:fields"); 16933 const { triggerEvent: triggerInjectionEvent } = (0, __TURBOPACK__imported__module__862013__["useInjectionSpotEvents"])(resolvedInjectionSpotId ?? "", injectionWidgets); 16934 const extendedInjectionEventsEnabled = CRUDFORM_EXTENDED_EVENTS_ENABLED && Boolean(resolvedInjectionSpotId); 16935 const widgetRequiredFieldIds = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 16936 const ids = /* @__PURE__ */ new Set(); 16937 for (const widget of injectionWidgets ?? []){ 16938 const metadata = widget.module?.metadata; 16939 if (!metadata || metadata.enabled === false) continue; 16940 for (const fieldId of metadata.requiredFields ?? [])ids.add(fieldId); 16941 } 16942 return ids; 16943 }, [ 16944 injectionWidgets 16945 ]); 16946 const transformValidationErrors = __TURBOPACK__imported__module__271645__["useCallback"](async (fieldErrors)=>{ 16947 if (!extendedInjectionEventsEnabled || !Object.keys(fieldErrors).length) return fieldErrors; 16948 try { 16949 const result = await triggerInjectionEvent("transformValidation", fieldErrors, injectionContextRef.current, { 16950 originalData: valuesRef.current 16951 }); 16952 const transformed = result.data; 16953 if (!transformed || typeof transformed !== "object" || Array.isArray(transformed)) return fieldErrors; 16954 return Object.fromEntries(Object.entries(transformed).map(([key, value])=>[ 16955 key, 16956 String(value) 16957 ])); 16958 } catch (err) { 16959 logger.error("Error in transformValidation", { 16960 err 16961 }); 16962 return fieldErrors; 16963 } 16964 }, [ 16965 extendedInjectionEventsEnabled, 16966 triggerInjectionEvent 16967 ]); 16968 const translateValidationMessage = __TURBOPACK__imported__module__271645__["useCallback"]((message)=>{ 16969 if (typeof message !== "string") return ""; 16970 const trimmed = message.trim(); 16971 if (!trimmed) return ""; 16972 return t(trimmed, trimmed); 16973 }, [ 16974 t 16975 ]); 16976 const translateValidationErrors = __TURBOPACK__imported__module__271645__["useCallback"]((fieldErrors)=>Object.fromEntries(Object.entries(fieldErrors).map(([fieldId, message])=>[ 16977 fieldId, 16978 translateValidationMessage(message) 16979 ])), [ 16980 translateValidationMessage 16981 ]); 16982 const mapDefsForValidation = __TURBOPACK__imported__module__271645__["useCallback"]((definitions)=>definitions.map((definition)=>({ 16983 key: definition.key, 16984 kind: definition.kind, 16985 configJson: { 16986 validation: Array.isArray(definition.validation) ? definition.validation : [] 16987 } 16988 })), []); 16989 const canNavigateTo = __TURBOPACK__imported__module__271645__["useCallback"](async (target)=>{ 16990 if (!extendedInjectionEventsEnabled) return true; 16991 try { 16992 const result = await triggerInjectionEvent("onBeforeNavigate", valuesRef.current, injectionContextRef.current, { 16993 target 16994 }); 16995 if (!result.ok) { 16996 (0, __TURBOPACK__imported__module__484973__["flash"])(result.message || t("ui.forms.flash.saveBlocked", "Save blocked by validation"), "error"); 16997 return false;
16998 } 16999 return true; 17000 } catch (err) { 17001 const message = err instanceof Error && err.message ? err.message : t("ui.forms.flash.saveBlocked", "Save blocked by validation"); 17002 (0, __TURBOPACK__imported__module__484973__["flash"])(message, "error"); 17003 return false; 17004 } 17005 }, [ 17006 extendedInjectionEventsEnabled, 17007 t, 17008 triggerInjectionEvent 17009 ]); 17010 const navigateWithGuard = __TURBOPACK__imported__module__271645__["useCallback"](async (target)=>{ 17011 if (!target) return; 17012 const allowed = await canNavigateTo(target); 17013 if (allowed) { 17014 allowNextNavigation(); 17015 router.push(target); 17016 } 17017 }, [ 17018 allowNextNavigation, 17019 canNavigateTo, 17020 router 17021 ]); 17022 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 17023 if (!extendedInjectionEventsEnabled || ("TURBOPACK compile-time value", "object") === "undefined") return; 17024 const handleEvent = (event)=>{ 17025 const customEvent = event; 17026 void triggerInjectionEvent("onAppEvent", valuesRef.current, injectionContextRef.current, { 17027 appEvent: customEvent.detail 17028 }).catch((err)=>{ 17029 logger.error("Error in onAppEvent", { 17030 err 17031 }); 17032 }); 17033 }; 17034 window.addEventListener("om:event", handleEvent); 17035 return ()=>{ 17036 window.removeEventListener("om:event", handleEvent); 17037 }; 17038 }, [ 17039 extendedInjectionEventsEnabled, 17040 triggerInjectionEvent 17041 ]); 17042 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 17043 if (!extendedInjectionEventsEnabled || typeof document === "undefined") return; 17044 const emitVisibility = ()=>{ 17045 void triggerInjectionEvent("onVisibilityChange", valuesRef.current, injectionContextRef.current, { 17046 visible: document.visibilityState === "visible" 17047 }).catch((err)=>{ 17048 logger.error("Error in onVisibilityChange", { 17049 err 17050 }); 17051 }); 17052 }; 17053 document.addEventListener("visibilitychange", emitVisibility); 17054 emitVisibility(); 17055 return ()=>{ 17056 document.removeEventListener("visibilitychange", emitVisibility); 17057 }; 17058 }, [ 17059 extendedInjectionEventsEnabled, 17060 triggerInjectionEvent 17061 ]); 17062 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 17063 if (!extendedInjectionEventsEnabled) return; 17064 const root = rootRef.current; 17065 if (!root || ("TURBOPACK compile-time value", "object") === "undefined") return; 17066 const handleClickCapture = (event)=>{ 17067 if (event.defaultPrevented) return; 17068 if (event.button !== 0) return; 17069 if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return; 17070 const targetElement = event.target instanceof Element ? event.target : null; 17071 const linkElement = targetElement?.closest("a[href]"); 17072 if (!(linkElement instanceof HTMLAnchorElement)) return; 17073 if (!root.contains(linkElement)) return; 17074 if (linkElement.target && linkElement.target !== "_self") return; 17075 const rawHref = linkElement.getAttribute("href"); 17076 if (!rawHref || rawHref.startsWith("#")) return; 17077 let target = rawHref; 17078 if (rawHref.startsWith("http://") || rawHref.startsWith("https://")) { 17079 try { 17080 const parsed = new URL(rawHref); 17081 if (parsed.origin !== window.location.origin) return; 17082 target = `${parsed.pathname}${parsed.search}${parsed.hash}`; 17083 } catch { 17084 return; 17085 } 17086 } else if (!rawHref.startsWith("/")) { 17087 return; 17088 } 17089 event.preventDefault(); 17090 void navigateWithGuard(target); 17091 }; 17092 root.addEventListener("click", handleClickCapture, true); 17093 return ()=>{ 17094 root.removeEventListener("click", handleClickCapture, true); 17095 }; 17096 }, [ 17097 extendedInjectionEventsEnabled, 17098 navigateWithGuard 17099 ]); 17100 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 17101 const root = rootRef.current; 17102 if (!root) return; 17103 setIsInDialog(Boolean(root.closest("[data-dialog-content]"))); 17104 }, []); 17105 const dialogFooterClass = isInDialog ? "sticky bottom-0 left-0 right-0 z-20 -mx-6 px-6 bg-card border-t border-border/70 py-2 sm:-mx-6 sm:px-6" : ""; 17106 const dialogFormPadding = ""; 17107 const buildCustomFieldsManageHref = __TURBOPACK__imported__module__271645__["useCallback"]((targetEntityId)=>{ 17108 if (!targetEntityId) return null; 17109 try { 17110 const encoded = encodeURIComponent(targetEntityId); 17111 return customEntity ? `/backend/entities/user/${encoded}` : `/backend/entities/system/${encoded}`;
17112 } catch { 17113 return null; 17114 } 17115 }, [ 17116 customEntity 17117 ]); 17118 const refreshCustomFieldDefinitions = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 17119 setCustomFieldDefsVersion((prev)=>prev + 1); 17120 }, []); 17121 const handleDelete = __TURBOPACK__imported__module__271645__["useCallback"](async ()=>{ 17122 if (!onDelete) return; 17123 if (deletingRef.current) return; 17124 deletingRef.current = true; 17125 const deletePayload = values; 17126 try { 17127 const confirmed = await confirm({ 17128 title: deleteConfirmMessage, 17129 variant: "destructive" 17130 }); 17131 if (!confirmed) return; 17132 let injectionRequestHeaders; 17133 if (resolvedInjectionSpotId) { 17134 try { 17135 const result = await triggerInjectionEvent("onBeforeDelete", deletePayload, injectionContext); 17136 if (!result.ok) { 17137 try { 17138 if ("TURBOPACK compile-time truthy", 1) { 17139 (0, __TURBOPACK__imported__module__781167__["dispatchBackendMutationError"])({ 17140 contextId: formId, 17141 formId, 17142 error: result.details ?? result 17143 }); 17144 window.dispatchEvent(new CustomEvent("om:crud-save-error", { 17145 detail: { 17146 formId, 17147 error: result.details ?? result 17148 } 17149 })); 17150 } 17151 } catch {} 17152 if (result.fieldErrors && Object.keys(result.fieldErrors).length) { 17153 const transformedErrors = await transformValidationErrors(result.fieldErrors); 17154 setErrors(translateValidationErrors(transformedErrors)); 17155 } 17156 const message = result.message || t("ui.forms.flash.saveBlocked", "Save blocked by validation"); 17157 (0, __TURBOPACK__imported__module__484973__["flash"])(message, "error"); 17158 return; 17159 } 17160 injectionRequestHeaders = result.requestHeaders; 17161 } catch (err) { 17162 logger.error("Error in onBeforeDelete", { 17163 err 17164 }); 17165 (0, __TURBOPACK__imported__module__484973__["flash"])(t("ui.forms.flash.saveBlocked", "Save blocked by validation"), "error"); 17166 return; 17167 } 17168 } 17169 setPending(true); 17170 if (resolvedInjectionSpotId) { 17171 try { 17172 await triggerInjectionEvent("onDelete", deletePayload, injectionContext); 17173 } catch (err) { 17174 logger.error("Error in onDelete", { 17175 err 17176 }); 17177 (0, __TURBOPACK__imported__module__484973__["flash"])(t("ui.forms.flash.saveBlocked", "Save blocked by validation"), "error"); 17178 return; 17179 } 17180 } 17181 const optimisticLockHeader = (0, __TURBOPACK__imported__module__977896__["buildOptimisticLockHeader"])(resolvedOptimisticLockUpdatedAt); 17182 const mergedDeleteHeaders = { 17183 ...injectionRequestHeaders ?? {}, 17184 ...optimisticLockHeader 17185 }; 17186 if (Object.keys(mergedDeleteHeaders).length > 0) { 17187 await (0, __TURBOPACK__imported__module__490746__["withScopedApiRequestHeaders"])(mergedDeleteHeaders, async ()=>{ 17188 await onDelete(); 17189 }); 17190 } else { 17191 await onDelete(); 17192 } 17193 if (resolvedInjectionSpotId) { 17194 try { 17195 await triggerInjectionEvent("onAfterDelete", deletePayload, injectionContext); 17196 } catch (err) { 17197 logger.error("Error in onAfterDelete", { 17198 err 17199 }); 17200 } 17201 } 17202 try { 17203 (0, __TURBOPACK__imported__module__484973__["flash"])(deleteSuccessMessage, "success"); 17204 } catch {} 17205 if (typeof deleteRedirect === "string" && deleteRedirect) { 17206 await navigateWithGuard(deleteRedirect); 17207 } 17208 } catch (err) { 17209 if (resolvedInjectionSpotId) { 17210 try { 17211 await triggerInjectionEvent("onDeleteError", deletePayload, injectionContext, { 17212 error: err 17213 }); 17214 } catch (hookError) { 17215 logger.error("Error in onDeleteError", { 17216 err: hookError 17217 }); 17218 } 17219 } 17220 try { 17221 if ("TURBOPACK compile-time truthy", 1) { 17222 (0, __TURBOPACK__imported__module__781167__["dispatchBackendMutationError"])({ 17223 contextId: formId, 17224 formId, 17225 error: err 17226 }); 17227 window.dispatchEvent(new CustomEvent("om:crud-save-error", { 17228 detail: { 17229 formId, 17230 error: err 17231 } 17232 })); 17233 } 17234 } catch {} 17235 const optimisticLockConflict = (0, __TURBOPACK__imported__module__977896__["extractOptimisticLockConflict"])(err); 17236 if (optimisticLockConflict) { 17237 try { 17238 (0, __TURBOPACK__imported__module__372790__["surfaceRecordConflict"])(err, t); 17239 } catch {} 17240 } else { 17241 const message = err instanceof Error && err.message ? err.message : deleteErrorMessage; 17242 try { 17243 (0, __TURBOPACK__imported__module__484973__["flash"])(message, "error"); 17244 } catch {} 17245 } 17246 } finally{ 17247 deletingRef.current = false;
17248 setPending(false); 17249 } 17250 }, [ 17251 confirm, 17252 deleteConfirmMessage, 17253 deleteErrorMessage, 17254 deleteRedirect, 17255 deleteSuccessMessage, 17256 formId, 17257 injectionContext, 17258 onDelete, 17259 resolvedInjectionSpotId, 17260 navigateWithGuard, 17261 t, 17262 transformValidationErrors, 17263 triggerInjectionEvent, 17264 values 17265 ]); 17266 const isNewRecord = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17267 const rawId = values.id; 17268 if (rawId === void 0 || rawId === null) return true; 17269 return typeof rawId === "string" ? rawId.trim().length === 0 : false; 17270 }, [ 17271 values 17272 ]); 17273 const showDelete = Boolean(onDelete) && (typeof deleteVisible === "boolean" ? deleteVisible : !isNewRecord); 17274 const versionHistoryEnabled = Boolean(versionHistory?.resourceId && String(versionHistory.resourceId).trim().length > 0); 17275 const versionHistoryAction = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__157467__["VersionHistoryAction"], { 17276 config: versionHistoryEnabled ? versionHistory : null, 17277 t, 17278 canUndoRedo: versionHistory?.canUndoRedo, 17279 autoCheckAcl: versionHistory?.autoCheckAcl 17280 }); 17281 const headerInjectionAction = headerInjectionSpotId ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__862013__["InjectionSpot"], { 17282 spotId: headerInjectionSpotId, 17283 context: injectionContext, 17284 data: values, 17285 onDataChange: (newData)=>setValues(newData), 17286 disabled: pending 17287 }) : null; 17288 const headerExtraActions = versionHistoryEnabled || headerInjectionAction || extraActions ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__843476__["Fragment"], { 17289 children: [ 17290 versionHistoryEnabled ? versionHistoryAction : null, 17291 headerInjectionAction, 17292 extraActions 17293 ] 17294 }) : void 0; 17295 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 17296 let cancelled = false; 17297 async function load() { 17298 if (!resolvedEntityIds.length) { 17299 setCfDefinitions([]); 17300 setCfMetadata(null); 17301 setIsLoadingCustomFields(false); 17302 return; 17303 } 17304 setIsLoadingCustomFields(true); 17305 try { 17306 const mod = await __turbopack_context__.A(672629); 17307 const { definitions, metadata } = await mod.fetchCustomFieldFormStructure(resolvedEntityIds, void 0, { 17308 bareIds: customEntity 17309 }); 17310 if (!cancelled) { 17311 setCfDefinitions(definitions); 17312 setCfMetadata(metadata); 17313 setCfFieldsetSelections((prev)=>{ 17314 const next = {}; 17315 let changed = false; 17316 resolvedEntityIds.forEach((entityId2)=>{ 17317 const existing = prev[entityId2]; 17318 const fieldsets = metadata.fieldsetsByEntity?.[entityId2] ?? []; 17319 const defaultSelection = fieldsets[0]?.code ?? null; 17320 const value = existing !== void 0 ? existing : defaultSelection; 17321 next[entityId2] = value; 17322 if (existing !== value) changed = true; 17323 }); 17324 if (Object.keys(prev).length !== Object.keys(next).length) changed = true; 17325 return changed ? next : prev; 17326 }); 17327 setIsLoadingCustomFields(false); 17328 } 17329 } catch { 17330 if (!cancelled) { 17331 setCfDefinitions([]); 17332 setCfMetadata(null); 17333 setIsLoadingCustomFields(false); 17334 } 17335 } 17336 } 17337 load(); 17338 return ()=>{ 17339 cancelled = true; 17340 }; 17341 }, [ 17342 resolvedEntityIds, 17343 customEntity, 17344 customFieldDefsVersion 17345 ]); 17346 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 17347 if (!customFieldsetBindings) return; 17348 setCfFieldsetSelections((prev)=>{ 17349 let changed = false;
17350 const next = { 17351 ...prev 17352 }; 17353 resolvedEntityIds.forEach((entityId2)=>{ 17354 const binding = customFieldsetBindings[entityId2]; 17355 if (!binding) return; 17356 const raw = values[binding.valueKey]; 17357 if (typeof raw === "string" && raw.trim().length > 0) { 17358 const normalized = raw.trim(); 17359 if (next[entityId2] !== normalized) { 17360 next[entityId2] = normalized; 17361 changed = true; 17362 } 17363 } 17364 }); 17365 return changed ? next : prev; 17366 }); 17367 }, [ 17368 customFieldsetBindings, 17369 resolvedEntityIds, 17370 values 17371 ]); 17372 const fieldsetsByEntity = cfMetadata?.fieldsetsByEntity ?? {}; 17373 const entitySettings = cfMetadata?.entitySettings ?? {}; 17374 const { cfFields, customFieldLayout } = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17375 if (!cfDefinitions.length) return { 17376 cfFields: [], 17377 customFieldLayout: [] 17378 }; 17379 const aggregated = []; 17380 const layout = []; 17381 const defsByEntity = new globalThis.Map(); 17382 cfDefinitions.forEach((def)=>{ 17383 const entityId2 = typeof def.entityId === "string" && def.entityId.trim().length ? def.entityId.trim() : resolvedEntityIds[0]; 17384 if (!entityId2) return; 17385 const bucket = defsByEntity.get(entityId2) ?? []; 17386 bucket.push(def); 17387 defsByEntity.set(entityId2, bucket); 17388 }); 17389 const buildSection = (entityId2, fieldsetCode, defList, fieldset)=>{ 17390 if (!defList.length) return null; 17391 const groupsMap = new globalThis.Map(); 17392 const order = []; 17393 const fieldsetGroupMap = new globalThis.Map(); 17394 if (Array.isArray(fieldset?.groups)) { 17395 fieldset.groups.forEach((group)=>{ 17396 if (!group?.code) return; 17397 fieldsetGroupMap.set(group.code, { 17398 code: group.code, 17399 title: group.title, 17400 hint: group.hint 17401 }); 17402 }); 17403 } 17404 const sortedDefs = [ 17405 ...defList 17406 ].filter((definition)=>(0, __TURBOPACK__imported__module__221019__["isDefVisible"])(definition, "form")).sort((a, b)=>(a.priority ?? 0) - (b.priority ?? 0)); 17407 const ensureBucket = (code, def)=>{ 17408 const key = code ?? "__default__"; 17409 let bucket = groupsMap.get(key); 17410 if (!bucket) { 17411 const fallbackMeta = code ? fieldsetGroupMap.get(code) : void 0; 17412 const directMeta = code ? def.group : void 0; 17413 const label = code === null ? void 0 : directMeta?.title || fallbackMeta?.title || directMeta?.code || fallbackMeta?.code || code; 17414 const hint = directMeta?.hint || fallbackMeta?.hint; 17415 bucket = { 17416 code, 17417 label, 17418 hint, 17419 fields: [] 17420 }; 17421 groupsMap.set(key, bucket); 17422 order.push(key); 17423 } else if (code && !bucket.label) { 17424 const fallbackMeta = fieldsetGroupMap.get(code); 17425 const directMeta = def.group ?? void 0; 17426 bucket.label = directMeta?.title || fallbackMeta?.title || directMeta?.code || fallbackMeta?.code || bucket.label; 17427 bucket.hint = directMeta?.hint || fallbackMeta?.hint || bucket.hint; 17428 } 17429 return bucket; 17430 }; 17431 sortedDefs.forEach((definition)=>{ 17432 const field = (0, __TURBOPACK__imported__module__861172__["buildFormFieldFromCustomFieldDef"])(definition, { 17433 bareIds: customEntity 17434 }); 17435 if (!field) return; 17436 aggregated.push(field); 17437 const bucket = ensureBucket(definition.group?.code ?? null, definition);
17438 bucket.fields.push(field); 17439 }); 17440 const groups2 = order.map((key)=>groupsMap.get(key)).filter((group)=>group.fields.length > 0); 17441 if (!groups2.length) return null; 17442 return { 17443 entityId: entityId2, 17444 fieldsetCode, 17445 fieldset, 17446 title: fieldset?.label ?? customFieldsLabel, 17447 description: fieldset?.description, 17448 groups: groups2 17449 }; 17450 }; 17451 const entityIds2 = resolvedEntityIds.length ? resolvedEntityIds : Array.from(defsByEntity.keys()); 17452 entityIds2.forEach((entityId2)=>{ 17453 const defsForEntity = defsByEntity.get(entityId2) ?? []; 17454 if (!defsForEntity.length) return; 17455 const availableFieldsets = fieldsetsByEntity[entityId2] ?? []; 17456 const hasFieldsets = availableFieldsets.length > 0; 17457 const singleFieldsetPerRecord = entitySettings[entityId2]?.singleFieldsetPerRecord !== false; 17458 const defsByFieldset = new globalThis.Map(); 17459 defsForEntity.forEach((def)=>{ 17460 const memberships = Array.isArray(def.fieldsets) ? def.fieldsets.filter((entry)=>typeof entry === "string").map((entry)=>entry.trim()).filter((entry)=>entry.length > 0) : []; 17461 if (memberships.length > 0) { 17462 memberships.forEach((code2)=>{ 17463 const bucket2 = defsByFieldset.get(code2) ?? []; 17464 bucket2.push(def); 17465 defsByFieldset.set(code2, bucket2); 17466 }); 17467 return; 17468 } 17469 const code = typeof def.fieldset === "string" && def.fieldset.trim().length > 0 ? def.fieldset.trim() : null; 17470 const bucket = defsByFieldset.get(code) ?? []; 17471 bucket.push(def); 17472 defsByFieldset.set(code, bucket); 17473 }); 17474 const sections = []; 17475 const createEmptySection = (code)=>{ 17476 const fieldset = code ? availableFieldsets.find((fs)=>fs.code === code) : void 0; 17477 return { 17478 entityId: entityId2, 17479 fieldsetCode: code, 17480 fieldset, 17481 title: fieldset?.label ?? customFieldsLabel, 17482 description: fieldset?.description, 17483 groups: [] 17484 }; 17485 }; 17486 if (!hasFieldsets) { 17487 const fallbackDefs = defsByFieldset.get(null) ?? Array.from(defsByFieldset.values()).flat(); 17488 const section = buildSection(entityId2, null, fallbackDefs, void 0); 17489 if (section) sections.push(section); 17490 } else if (singleFieldsetPerRecord) { 17491 const availableCodes = availableFieldsets.map((fs)=>fs.code); 17492 const activeFieldset = cfFieldsetSelections[entityId2] && availableCodes.includes(cfFieldsetSelections[entityId2]) ? cfFieldsetSelections[entityId2] : availableFieldsets[0]?.code ?? null; 17493 const targetDefs = activeFieldset ? defsByFieldset.get(activeFieldset) ?? [] : defsByFieldset.get(null) ?? []; 17494 const targetSection = activeFieldset ? buildSection(entityId2, activeFieldset, targetDefs, availableFieldsets.find((fs)=>fs.code === activeFieldset)) : buildSection(entityId2, null, targetDefs, void 0); 17495 if (targetSection) { 17496 sections.push(targetSection); 17497 } else if (activeFieldset) { 17498 sections.push(createEmptySection(activeFieldset)); 17499 } 17500 const unassigned = defsByFieldset.get(null); 17501 if (unassigned?.length && activeFieldset) { 17502 const generalSection = buildSection(entityId2, null, unassigned, void 0); 17503 if (generalSection) sections.push(generalSection); 17504 } 17505 } else { 17506 availableFieldsets.forEach((fieldset)=>{ 17507 const list = defsByFieldset.get(fieldset.code) ?? []; 17508 const section = buildSection(entityId2, fieldset.code, list, fieldset); 17509 if (section) sections.push(section); 17510 }); 17511 const unassigned = defsByFieldset.get(null); 17512 if (unassigned?.length) { 17513 const section = buildSection(entityId2, null, unassigned, void 0); 17514 if (section) sections.push(section); 17515 } 17516 } 17517 if (!sections.length && hasFieldsets) { 17518 const fallbackCode = availableFieldsets[0]?.code ?? null; 17519 sections.push(createEmptySection(fallbackCode)); 17520 } 17521 layout.push({ 17522 entityId: entityId2, 17523 sections, 17524 availableFieldsets, 17525 singleFieldsetPerRecord, 17526 hasFieldsets, 17527 activeFieldset: cfFieldsetSelections[entityId2] ?? availableFieldsets[0]?.code ?? null 17528 }); 17529 }); 17530 return { 17531 cfFields: aggregated, 17532 customFieldLayout: layout 17533 }; 17534 }, [ 17535 cfDefinitions, 17536 cfFieldsetSelections, 17537 customEntity, 17538 customFieldsLabel, 17539 entitySettings, 17540 fieldsetsByEntity, 17541 resolvedEntityIds 17542 ]); 17543 const injectedFieldDefinitions = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17544 const definitions = []; 17545 for (const widget of injectedFieldWidgets){ 17546 if (!("fields" in widget)) continue; 17547 for (const field of widget.fields ?? []){ 17548 definitions.push(field); 17549 } 17550 } 17551 return definitions; 17552 }, [ 17553 injectedFieldWidgets 17554 ]); 17555 const injectedFieldContext = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17556 const recordValues = values; 17557 const organizationId = typeof recordValues.organizationId === "string" ? recordValues.organizationId : null; 17558 const tenantId = typeof recordValues.tenantId === "string" ? recordValues.tenantId : null; 17559 const userId = typeof recordValues.userId === "string" ? recordValues.userId : null; 17560 return { 17561 organizationId, 17562 tenantId, 17563 userId,
17564 record: recordValues 17565 }; 17566 }, [ 17567 values 17568 ]); 17569 const hiddenBaseFieldIds = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17570 const hidden = /* @__PURE__ */ new Set(); 17571 const recordValues = values; 17572 for (const field of fields){ 17573 if (!evaluateFieldVisibility(field.visibleWhen, recordValues)) { 17574 hidden.add(field.id); 17575 } 17576 } 17577 return hidden; 17578 }, [ 17579 fields, 17580 values 17581 ]); 17582 const hiddenInjectedFieldIds = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17583 const hidden = /* @__PURE__ */ new Set(); 17584 for (const definition of injectedFieldDefinitions){ 17585 if (!evaluateInjectedVisibility(definition.visibleWhen, values, injectedFieldContext)) { 17586 hidden.add(definition.id); 17587 } 17588 } 17589 return hidden; 17590 }, [ 17591 injectedFieldContext, 17592 injectedFieldDefinitions, 17593 values 17594 ]); 17595 const injectedFieldIdSet = __TURBOPACK__imported__module__271645__["useMemo"](()=>new Set(injectedFieldDefinitions.map((definition)=>definition.id)), [ 17596 injectedFieldDefinitions 17597 ]); 17598 const injectedCrudFields = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17599 return injectedFieldDefinitions.map((definition)=>{ 17600 const injectedFieldRendersOwnLabel = !(definition.type === "custom" && definition.customComponent); 17601 return { 17602 id: definition.id, 17603 label: injectedFieldRendersOwnLabel ? "" : definition.label, 17604 type: "custom", 17605 readOnly: definition.readOnly, 17606 component: ({ value, setValue: setValue2, values: formValues })=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(InjectedField, { 17607 field: definition, 17608 value, 17609 onChange: (_, nextValue)=>setValue2(nextValue), 17610 context: injectedFieldContext, 17611 formData: formValues ?? values 17612 }) 17613 }; 17614 }); 17615 }, [ 17616 injectedFieldContext, 17617 injectedFieldDefinitions, 17618 values 17619 ]); 17620 const allFields = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17621 const base = [ 17622 ...fields, 17623 ...injectedCrudFields 17624 ]; 17625 if (groups) { 17626 const provided2 = new Set(base.map((f)=>f.id)); 17627 for (const group of groups){ 17628 if (!group.fields) continue; 17629 for (const entry of group.fields){ 17630 if (typeof entry === "string") continue; 17631 if (!provided2.has(entry.id)) { 17632 provided2.add(entry.id); 17633 base.push(entry); 17634 } 17635 } 17636 } 17637 } 17638 if (!cfFields.length) return base; 17639 const provided = new Set(base.map((f)=>f.id)); 17640 const extras = cfFields.filter((f)=>!provided.has(f.id)); 17641 return [ 17642 ...base, 17643 ...extras 17644 ]; 17645 }, [ 17646 fields, 17647 injectedCrudFields, 17648 cfFields, 17649 groups 17650 ]); 17651 const fieldById = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17652 return new globalThis.Map(allFields.map((f)=>[ 17653 f.id, 17654 f 17655 ])); 17656 }, [ 17657 allFields 17658 ]); 17659 const dotPathBaseFieldIds = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17660 const ids = /* @__PURE__ */ new Set(); 17661 const cfFieldIds = new Set(cfFields.map((field)=>field.id)); 17662 for (const field of allFields){ 17663 const fieldId = field.id; 17664 if (!fieldId.includes(".")) continue; 17665 if (injectedFieldIdSet.has(fieldId)) continue; 17666 if (fieldId.startsWith("cf_") || fieldId.startsWith("cf:")) continue; 17667 if (cfFieldIds.has(fieldId)) continue; 17668 ids.add(fieldId); 17669 } 17670 return ids; 17671 }, [ 17672 allFields, 17673 injectedFieldIdSet, 17674 cfFields 17675 ]); 17676 const validateFieldOnBlur = __TURBOPACK__imported__module__271645__["useCallback"](async (fieldId, sourceValues)=>{ 17677 if (formReadOnly) return; 17678 const field = fieldById.get(fieldId); 17679 if (!field || field.disabled) return; 17680 if (hiddenBaseFieldIds.has(fieldId) || hiddenInjectedFieldIds.has(fieldId)) return; 17681 const nextValues = sourceValues ?? valuesRef.current; 17682 const nextFieldErrors = {}; 17683 const requiredMessage = t("ui.forms.errors.required"); 17684 const value = nextValues[fieldId]; 17685 const isArray = Array.isArray(value); 17686 const isString = typeof value === "string"; 17687 const empty = value === void 0 || value === null || isString && value.trim() === "" || isArray && value.length === 0 || field.type === "checkbox" && value !== true; 17688 if (field.required && empty) { 17689 nextFieldErrors[fieldId] = requiredMessage; 17690 } 17691 const customFieldKey = customEntity ? cfDefinitions.some((definition)=>definition.key === fieldId) ? fieldId : null : fieldId.startsWith("cf_") ? fieldId.replace(/^cf_/, "") : null; 17692 if (!Object.keys(nextFieldErrors).length && customFieldKey) { 17693 const defsForField = cfDefinitions.filter((definition)=>definition.key === customFieldKey); 17694 if (defsForField.length) { 17695 try { 17696 const { validateValuesAgainstDefs } = await __turbopack_context__.A(908644); 17697 const validationResult = validateValuesAgainstDefs({ 17698 [customFieldKey]: value 17699 }, mapDefsForValidation(defsForField)); 17700 if (!validationResult.ok) { 17701 const normalizedFieldErrors = customEntity ? Object.fromEntries(Object.entries(validationResult.fieldErrors).map(([key, message])=>[ 17702 key.replace(/^cf_/, ""), 17703 String(message) 17704 ])) : Object.fromEntries(Object.entries(validationResult.fieldErrors).map(([key, message])=>[ 17705 key, 17706 String(message) 17707 ])); 17708 const transformedErrors = await transformValidationErrors(normalizedFieldErrors); 17709 Object.assign(nextFieldErrors, translateValidationErrors(transformedErrors)); 17710 } 17711 } catch {} 17712 } 17713 } 17714 if (!Object.keys(nextFieldErrors).length && schema) { 17715 const widgetValues = { 17716 ...nextValues 17717 }; 17718 for (const hiddenId of hiddenInjectedFieldIds){ 17719 delete widgetValues[hiddenId]; 17720 } 17721 const coreValues = { 17722 ...widgetValues 17723 }; 17724 for (const injectedId of injectedFieldIdSet){ 17725 delete coreValues[injectedId]; 17726 } 17727 const result = schema.safeParse(collapseDotPathFields(coreValues, dotPathBaseFieldIds)); 17728 if (!result.success) { 17729 const schemaFieldErrors = {};
17730 result.error.issues.forEach((issue)=>{ 17731 const path = serializeIssuePath(issue.path); 17732 if (!path) return; 17733 if (path === fieldId || path.startsWith(`${fieldId}.`) || fieldId.startsWith(`${path}.`)) { 17734 schemaFieldErrors[path] = issue.message; 17735 } 17736 }); 17737 if (Object.keys(schemaFieldErrors).length) { 17738 const transformedErrors = await transformValidationErrors(schemaFieldErrors); 17739 Object.assign(nextFieldErrors, translateValidationErrors(transformedErrors)); 17740 } 17741 } 17742 } 17743 setErrors((prev)=>{ 17744 const next = Object.fromEntries(Object.entries(prev).filter(([existingFieldId])=>!(existingFieldId === fieldId || existingFieldId.startsWith(`${fieldId}.`) || fieldId.startsWith(`${existingFieldId}.`)))); 17745 for (const [key, message] of Object.entries(nextFieldErrors)){ 17746 next[key] = message; 17747 } 17748 const same = Object.keys(next).length === Object.keys(prev).length && Object.entries(next).every(([key, message])=>prev[key] === message); 17749 return same ? prev : next; 17750 }); 17751 }, [ 17752 cfDefinitions, 17753 customEntity, 17754 dotPathBaseFieldIds, 17755 fieldById, 17756 formReadOnly, 17757 hiddenBaseFieldIds, 17758 hiddenInjectedFieldIds, 17759 injectedFieldIdSet, 17760 mapDefsForValidation, 17761 schema, 17762 t, 17763 transformValidationErrors, 17764 translateValidationErrors 17765 ]); 17766 const allFieldsRef = __TURBOPACK__imported__module__271645__["useRef"](allFields); 17767 allFieldsRef.current = allFields; 17768 const dynamicOptionLoaderKey = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17769 return allFields.filter((f)=>f.type !== "custom" && typeof f.loadOptions === "function").map((f)=>f.id).join("\0"); 17770 }, [ 17771 allFields 17772 ]); 17773 const injectionGroupCards = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17774 if (!injectionWidgets || injectionWidgets.length === 0) return []; 17775 const pairs = injectionWidgets.filter((widget)=>(widget.placement?.kind ?? "stack") === "group").map((widget)=>{ 17776 const priority = typeof widget.placement?.priority === "number" ? widget.placement.priority : 0; 17777 const group = { 17778 id: `widget:${widget.widgetId}`, 17779 title: widget.placement?.groupLabel ?? widget.module.metadata.title, 17780 description: widget.placement?.groupDescription ?? widget.module.metadata.description, 17781 column: widget.placement?.column === 2 ? 2 : 1, 17782 component: ()=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(widget.module.Widget, { 17783 context: injectionContext, 17784 data: values, 17785 onDataChange: (next)=>setValues(next), 17786 disabled: pending 17787 }) 17788 }; 17789 return { 17790 group, 17791 priority 17792 }; 17793 }); 17794 pairs.sort((a, b)=>b.priority - a.priority); 17795 return pairs.map((p)=>p.group); 17796 }, [ 17797 injectionWidgets, 17798 injectionContext, 17799 pending, 17800 setValues, 17801 values 17802 ]); 17803 const groupsWithInjectedFields = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17804 if (!groups || groups.length === 0 || injectedFieldDefinitions.length === 0) return groups; 17805 const cloned = groups.map((group)=>({ 17806 ...group, 17807 fields: [ 17808 ...group.fields ?? [] 17809 ] 17810 })); 17811 const fallbackIndex = cloned.length - 1; 17812 for (const definition of injectedFieldDefinitions){ 17813 const targetIndex = cloned.findIndex((group)=>group.id === definition.group); 17814 const index = targetIndex >= 0 ? targetIndex : fallbackIndex; 17815 if (targetIndex < 0 && ("TURBOPACK compile-time value", "production") !== "production") //TURBOPACK unreachable 17816 ; 17817 if (index < 0) continue; 17818 const fieldEntries = cloned[index].fields ?? []; 17819 const alreadyPresent = fieldEntries.some((entry)=>{ 17820 const entryId = typeof entry === "string" ? entry : entry.id; 17821 return entryId === definition.id; 17822 }); 17823 cloned[index].fields = alreadyPresent ? fieldEntries : (0, __TURBOPACK__imported__module__238232__["insertByInjectionPlacement"])(fieldEntries, definition.id, definition.placement, (entry)=>typeof entry === "string" ? entry : entry.id); 17824 } 17825 return cloned; 17826 }, [ 17827 groups, 17828 injectedFieldDefinitions 17829 ]); 17830 const shouldAutoGroup = (!groupsWithInjectedFields || groupsWithInjectedFields.length === 0) && injectionGroupCards.length > 0; 17831 const resolvedGroupsForLayout = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17832 const baseGroups = groupsWithInjectedFields && groupsWithInjectedFields.length ? groupsWithInjectedFields : []; 17833 const autoGroup = shouldAutoGroup ? [ 17834 { 17835 id: "__auto-fields__", 17836 fields: allFields 17837 } 17838 ] : []; 17839 return [ 17840 ...baseGroups.length ? baseGroups : autoGroup, 17841 ...injectionGroupCards 17842 ]; 17843 }, [ 17844 allFields, 17845 groupsWithInjectedFields, 17846 injectionGroupCards, 17847 shouldAutoGroup 17848 ]); 17849 const useGroupedLayout = resolvedGroupsForLayout.length > 0; 17850 const defaultGroupIds = __TURBOPACK__imported__module__271645__["useMemo"](()=>resolvedGroupsForLayout.map((g)=>g.id), [ 17851 resolvedGroupsForLayout 17852 ]); 17853 const { orderedIds: sortedGroupIds, reorder: reorderGroups } = useGroupOrder(sortablePageType, defaultGroupIds); 17854 const sortableSensors = (0, __TURBOPACK__imported__module__477183__["useSensors"])((0, __TURBOPACK__imported__module__477183__["useSensor"])(__TURBOPACK__imported__module__477183__["PointerSensor"], { 17855 activationConstraint: { 17856 distance: 5 17857 } 17858 }), (0, __TURBOPACK__imported__module__477183__["useSensor"])(GuardedKeyboardSensor)); 17859 const handleGroupDragEnd = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 17860 const { active, over } = event; 17861 if (!over || active.id === over.id) return; 17862 const oldIndex = sortedGroupIds.indexOf(String(active.id)); 17863 const newIndex = sortedGroupIds.indexOf(String(over.id)); 17864 if (oldIndex !== -1 && newIndex !== -1) reorderGroups(oldIndex, newIndex); 17865 }, [ 17866 sortedGroupIds, 17867 reorderGroups 17868 ]); 17869 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 17870 if (!collapsibleGroupsEnabled || Object.keys(errors).length === 0) return; 17871 const errorFieldIds = new Set(Object.keys(errors)); 17872 for (const g of resolvedGroupsForLayout){ 17873 const groupFieldIds = (g.fields ?? []).map((f)=>typeof f === "string" ? f : f.id); 17874 const hasError = groupFieldIds.some((id)=>errorFieldIds.has(id)); 17875 if (hasError) { 17876 groupCollapseRefs.current.get(g.id)?.expand(); 17877 } 17878 } 17879 }, [ 17880 errors, 17881 collapsibleGroupsEnabled, 17882 resolvedGroupsForLayout 17883 ]); 17884 const stackedInjectionWidgets = __TURBOPACK__imported__module__271645__["useMemo"](()=>(injectionWidgets ?? []).filter((widget)=>(widget.placement?.kind ?? "stack") === "stack"), [ 17885 injectionWidgets 17886 ]); 17887 const placedCustomFieldIds = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17888 const placed = /* @__PURE__ */ new Set(); 17889 for (const other of groups ?? []){ 17890 if (other.kind === "customFields" || !other.fields) continue; 17891 for (const entry of other.fields){ 17892 if (typeof entry === "string") placed.add(entry); 17893 else if (entry && typeof entry.id === "string") placed.add(entry.id); 17894 } 17895 } 17896 return placed; 17897 }, [ 17898 groups 17899 ]); 17900 const resolveGroupFields = __TURBOPACK__imported__module__271645__["useCallback"]((g)=>{ 17901 if (g.kind === "customFields") { 17902 return cfFields.filter((f)=>!placedCustomFieldIds.has(f.id)); 17903 }
17904 const src = g.fields || []; 17905 const result = []; 17906 for (const item of src){ 17907 if (typeof item === "string") { 17908 const found = fieldById.get(item); 17909 if (found) result.push(found); 17910 } else if (item) { 17911 result.push(item); 17912 } 17913 } 17914 return result; 17915 }, [ 17916 cfFields, 17917 fieldById, 17918 placedCustomFieldIds 17919 ]); 17920 const customFieldsManageHref = __TURBOPACK__imported__module__271645__["useMemo"](()=>buildCustomFieldsManageHref(primaryEntityId), [ 17921 buildCustomFieldsManageHref, 17922 primaryEntityId 17923 ]); 17924 const customFieldsEmptyState = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17925 const text = t("entities.customFields.empty"); 17926 const action = t("entities.customFields.addFirst"); 17927 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 17928 className: "rounded-md border border-dashed border-muted-foreground/50 bg-muted/30 px-3 py-4 text-sm text-muted-foreground", 17929 children: [
17930 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("span", { 17931 children: [ 17932 text, 17933 " " 17934 ] 17935 }), 17936 customFieldsManageHref ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__522016__["default"], { 17937 href: customFieldsManageHref, 17938 className: "font-medium text-primary hover:underline", 17939 children: action 17940 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 17941 className: "font-medium text-foreground", 17942 children: action 17943 }) 17944 ] 17945 }); 17946 }, [ 17947 customFieldsManageHref, 17948 t 17949 ]); 17950 const firstFieldId = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 17951 if (useGroupedLayout) { 17952 const col1 = []; 17953 const col2 = []; 17954 for (const g of resolvedGroupsForLayout){ 17955 if ((g.column ?? 1) === 2) col2.push(g); 17956 else col1.push(g); 17957 } 17958 const scan = (list)=>{ 17959 for (const group of list){ 17960 const resolved = resolveGroupFields(group); 17961 for (const field of resolved){ 17962 if (field?.id && !field.disabled) return field.id; 17963 } 17964 } 17965 return null; 17966 }; 17967 const fromCol1 = scan(col1); 17968 if (fromCol1) return fromCol1; 17969 const fromCol2 = scan(col2); 17970 if (fromCol2) return fromCol2; 17971 } 17972 for (const field of allFields){ 17973 if (field?.id && !field.disabled) return field.id; 17974 } 17975 return null; 17976 }, [ 17977 allFields, 17978 resolveGroupFields, 17979 resolvedGroupsForLayout, 17980 useGroupedLayout 17981 ]); 17982 const requestSubmit = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 17983 if (formReadOnly) return; 17984 if (typeof document === "undefined") return; 17985 const form = document.getElementById(formId); 17986 form?.requestSubmit(); 17987 }, [ 17988 formId, 17989 formReadOnly 17990 ]); 17991 const lastFocusedFieldRef = __TURBOPACK__imported__module__271645__["useRef"](null); 17992 const lastErrorFieldRef = __TURBOPACK__imported__module__271645__["useRef"](null); 17993 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 17994 if (("TURBOPACK compile-time value", "object") === "undefined" || typeof document === "undefined") return; 17995 if (disableInitialFocus || isLoading || isLoadingCustomFields || formReadOnly) { 17996 lastFocusedFieldRef.current = null; 17997 return; 17998 } 17999 if (!firstFieldId) return; 18000 if (lastFocusedFieldRef.current === firstFieldId) return; 18001 const run = ()=>{ 18002 const form = document.getElementById(formId); 18003 if (!form) return; 18004 const active = typeof document !== "undefined" ? document.activeElement : null; 18005 if (active && form.contains(active)) { 18006 return; 18007 } 18008 const container = form.querySelector(`[data-crud-field-id="${firstFieldId}"]`); 18009 const target = container?.querySelector(FOCUSABLE_SELECTOR) ?? form.querySelector(FOCUSABLE_SELECTOR); 18010 if (target && typeof target.focus === "function") { 18011 target.focus({ 18012 preventScroll: true 18013 }); 18014 if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) { 18015 try { 18016 target.select(); 18017 } catch {} 18018 } 18019 lastFocusedFieldRef.current = firstFieldId; 18020 } 18021 }; 18022 const frame = typeof window.requestAnimationFrame === "function" ? window.requestAnimationFrame(run) : window.setTimeout(run, 0); 18023 return ()=>{ 18024 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 18025 ; 18026 if (typeof window.cancelAnimationFrame === "function") { 18027 window.cancelAnimationFrame(frame); 18028 } else { 18029 window.clearTimeout(frame); 18030 } 18031 }; 18032 }, [ 18033 disableInitialFocus, 18034 firstFieldId, 18035 formId, 18036 formReadOnly, 18037 isLoading, 18038 isLoadingCustomFields 18039 ]); 18040 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 18041 if (("TURBOPACK compile-time value", "object") === "undefined" || typeof document === "undefined") return; 18042 const entries = Object.entries(errors); 18043 if (!entries.length) { 18044 lastErrorFieldRef.current = null; 18045 return; 18046 } 18047 const [fieldId] = entries[0]; 18048 if (!fieldId || lastErrorFieldRef.current === fieldId) return; 18049 const form = document.getElementById(formId); 18050 if (!form) return; 18051 const active = document.activeElement; 18052 if (active instanceof HTMLElement && form.contains(active)) { 18053 lastErrorFieldRef.current = fieldId; 18054 return; 18055 } 18056 const container = form.querySelector(`[data-crud-field-id="${fieldId}"]`); 18057 const target = container?.querySelector(FOCUSABLE_SELECTOR) ?? form.querySelector(`[name="${fieldId}"]`) ?? container ?? null;
18058 if (target && typeof target.focus === "function") { 18059 target.focus(); 18060 if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) { 18061 try { 18062 target.select(); 18063 } catch {} 18064 } 18065 lastErrorFieldRef.current = fieldId; 18066 } 18067 }, [ 18068 errors, 18069 formId 18070 ]); 18071 const scrollToInjectionBlockedTarget = __TURBOPACK__imported__module__271645__["useCallback"]((fieldErrors)=>{ 18072 if (typeof document === "undefined") return; 18073 const form = document.getElementById(formId); 18074 if (!form) return; 18075 let target = null; 18076 for (const fieldId of fieldErrors ? Object.keys(fieldErrors) : []){ 18077 const fieldContainer = form.querySelector(`[data-crud-field-id="${fieldId}"]`); 18078 if (fieldContainer) { 18079 target = fieldContainer; 18080 break; 18081 } 18082 } 18083 if (!target) { 18084 target = form.querySelector("[data-crud-injection-region]"); 18085 } 18086 if (target && typeof target.scrollIntoView === "function") { 18087 target.scrollIntoView({ 18088 behavior: "smooth", 18089 block: "center" 18090 }); 18091 } 18092 }, [ 18093 formId 18094 ]); 18095 const updateEditedFieldMarker = __TURBOPACK__imported__module__271645__["useCallback"]((id, nextValue, baselineSource = dirtyBaselineValuesRef.current)=>{ 18096 if (baselineSource && createDirtyValueSnapshot(baselineSource[id]) === createDirtyValueSnapshot(nextValue)) { 18097 userEditedFieldIdsRef.current.delete(id); 18098 return; 18099 } 18100 userEditedFieldIdsRef.current.add(id); 18101 }, []); 18102 const setValue = __TURBOPACK__imported__module__271645__["useCallback"]((id, nextValue)=>{ 18103 let nextData = null; 18104 let nextDirty = null; 18105 const currentValue = valuesRef.current[id]; 18106 if (!Object.is(currentValue, nextValue)) { 18107 updateEditedFieldMarker(id, nextValue); 18108 } 18109 setValues((prev)=>{ 18110 if (Object.is(prev[id], nextValue)) return prev; 18111 const baselineSource = dirtyBaselineValuesRef.current ?? prev; 18112 updateEditedFieldMarker(id, nextValue, baselineSource); 18113 nextData = { 18114 ...prev, 18115 [id]: nextValue 18116 }; 18117 valuesRef.current = nextData; 18118 if (!(embedded && !trackDirtyWhenEmbedded)) { 18119 const baseline = dirtyBaselineSnapshotRef.current ?? createDirtySnapshot(prev); 18120 dirtyBaselineSnapshotRef.current = baseline; 18121 dirtyBaselineValuesRef.current = baselineSource; 18122 nextDirty = createDirtySnapshot(nextData) !== baseline; 18123 } 18124 return nextData; 18125 }); 18126 if (nextDirty !== null) { 18127 isDirtyRef.current = nextDirty; 18128 setHasUnsavedChanges(nextDirty); 18129 } 18130 const clearedMessages = []; 18131 setErrors((prev)=>{ 18132 if (!Object.keys(prev).length) return prev; 18133 let changed = false; 18134 const nextEntries = Object.entries(prev).filter(([fieldId, message])=>{ 18135 const shouldClear = fieldId === id || fieldId.startsWith(`${id}.`) || id.startsWith(`${fieldId}.`); 18136 if (shouldClear) { 18137 changed = true; 18138 clearedMessages.push(message); 18139 } 18140 return !shouldClear; 18141 }); 18142 return changed ? Object.fromEntries(nextEntries) : prev; 18143 }); 18144 if (clearedMessages.length) { 18145 const highlightedMessage = t("ui.forms.errors.highlighted"); 18146 const translatedMessages = new Set(clearedMessages.map((message)=>translateValidationMessage(message)).filter((message)=>message.trim().length > 0)); 18147 setFormError((prev)=>{ 18148 if (!prev) return prev; 18149 const normalized = prev.trim(); 18150 if (!normalized) return null; 18151 if (normalized === highlightedMessage || translatedMessages.has(normalized)) { 18152 return null; 18153 } 18154 return prev; 18155 }); 18156 } 18157 if (!nextData || !extendedInjectionEventsEnabled) return; 18158 void triggerInjectionEvent("onFieldChange", nextData, injectionContextRef.current, { 18159 fieldId: id, 18160 fieldValue: nextValue 18161 }).then((result)=>{ 18162 if (!result.ok) return; 18163 const change = result.fieldChange; 18164 if (!change) return; 18165 const updates = { 18166 ...change.sideEffects ?? {} 18167 }; 18168 if (change.value !== void 0) { 18169 updates[id] = change.value; 18170 } 18171 if (Object.keys(updates).length > 0) { 18172 setValues((prev)=>{ 18173 let changed = false;
18174 const next = { 18175 ...prev 18176 }; 18177 for (const [key, value] of Object.entries(updates)){ 18178 if (Object.is(next[key], value)) continue; 18179 next[key] = value; 18180 changed = true; 18181 } 18182 return changed ? next : prev; 18183 }); 18184 } 18185 for (const message of change.messages ?? []){ 18186 (0, __TURBOPACK__imported__module__484973__["flash"])(message.text, message.severity); 18187 } 18188 }).catch((err)=>{ 18189 logger.error("Error in onFieldChange", { 18190 err 18191 }); 18192 }); 18193 }, [ 18194 embedded, 18195 extendedInjectionEventsEnabled, 18196 __TURBOPACK__imported__module__484973__["flash"], 18197 t, 18198 trackDirtyWhenEmbedded, 18199 translateValidationMessage, 18200 triggerInjectionEvent, 18201 updateEditedFieldMarker 18202 ]); 18203 const onBlurRequest = __TURBOPACK__imported__module__271645__["useCallback"]((fieldId)=>{ 18204 void validateFieldOnBlur(fieldId); 18205 }, [ 18206 validateFieldOnBlur 18207 ]); 18208 const handleFieldsetSelectionChange = __TURBOPACK__imported__module__271645__["useCallback"]((entityId2, nextCode)=>{ 18209 setCfFieldsetSelections((prev)=>({ 18210 ...prev, 18211 [entityId2]: nextCode 18212 })); 18213 const bindingKey = customFieldsetBindings?.[entityId2]?.valueKey; 18214 if (bindingKey) { 18215 setValue(bindingKey, nextCode ?? void 0); 18216 } 18217 }, [ 18218 customFieldsetBindings, 18219 setValue 18220 ]); 18221 const handleOpenFieldsetEditor = __TURBOPACK__imported__module__271645__["useCallback"]((entityId2, fieldsetCode, view = "entity")=>{ 18222 const href = buildCustomFieldsManageHref(entityId2); 18223 if (!href) return; 18224 if (customFieldsManageMode === "page") { 18225 const params = fieldsetCode ? `${href.includes("?") ? "&" : "?"}fieldset=${encodeURIComponent(fieldsetCode)}` : ""; 18226 if ("TURBOPACK compile-time truthy", 1) window.open(`${href}${params}`, "_blank", "noopener"); 18227 return; 18228 } 18229 setFieldsetEditorTarget({ 18230 entityId: entityId2, 18231 fieldsetCode, 18232 view 18233 }); 18234 }, [ 18235 buildCustomFieldsManageHref, 18236 customFieldsManageMode 18237 ]); 18238 const appliedInitialValuesSnapshotRef = __TURBOPACK__imported__module__271645__["useRef"](void 0); 18239 const dirtyBaselineSnapshotRef = __TURBOPACK__imported__module__271645__["useRef"](void 0); 18240 const dirtyBaselineValuesRef = __TURBOPACK__imported__module__271645__["useRef"](void 0); 18241 const userEditedFieldIdsRef = __TURBOPACK__imported__module__271645__["useRef"](/* @__PURE__ */ new Set()); 18242 __TURBOPACK__imported__module__271645__["useLayoutEffect"](()=>{ 18243 if (!initialValues) return; 18244 const snapshot = JSON.stringify({ 18245 initialValues, 18246 injectedFieldIds: injectedFieldDefinitions.map((definition)=>definition.id), 18247 customFieldMappings: cfDefinitions.map((definition)=>definition.key), 18248 dotPathBaseFieldIds: Array.from(dotPathBaseFieldIds) 18249 }); 18250 if (appliedInitialValuesSnapshotRef.current === snapshot) return; 18251 appliedInitialValuesSnapshotRef.current = snapshot; 18252 const initialRecord = initialValues; 18253 let mergedValues = null; 18254 let hadUnsavedEdits = false; 18255 setValues((prev)=>{ 18256 const priorBaseline = dirtyBaselineSnapshotRef.current; 18257 const editedFieldIds = userEditedFieldIdsRef.current; 18258 hadUnsavedEdits = editedFieldIds.size > 0 || priorBaseline !== void 0 && createDirtySnapshot(prev) !== priorBaseline; 18259 const merged = { 18260 ...prev 18261 }; 18262 const mergedRecord = merged; 18263 for (const [key, value] of Object.entries(initialValues)){ 18264 if (editedFieldIds.has(key)) continue; 18265 mergedRecord[key] = value; 18266 } 18267 for (const definition of injectedFieldDefinitions){ 18268 if (merged[definition.id] !== void 0) continue; 18269 const extracted = readByDotPath(initialRecord, definition.id); 18270 if (extracted !== void 0) { 18271 ; 18272 merged[definition.id] = extracted; 18273 } 18274 } 18275 for (const definition of cfDefinitions){ 18276 const targetId = customEntity ? definition.key : `cf_${definition.key}`; 18277 if (!targetId || merged[targetId] !== void 0) continue; 18278 const extracted = readInitialCustomFieldValue(initialRecord, definition.key); 18279 if (extracted !== void 0) { 18280 ; 18281 merged[targetId] = extracted; 18282 } 18283 } 18284 for (const fieldId of dotPathBaseFieldIds){ 18285 if (merged[fieldId] !== void 0) continue; 18286 const extracted = readByDotPath(initialRecord, fieldId); 18287 if (extracted !== void 0) { 18288 ; 18289 merged[fieldId] = extracted; 18290 } 18291 } 18292 mergedValues = merged; 18293 return mergedValues; 18294 }); 18295 if (mergedValues && !hadUnsavedEdits) { 18296 dirtyBaselineSnapshotRef.current = createDirtySnapsh
18296ot(mergedValues); 18297 dirtyBaselineValuesRef.current = { 18298 ...mergedValues 18299 }; 18300 } 18301 if (!extendedInjectionEventsEnabled || !mergedValues) return; 18302 let cancelled = false; 18303 const run = async ()=>{ 18304 try { 18305 const result = await triggerInjectionEvent("transformDisplayData", mergedValues, injectionContextRef.current); 18306 const transformed = result.data; 18307 if (cancelled || !transformed) return; 18308 if (isDirtyRef.current) return; 18309 dirtyBaselineSnapshotRef.current = createDirtySnapshot(transformed); 18310 dirtyBaselineValuesRef.current = { 18311 ...transformed 18312 }; 18313 setValues(transformed); 18314 } catch (err) { 18315 logger.error("Error in transformDisplayData", { 18316 err 18317 }); 18318 } 18319 }; 18320 void run(); 18321 return ()=>{ 18322 cancelled = true; 18323 }; 18324 }, [ 18325 cfDefinitions, 18326 customEntity, 18327 dotPathBaseFieldIds, 18328 extendedInjectionEventsEnabled, 18329 initialValues, 18330 injectedFieldDefinitions, 18331 triggerInjectionEvent 18332 ]); 18333 const cfDefaultsAppliedRef = __TURBOPACK__imported__module__271645__["useRef"](false); 18334 const initialValuesHasId = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 18335 if (!initialValues) return false; 18336 const raw = initialValues.id; 18337 return raw !== void 0 && raw !== null && raw !== ""; 18338 }, [ 18339 initialValues 18340 ]); 18341 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 18342 if (isLoading) return; 18343 if (initialValuesHasId) return; 18344 if (!cfDefinitions.length) return; 18345 if (cfDefaultsAppliedRef.current) return; 18346 cfDefaultsAppliedRef.current = true; 18347 const defaults = {}; 18348 const prefix = customEntity ? "" : "cf_"; 18349 for (const def of cfDefinitions){ 18350 if (def.defaultValue === void 0 || def.defaultValue === null) continue; 18351 const fieldId = `${prefix}${def.key}`; 18352 defaults[fieldId] = def.defaultValue; 18353 } 18354 if (Object.keys(defaults).length === 0) return; 18355 let mergedValues = null; 18356 setValues((prev)=>{ 18357 const merged = { 18358 ...prev 18359 }; 18360 let applied = false; 18361 for (const [fieldId, defaultVal] of Object.entries(defaults)){ 18362 if (merged[fieldId] !== void 0) continue; 18363 merged[fieldId] = defaultVal; 18364 applied = true; 18365 } 18366 if (!applied) return prev; 18367 mergedValues = merged; 18368 return mergedValues; 18369 }); 18370 if (mergedValues) { 18371 dirtyBaselineSnapshotRef.current = createDirtySnapshot(mergedValues); 18372 dirtyBaselineValuesRef.current = { 18373 ...mergedValues 18374 }; 18375 } 18376 }, [ 18377 isLoading, 18378 initialValuesHasId, 18379 cfDefinitions, 18380 customEntity 18381 ]); 18382 const markFormAsClean = __TURBOPACK__imported__module__271645__["useCallback"]((snapshotSource)=>{ 18383 clearDirtyState(snapshotSource); 18384 }, [ 18385 clearDirtyState 18386 ]); 18387 const buildFieldsetEditorHref = __TURBOPACK__imported__module__271645__["useCallback"]((includeViewParam)=>{ 18388 if (!fieldsetEditorTarget) return null; 18389 const base = buildCustomFieldsManageHref(fieldsetEditorTarget.entityId); 18390 if (!base) return null; 18391 const params = []; 18392 if (fieldsetEditorTarget.fieldsetCode) { 18393 params.push(`fieldset=${encodeURIComponent(fieldsetEditorTarget.fieldsetCode)}`); 18394 } 18395 if (includeViewParam && fieldsetEditorTarget.view === "fieldset") { 18396 params.push("view=fieldset"); 18397 } 18398 if (!params.length) return base; 18399 const connector = base.includes("?") ? "&" : "?"; 18400 return `${base}${connector}${params.join("&")}`; 18401 }, [ 18402 buildCustomFieldsManageHref, 18403 fieldsetEditorTarget 18404 ]); 18405 const fieldsetEditorFullHref = __TURBOPACK__imported__module__271645__["useMemo"](()=>buildFieldsetEditorHref(false), [ 18406 buildFieldsetEditorHref 18407 ]); 18408 const handleFieldsetDialogSave = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 18409 if (!fieldsetManagerRef.current) return; 18410 void fieldsetManagerRef.current.submit(); 18411 }, []); 18412 const handleSubmit = async (e)=>{ 18413 e.preventDefault(); 18414 if (formReadOnly) return; 18415 if (submittingRef.current) return; 18416 submittingRef.current = true; 18417 try { 18418 setFormError(null); 18419 setErrors({}); 18420 const requiredMessage = t("ui.forms.errors.required"); 18421 const highlightedMessage = t("ui.forms.errors.highlighted"); 18422 try { 18423 if (typeof document !== "undefined") { 18424 const activeElement = document.activeElement; 18425 if (activeElement instanceof HTMLElement) { 18426 activeElement.blur(); 18427 await new Promise((resolve)=>setTimeout(resolve, 0)); 18428 } 18429 } 18430 } catch {} 18431 const requiredErrors = {}; 18432 for (const field of allFields){ 18433 if (!field.required) continue; 18434 if (field.disabled) continue; 18435 if (hiddenBaseFieldIds.has(field.id) || hiddenInjectedFieldIds.has(field.id)) continue; 18436 const v = values[field.id]; 18437 const isArray = Array.isArray(v); 18438 const isString = typeof v === "string"; 18439 const empty = v === void 0 || v === null || isString && v.trim() === "" || isArray && v.length === 0 || field.type === "checkbox" && v !== true; 18440 if (empty) requiredErrors[field.id] = requiredMessage; 18441 } 18442 if (Object.keys(requiredErrors).length) { 18443 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 18444 ; 18445 const transformedErrors = await transformValidationErrors(requiredErrors); 18446 setErrors(transformedErrors); 18447 (0, __TURBOPACK__imported__module__484973__["flash"])(highlightedMessage, "error"); 18448 return; 18449 } 18450 if (resolvedEntityIds.length) { 18451 try { 18452 const defs = cfDefinitions.length ? cfDefinitions : await __turbopack_context__.A(679430).then((mod)=>mod.fetchCustomFieldDefs(resolvedEntityIds)); 18453 const { validateValuesAgainstDefs } = await __turbopack_context__.A(908644); 18454 const cfValues = {}; 18455 if (customEntity) { 18456 for (const def of defs){ 18457 if (Object.prototype.hasOwnProperty.call(values, def.key)) { 18458 cfValues[def.key] = values[def.key]; 18459 } 18460 } 18461 } else { 18462 for (const [k, v] of Object.entries(values)){ 18463 if (k.startsWith("cf_")) cfValues[k.replace(/^cf_/, "")] = v; 18464 } 18465 } 18466 const defsForValidation = mapDefsForValidation(defs); 18467 const result = validateValuesAgainstDefs(cfValues, defsForValidation); 18468 if (!result.ok) { 18469 if (customEntity) { 18470 const mapped = {}; 18471 for (const [ek, ev] of Object.entries(result.fieldErrors))mapped[ek.replace(/^cf_/, "")] = String(ev); 18472 const transformedErrors = await transformValidationErrors(mapped); 18473 setErrors((prev)=>({ 18474 ...prev, 18475 ...translateValidationErrors(transformedErrors) 18476 })); 18477 } else { 18478 const transformedErrors = await transformValidationErrors(Object.fromEntries(Object.entries(result.fieldErrors).map(([key, value])=>[ 18479 key, 18480 String(value) 18481 ]))); 18482 setErrors((prev)=>({ 18483 ...prev, 18484 ...translateValidationErrors(transformedErrors) 18485 })); 18486 } 18487 (0, __TURBOPACK__imported__module__484973__["flash"])(highlightedMessage, "error"); 18488 return; 18489 } 18490 } catch {} 18491 } 18492 const widgetValues = { 18493 ...valuesRef.current 18494 }; 18495 for (const hiddenId of hiddenInjectedFieldIds){ 18496 delete widgetValues[hiddenId]; 18497 } 18498 const coreValues = { 18499 ...widgetValues 18500 }; 18501 for (const injectedId of injectedFieldIdSet){ 18502 delete coreValues[injectedId]; 18503 } 18504 if (customEntity) { 18505 const allowedKeys = new Set(cfDefinitions.map((definition)=>
18505definition.key).filter(Boolean)); 18506 for (const key of Object.keys(coreValues)){ 18507 if (!allowedKeys.has(key)) delete coreValues[key]; 18508 } 18509 } 18510 let parsedValues; 18511 if (schema) { 18512 const res = schema.safeParse(collapseDotPathFields(coreValues, dotPathBaseFieldIds)); 18513 if (!res.success) { 18514 const fieldErrors = {}; 18515 res.error.issues.forEach((issue)=>{ 18516 const path = serializeIssuePath(issue.path); 18517 if (path) fieldErrors[path] = issue.message; 18518 }); 18519 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 18520 ; 18521 const transformedErrors = await transformValidationErrors(fieldErrors); 18522 setErrors(translateValidationErrors(transformedErrors)); 18523 (0, __TURBOPACK__imported__module__484973__["flash"])(highlightedMessage, "error"); 18524 return; 18525 } 18526 parsedValues = res.data; 18527 } else { 18528 parsedValues = coreValues; 18529 } 18530 let submitValues = widgetValues; 18531 let coreSubmitValues = parsedValues; 18532 if (extendedInjectionEventsEnabled) { 18533 try { 18534 const result = await triggerInjectionEvent("transformFormData", submitValues, injectionContext); 18535 if (result.data) { 18536 submitValues = result.data; 18537 const projectedCoreValues = { 18538 ...result.data 18539 }; 18540 for (const injectedId of injectedFieldIdSet){ 18541 delete projectedCoreValues[injectedId]; 18542 } 18543 if (customEntity) { 18544 const allowedKeys = new Set(cfDefinitions.map((definition)=>definition.key).filter(Boolean)); 18545 for (const key of Object.keys(projectedCoreValues)){ 18546 if (!allowedKeys.has(key)) delete projectedCoreValues[key]; 18547 } 18548 } 18549 coreSubmitValues = schema ? schema.parse(collapseDotPathFields(projectedCoreValues, dotPathBaseFieldIds)) : projectedCoreValues; 18550 if (result.applyToForm) { 18551 setValues(result.data); 18552 } 18553 } 18554 } catch (err) { 18555 logger.error("Error in transformFormData", { 18556 err 18557 }); 18558 } 18559 } 18560 let injectionRequestHeaders; 18561 if (resolvedInjectionSpotId) { 18562 try { 18563 const result = await triggerInjectionEvent("onBeforeSave", submitValues, injectionContext); 18564 if (!result.ok) { 18565 try { 18566 if ("TURBOPACK compile-time truthy", 1) { 18567 (0, __TURBOPACK__imported__module__781167__["dispatchBackendMutationError"])({ 18568 contextId: formId, 18569 formId, 18570 error: result.details ?? result 18571 }); 18572 window.dispatchEvent(new CustomEvent("om:crud-save-error", { 18573 detail: { 18574 formId, 18575 error: result.details ?? result 18576 } 18577 })); 18578 } 18579 } catch {} 18580 if (result.fieldErrors && Object.keys(result.fieldErrors).length) { 18581 const transformedErrors = await transformValidationErrors(result.fieldErrors); 18582 setErrors(translateValidationErrors(transformedErrors)); 18583 } 18584 const message = result.message || t("ui.forms.flash.saveBlocked", "Save blocked by validation"); 18585 (0, __TURBOPACK__imported__module__484973__["flash"])(message, "error"); 18586 scrollToInjectionBlockedTarget(result.fieldErrors); 18587 setPending(false); 18588 return; 18589 } 18590 injectionRequestHeaders = result.requestHeaders; 18591 } catch (err) { 18592 logger.error("Error in onBeforeSave", { 18593 err 18594 }); 18595 (0, __TURBOPACK__imported__module__484973__["flash"])(t("ui.forms.flash.saveBlocked", "Save blocked by validation"), "error"); 18596 setPending(false); 18597 return; 18598 } 18599 } 18600 setPending(true); 18601 const nativeSubmitter = "nativeEvent" in e ? e.nativeEvent.submitter : null; 18602 const submitContext = nativeSubmitter instanceof HTMLElement ? { 18603 submitter: { 18604 id: nativeSubmitter.id || void 0, 18605 name: "name" in nativeSubmitter && typeof nativeSubmitter.name === "string" && nativeSubmitter.name.trim().length > 0 ? nativeSubmitter.name : void 0, 18606 value: "value" in nativeSubmitter && typeof nativeSubmitter.value === "string" && nativeSubmitter.value.trim().length > 0 ? nativeSubmitter.value : void 0, 18607 dataset: Object.fromEntries(Object.entries(nativeSubmitter.dataset).filter((entry)=>typeof entry[1] === "string")) 18608 } 18609 } : void 0; 18610 if (resolvedInjectionSpotId) { 18611 try { 18612 await triggerInjectionEvent("onSave", submitValues, injectionContext); 18613 } catch (err) { 18614 logger.error("Error in onSave", { 18615 err 18616 }); 18617 (0, __TURBOPACK__imported__module__484973__["flash"])(t("ui.forms.flash.saveBlocked", "Save blocked by validation"), "error"); 18618 setPending(false); 18619 return; 18620 } 18621 } 18622 try { 18623 submitNavigationBypassRef.current = true; 18624 const optimisticLockHeader = (0, __TURBOPACK__imported__module__977896__["buildOptimisticLockHeader"])(resolvedOptimisticLockUpdatedAt); 18625 const mergedSubmitHeaders = { 18626 ...injectionRequestHeaders ?? {}, 18627 ...optimisticLockHeader 18628 }; 18629 if (Object.keys(mergedSubmitHeaders).length > 0) { 18630 await (0, __TURBOPACK__imported__module__490746__["withScopedApiRequestHeaders"])(mergedSubmitHeaders, async ()=>{ 18631 await onSubmit?.(coreSubmitValues, submitContext); 18632 }); 18633 } else { 18634 await onSubmit?.(coreSubmitValues, submitContext); 18635 } 18636 if (resolvedInjectionSpotId) { 18637 try { 18638 await triggerInjectionEvent("onAfterSave", submitValues, injectionContext); 18639 } catch (err) { 18640 logger.error("Error in onAfterSave", { 18641 err 18642 }); 18643 } 18644 } 18645 markFormAsClean(valuesRef.current); 18646 keepSubmitNavigationBypassAlive(); 18647 if (successRedirect) await navigateWithGuard(successRedirect); 18648 } catch (err) { 18649 clearSubmitNavigationBypass(); 18650 try { 18651 if ("TURBOPACK compile-time truthy", 1) { 18652 (0, __TURBOPACK__imported__module__781167__["dispatchBackendMutationError"])({ 18653 contextId: formId, 18654 formId, 18655 error: err 18656 }); 18657 window.dispatchEvent(new CustomEvent("om:crud-save-error", { 18658 detail: { 18659 formId, 18660 error: err 18661 } 18662 })); 18663 } 18664 } catch {} 18665 const { message: helperMessage, fieldErrors: serverFieldErrors } = (0, __TURBOPACK__imported__module__685008__["mapCrudServerErrorToFormErrors"])(err, { 18666 customEntity 18667 }); 18668 const combinedFieldErrors = serverFieldErrors ?? {}; 18669 const hasFieldErrors = Object.keys(combinedFieldErrors).length > 0; 18670 const firstFieldMessage = hasFieldErrors ? (()=>{ 18671 const firstKey = Object.keys(combinedFieldErrors)[0];
18672 if (!firstKey) return null; 18673 const value = combinedFieldErrors[firstKey]; 18674 if (typeof value !== "string" || !value.trim().length) return null; 18675 return translateValidationMessage(value); 18676 })() : null; 18677 if (hasFieldErrors) { 18678 const transformedErrors = await transformValidationErrors(combinedFieldErrors); 18679 setErrors(translateValidationErrors(transformedErrors)); 18680 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 18681 ; 18682 } 18683 const optimisticLockConflict = (0, __TURBOPACK__imported__module__977896__["extractOptimisticLockConflict"])(err); 18684 let displayMessage = optimisticLockConflict ? t("ui.forms.flash.recordModified", "This record was modified by someone else. Refresh and try again.") : typeof helperMessage === "string" && helperMessage.trim() ? helperMessage.trim() : ""; 18685 if (hasFieldErrors) { 18686 const lowered = displayMessage.toLowerCase(); 18687 const highlightedLower = highlightedMessage.toLowerCase(); 18688 if (!displayMessage || lowered === "invalid input" || lowered === highlightedLower) { 18689 displayMessage = firstFieldMessage ?? highlightedMessage; 18690 } 18691 } 18692 if (!displayMessage && err instanceof Error && typeof err.message === "string" && err.message.trim()) { 18693 displayMessage = err.message.trim(); 18694 } 18695 if (!displayMessage) { 18696 displayMessage = hasFieldErrors ? highlightedMessage : saveErrorMessage; 18697 } 18698 displayMessage = (0, __TURBOPACK__imported__module__685008__["parseServerMessage"])(displayMessage); 18699 if (optimisticLockConflict) { 18700 try { 18701 (0, __TURBOPACK__imported__module__372790__["surfaceRecordConflict"])(err, t); 18702 } catch {} 18703 } else if (!hasFieldErrors) { 18704 (0, __TURBOPACK__imported__module__484973__["flash"])(displayMessage, "error"); 18705 } 18706 setFormError(displayMessage); 18707 } finally{ 18708 setPending(false); 18709 } 18710 } finally{ 18711 submittingRef.current = false; 18712 } 18713 }; 18714 const dynamicOptionLoadersRef = __TURBOPACK__imported__module__271645__["useRef"](/* @__PURE__ */ new Map()); 18715 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 18716 let cancelled = false; 18717 const loadAll = async ()=>{ 18718 const loaders = allFieldsRef.current.filter((f)=>f.type !== "custom" && typeof f.loadOptions === "function").map(async (f)=>{ 18719 try { 18720 dynamicOptionLoadersRef.current.set(f.id, f.loadOptions); 18721 const opts = await f.loadOptions(); 18722 if (!cancelled) setDynamicOptions((prev)=>({ 18723 ...prev, 18724 [f.id]: opts 18725 })); 18726 } catch {} 18727 }); 18728 await Promise.all(loaders); 18729 }; 18730 loadAll(); 18731 return ()=>{ 18732 cancelled = true; 18733 }; 18734 }, [ 18735 dynamicOptionLoaderKey 18736 ]); 18737 const loadFieldOptions = __TURBOPACK__imported__module__271645__["useCallback"](async (field, query)=>{ 18738 if (!("type" in field) || field.type === "custom") return EMPTY_OPTIONS; 18739 const builtin = field; 18740 const loader = builtin.loadOptions; 18741 if (typeof loader === "function") { 18742 const previousLoader = dynamicOptionLoadersRef.current.get(field.id); 18743 const loaderChanged = previousLoader !== loader; 18744 dynamicOptionLoadersRef.current.set(field.id, loader); 18745 if (query === void 0 && !loaderChanged && Array.isArray(dynamicOptions[field.id])) { 18746 return dynamicOptions[field.id]; 18747 } 18748 try { 18749 const fetched = await loader(query); 18750 if (query === void 0) { 18751 setDynamicOptions((prev)=>({ 18752 ...prev, 18753 [field.id]: fetched 18754 })); 18755 } 18756 return fetched; 18757 } catch {
18758 return builtin.options ?? EMPTY_OPTIONS; 18759 } 18760 } 18761 return dynamicOptions[field.id] || builtin.options || EMPTY_OPTIONS; 18762 }, [ 18763 dynamicOptions 18764 ]); 18765 const fieldOptionsById = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 18766 const map = new globalThis.Map(); 18767 for (const f of allFields){ 18768 if (!("type" in f) || f.type === "custom") continue; 18769 const builtin = f; 18770 const staticOptions = builtin.options ?? EMPTY_OPTIONS; 18771 const dynamic = dynamicOptions[f.id]; 18772 if (dynamic && dynamic.length) { 18773 const merged = []; 18774 const seen = /* @__PURE__ */ new Set(); 18775 for (const opt of staticOptions){ 18776 if (seen.has(opt.value)) continue; 18777 seen.add(opt.value); 18778 merged.push(opt); 18779 } 18780 for (const opt of dynamic){ 18781 if (seen.has(opt.value)) continue; 18782 seen.add(opt.value); 18783 merged.push(opt); 18784 } 18785 map.set(f.id, merged); 18786 } else if (staticOptions.length) { 18787 map.set(f.id, staticOptions); 18788 } else if (dynamic) { 18789 map.set(f.id, dynamic); 18790 } 18791 } 18792 return map; 18793 }, [ 18794 allFields, 18795 dynamicOptions 18796 ]); 18797 const usesResponsiveLayout = allFields.some((field)=>field.layout === "half" || field.layout === "third"); 18798 const grid = twoColumn ? "grid grid-cols-1 lg:grid-cols-[7fr_3fr] gap-4" : usesResponsiveLayout ? "grid grid-cols-1 gap-4 md:grid-cols-6" : "grid grid-cols-1 gap-4"; 18799 const resolveLayoutClass = (layout)=>{ 18800 switch(layout){ 18801 case "half": 18802 return "md:col-span-3"; 18803 case "third": 18804 return "md:col-span-2"; 18805 default: 18806 return "md:col-span-6"; 18807 } 18808 }; 18809 const renderFields = (fieldList)=>{ 18810 const usesResponsive = fieldList.some((field)=>field.layout === "half" || field.layout === "third"); 18811 const gridClass = usesResponsive ? "grid grid-cols-1 gap-4 md:grid-cols-6" : "grid grid-cols-1 gap-4"; 18812 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18813 className: gridClass, 18814 children: fieldList.map((f)=>{ 18815 const layout = f.layout ?? "full"; 18816 const wrapperClassName = usesResponsive ? resolveLayoutClass(layout) : void 0; 18817 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(FieldControl, { 18818 field: f, 18819 value: readRenderedFieldValue(values, f.id), 18820 error: errors[f.id], 18821 options: fieldOptionsById.get(f.id) || EMPTY_OPTIONS, 18822 setValue, 18823 onBlurRequest, 18824 values, 18825 loadFieldOptions, 18826 autoFocus: !disableInitialFocus && !formReadOnly && Boolean(firstFieldId && f.id === firstFieldId), 18827 onSubmitRequest: requestSubmit, 18828 wrapperClassName, 18829 entityIdForField: primaryEntityId ?? void 0, 18830 recordId, 18831 markRequired: widgetRequiredFieldIds.has(f.id) 18832 }, f.id); 18833 }) 18834 }); 18835 }; 18836 const renderCustomFieldsContent = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 18837 if (!customFieldLayout.length) { 18838 return [
18839 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18840 className: "rounded-lg border bg-card p-4", 18841 children: customFieldsEmptyState 18842 }, "custom-fields-empty") 18843 ]; 18844 } 18845 const nodes = []; 18846 const multipleEntities = customFieldLayout.length > 1; 18847 customFieldLayout.forEach((entityLayout)=>{ 18848 const manageHref = buildCustomFieldsManageHref(entityLayout.entityId); 18849 const showSelector = entityLayout.hasFieldsets && entityLayout.singleFieldsetPerRecord && entityLayout.availableFieldsets.length > 0; 18850 if (multipleEntities) { 18851 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18852 className: "px-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", 18853 children: entityLayout.entityId 18854 }, `custom-fields-entity-${entityLayout.entityId}`)); 18855 } 18856 if (showSelector) { 18857 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18858 className: "rounded-lg border bg-card p-4", 18859 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 18860 className: "flex flex-wrap items-center gap-2 text-sm", 18861 children: [
18862 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("label", { 18863 className: "text-xs uppercase tracking-wide text-muted-foreground", 18864 children: fieldsetSelectorLabel 18865 }), 18866 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__262524__["Select"], { 18867 value: entityLayout.activeFieldset || void 0, 18868 onValueChange: (value)=>handleFieldsetSelectionChange(entityLayout.entityId, value || null), 18869 children: [ 18870 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectTrigger"], { 18871 className: "w-auto min-w-[10rem]", 18872 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectValue"], { 18873 placeholder: defaultFieldsetLabel 18874 }) 18875 }),
18876 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectContent"], { 18877 children: entityLayout.availableFieldsets.map((fs)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectItem"], { 18878 value: fs.code, 18879 children: fs.label 18880 }, fs.code)) 18881 }) 18882 ] 18883 }), 18884 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__741870__["IconButton"], { 18885 variant: "outline", 18886 className: "text-muted-foreground hover:text-foreground", 18887 onClick: ()=>handleOpenFieldsetEditor(entityLayout.entityId, entityLayout.activeFieldset ?? null, "fieldset"), 18888 disabled: !manageHref, 18889 title: manageFieldsetLabel, 18890 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__239616__["Settings"], { 18891 className: "size-4" 18892 }) 18893 }) 18894 ] 18895 }) 18896 }, `custom-fields-selector-${entityLayout.entityId}`)); 18897 } 18898 if (entityLayout.sections.length) { 18899 entityLayout.sections.forEach((section)=>{ 18900 const FieldsetIcon = section.fieldset?.icon ? FIELDSET_ICON_COMPONENTS[section.fieldset.icon] : null; 18901 const sectionKey = `${entityLayout.entityId}:${section.fieldsetCode ?? "default"}`; 18902 const manageDisabled = !manageHref; 18903 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 18904 className: "rounded-lg border bg-card p-4 space-y-4", 18905 children: [
18906 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 18907 className: "flex items-start justify-between gap-3", 18908 children: [ 18909 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 18910 className: "flex items-start gap-2", 18911 children: [ 18912 FieldsetIcon ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(FieldsetIcon, { 18913 className: "size-5 text-muted-foreground" 18914 }) : null, 18915 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 18916 children: [ 18917 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18918 className: "text-sm font-medium", 18919 children: section.title 18920 }), 18921 section.description ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18922 className: "text-xs text-muted-foreground", 18923 children: section.description 18924 }) : null 18925 ] 18926 }) 18927 ] 18928 }),
18929 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__110035__["Button"], { 18930 type: "button", 18931 variant: "muted", 18932 size: "sm", 18933 className: "text-xs", 18934 onClick: ()=>handleOpenFieldsetEditor(entityLayout.entityId, section.fieldsetCode, "fieldset"), 18935 disabled: manageDisabled, 18936 children: [ 18937 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__239616__["Settings"], { 18938 className: "size-4" 18939 }), 18940 manageFieldsetLabel 18941 ] 18942 }) 18943 ] 18944 }), 18945 section.groups.map((group)=>{ 18946 const groupKey = `${section.fieldsetCode ?? "default"}:${group.code ?? "default"}`; 18947 const visibleFields = placedCustomFieldIds.size > 0 ? group.fields.filter((f)=>!placedCustomFieldIds.has(f.id)) : group.fields; 18948 if (!visibleFields.length) return null; 18949 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 18950 className: "space-y-2", 18951 children: [
18952 group.label ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 18953 children: [ 18954 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18955 className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", 18956 children: group.label 18957 }), 18958 group.hint ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18959 className: "text-xs text-muted-foreground", 18960 children: group.hint 18961 }) : null 18962 ] 18963 }) : null, 18964 renderFields(visibleFields) 18965 ] 18966 }, groupKey); 18967 }), 18968 !section.groups.length ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18969 className: "text-xs text-muted-foreground", 18970 children: emptyFieldsetMessage 18971 }) : null 18972 ] 18973 }, sectionKey)); 18974 }); 18975 } else { 18976 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 18977 className: "rounded-lg border bg-card p-4", 18978 children: customFieldsEmptyState 18979 }, `custom-fields-empty-${entityLayout.entityId}`)); 18980 } 18981 }); 18982 return nodes; 18983 }, [ 18984 buildCustomFieldsManageHref, 18985 customFieldLayout, 18986 customFieldsEmptyState, 18987 defaultFieldsetLabel, 18988 emptyFieldsetMessage, 18989 fieldsetSelectorLabel, 18990 handleFieldsetSelectionChange, 18991 handleOpenFieldsetEditor, 18992 manageFieldsetLabel, 18993 placedCustomFieldIds, 18994 renderFields 18995 ]); 18996 const fieldsetManagerDialog = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__644149__["Dialog"], { 18997 open: fieldsetEditorTarget !== null, 18998 onOpenChange: (open)=>{ 18999 if (!open) setFieldsetEditorTarget(null); 19000 }, 19001 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__644149__["DialogContent"], { 19002 className: "max-w-5xl w-full", 19003 "aria-describedby": void 0, 19004 onKeyDown: (event)=>{ 19005 if ((event.metaKey || event.ctrlKey) && event.key === "Enter") { 19006 event.preventDefault(); 19007 handleFieldsetDialogSave(); 19008 } 19009 }, 19010 children: [
19011 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__644149__["DialogHeader"], { 19012 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__644149__["DialogTitle"], { 19013 children: fieldsetDialogTitle 19014 }) 19015 }), 19016 fieldsetEditorTarget ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(FieldDefinitionsManagerErrorBoundary, { 19017 onClose: ()=>setFieldsetEditorTarget(null), 19018 unavailableMessage: fieldsetDialogUnavailable, 19019 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(FieldDefinitionsManager, { 19020 ref: fieldsetManagerRef, 19021 entityId: fieldsetEditorTarget.entityId, 19022 initialFieldset: fieldsetEditorTarget.fieldsetCode, 19023 fullEditorHref: fieldsetEditorFullHref ?? void 0, 19024 onSaved: refreshCustomFieldDefinitions, 19025 onClose: ()=>setFieldsetEditorTarget(null) 19026 }) 19027 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19028 className: "flex h-full items-center justify-center text-sm text-muted-foreground px-4 text-center", 19029 children: fieldsetDialogUnavailable 19030 }) 19031 ] 19032 }) 19033 }); 19034 const handleReadOnlyFocusCapture = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 19035 if (!formReadOnly) return; 19036 const target = event.target; 19037 if (target instanceof HTMLElement) target.blur(); 19038 }, [ 19039 formReadOnly 19040 ]); 19041 const handleReadOnlyKeyDownCapture = __TURBOPACK__imported__module__271645__["useCallback"]((event)=>{ 19042 if (!formReadOnly) return; 19043 event.preventDefault(); 19044 }, [ 19045 formReadOnly 19046 ]); 19047 const wrapFormBody = __TURBOPACK__imported__module__271645__["useCallback"]((children, className)=>{ 19048 if (!formReadOnly) return children; 19049 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19050 className: (0, __TURBOPACK__imported__module__406911__1["cn"])("relative", className), 19051 onFocusCapture: handleReadOnlyFocusCapture, 19052 onKeyDownCapture: handleReadOnlyKeyDownCapture, 19053 children: [
19054 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19055 className: "pointer-events-none select-none opacity-70", 19056 children 19057 }), 19058 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19059 className: "absolute inset-0 z-10 flex items-start justify-center rounded-lg bg-background/80 p-4 backdrop-blur-[1px] sm:p-6", 19060 children: readOnlyOverlay ?? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19061 className: "rounded-xl border border-border/70 bg-background/95 px-4 py-3 shadow-sm" 19062 }) 19063 }) 19064 ] 19065 }); 19066 }, [ 19067 formReadOnly, 19068 handleReadOnlyFocusCapture, 19069 handleReadOnlyKeyDownCapture, 19070 readOnlyOverlay 19071 ]); 19072 if (useGroupedLayout) { 19073 const sortedGroups = sortableGroupsEnabled ? [ 19074 ...resolvedGroupsForLayout 19075 ].sort((a, b)=>{ 19076 const ai = sortedGroupIds.indexOf(a.id); 19077 const bi = sortedGroupIds.indexOf(b.id); 19078 return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi); 19079 }) : resolvedGroupsForLayout; 19080 const col1 = []; 19081 const col2 = []; 19082 for (const g of sortedGroups){ 19083 if ((g.column ?? 1) === 2) col2.push(g); 19084 else col1.push(g); 19085 } 19086 const col1Ids = col1.map((g)=>g.id); 19087 const renderGroupedCards = (items)=>{ 19088 const nodes = []; 19089 for (const g of items){ 19090 const isCustomFieldsGroup = g.kind === "customFields"; 19091 if (isCustomFieldsGroup) { 19092 if (isLoadingCustomFields) { 19093 const loadingContent = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19094 className: "rounded-lg border bg-card p-4", 19095 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__542969__["DataLoader"], { 19096 isLoading: true, 19097 loadingMessage: resolvedCustomFieldsLoadingMessage, 19098 spinnerSize: "md", 19099 className: "min-h-[1px]", 19100 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", {}) 19101 }) 19102 }, `${g.id}-loading`); 19103 if (collapsibleGroupsEnabled && g.title) { 19104 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(CollapsibleGroup, { 19105 groupId: g.id, 19106 title: t(g.title, g.title), 19107 pageType: collapsiblePageType, 19108 chevronPosition: collapsibleChevronPosition, 19109 children: loadingContent 19110 }, `${g.id}-loading-collapsible`)); 19111 } else { 19112 nodes.push(loadingContent); 19113 } 19114 continue; 19115 } 19116 const customFieldsInnerNodes = []; 19117 if (g.component) { 19118 customFieldsInnerNodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19119 className: "rounded-lg border bg-card px-4 py-3", 19120 children: g.component({ 19121 values, 19122 setValue, 19123 errors, 19124 requiredFieldIds: widgetRequiredFieldIds 19125 }) 19126 }, `${g.id}-component`)); 19127 } 19128 const renderedSections = renderCustomFieldsContent(); 19129 if (renderedSections.length) customFieldsInnerNodes.push(...renderedSections); 19130 if (collapsibleGroupsEnabled && g.title) { 19131 const customFieldCount = customFieldLayout.reduce((sum, entity)=>sum + entity.sections.reduce((sSum, section)=>sSum + section.groups.reduce((gSum, group)=>gSum + group.fields.length, 0), 0), 0); 19132 const customFieldErrors = customFieldLayout.reduce((sum, entity)=>sum + entity.sections.reduce((sSum, section)=>sSum + section.groups.reduce((gSum, group)=>gSum + group.fields.filter((f)=>errors[f.id]).length, 0), 0), 0); 19133 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(CollapsibleGroup, { 19134 ref: (handle)=>{ 19135 if (handle) groupCollapseRefs.current.set(g.id, handle); 19136 else groupCollapseRefs.current.delete(g.id); 19137 }, 19138 groupId: g.id, 19139 title: t(g.title, g.title), 19140 pageType: collapsiblePageType, 19141 errorCount: customFieldErrors, 19142 fieldCount: customFieldCount, 19143 chevronPosition: collapsibleChevronPosition, 19144 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19145 className: "space-y-3", 19146 children: customFieldsInnerNodes 19147 }) 19148 }, g.id)); 19149 } else { 19150 nodes.push(...customFieldsInnerNodes); 19151 } 19152 continue; 19153 } 19154 const componentNode = g.component ? g.component({ 19155 values, 19156 setValue, 19157 errors, 19158 requiredFieldIds: widgetRequiredFieldIds 19159 }) : null; 19160 if (g.bare) { 19161 if (componentNode) { 19162 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__271645__["Fragment"], { 19163 children: componentNode 19164 }, g.id)); 19165 } 19166 continue; 19167 } 19168 const groupFields = resolveGroupFields(g); 19169 const groupFieldIds = (g.fields ?? []).map((f)=>typeof f === "string" ? f : f.id); 19170 const groupErrorCount = groupFieldIds.filter((id)=>errors[id]).length; 19171 const groupContent = /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__843476__["Fragment"], { 19172 children: [
19173 g.description ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19174 className: "text-xs text-muted-foreground", 19175 children: t(g.description, g.description) 19176 }) : null, 19177 componentNode ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19178 children: componentNode 19179 }) : null, 19180 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__542969__["DataLoader"], { 19181 isLoading: false, 19182 loadingMessage: resolvedLoadingMessage, 19183 spinnerSize: "md", 19184 className: "min-h-[1px]", 19185 children: groupFields.length > 0 ? renderFields(groupFields) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19186 className: "min-h-[1px]" 19187 }) 19188 }) 19189 ] 19190 }); 19191 if (collapsibleGroupsEnabled && g.title) { 19192 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(CollapsibleGroup, { 19193 ref: (handle)=>{ 19194 if (handle) groupCollapseRefs.current.set(g.id, handle); 19195 else groupCollapseRefs.current.delete(g.id); 19196 }, 19197 groupId: g.id, 19198 title: t(g.title, g.title), 19199 pageType: collapsiblePageType, 19200 errorCount: groupErrorCount, 19201 fieldCount: groupFields.length, 19202 chevronPosition: collapsibleChevronPosition, 19203 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19204 className: "space-y-3", 19205 children: groupContent 19206 }) 19207 }, g.id)); 19208 } else { 19209 nodes.push(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19210 className: "rounded-lg border bg-card px-4 py-3 space-y-3", 19211 children: [
19212 g.title ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19213 className: "text-sm font-medium", 19214 children: t(g.title, g.title) 19215 }) : null, 19216 groupContent 19217 ] 19218 }, g.id)); 19219 } 19220 } 19221 return nodes; 19222 }; 19223 const col1Nodes = renderGroupedCards(col1); 19224 const col2Content = renderGroupedCards(col2); 19225 const col1Content = sortableGroupsEnabled ? col1Nodes.map((node, i)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(SortableGroupItem, { 19226 id: col1[i]?.id ?? String(i), 19227 children: node 19228 }, col1[i]?.id ?? i)) : col1Nodes; 19229 const hasSecondaryColumn = col2Content.length > 0; 19230 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19231 className: "space-y-4", 19232 ref: rootRef, 19233 "data-component-handle": resolvedReplacementHandle, 19234 children: [ 19235 !embedded ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__871241__["FormHeader"], { 19236 mode: "edit", 19237 backHref, 19238 backLabel, 19239 title, 19240 actions: { 19241 extraActions: headerExtraActions, 19242 showDelete: !formReadOnly && showDelete, 19243 onDelete: handleDelete, 19244 // NOSONAR â asyncâvoid assignment is valid TypeScript 19245 deleteLabel, 19246 cancelHref, 19247 cancelLabel, 19248 submit: formReadOnly ? void 0 : { 19249 formId, 19250 pending, 19251 label: resolvedSubmitLabel, 19252 pendingLabel: savingLabel, 19253 icon: submitIcon 19254 } 19255 } 19256 }) : headerExtraActions ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19257 className: "flex justify-end gap-2 mb-2", 19258 children: headerExtraActions 19259 }) : null, 19260 contentHeader,
19261 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__542969__["DataLoader"], { 19262 isLoading, 19263 loadingMessage: resolvedLoadingMessage, 19264 spinnerSize: "md", 19265 className: embedded ? "min-h-[1px]" : "min-h-[400px]", 19266 children: wrapFormBody(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("form", { 19267 id: formId, 19268 onSubmit: handleSubmit, 19269 className: `space-y-4 ${dialogFormPadding}`, 19270 children: [ 19271 resolvedInjectionSpotId ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__862013__["InjectionSpot"], { 19272 spotId: resolvedInjectionSpotId, 19273 context: injectionContext, 19274 data: values, 19275 onDataChange: (newData)=>setValues(newData), 19276 disabled: pending || formReadOnly, 19277 widgetsOverride: stackedInjectionWidgets 19278 }) : null,
19279 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19280 className: hasSecondaryColumn ? "grid grid-cols-1 lg:grid-cols-[7fr_3fr] gap-4" : "grid grid-cols-1 gap-4", 19281 children: [ 19282 sortableGroupsEnabled ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__477183__["DndContext"], { 19283 sensors: sortableSensors, 19284 collisionDetection: __TURBOPACK__imported__module__477183__["closestCenter"], 19285 onDragEnd: handleGroupDragEnd, 19286 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__76590__["SortableContext"], { 19287 items: col1Ids, 19288 strategy: __TURBOPACK__imported__module__76590__["verticalListSortingStrategy"], 19289 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19290 className: "space-y-3", 19291 children: col1Content 19292 }) 19293 }) 19294 }) : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19295 className: "space-y-3", 19296 children: col1Content 19297 }), 19298 hasSecondaryColumn ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19299 className: "space-y-3", 19300 "data-crud-injection-region": true, 19301 children: col2Content 19302 }) : null 19303 ] 19304 }), 19305 formError && !Object.keys(errors).length ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19306 className: "text-sm text-status-error-text", 19307 children: formError 19308 }) : null, 19309 hideFooterActions || formReadOnly ? null : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__754114__["FormFooter"], { 19310 embedded, 19311 className: dialogFooterClass, 19312 actions: { 19313 extraActions, 19314 showDelete: !embedded && showDelete, 19315 onDelete: handleDelete, 19316 // NOSONAR â asyncâvoid assignment is valid TypeScript 19317 deleteLabel, 19318 cancelHref: !embedded ? cancelHref : void 0, 19319 cancelLabel, 19320 submit: { 19321 pending, 19322 label: resolvedSubmitLabel, 19323 pendingLabel: savingLabel, 19324 icon: submitIcon 19325 } 19326 } 19327 }) 19328 ] 19329 })) 19330 }), 19331 fieldsetManagerDialog, 19332 ConfirmDialogElement 19333 ] 19334 }); 19335 } 19336 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19337 className: "space-y-4", 19338 ref: rootRef, 19339 "data-component-handle": resolvedReplacementHandle, 19340 children: [
19341 !embedded ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__871241__["FormHeader"], { 19342 mode: "edit", 19343 backHref, 19344 backLabel, 19345 title, 19346 actions: { 19347 extraActions: headerExtraActions, 19348 showDelete: !formReadOnly && showDelete, 19349 onDelete: handleDelete, 19350 // NOSONAR â asyncâvoid assignment is valid TypeScript 19351 deleteLabel, 19352 cancelHref, 19353 cancelLabel, 19354 submit: formReadOnly ? void 0 : { 19355 formId, 19356 pending, 19357 label: resolvedSubmitLabel, 19358 pendingLabel: savingLabel, 19359 icon: submitIcon 19360 } 19361 } 19362 }) : headerExtraActions ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19363 className: "flex justify-end gap-2 mb-2", 19364 children: headerExtraActions 19365 }) : null, 19366 contentHeader,
19367 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__542969__["DataLoader"], { 19368 isLoading, 19369 loadingMessage: resolvedLoadingMessage, 19370 spinnerSize: "md", 19371 className: embedded ? "min-h-[1px]" : "min-h-[400px]", 19372 children: wrapFormBody(/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19373 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("form", { 19374 id: formId, 19375 onSubmit: handleSubmit, 19376 className: `${embedded ? "space-y-4" : "rounded-lg border bg-card p-4 space-y-4"} ${dialogFormPadding}`, 19377 children: [ 19378 resolvedInjectionSpotId ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__862013__["InjectionSpot"], { 19379 spotId: resolvedInjectionSpotId, 19380 context: injectionContext, 19381 data: values, 19382 onDataChange: (newData)=>setValues(newData), 19383 disabled: pending || formReadOnly, 19384 widgetsOverride: stackedInjectionWidgets 19385 }) : null,
19386 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19387 className: grid, 19388 children: allFields.map((f)=>{ 19389 if (hiddenBaseFieldIds.has(f.id) || hiddenInjectedFieldIds.has(f.id)) return null; 19390 const layout = f.layout ?? "full"; 19391 const wrapperClassName = usesResponsiveLayout ? resolveLayoutClass(layout) : void 0; 19392 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(FieldControl, { 19393 field: f, 19394 value: values[f.id], 19395 error: errors[f.id], 19396 options: fieldOptionsById.get(f.id) || EMPTY_OPTIONS, 19397 setValue, 19398 onBlurRequest, 19399 values, 19400 loadFieldOptions, 19401 autoFocus: !disableInitialFocus && !formReadOnly && Boolean(firstFieldId && f.id === firstFieldId), 19402 onSubmitRequest: requestSubmit, 19403 wrapperClassName, 19404 entityIdForField: primaryEntityId ?? void 0, 19405 recordId, 19406 markRequired: widgetRequiredFieldIds.has(f.id) 19407 }, f.id); 19408 }) 19409 }), 19410 formError && !Object.keys(errors).length ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19411 className: "text-sm text-status-error-text", 19412 children: formError 19413 }) : null, 19414 hideFooterActions || formReadOnly ? null : /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__754114__["FormFooter"], { 19415 embedded, 19416 className: dialogFooterClass, 19417 actions: { 19418 extraActions, 19419 showDelete: !embedded && showDelete, 19420 onDelete: handleDelete, 19421 // NOSONAR â asyncâvoid assignment is valid TypeScript 19422 deleteLabel, 19423 cancelHref: !embedded ? cancelHref : void 0, 19424 cancelLabel, 19425 submit: { 19426 pending, 19427 label: resolvedSubmitLabel, 19428 pendingLabel: savingLabel, 19429 icon: submitIcon 19430 } 19431 } 19432 }) 19433 ] 19434 }) 19435 })) 19436 }), 19437 fieldsetManagerDialog, 19438 ConfirmDialogElement 19439 ] 19440 }); 19441} 19442function RelationSelect({ value, onChange, options, placeholder, autoFocus }) { 19443 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 19444 const [query, setQuery] = __TURBOPACK__imported__module__271645__["useState"](""); 19445 const inputRef = __TURBOPACK__imported__module__271645__["useRef"](null); 19446 const filtered = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 19447 const q = query.toLowerCase().trim(); 19448 if (!q) return options; 19449 return options.filter((o)=>o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q)); 19450 }, [ 19451 query, 19452 options 19453 ]); 19454 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19455 className: "space-y-1", 19456 children: [
19457 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__987030__["Input"], { 19458 ref: inputRef, 19459 placeholder: placeholder || t("ui.forms.listbox.searchPlaceholder", "Search..."), 19460 value: query, 19461 onChange: (e)=>setQuery(e.target.value), 19462 autoFocus, 19463 "data-crud-focus-target": "" 19464 }), 19465 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19466 className: "max-h-40 overflow-auto rounded border", 19467 children: [ 19468 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 19469 variant: "ghost", 19470 size: "sm", 19471 className: "w-full justify-start rounded-none font-normal", 19472 onClick: ()=>onChange(""), 19473 children: "\u2014" 19474 }), 19475 filtered.map((opt)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 19476 variant: "ghost", 19477 size: "sm", 19478 className: `w-full justify-start rounded-none font-normal ${value === opt.value ? "bg-muted" : ""}`, 19479 onClick: ()=>onChange(opt.value), 19480 children: opt.label 19481 }, opt.value)) 19482 ] 19483 }) 19484 ] 19485 }); 19486} 19487function TextInput({ value, onChange, placeholder, autoFocus, onSubmit, disabled, readOnly, suggestions, inputType = "text" }) { 19488 const [local, setLocal] = __TURBOPACK__imported__module__271645__["useState"](value); 19489 const isFocusedRef = __TURBOPACK__imported__module__271645__["useRef"](false); 19490 const userTypingRef = __TURBOPACK__imported__module__271645__["useRef"](false); 19491 const datalistId = __TURBOPACK__imported__module__271645__["useId"](); 19492 const commitIfChanged = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19493 if (local === value) return; 19494 onChange(local); 19495 }, [ 19496 local, 19497 onChange, 19498 value 19499 ]); 19500 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 19501 if (!isFocusedRef.current || !userTypingRef.current) { 19502 setLocal(value); 19503 } 19504 }, [ 19505 value 19506 ]); 19507 const handleChange = __TURBOPACK__imported__module__271645__["useCallback"]((e)=>{ 19508 if (disabled || readOnly) return; 19509 const next = e.target.value; 19510 userTypingRef.current = true; 19511 setLocal(next); 19512 onChange(next); 19513 }, [ 19514 disabled, 19515 readOnly, 19516 onChange 19517 ]); 19518 const handleKeyDown = __TURBOPACK__imported__module__271645__["useCallback"]((e)=>{ 19519 if (disabled) return; 19520 if (e.key === "Enter" && !e.shiftKey) { 19521 e.preventDefault(); 19522 commitIfChanged(); 19523 onSubmit?.(); 19524 } 19525 }, [ 19526 commitIfChanged, 19527 disabled, 19528 onSubmit 19529 ]); 19530 const handleFocus = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19531 isFocusedRef.current = true; 19532 }, []); 19533 const handleBlur = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19534 isFocusedRef.current = false; 19535 userTypingRef.current = false; 19536 commitIfChanged(); 19537 }, [ 19538 commitIfChanged 19539 ]); 19540 if (inputType === "password") { 19541 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__949915__["PasswordInput"], { 19542 placeholder, 19543 value: local, 19544 onChange: handleChange, 19545 onKeyDown: handleKeyDown, 19546 onFocus: handleFocus, 19547 onBlur: handleBlur, 19548 spellCheck: false, 19549 autoFocus, 19550 "data-crud-focus-target": "", 19551 disabled, 19552 readOnly 19553 }); 19554 } 19555 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__843476__["Fragment"], { 19556 children: [
19557 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__987030__["Input"], { 19558 type: inputType, 19559 placeholder, 19560 value: local, 19561 onChange: handleChange, 19562 onKeyDown: handleKeyDown, 19563 onFocus: handleFocus, 19564 onBlur: handleBlur, 19565 spellCheck: false, 19566 autoFocus, 19567 "data-crud-focus-target": "", 19568 disabled, 19569 readOnly, 19570 list: suggestions && suggestions.length > 0 ? datalistId : void 0 19571 }), 19572 suggestions && suggestions.length > 0 && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("datalist", { 19573 id: datalistId, 19574 children: suggestions.map((suggestion)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("option", { 19575 value: suggestion 19576 }, suggestion)) 19577 }) 19578 ] 19579 }); 19580} 19581function NumberInput({ value, onChange, placeholder, autoFocus, onSubmit }) { 19582 const serializedValue = value !== void 0 && value !== null ? String(value) : ""; 19583 const [local, setLocal] = __TURBOPACK__imported__module__271645__["useState"](serializedValue); 19584 const isFocusedRef = __TURBOPACK__imported__module__271645__["useRef"](false); 19585 const commitIfChanged = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19586 if (local === serializedValue) return; 19587 const numValue = local === "" ? void 0 : Number(local); 19588 onChange(numValue); 19589 }, [ 19590 local, 19591 onChange, 19592 serializedValue 19593 ]); 19594 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 19595 if (!isFocusedRef.current) { 19596 setLocal(serializedValue); 19597 } 19598 }, [ 19599 serializedValue 19600 ]); 19601 const handleChange = __TURBOPACK__imported__module__271645__["useCallback"]((e)=>{ 19602 const next = e.target.value; 19603 setLocal(next); 19604 const numValue = next === "" ? void 0 : Number(next); 19605 onChange(numValue); 19606 }, [ 19607 onChange 19608 ]); 19609 const handleKeyDown = __TURBOPACK__imported__module__271645__["useCallback"]((e)=>{ 19610 if (e.key === "Enter" && !e.shiftKey) { 19611 e.preventDefault(); 19612 commitIfChanged(); 19613 onSubmit?.(); 19614 } 19615 }, [ 19616 commitIfChanged, 19617 onSubmit 19618 ]); 19619 const handleFocus = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19620 isFocusedRef.current = true; 19621 }, []); 19622 const handleBlur = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19623 isFocusedRef.current = false; 19624 commitIfChanged(); 19625 }, [ 19626 commitIfChanged 19627 ]); 19628 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__987030__["Input"], { 19629 type: "number", 19630 placeholder, 19631 value: local, 19632 onChange: handleChange, 19633 onKeyDown: handleKeyDown, 19634 onFocus: handleFocus, 19635 onBlur: handleBlur, 19636 autoFocus, 19637 "data-crud-focus-target": "" 19638 }); 19639} 19640function TextAreaInput({ value, onChange, placeholder, autoFocus, maxLength, showCount, rows, disabled, readOnly }) { 19641 const [local, setLocal] = __TURBOPACK__imported__module__271645__["useState"](value); 19642 const isFocusedRef = __TURBOPACK__imported__module__271645__["useRef"](false); 19643 const commitIfChanged = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19644 if (local === value) return; 19645 onChange(local); 19646 }, [ 19647 local, 19648 onChange, 19649 value 19650 ]); 19651 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 19652 if (!isFocusedRef.current) setLocal(value); 19653 }, [ 19654 value 19655 ]); 19656 const handleChange = __TURBOPACK__imported__module__271645__["useCallback"]((e)=>{ 19657 if (disabled || readOnly) return; 19658 const next = e.target.value; 19659 setLocal(next); 19660 onChange(next); 19661 }, [ 19662 disabled, 19663 readOnly, 19664 onChange 19665 ]); 19666 const handleFocus = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19667 isFocusedRef.current = true; 19668 }, []); 19669 const handleBlur = __TURBOPACK__imported__module__271645__["useCallback"](()=>{ 19670 isFocusedRef.current = false;
19671 commitIfChanged(); 19672 }, [ 19673 commitIfChanged 19674 ]); 19675 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__268153__["Textarea"], { 19676 placeholder, 19677 value: local, 19678 onChange: handleChange, 19679 onFocus: handleFocus, 19680 onBlur: handleBlur, 19681 autoFocus, 19682 maxLength, 19683 showCount, 19684 rows, 19685 disabled, 19686 readOnly, 19687 "data-crud-focus-target": "" 19688 }); 19689} 19690const MarkdownEditor = /*#__PURE__*/ __TURBOPACK__imported__module__271645__["memo"](function MarkdownEditor2({ value = "", onChange }) { 19691 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__167556__["default"], { 19692 value, 19693 onChange 19694 }); 19695}, (prev, next)=>prev.value === next.value); 19696const HtmlRichEditorField = /*#__PURE__*/ __TURBOPACK__imported__module__271645__["memo"](function HtmlRichEditorField2({ value = "", onChange }) { 19697 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 19698 const labels = __TURBOPACK__imported__module__271645__["useMemo"](()=>({ 19699 bold: t("ui.forms.richtext.bold"), 19700 italic: t("ui.forms.richtext.italic"), 19701 underline: t("ui.forms.richtext.underline"), 19702 unorderedList: t("ui.forms.richtext.list"), 19703 orderedList: t("ui.forms.richtext.orderedList", "Numbered list"), 19704 heading: t("ui.forms.richtext.heading", "Heading"), 19705 heading1: t("ui.forms.richtext.heading1", "Heading 1"), 19706 heading2: t("ui.forms.richtext.heading2", "Heading 2"), 19707 heading3: t("ui.forms.richtext.heading3"), 19708 paragraph: t("ui.forms.richtext.paragraph", "Paragraph"), 19709 link: t("ui.forms.richtext.link"), 19710 linkUrlPrompt: t("ui.forms.richtext.linkUrlPrompt"), 19711 placeholder: t("ui.forms.richtext.placeholder"), 19712 comment: t("ui.forms.richtext.comment", "Add comment"), 19713 mention: t("ui.forms.richtext.mention", "Mention"), 19714 more: t("ui.forms.richtext.more", "More") 19715 }), [ 19716 t 19717 ]); 19718 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(RichEditor, { 19719 value, 19720 onChange, 19721 variant: "full", 19722 labels 19723 }); 19724}, (prev, next)=>prev.value === next.value); 19725const SimpleMarkdownEditor = /*#__PURE__*/ __TURBOPACK__imported__module__271645__["memo"](function SimpleMarkdownEditor2({ value = "", onChange }) { 19726 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 19727 const boldLabel = t("ui.forms.richtext.bold"); 19728 const italicLabel = t("ui.forms.richtext.italic"); 19729 const underlineLabel = t("ui.forms.richtext.underline"); 19730 const markdownPlaceholder = t("ui.forms.richtext.placeholder"); 19731 const sampleText = t("ui.forms.richtext.sampleText"); 19732 const taRef = __TURBOPACK__imported__module__271645__["useRef"](null); 19733 const [local, setLocal] = __TURBOPACK__imported__module__271645__["useState"](value); 19734 const typingRef = __TURBOPACK__imported__module__271645__["useRef"](false); 19735 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 19736 if (!typingRef.current) setLocal(value); 19737 }, [ 19738 value 19739 ]); 19740 const wrap = (before, after = before)=>{ 19741 const el = taRef.current; 19742 if (!el) return; 19743 const start = el.selectionStart ?? 0; 19744 const end = el.selectionEnd ?? 0; 19745 const sel = value.slice(start, end) || sampleText; 19746 const next = value.slice(0, start) + before + sel + after + value.slice(end); 19747 onChange(next); 19748 queueMicrotask(()=>{ 19749 const caret = start + before.length + sel.length + after.length; 19750 el.focus(); 19751 el.setSelectionRange(caret, caret); 19752 }); 19753 }; 19754 const onKeyDown = (e)=>{ 19755 const isMod = e.metaKey || e.ctrlKey; 19756 if (!isMod) return; 19757 const key = e.key.toLowerCase(); 19758 if (key === "b") { 19759 e.preventDefault(); 19760 wrap("**"); 19761 } 19762 if (key === "i") { 19763 e.preventDefault(); 19764 wrap("_"); 19765 } 19766 if (key === "u") { 19767 e.preventDefault(); 19768 wrap("__"); 19769 } 19770 }; 19771 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19772 className: "w-full rounded border", 19773 children: [
19774 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19775 className: "flex items-center gap-1 px-2 py-1 border-b", 19776 children: [ 19777 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 19778 variant: "ghost", 19779 size: "sm", 19780 className: "h-auto px-2 py-0.5 text-xs", 19781 onMouseDown: (e)=>e.preventDefault(), 19782 onClick: ()=>wrap("**"), 19783 children: boldLabel 19784 }), 19785 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 19786 variant: "ghost", 19787 size: "sm", 19788 className: "h-auto px-2 py-0.5 text-xs", 19789 onMouseDown: (e)=>e.preventDefault(), 19790 onClick: ()=>wrap("_"), 19791 children: italicLabel 19792 }),
19793 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 19794 variant: "ghost", 19795 size: "sm", 19796 className: "h-auto px-2 py-0.5 text-xs", 19797 onMouseDown: (e)=>e.preventDefault(), 19798 onClick: ()=>wrap("__"), 19799 children: underlineLabel 19800 }) 19801 ] 19802 }), 19803 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("textarea", { 19804 ref: taRef, 19805 className: "w-full min-h-[100px] sm:min-h-[160px] resize-y px-2 py-2 font-mono text-sm outline-none", 19806 spellCheck: false, 19807 value: local, 19808 onChange: (e)=>{ 19809 typingRef.current = true; 19810 setLocal(e.target.value); 19811 }, 19812 onBlur: ()=>{ 19813 if (typingRef.current) { 19814 typingRef.current = false; 19815 onChange(local); 19816 } 19817 }, 19818 onKeyDown, 19819 placeholder: markdownPlaceholder 19820 }) 19821 ] 19822 }); 19823}, (prev, next)=>prev.value === next.value); 19824function supportsWrapperBlurValidation(field) { 19825 return field.type === "text" || field.type === "password" || field.type === "textarea" || field.type === "checkbox" || field.type === "select" || field.type === "number"; 19826} 19827const ListboxMultiSelect = /*#__PURE__*/ __TURBOPACK__imported__module__271645__["memo"](function ListboxMultiSelect2({ options, placeholder, value, onChange, autoFocus }) { 19828 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 19829 const searchPlaceholder = placeholder || t("ui.forms.listbox.searchPlaceholder"); 19830 const noMatchesLabel = t("ui.forms.listbox.noMatches"); 19831 const [query, setQuery] = __TURBOPACK__imported__module__271645__["useState"](""); 19832 const filtered = __TURBOPACK__imported__module__271645__["useMemo"](()=>{ 19833 const q = query.toLowerCase().trim(); 19834 if (!q) return options; 19835 return options.filter((o)=>o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q)); 19836 }, [ 19837 options, 19838 query 19839 ]); 19840 const toggle = __TURBOPACK__imported__module__271645__["useCallback"]((val)=>{ 19841 const set = new Set(value); 19842 if (set.has(val)) set.delete(val); 19843 else set.add(val); 19844 onChange(Array.from(set)); 19845 }, [ 19846 value, 19847 onChange 19848 ]); 19849 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19850 className: "w-full", 19851 children: [
19852 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__987030__["Input"], { 19853 className: "mb-2", 19854 size: "sm", 19855 placeholder: searchPlaceholder, 19856 value: query, 19857 onChange: (e)=>setQuery(e.target.value), 19858 autoFocus, 19859 "data-crud-focus-target": "" 19860 }), 19861 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19862 className: "rounded border max-h-48 overflow-auto divide-y", 19863 children: [ 19864 filtered.map((opt)=>{ 19865 const isSel = value.includes(opt.value); 19866 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__110035__["Button"], { 19867 type: "button", 19868 variant: "ghost", 19869 size: "sm", 19870 onClick: ()=>toggle(opt.value), 19871 className: `w-full justify-start rounded-none font-normal px-3 py-2 ${isSel ? "bg-muted" : ""}`, 19872 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("span", { 19873 className: "inline-flex items-center gap-2", 19874 children: [
19875 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 19876 "aria-hidden": "true", 19877 className: `inline-flex size-4 shrink-0 items-center justify-center rounded-[4px] border transition-colors ${isSel ? "border-accent-indigo bg-accent-indigo text-accent-indigo-foreground" : "border-input bg-background"}`, 19878 children: isSel ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__643531__["Check"], { 19879 className: "size-3.5", 19880 "aria-hidden": "true" 19881 }) : null 19882 }), 19883 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 19884 children: opt.label 19885 }) 19886 ] 19887 }) 19888 }, opt.value); 19889 }), 19890 !filtered.length ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 19891 className: "px-3 py-2 text-sm text-muted-foreground", 19892 children: noMatchesLabel 19893 }) : null 19894 ] 19895 }) 19896 ] 19897 }); 19898}); 19899const FieldControl = /*#__PURE__*/ __TURBOPACK__imported__module__271645__["memo"](function FieldControlImpl({ field, value, error, options, setValue, onBlurRequest, values, loadFieldOptions, autoFocus, onSubmitRequest, wrapperClassName, entityIdForField, recordId, markRequired }) { 19900 const t = (0, __TURBOPACK__imported__module__928441__["useT"])(); 19901 const fieldSetValue = __TURBOPACK__imported__module__271645__["useCallback"]((nextValue)=>setValue(field.id, nextValue), [ 19902 setValue, 19903 field.id 19904 ]); 19905 const setFormValue = __TURBOPACK__imported__module__271645__["useCallback"]((targetId, nextValue)=>setValue(targetId, nextValue), [ 19906 setValue 19907 ]); 19908 const builtin = field.type === "custom" ? null : field; 19909 const hasLoader = typeof builtin?.loadOptions === "function"; 19910 const disabled = Boolean(field.disabled); 19911 const readOnly = Boolean(field.readOnly); 19912 const autoFocusField = autoFocus && !disabled; 19913 __TURBOPACK__imported__module__271645__["useEffect"](()=>{ 19914 if (!hasLoader || field.type === "custom") return; 19915 loadFieldOptions(field).catch(()=>{}); 19916 }, [ 19917 field, 19918 hasLoader, 19919 loadFieldOptions 19920 ]); 19921 const placeholder = builtin?.placeholder; 19922 const rootClassName = wrapperClassName ? `space-y-1 ${wrapperClassName}` : "space-y-1"; 19923 const validateOnWrapperBlur = supportsWrapperBlurValidation(field); 19924 const singleSelectValue = Array.isArray(value) ? String(value[0] ?? "") : value == null ? "" : String(value); 19925 const singleSelectOptionsKey = __TURBOPACK__imported__module__271645__["useMemo"](()=>options.map((opt)=>`${opt.value}:${opt.label}`).join("\0"), [ 19926 options 19927 ]); 19928 const singleSelectLabel = singleSelectValue ? options.find((option)=>option.value === singleSelectValue)?.label : void 0; 19929 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 19930 className: rootClassName, 19931 "data-crud-field-id": field.id, 19932 onBlur: validateOnWrapperBlur ? (event)=>{ 19933 const nextFocused = event.relatedTarget; 19934 if (nextFocused instanceof Node && event.currentTarget.contains(nextFocused)) return; 19935 onBlurRequest(field.id); 19936 } : void 0, 19937 children: [ 19938 field.type !== "checkbox" && field.label.trim().length > 0 ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("label", { 19939 className: "block text-sm font-medium", 19940 children: [ 19941 field.label,
19942 field.required || markRequired ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 19943 className: "text-status-error-text", 19944 children: " *" 19945 }) : null 19946 ] 19947 }) : null, 19948 field.type === "text" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(TextInput, { 19949 value: value == null ? "" : String(value), 19950 placeholder, 19951 onChange: (next)=>fieldSetValue(next), 19952 autoFocus: autoFocusField, 19953 onSubmit: onSubmitRequest, 19954 disabled, 19955 readOnly, 19956 suggestions: field.type === "text" ? field.suggestions : void 0 19957 }), 19958 field.type === "password" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(TextInput, { 19959 value: value == null ? "" : String(value), 19960 placeholder, 19961 onChange: (next)=>fieldSetValue(next), 19962 autoFocus: autoFocusField, 19963 onSubmit: onSubmitRequest, 19964 disabled, 19965 readOnly, 19966 inputType: "password" 19967 }), 19968 field.type === "number" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(NumberInput, { 19969 value: typeof value === "number" || typeof value === "string" ? value : null, 19970 placeholder, 19971 onChange: fieldSetValue, 19972 autoFocus: autoFocusField, 19973 onSubmit: onSubmitRequest 19974 }), 19975 field.type === "date" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__283531__["DatePicker"], { 19976 value: typeof value === "string" && value ? (0, __TURBOPACK__imported__module__826514__["parseISO"])(value) : value instanceof Date ? value : null, 19977 onChange: (date)=>setValue(field.id, date ? (0, __TURBOPACK__imported__module__401851__["format"])(date, "yyyy-MM-dd") : void 0), 19978 disabled, 19979 readOnly, 19980 placeholder, 19981 minDate: builtin?.minDate, 19982 maxDate: builtin?.maxDate, 19983 displayFormat: builtin?.displayFormat, 19984 closeOnSelect: builtin?.closeOnSelect, 19985 locale: builtin?.locale 19986 }), 19987 field.type === "datetime-local" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__129474__["DateTimePicker"], { 19988 value: typeof value === "string" && value ? new Date(value) : value instanceof Date ? value : null, 19989 onChange: (date)=>setValue(field.id, date ? (0, __TURBOPACK__imported__module__401851__["format"])(date, "yyyy-MM-dd'T'HH:mm") : void 0), 19990 disabled, 19991 readOnly, 19992 placeholder, 19993 minuteStep: builtin?.minuteStep, 19994 minDate: builtin?.minDate, 19995 maxDate: builtin?.maxDate, 19996 displayFormat: builtin?.displayFormat, 19997 locale: builtin?.locale 19998 }), 19999 field.type === "datepicker" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__283531__["DatePicker"], { 20000 value: typeof value === "string" && value ? (0, __TURBOPACK__imported__module__826514__["parseISO"])(value) : value instanceof Date ? value : null, 20001 onChange: (date)=>setValue(field.id, date ? (0, __TURBOPACK__imported__module__401851__["format"])(date, "yyyy-MM-dd") : void 0), 20002 disabled, 20003 readOnly, 20004 placeholder, 20005 minDate: builtin?.minDate, 20006 maxDate: builtin?.maxDate, 20007 displayFormat: builtin?.displayFormat, 20008 closeOnSelect: builtin?.closeOnSelect, 20009 locale: builtin?.locale 20010 }), 20011 field.type === "datetime" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__129474__["DateTimePicker"], { 20012 value: typeof value === "string" && value ? new Date(value) : value instanceof Date ? value : null, 20013 onChange: (date)=>setValue(field.id, date ? date.toISOString() : void 0), 20014 disabled, 20015 readOnly, 20016 placeholder, 20017 minuteStep: builtin?.minuteStep, 20018 minDate: builtin?.minDate, 20019 maxDate: builtin?.maxDate, 20020 displayFormat: builtin?.displayFormat, 20021 locale: builtin?.locale 20022 }),
20023 field.type === "time" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__637688__["TimePicker"], { 20024 value: typeof value === "string" ? value : null, 20025 onChange: (time)=>setValue(field.id, time ?? void 0), 20026 disabled, 20027 readOnly, 20028 placeholder, 20029 minuteStep: builtin?.minuteStep 20030 }), 20031 field.type === "textarea" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(TextAreaInput, { 20032 value: value == null ? "" : String(value), 20033 placeholder, 20034 onChange: (next)=>fieldSetValue(next), 20035 autoFocus: autoFocusField, 20036 maxLength: builtin?.maxLength, 20037 showCount: builtin?.showCount, 20038 rows: builtin?.rows, 20039 disabled, 20040 readOnly 20041 }), 20042 field.type === "richtext" && builtin?.editor === "simple" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(SimpleMarkdownEditor, { 20043 value: String(value ?? ""), 20044 onChange: fieldSetValue 20045 }), 20046 field.type === "richtext" && builtin?.editor === "html" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(HtmlRichEditorField, { 20047 value: String(value ?? ""), 20048 onChange: fieldSetValue 20049 }), 20050 field.type === "richtext" && (!builtin?.editor || builtin.editor !== "simple" && builtin.editor !== "html") && /* @__P
20050URE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(MarkdownEditor, { 20051 value: String(value ?? ""), 20052 onChange: fieldSetValue 20053 }), 20054 field.type === "tags" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__276583__["TagsInput"], { 20055 value: Array.isArray(value) ? value.filter((item)=>typeof item === "string") : [], 20056 onChange: (next)=>fieldSetValue(next), 20057 placeholder, 20058 autoFocus: autoFocusField, 20059 suppressInitialSuggestionsOnFocus: autoFocusField, 20060 suggestions: options.map((opt)=>({ 20061 value: opt.value, 20062 label: opt.label 20063 })), 20064 loadSuggestions: typeof builtin?.loadOptions === "function" ? async (query)=>{ 20065 const opts = await loadFieldOptions(field, query); 20066 return opts.map((opt)=>({ 20067 value: opt.value, 20068 label: opt.label 20069 })); 20070 } : void 0 20071 }), 20072 field.type === "combobox" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__341881__["ComboboxInput"], { 20073 value: typeof value === "string" ? value : String(value ?? ""), 20074 onChange: (next)=>fieldSetValue(next), 20075 placeholder, 20076 autoFocus: autoFocusField, 20077 suggestions: builtin?.suggestions ? builtin.suggestions : options.map((opt)=>({ 20078 value: opt.value, 20079 label: opt.label 20080 })), 20081 seedOptions: builtin?.seedOptions ? builtin.seedOptions.map((opt)=>({ 20082 value: opt.value, 20083 label: opt.label 20084 })) : void 0, 20085 resolveLabel: builtin?.resolveLabel, 20086 loadSuggestions: typeof builtin?.loadOptions === "function" ? async (query)=>{ 20087 const opts = await loadFieldOptions(field, query); 20088 return opts.map((opt)=>({ 20089 value: opt.value, 20090 label: opt.label 20091 })); 20092 } : void 0, 20093 allowCustomValues: builtin?.allowCustomValues ?? true, 20094 clearable: !field.required, 20095 disabled 20096 }), 20097 field.type === "checkbox" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("label", { 20098 className: "inline-flex items-center gap-2 cursor-pointer", 20099 children: [
20100 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__848476__["Checkbox"], { 20101 checked: value === true, 20102 onCheckedChange: (next)=>setValue(field.id, next === true), 20103 "data-crud-focus-target": "", 20104 disabled 20105 }), 20106 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 20107 className: "text-sm", 20108 children: field.label 20109 }) 20110 ] 20111 }), 20112 field.type === "select" && !builtin?.multiple && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__262524__["Select"], { 20113 value: singleSelectValue, 20114 onValueChange: (next)=>{ 20115 if (!next || next === SELECT_CLEAR_SENTINEL) { 20116 const isCustomField = field.id.startsWith("cf_") || field.id.startsWith("cf:"); 20117 setValue(field.id, isCustomField ? null : void 0); 20118 return; 20119 } 20120 setValue(field.id, next); 20121 }, 20122 disabled: disabled || readOnly, 20123 children: [
20124 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectTrigger"], { 20125 "data-crud-focus-target": "", 20126 children: /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectValue"], { 20127 placeholder: t("ui.forms.select.emptyOption", "\u2014"), 20128 children: singleSelectLabel 20129 }) 20130 }), 20131 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])(__TURBOPACK__imported__module__262524__["SelectContent"], { 20132 children: [ 20133 !field.required && value != null && value !== "" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectItem"], { 20134 value: SELECT_CLEAR_SENTINEL, 20135 children: t("ui.forms.select.clearOption", "\u2014 Clear \u2014") 20136 }), 20137 options.filter((opt)=>opt.value !== "").map((opt)=>/* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__262524__["SelectItem"], { 20138 value: opt.value, 20139 children: opt.label 20140 }, opt.value)) 20141 ] 20142 }) 20143 ] 20144 }, `${field.id}:${singleSelectValue}:${singleSelectOptionsKey}`), 20145 field.type === "select" && builtin?.multiple && builtin.listbox === true && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(ListboxMultiSelect, { 20146 options, 20147 placeholder, 20148 value: Array.isArray(value) ? value.filter((item)=>typeof item === "string") : [], 20149 onChange: (vals)=>setValue(field.id, vals), 20150 autoFocus: autoFocusField 20151 }), 20152 field.type === "select" && builtin?.multiple && builtin.listbox !== true && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 20153 className: "flex flex-wrap gap-3", 20154 children: options.map((opt)=>{ 20155 const arr = Array.isArray(value) ? value.filter((item)=>typeof item === "string") : []; 20156 const checked = arr.includes(opt.value); 20157 return /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("label", { 20158 className: "inline-flex items-center gap-2 cursor-pointer", 20159 children: [
20160 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__848476__["Checkbox"], { 20161 checked, 20162 onCheckedChange: (state)=>{ 20163 const next = new Set(arr); 20164 if (state === true) { 20165 next.add(opt.value); 20166 } else { 20167 next.delete(opt.value); 20168 } 20169 setValue(field.id, Array.from(next)); 20170 }, 20171 disabled 20172 }), 20173 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("span", { 20174 className: "text-sm", 20175 children: opt.label 20176 }) 20177 ] 20178 }, opt.value); 20179 }) 20180 }), 20181 field.type === "relation" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(RelationSelect, { 20182 options, 20183 placeholder, 20184 value: Array.isArray(value) ? String(value[0] ?? "") : value == null ? "" : String(value), 20185 onChange: (selected)=>setValue(field.id, selected), 20186 autoFocus: autoFocusField 20187 }), 20188 field.type === "custom" && /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__843476__["Fragment"], { 20189 children: field.component({ 20190 id: field.id, 20191 value, 20192 error, 20193 setValue: fieldSetValue, 20194 setFormValue, 20195 values, 20196 entityId: entityIdForField, 20197 recordId, 20198 autoFocus, 20199 disabled 20200 }) 20201 }), 20202 field.description ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsxs"])("div", { 20203 className: "flex items-start gap-2 text-xs text-muted-foreground", 20204 children: [
20205 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])(__TURBOPACK__imported__module__952571__["Info"], { 20206 className: "mt-0.5 h-3.5 w-3.5 shrink-0" 20207 }), 20208 /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 20209 children: field.description 20210 }) 20211 ] 20212 }) : null, 20213 error ? /* @__PURE__ */ (0, __TURBOPACK__imported__module__843476__["jsx"])("div", { 20214 className: "text-xs text-status-error-text", 20215 children: error 20216 }) : null 20217 ] 20218 }); 20219}, (prev, next)=>prev.field.id === next.field.id && prev.field.type === next.field.type && prev.field.label === next.field.label && prev.field.description === next.field.description && prev.field.required === next.field.required && prev.markRequired === next.markRequired && prev.value === next.value && prev.error === next.error && prev.options === next.options && prev.loadFieldOptions === next.loadFieldOptions && prev.autoFocus === next.autoFocus && prev.onSubmitRequest === next.onSubmitRequest && prev.setValue === next.setValue && prev.onBlurRequest === next.onBlurRequest && prev.wrapperClassName === next.wrapperClassName && prev.entityIdForField === next.entityIdForField && prev.recordId === next.recordId && (prev.field.type !== "custom" || prev.values === next.values && prev.field.component === next.field.component)); 20220; 20221__turbopack_context__.s([ 20222 "CrudForm", 20223 0, 20224 CrudForm 20225], 33477); 20226}), 20227]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.