1import { T as Toolbar, W as Webcam, a as Webcam$1, b as ImagePaste, S as StaticImage } from './ImageUploader-2eb1c2b7.js'; 2import { B as Block } from './Button-4603580c.js'; 3import { w as writable, a as getDefaultExportFromCjs, c as commonjsGlobal, f as getAugmentedNamespace, h as spring, S as Static } from './Index-1fd72dbe.js'; 4import { n as normalise_file, u as upload, p as prepare_files } from './index-a4a7fd54.js'; 5import './Example.svelte_svelte_type_style_lang-67e00421.js'; 6import { _ as __viteBrowserExternal } from './__vite-browser-external-cb19bde2.js'; 7import { I as IconButton } from './IconButton-a83f4ef3.js'; 8import { C as Check } from './Check-1d114215.js'; 9import { C as Clear } from './Clear-9760deed.js'; 10import { U as Undo } from './Undo-6c110254.js'; 11/* empty css */import { D as DropdownArrow } from './DropdownArrow-835e9379.js'; 12import { I as Image$1 } from './Image-6cbf81d1.js'; 13import { U as Upload$1 } from './Upload-8f4bfd80.js'; 14import { U as Upload } from './Upload-5eb3d513.js'; 15import './utils-8f25e669.js'; 16import './BlockLabel-29e86818.js'; 17import './Empty-e2e0272e.js'; 18import './ShareButton-0349c9cf.js'; 19import './Download-ea83bae3.js'; 20import './svelte/svelte.js'; 21import './file-url-7e88bc31.js'; 22 23/* home/runner/work/gradio/gradio/js/icons/src/Brush.svelte generated by Svelte v4.2.2 */ 24const { 25 SvelteComponent: SvelteComponent$m, 26 append: append$j, 27 attr: attr$k, 28 detach: detach$m, 29 init: init$n, 30 insert: insert$m, 31 noop: noop$b, 32 safe_not_equal: safe_not_equal$m, 33 svg_element: svg_element$6 34} = window.__gradio__svelte__internal; 35function create_fragment$m(ctx) { 36 let svg; 37 let path0; 38 let path1; 39 40 return { 41 c() { 42 svg = svg_element$6("svg"); 43 path0 = svg_element$6("path"); 44 path1 = svg_element$6("path"); 45 attr$k(path0, "d", "M28.828 3.172a4.094 4.094 0 0 0-5.656 0L4.05 22.292A6.954 6.954 0 0 0 2 27.242V30h2.756a6.952 6.952 0 0 0 4.95-2.05L28.828 8.829a3.999 3.999 0 0 0 0-5.657zM10.91 18.26l2.829 2.829l-2.122 2.121l-2.828-2.828zm-2.619 8.276A4.966 4.966 0 0 1 4.756 28H4v-.759a4.967 4.967 0 0 1 1.464-3.535l1.91-1.91l2.829 2.828zM27.415 7.414l-12.261 12.26l-2.829-2.828l12.262-12.26a2.047 2.047 0 0 1 2.828 0a2 2 0 0 1 0 2.828z"); 46 attr$k(path0, "fill", "currentColor"); 47 attr$k(path1, "d", "M6.5 15a3.5 3.5 0 0 1-2.475-5.974l3.5-3.5a1.502 1.502 0 0 0 0-2.121a1.537 1.537 0 0 0-2.121 0L3.415 5.394L2 3.98l1.99-1.988a3.585 3.585 0 0 1 4.95 0a3.504 3.504 0 0 1 0 4.949L5.439 10.44a1.502 1.502 0 0 0 0 2.121a1.537 1.537 0 0 0 2.122 0l4.024-4.024L13 9.95l-4.025 4.024A3.475 3.475 0 0 1 6.5 15z");
48 attr$k(path1, "fill", "currentColor"); 49 attr$k(svg, "width", "100%"); 50 attr$k(svg, "height", "100%"); 51 attr$k(svg, "viewBox", "0 0 32 32"); 52 }, 53 m(target, anchor) { 54 insert$m(target, svg, anchor); 55 append$j(svg, path0); 56 append$j(svg, path1); 57 }, 58 p: noop$b, 59 i: noop$b, 60 o: noop$b, 61 d(detaching) { 62 if (detaching) { 63 detach$m(svg); 64 } 65 } 66 }; 67} 68 69let Brush$1 = class Brush extends SvelteComponent$m { 70 constructor(options) { 71 super(); 72 init$n(this, options, null, create_fragment$m, safe_not_equal$m, {}); 73 } 74}; 75 76/* home/runner/work/gradio/gradio/js/icons/src/BrushSize.svelte generated by Svelte v4.2.2 */ 77const { 78 SvelteComponent: SvelteComponent$l, 79 append: append$i, 80 attr: attr$j, 81 detach: detach$l, 82 init: init$m, 83 insert: insert$l, 84 noop: noop$a, 85 safe_not_equal: safe_not_equal$l, 86 svg_element: svg_element$5 87} = window.__gradio__svelte__internal; 88function create_fragment$l(ctx) { 89 let svg; 90 let path; 91 92 return { 93 c() { 94 svg = svg_element$5("svg"); 95 path = svg_element$5("path"); 96 attr$j(path, "fill", "currentColor"); 97 attr$j(path, "d", "M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10s10-4.47 10-10S17.53 2 12 2z"); 98 attr$j(svg, "xmlns", "http://www.w3.org/2000/svg"); 99 attr$j(svg, "width", "100%"); 100 attr$j(svg, "height", "100%"); 101 attr$j(svg, "viewBox", "0 0 24 24"); 102 }, 103 m(target, anchor) { 104 insert$l(target, svg, anchor); 105 append$i(svg, path); 106 }, 107 p: noop$a, 108 i: noop$a, 109 o: noop$a, 110 d(detaching) { 111 if (detaching) { 112 detach$l(svg); 113 } 114 } 115 }; 116} 117 118let BrushSize$1 = class BrushSize extends SvelteComponent$l { 119 constructor(options) { 120 super(); 121 init$m(this, options, null, create_fragment$l, safe_not_equal$l, {}); 122 } 123}; 124 125/* home/runner/work/gradio/gradio/js/icons/src/Crop.svelte generated by Svelte v4.2.2 */ 126const { 127 SvelteComponent: SvelteComponent$k, 128 append: append$h, 129 attr: attr$i, 130 detach: detach$k, 131 init: init$l, 132 insert: insert$k, 133 noop: noop$9, 134 safe_not_equal: safe_not_equal$k, 135 svg_element: svg_element$4 136} = window.__gradio__svelte__internal; 137function create_fragment$k(ctx) { 138 let svg; 139 let path; 140 141 return { 142 c() { 143 svg = svg_element$4("svg"); 144 path = svg_element$4("path"); 145 attr$i(path, "fill", "currentColor"); 146 attr$i(path, "d", "M17 23v-4H7q-.825 0-1.413-.588T5 17V7H1V5h4V1h2v16h16v2h-4v4h-2Zm0-8V7H9V5h8q.825 0 1.413.588T19 7v8h-2Z"); 147 attr$i(svg, "xmlns", "http://www.w3.org/2000/svg"); 148 attr$i(svg, "width", "100%"); 149 attr$i(svg, "height", "100%"); 150 attr$i(svg, "viewBox", "0 0 24 24"); 151 }, 152 m(target, anchor) { 153 insert$k(target, svg, anchor); 154 append$h(svg, path); 155 }, 156 p: noop$9, 157 i: noop$9, 158 o: noop$9, 159 d(detaching) { 160 if (detaching) { 161 detach$k(svg); 162 } 163 } 164 }; 165} 166 167let Crop$1 = class Crop extends SvelteComponent$k { 168 constructor(options) { 169 super(); 170 init$l(this, options, null, create_fragment$k, safe_not_equal$k, {}); 171 } 172}; 173 174/* home/runner/work/gradio/gradio/js/icons/src/Erase.svelte generated by Svelte v4.2.2 */ 175const { 176 SvelteComponent: SvelteComponent$j, 177 append: append$g, 178 attr: attr$h, 179 detach: detach$j, 180 init: init$k, 181 insert: insert$j, 182 noop: noop$8, 183 safe_not_equal: safe_not_equal$j, 184 svg_element: svg_element$3 185} = window.__gradio__svelte__internal; 186function create_fragment$j(ctx) { 187 let svg; 188 let g; 189 let path0; 190 let path1; 191 192 return { 193 c() { 194 svg = svg_element$3("svg"); 195 g = svg_element$3("g"); 196 path0 = svg_element$3("path"); 197 path1 = svg_element$3("path"); 198 attr$h(path0, "fill", "currentColor"); 199 attr$h(path0, "d", "m5.505 11.41l.53.53l-.53-.53ZM3 14.952h-.75H3ZM9.048 21v.75V21ZM11.41 5.505l-.53-.53l.53.53Zm1.831 12.34a.75.75 0 0 0 1.06-1.061l-1.06 1.06ZM7.216 9.697a.75.75 0 1 0-1.06 1.061l1.06-1.06Zm10.749 2.362l-5.905 5.905l1.06 1.06l5.905-5.904l-1.06-1.06Zm-11.93-.12l5.905-5.905l-1.06-1.06l-5.905 5.904l1.06 1.06Zm0 6.025c-.85-.85-1.433-1.436-1.812-1.933c-.367-.481-.473-.79-.473-1.08h-1.5c0 .749.312 1.375.78 1.99c.455.596 1.125 1.263 1.945 2.083l1.06-1.06Zm-1.06-7.086c-.82.82-1.49 1.488-1.945 2.084c-.468.614-.78 1.24-.78 1.99h1.5c0-.29.106-.6.473-1.08c.38-.498.962-1.083 1.812-1.933l-1.06-1.06Zm7.085 7.086c-.85.85-1.435 1.433-1.933 1.813c-.48.366-.79.472-1.08.472v1.5c.75 0 1.376-.312 1.99-.78c.596-.455 1.264-1.
199125 2.084-1.945l-1.06-1.06Zm-7.085 1.06c.82.82 1.487 1.49 2.084 1.945c.614.468 1.24.78 1.989.78v-1.5c-.29 0-.599-.106-1.08-.473c-.497-.38-1.083-.962-1.933-1.812l-1.06 1.06Zm12.99-12.99c.85.85 1.433 1.436 1.813 1.933c.366.481.472.79.472 1.08h1.5c0-.749-.312-1.375-.78-1.99c-.455-.596-1.125-1.263-1.945-2.083l-1.06 1.06Zm1.06 7.086c.82-.82 1.49-1.488 1.945-2.084c.468-.614.78-1.24.78-1.99h-1.5c0 .29-.106.6-.473 1.08c-.38.498-.962 1.083-1.812 1.933l1.06 1.06Zm0-8.146c-.82-.82-1.487-1.49-2.084-1.945c-.614-.468-1.24-.78-1.989-.78v1.5c.29 0 .599.106 1.08.473c.497.38 1.083.962 1.933 1.812l1.06-1.06Zm-7.085 1.06c.85-.85 1.435-1.433 1.933-1.812c.48-.367.79-.473 1.08-.473v-1.5c-.75 0-1.376.312-1.99.78c-.596.455-1.264 1.125-2.084 1.945l1.06 1.06Zm2.362 10.749L7.216 9.698l-1.06 1.061l7.085 7.085l1.06-1.06Z"); 200 attr$h(path1, "stroke", "currentColor"); 201 attr$h(path1, "stroke-linecap", "round"); 202 attr$h(path1, "stroke-width", "1.5"); 203 attr$h(path1, "d", "M9 21h12"); 204 attr$h(g, "fill", "none"); 205 attr$h(svg, "xmlns", "http://www.w3.org/2000/svg"); 206 attr$h(svg, "width", "100%"); 207 attr$h(svg, "height", "100%"); 208 attr$h(svg, "viewBox", "0 0 24 24"); 209 }, 210 m(target, anchor) { 211 insert$j(target, svg, anchor); 212 append$g(svg, g); 213 append$g(g, path0); 214 append$g(g, path1); 215 }, 216 p: noop$8, 217 i: noop$8, 218 o: noop$8, 219 d(detaching) { 220 if (detaching) { 221 detach$j(svg); 222 } 223 } 224 }; 225} 226 227class Erase extends SvelteComponent$j { 228 constructor(options) { 229 super(); 230 init$k(this, options, null, create_fragment$j, safe_not_equal$j, {}); 231 } 232} 233 234/* home/runner/work/gradio/gradio/js/icons/src/Eyedropper.svelte generated by Svelte v4.2.2 */ 235const { 236 SvelteComponent: SvelteComponent$i, 237 append: append$f, 238 attr: attr$g, 239 detach: detach$i, 240 init: init$j, 241 insert: insert$i, 242 noop: noop$7, 243 safe_not_equal: safe_not_equal$i, 244 svg_element: svg_element$2 245} = window.__gradio__svelte__internal; 246function create_fragment$i(ctx) { 247 let svg; 248 let path; 249 250 return { 251 c() { 252 svg = svg_element$2("svg"); 253 path = svg_element$2("path"); 254 attr$g(path, "fill", "currentColor"); 255 attr$g(path, "d", "M21.03 2.97a3.578 3.578 0 0 0-5.06 0L14 4.94l-.013-.013a1.75 1.75 0 0 0-2.475 0l-.585.586a1.75 1.75 0 0 0 0 2.475l.012.012l-6.78 6.78a2.25 2.25 0 0 0-.659 1.592v.687l-1.28 2.347c-.836 1.533.841 3.21 2.374 2.375l2.347-1.28h.688a2.25 2.25 0 0 0 1.59-.66L16 13.061l.012.012a1.75 1.75 0 0 0 2.475 0l.586-.585a1.75 1.75 0 0 0 0-2.475L19.061 10l1.97-1.97a3.578 3.578 0 0 0 0-5.06ZM12 9.061l2.94 2.94l-6.78 6.78a.75.75 0 0 1-.531.22H6.75a.75.75 0 0 0-.359.09l-2.515 1.373a.234.234 0 0 1-.159.032a.264.264 0 0 1-.138-.075a.264.264 0 0 1-.075-.138a.234.234 0 0 1 .033-.158l1.372-2.515A.75.75 0 0 0 5 17.25v-.878a.75.75 0 0 1 .22-.53L12 9.06Z"); 256 attr$g(svg, "xmlns", "http://www.w3.org/2000/svg"); 257 attr$g(svg, "width", "100%"); 258 attr$g(svg, "height", "100%"); 259 attr$g(svg, "viewBox", "0 0 24 24"); 260 }, 261 m(target, anchor) { 262 insert$i(target, svg, anchor); 263 append$f(svg, path); 264 }, 265 p: noop$7, 266 i: noop$7, 267 o: noop$7, 268 d(detaching) { 269 if (detaching) { 270 detach$i(svg); 271 } 272 } 273 }; 274} 275 276class Eyedropper extends SvelteComponent$i { 277 constructor(options) { 278 super(); 279 init$j(this, options, null, create_fragment$i, safe_not_equal$i, {}); 280 } 281} 282 283/* home/runner/work/gradio/gradio/js/icons/src/Palette.svelte generated by Svelte v4.2.2 */ 284const { 285 SvelteComponent: SvelteComponent$h, 286 append: append$e, 287 attr: attr$f, 288 detach: detach$h, 289 init: init$i, 290 insert: insert$h, 291 noop: noop$6, 292 safe_not_equal: safe_not_equal$h, 293 svg_element: svg_element$1 294} = window.__gradio__svelte__internal; 295function create_fragment$h(ctx) { 296 let svg; 297 let g; 298 let path0; 299 let circle0; 300 let circle1; 301 let path1; 302 303 return { 304 c() { 305 svg = svg_element$1("svg"); 306 g = svg_element$1("g"); 307 path0 = svg_element$1("path"); 308 circle0 = svg_element$1("circle"); 309 circle1 = svg_element$1("circle"); 310 path1 = svg_element$1("path"); 311 attr$f(path0, "d", "M2 12.026c0 5.146 3.867 9.387 8.847 9.96c.735.085 1.447-.228 1.97-.753a1.68 1.68 0 0 0 0-2.372c-.523-.525-.95-1.307-.555-1.934c1.576-2.508 9.738 3.251 9.738-4.9C22 6.488 17.523 2 12 2S2 6.489 2 12.026Z"); 312 attr$f(circle0, "cx", "17.5"); 313 attr$f(circle0, "cy", "11.5"); 314 attr$f(circle0, "r", ".75"); 315 attr$f(circle1, "cx", "6.5"); 316 attr$f(circle1, "cy", "11.5"); 317 attr$f(circle1, "r", ".75"); 318 attr$f(path1, "d", "M10.335 7a.75.75 0 1 1-1.5 0a.75.75 0 0 1 1.5 0Zm4.915 0a.75.75 0 1 1-1.5 0a.75.75 0 0 1 1.5 0Z"); 319 attr$f(g, "fill", "none"); 320 attr$f(g, "stroke", "currentColor"); 321 attr$f(g, "stroke-width", "1.5"); 322 attr$f(svg, "xmlns", "http://www.w3.org/2000/svg"); 323 attr$f(svg, "width", "100%"); 324 attr$f(svg, "height", "100%"); 325 attr$f(svg, "viewBox", "0 0 24 24"); 326 }, 327 m(target, anchor) { 328 insert$h(target, svg, anchor); 329 append$e(svg, g); 330 append$e(g, path0); 331 append$e(g, circle0); 332 append$e(g, circle1); 333 append$e(g, path1); 334 }, 335 p: noop$6, 336 i: noop$6, 337 o: noop$6, 338 d(detaching) { 339 if (detaching) { 340 detach$h(svg); 341 } 342 } 343 }; 344} 345 346class Palette extends SvelteComponent$h { 347 constructor(options) { 348 super(); 349 init$i(this, options, null, create_fragment$h, safe_not_equal$h, {}); 350 } 351} 352 353/* home/runner/work/gradio/gradio/js/icons/src/Redo.svelte generated by Svelte v4.2.2 */ 354const { 355 SvelteComponent: SvelteComponent$g, 356 append: append$d, 357 attr: attr$e, 358 detach: detach$g, 359 init: init$h, 360 insert: insert$g,
361 noop: noop$5, 362 safe_not_equal: safe_not_equal$g, 363 set_style: set_style$8, 364 svg_element 365} = window.__gradio__svelte__internal; 366function create_fragment$g(ctx) { 367 let svg; 368 let polyline; 369 let path; 370 371 return { 372 c() { 373 svg = svg_element("svg"); 374 polyline = svg_element("polyline"); 375 path = svg_element("path"); 376 attr$e(polyline, "points", "1 4 1 10 7 10"); 377 attr$e(path, "d", "M3.51 15a9 9 0 1 0 2.13-9.36L1 10"); 378 attr$e(svg, "xmlns", "http://www.w3.org/2000/svg"); 379 attr$e(svg, "width", "100%"); 380 attr$e(svg, "height", "100%"); 381 attr$e(svg, "viewBox", "0 0 24 24"); 382 attr$e(svg, "fill", "none"); 383 attr$e(svg, "stroke", "currentColor"); 384 attr$e(svg, "stroke-width", "2"); 385 attr$e(svg, "stroke-linecap", "round"); 386 attr$e(svg, "stroke-linejoin", "round"); 387 attr$e(svg, "class", "feather feather-rotate-ccw"); 388 set_style$8(svg, "transform", "rotateY(180deg)"); 389 }, 390 m(target, anchor) { 391 insert$g(target, svg, anchor); 392 append$d(svg, polyline); 393 append$d(svg, path); 394 }, 395 p: noop$5, 396 i: noop$5, 397 o: noop$5, 398 d(detaching) { 399 if (detaching) { 400 detach$g(svg); 401 } 402 } 403 }; 404} 405 406class Redo extends SvelteComponent$g { 407 constructor(options) { 408 super(); 409 init$h(this, options, null, create_fragment$g, safe_not_equal$g, {}); 410 } 411} 412 413const Tools_svelte_svelte_type_style_lang = ''; 414 415/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/Tools.svelte generated by Svelte v4.2.2 */ 416const { 417 SvelteComponent: SvelteComponent$f,
418 append: append$c, 419 attr: attr$d, 420 check_outros: check_outros$8, 421 component_subscribe: component_subscribe$5, 422 create_component: create_component$b, 423 create_slot: create_slot$1, 424 destroy_component: destroy_component$b, 425 detach: detach$f, 426 element: element$d, 427 empty: empty$6, 428 ensure_array_like: ensure_array_like$4, 429 get_all_dirty_from_scope: get_all_dirty_from_scope$1, 430 get_slot_changes: get_slot_changes$1, 431 group_outros: group_outros$8, 432 init: init$g, 433 insert: insert$f, 434 mount_component: mount_component$b, 435 outro_and_destroy_block, 436 safe_not_equal: safe_not_equal$f, 437 set_store_value: set_store_value$3, 438 space: space$c, 439 transition_in: transition_in$b, 440 transition_out: transition_out$b, 441 update_keyed_each: update_keyed_each$1, 442 update_slot_base: update_slot_base$1 443} = window.__gradio__svelte__internal;const { getContext: getContext$4, setContext: setContext$1 } = window.__gradio__svelte__internal; 444function get_each_context$4(ctx, list, i) { 445 const child_ctx = ctx.slice(); 446 child_ctx[17] = list[i]; 447 return child_ctx; 448} 449 450function get_each_context_1$2(ctx, list, i) { 451 const child_ctx = ctx.slice(); 452 child_ctx[20] = list[i]; 453 return child_ctx; 454} 455 456// (69:2) {#if sub_menu} 457function create_if_block$a(ctx) { 458 let each_blocks = []; 459 let each_1_lookup = new Map(); 460 let each_1_anchor; 461 let current; 462 let each_value_1 = ensure_array_like$4(/*sub_menu*/ ctx[3].options); 463 const get_key = ctx => /*meta*/ ctx[20].id; 464 465 for (let i = 0; i < each_value_1.length; i += 1) { 466 let child_ctx = get_each_context_1$2(ctx, each_value_1, i); 467 let key = get_key(child_ctx); 468 each_1_lookup.set(key, each_blocks[i] = create_each_block_1$2(key, child_ctx)); 469 } 470 471 return { 472 c() { 473 for (let i = 0; i < each_blocks.length; i += 1) { 474 each_blocks[i].c(); 475 } 476 477 each_1_anchor = empty$6(); 478 }, 479 m(target, anchor) { 480 for (let i = 0; i < each_blocks.length; i += 1) { 481 if (each_blocks[i]) { 482 each_blocks[i].m(target, anchor); 483 } 484 } 485 486 insert$f(target, each_1_anchor, anchor); 487 current = true; 488 }, 489 p(ctx, dirty) { 490 if (dirty & /*sub_tool, sub_menu, $active_tool, $current_color, undefined, tool_context*/ 541) { 491 each_value_1 = ensure_array_like$4(/*sub_menu*/ ctx[3].options); 492 group_outros$8(); 493 each_blocks = update_keyed_each$1(each_blocks, dirty, get_key, 1, ctx, each_value_1, each_1_lookup, each_1_anchor.parentNode, outro_and_destroy_block, create_each_block_1$2, each_1_anchor, get_each_context_1$2); 494 check_outros$8(); 495 } 496 }, 497 i(local) { 498 if (current) return; 499 500 for (let i = 0; i < each_value_1.length; i += 1) { 501 transition_in$b(each_blocks[i]); 502 } 503 504 current = true; 505 }, 506 o(local) { 507 for (let i = 0; i < each_blocks.length; i += 1) { 508 transition_out$b(each_blocks[i]); 509 } 510 511 current = false; 512 }, 513 d(detaching) { 514 if (detaching) { 515 detach$f(each_1_anchor); 516 } 517 518 for (let i = 0; i < each_blocks.length; i += 1) { 519 each_blocks[i].d(detaching); 520 } 521 } 522 }; 523} 524 525// (70:3) {#each sub_menu.options as meta (meta.id)} 526function create_each_block_1$2(key_1, ctx) { 527 let first; 528 let iconbutton; 529 let current; 530 531 function click_handler() { 532 return /*click_handler*/ ctx[14](/*meta*/ ctx[20]); 533 } 534 535 iconbutton = new IconButton({ 536 props: { 537 highlight: /*sub_tool*/ ctx[2] === /*meta*/ ctx[20].id && /*meta*/ ctx[20].id !== "brush_size", 538 color: /*$active_tool*/ ctx[0] === "draw" && /*meta*/ ctx[20].id === "brush_size" 539 ? /*$current_color*/ ctx[4] 540 : undefined, 541 Icon: /*meta*/ ctx[20].icon, 542 size: "large", 543 padded: false, 544 label: /*meta*/ ctx[20].label + " button", 545 hasPopup: true, 546 transparent: true 547 } 548 }); 549 550 iconbutton.$on("click", click_handler); 551 552 return { 553 key: key_1, 554 first: null, 555 c() { 556 first = empty$6(); 557 create_component$b(iconbutton.$$.fragment); 558 this.first = first; 559 }, 560 m(target, anchor) { 561 insert$f(target, first, anchor); 562 mount_component$b(iconbutton, target, anchor); 563 current = true; 564 }, 565 p(new_ctx, dirty) { 566 ctx = new_ctx; 567 const iconbutton_changes = {}; 568 if (dirty & /*sub_tool, sub_menu*/ 12) iconbutton_changes.highlight = /*sub_tool*/ ctx[2] === /*meta*/ ctx[20].id && /*meta*/ ctx[20].id !== "brush_size"; 569
570 if (dirty & /*$active_tool, sub_menu, $current_color*/ 25) iconbutton_changes.color = /*$active_tool*/ ctx[0] === "draw" && /*meta*/ ctx[20].id === "brush_size" 571 ? /*$current_color*/ ctx[4] 572 : undefined; 573 574 if (dirty & /*sub_menu*/ 8) iconbutton_changes.Icon = /*meta*/ ctx[20].icon; 575 if (dirty & /*sub_menu*/ 8) iconbutton_changes.label = /*meta*/ ctx[20].label + " button"; 576 iconbutton.$set(iconbutton_changes); 577 }, 578 i(local) { 579 if (current) return; 580 transition_in$b(iconbutton.$$.fragment, local); 581 current = true; 582 }, 583 o(local) { 584 transition_out$b(iconbutton.$$.fragment, local); 585 current = false; 586 }, 587 d(detaching) { 588 if (detaching) { 589 detach$f(first); 590 } 591 592 destroy_component$b(iconbutton, detaching); 593 } 594 }; 595} 596 597// (68:1) <Toolbar show_border={false}> 598function create_default_slot_1$2(ctx) { 599 let if_block_anchor; 600 let current; 601 let if_block = /*sub_menu*/ ctx[3] && create_if_block$a(ctx); 602 603 return { 604 c() { 605 if (if_block) if_block.c(); 606 if_block_anchor = empty$6(); 607 }, 608 m(target, anchor) { 609 if (if_block) if_block.m(target, anchor); 610 insert$f(target, if_block_anchor, anchor); 611 current = true; 612 }, 613 p(ctx, dirty) { 614 if (/*sub_menu*/ ctx[3]) { 615 if (if_block) { 616 if_block.p(ctx, dirty); 617 618 if (dirty & /*sub_menu*/ 8) { 619 transition_in$b(if_block, 1); 620 } 621 } else { 622 if_block = create_if_block$a(ctx); 623 if_block.c(); 624 transition_in$b(if_block, 1); 625 if_block.m(if_block_anchor.parentNode, if_block_anchor); 626 } 627 } else if (if_block) { 628 group_outros$8(); 629 630 transition_out$b(if_block, 1, 1, () => { 631 if_block = null; 632 }); 633 634 check_outros$8(); 635 } 636 }, 637 i(local) { 638 if (current) return; 639 transition_in$b(if_block); 640 current = true; 641 }, 642 o(local) { 643 transition_out$b(if_block); 644 current = false; 645 }, 646 d(detaching) { 647 if (detaching) { 648 detach$f(if_block_anchor); 649 } 650 651 if (if_block) if_block.d(detaching); 652 } 653 }; 654} 655 656// (89:2) {#each tools as tool (tool)} 657function create_each_block$4(key_1, ctx) { 658 let first; 659 let iconbutton; 660 let current; 661 662 function click_handler_1() { 663 return /*click_handler_1*/ ctx[15](/*tool*/ ctx[17]); 664 } 665 666 iconbutton = new IconButton({ 667 props: { 668 disabled: /*tool*/ ctx[17] === "bg" && !!/*$current_history*/ ctx[5].previous, 669 highlight: /*$active_tool*/ ctx[0] === /*tool*/ ctx[17], 670 Icon: /*tools_meta*/ ctx[10][/*tool*/ ctx[17]].icon, 671 size: "large", 672 padded: false, 673 label: /*tools_meta*/ ctx[10][/*tool*/ ctx[17]].label + " button", 674 transparent: true 675 } 676 }); 677 678 iconbutton.$on("click", click_handler_1); 679 680 return { 681 key: key_1, 682 first: null, 683 c() { 684 first = empty$6(); 685 create_component$b(iconbutton.$$.fragment); 686 this.first = first; 687 }, 688 m(target, anchor) { 689 insert$f(target, first, anchor); 690 mount_component$b(iconbutton, target, anchor); 691 current = true; 692 }, 693 p(new_ctx, dirty) { 694 ctx = new_ctx; 695 const iconbutton_changes = {}; 696 if (dirty & /*tools, $current_history*/ 34) iconbutton_changes.disabled = /*tool*/ ctx[17] === "bg" && !!/*$current_history*/ ctx[5].previous; 697 if (dirty & /*$active_tool, tools*/ 3) iconbutton_changes.highlight = /*$active_tool*/ ctx[0] === /*tool*/ ctx[17]; 698 if (dirty & /*tools*/ 2) iconbutton_changes.Icon = /*tools_meta*/ ctx[10][/*tool*/ ctx[17]].icon; 699 if (dirty & /*tools*/ 2) iconbutton_changes.label = /*tools_meta*/ ctx[10][/*tool*/ ctx[17]].label + " button"; 700 iconbutton.$set(iconbutton_changes); 701 }, 702 i(local) { 703 if (current) return; 704 transition_in$b(iconbutton.$$.fragment, local); 705 current = true; 706 }, 707 o(local) { 708 transition_out$b(iconbutton.$$.fragment, local); 709 current = false; 710 }, 711 d(detaching) { 712 if (detaching) { 713 detach$f(first); 714 } 715 716 destroy_component$b(iconbutton, detaching); 717 } 718 }; 719} 720 721// (88:1) <Toolbar show_border={false}> 722function create_default_slot$2(ctx) { 723 let each_blocks = []; 724 let each_1_lookup = new Map(); 725 let each_1_anchor; 726 let current; 727 let each_value = ensure_array_like$4(/*tools*/ ctx[1]); 728 const get_key = ctx => /*tool*/ ctx[17]; 729 730 for (let i = 0; i < each_value.length; i += 1) { 731 let child_ctx = get_each_context$4(ctx, each_value, i); 732 let key = get_key(child_ctx); 733 each_1_lookup.set(key, each_blocks[i] = create_each_block$4(key, child_ctx)); 734 } 735 736 return { 737 c() { 738 for (let i = 0; i < each_blocks.length; i += 1) { 739 each_blocks[i].c(); 740 } 741 742 each_1_anchor = empty$6(); 743 }, 744 m(target, anchor) { 745 for (let i = 0; i < each_blocks.length; i += 1) { 746 if (each_blocks[i]) { 747 each_blocks[i].m(target, anchor); 748 } 749 } 750 751 insert$f(target, each_1_anchor, anchor); 752 current = true; 753 }, 754 p(ctx, dirty) {
755 if (dirty & /*tools, $current_history, $active_tool, tools_meta*/ 1059) { 756 each_value = ensure_array_like$4(/*tools*/ ctx[1]); 757 group_outros$8(); 758 each_blocks = update_keyed_each$1(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, outro_and_destroy_block, create_each_block$4, each_1_anchor, get_each_context$4); 759 check_outros$8(); 760 } 761 }, 762 i(local) { 763 if (current) return; 764 765 for (let i = 0; i < each_value.length; i += 1) { 766 transition_in$b(each_blocks[i]); 767 } 768 769 current = true; 770 }, 771 o(local) { 772 for (let i = 0; i < each_blocks.length; i += 1) { 773 transition_out$b(each_blocks[i]); 774 } 775 776 current = false; 777 }, 778 d(detaching) { 779 if (detaching) { 780 detach$f(each_1_anchor); 781 } 782 783 for (let i = 0; i < each_blocks.length; i += 1) { 784 each_blocks[i].d(detaching); 785 } 786 } 787 }; 788} 789 790function create_fragment$f(ctx) { 791 let t0; 792 let div; 793 let toolbar0; 794 let t1; 795 let toolbar1; 796 let current; 797 const default_slot_template = /*#slots*/ ctx[13].default; 798 const default_slot = create_slot$1(default_slot_template, ctx, /*$$scope*/ ctx[16], null); 799 800 toolbar0 = new Toolbar({ 801 props: { 802 show_border: false, 803 $$slots: { default: [create_default_slot_1$2] }, 804 $$scope: { ctx } 805 } 806 }); 807 808 toolbar1 = new Toolbar({ 809 props: { 810 show_border: false, 811 $$slots: { default: [create_default_slot$2] }, 812 $$scope: { ctx } 813 } 814 }); 815 816 return { 817 c() { 818 if (default_slot) default_slot.c(); 819 t0 = space$c(); 820 div = element$d("div"); 821 create_component$b(toolbar0.$$.fragment); 822 t1 = space$c(); 823 create_component$b(toolbar1.$$.fragment); 824 attr$d(div, "class", "toolbar-wrap svelte-dybhw0"); 825 }, 826 m(target, anchor) { 827 if (default_slot) { 828 default_slot.m(target, anchor); 829 } 830 831 insert$f(target, t0, anchor); 832 insert$f(target, div, anchor); 833 mount_component$b(toolbar0, div, null); 834 append$c(div, t1);
835 mount_component$b(toolbar1, div, null); 836 current = true; 837 }, 838 p(ctx, [dirty]) { 839 if (default_slot) { 840 if (default_slot.p && (!current || dirty & /*$$scope*/ 65536)) { 841 update_slot_base$1( 842 default_slot, 843 default_slot_template, 844 ctx, 845 /*$$scope*/ ctx[16], 846 !current 847 ? get_all_dirty_from_scope$1(/*$$scope*/ ctx[16]) 848 : get_slot_changes$1(default_slot_template, /*$$scope*/ ctx[16], dirty, null), 849 null 850 ); 851 } 852 } 853 854 const toolbar0_changes = {}; 855 856 if (dirty & /*$$scope, sub_menu, sub_tool, $active_tool, $current_color*/ 65565) { 857 toolbar0_changes.$$scope = { dirty, ctx }; 858 } 859 860 toolbar0.$set(toolbar0_changes); 861 const toolbar1_changes = {}; 862 863 if (dirty & /*$$scope, tools, $current_history, $active_tool*/ 65571) { 864 toolbar1_changes.$$scope = { dirty, ctx }; 865 } 866 867 toolbar1.$set(toolbar1_changes); 868 }, 869 i(local) { 870 if (current) return; 871 transition_in$b(default_slot, local); 872 transition_in$b(toolbar0.$$.fragment, local); 873 transition_in$b(toolbar1.$$.fragment, local); 874 current = true; 875 }, 876 o(local) { 877 transition_out$b(default_slot, local); 878 transition_out$b(toolbar0.$$.fragment, local); 879 transition_out$b(toolbar1.$$.fragment, local); 880 current = false; 881 }, 882 d(detaching) { 883 if (detaching) { 884 detach$f(t0); 885 detach$f(div); 886 } 887 888 if (default_slot) default_slot.d(detaching); 889 destroy_component$b(toolbar0); 890 destroy_component$b(toolbar1); 891 } 892 }; 893} 894 895const TOOL_KEY = Symbol("tool"); 896 897function instance$f($$self, $$props, $$invalidate) { 898 let sub_menu; 899 let $active_tool; 900 let $current_color; 901 let $current_history; 902 let { $$slots: slots = {}, $$scope } = $$props; 903 const { current_history, active_tool } = getContext$4(EDITOR_KEY); 904 component_subscribe$5($$self, current_history, value => $$invalidate(5, $current_history = value)); 905 component_subscribe$5($$self, active_tool, value => $$invalidate(0, $active_tool = value)); 906 let { i18n } = $$props; 907 let tools = []; 908 909 const metas = { 910 draw: null, 911 erase: null, 912 crop: null, 913 bg: null 914 }; 915 916 let current_color = writable("#000000"); 917 component_subscribe$5($$self, current_color, value => $$invalidate(4, $current_color = value)); 918 let sub_tool; 919 920 const tool_context = { 921 current_color, 922 register_tool: (type, meta) => { 923 $$invalidate(1, tools = [...tools, type]); 924 $$invalidate(12, metas[type] = meta, metas); 925 926 return () => { 927 $$invalidate(1, tools = tools.filter(tool => tool !== type)); 928 }; 929 }, 930 active_tool: { subscribe: active_tool.subscribe }, 931 activate_subtool: (_sub_tool, cb) => { 932 $$invalidate(2, sub_tool = _sub_tool); 933 if (cb) cb(); 934 } 935 }; 936 937 setContext$1(TOOL_KEY, tool_context); 938 939 const tools_meta = { 940 bg: { 941 order: 0, 942 label: i18n("Image"), 943 icon: Image$1 944 }, 945 crop: { 946 order: 1, 947 label: i18n("Transform"), 948 icon: Crop$1 949 }, 950 draw: { 951 order: 2, 952 label: i18n("Draw"), 953 icon: Brush$1 954 }, 955 erase: { 956 order: 2, 957 label: i18n("Erase"), 958 icon: Erase 959 } 960 }; 961 962 const click_handler = meta => tool_context.activate_subtool(meta.id, meta.cb); 963 const click_handler_1 = tool => set_store_value$3(active_tool, $active_tool = tool, $active_tool); 964 965 $$self.$$set = $$props => {
966 if ('i18n' in $$props) $$invalidate(11, i18n = $$props.i18n); 967 if ('$$scope' in $$props) $$invalidate(16, $$scope = $$props.$$scope); 968 }; 969 970 $$self.$$.update = () => { 971 if ($$self.$$.dirty & /*$active_tool, metas*/ 4097) { 972 $$invalidate(3, sub_menu = $active_tool && metas[$active_tool]); 973 } 974 }; 975 976 return [ 977 $active_tool, 978 tools, 979 sub_tool, 980 sub_menu, 981 $current_color, 982 $current_history, 983 current_history, 984 active_tool, 985 current_color, 986 tool_context, 987 tools_meta, 988 i18n, 989 metas, 990 slots, 991 click_handler, 992 click_handler_1, 993 $$scope 994 ]; 995} 996 997class Tools extends SvelteComponent$f { 998 constructor(options) { 999 super(); 1000 init$g(this, options, instance$f, create_fragment$f, safe_not_equal$f, { i18n: 11 }); 1001 } 1002}
vendor: 34,978 bytes, lines 1002-2182
1002 1003 1004// This file is autogenerated. It's used to publish ESM to npm. 1005function _typeof(obj) { 1006 "@babel/helpers - typeof"; 1007 1008 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { 1009 return typeof obj; 1010 } : function (obj) { 1011 return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 1012 }, _typeof(obj); 1013} 1014 1015// https://github.com/bgrins/TinyColor 1016// Brian Grinstead, MIT License 1017 1018var trimLeft = /^\s+/; 1019var trimRight = /\s+$/; 1020function tinycolor(color, opts) { 1021 color = color ? color : ""; 1022 opts = opts || {}; 1023 1024 // If input is already a tinycolor, return itself 1025 if (color instanceof tinycolor) { 1026 return color; 1027 } 1028 // If we are called as a function, call using new instead 1029 if (!(this instanceof tinycolor)) { 1030 return new tinycolor(color, opts); 1031 } 1032 var rgb = inputToRGB(color); 1033 this._originalInput = color, this._r = rgb.r, this._g = rgb.g, this._b = rgb.b, this._a = rgb.a, this._roundA = Math.round(100 * this._a) / 100, this._format = opts.format || rgb.format; 1034 this._gradientType = opts.gradientType; 1035 1036 // Don't let the range of [0,255] come back in [0,1]. 1037 // Potentially lose a little bit of precision here, but will fix issues where 1038 // .5 gets interpreted as half of the total, instead of half of 1 1039 // If it was supposed to be 128, this was already taken care of by `inputToRgb` 1040 if (this._r < 1) this._r = Math.round(this._r); 1041 if (this._g < 1) this._g = Math.round(this._g); 1042 if (this._b < 1) this._b = Math.round(this._b); 1043 this._ok = rgb.ok; 1044} 1045tinycolor.prototype = { 1046 isDark: function isDark() { 1047 return this.getBrightness() < 128; 1048 }, 1049 isLight: function isLight() { 1050 return !this.isDark(); 1051 }, 1052 isValid: function isValid() { 1053 return this._ok; 1054 }, 1055 getOriginalInput: function getOriginalInput() { 1056 return this._originalInput; 1057 }, 1058 getFormat: function getFormat() { 1059 return this._format; 1060 }, 1061 getAlpha: function getAlpha() { 1062 return this._a; 1063 }, 1064 getBrightness: function getBrightness() { 1065 //http://www.w3.org/TR/AERT#color-contrast 1066 var rgb = this.toRgb(); 1067 return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; 1068 }, 1069 getLuminance: function getLuminance() { 1070 //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef 1071 var rgb = this.toRgb(); 1072 var RsRGB, GsRGB, BsRGB, R, G, B; 1073 RsRGB = rgb.r / 255; 1074 GsRGB = rgb.g / 255; 1075 BsRGB = rgb.b / 255; 1076 if (RsRGB <= 0.03928) R = RsRGB / 12.92;else R = Math.pow((RsRGB + 0.055) / 1.055, 2.4); 1077 if (GsRGB <= 0.03928) G = GsRGB / 12.92;else G = Math.pow((GsRGB + 0.055) / 1.055, 2.4); 1078 if (BsRGB <= 0.03928) B = BsRGB / 12.92;else B = Math.pow((BsRGB + 0.055) / 1.055, 2.4); 1079 return 0.2126 * R + 0.7152 * G + 0.0722 * B; 1080 }, 1081 setAlpha: function setAlpha(value) { 1082 this._a = boundAlpha(value); 1083 this._roundA = Math.round(100 * this._a) / 100; 1084 return this; 1085 }, 1086 toHsv: function toHsv() { 1087 var hsv = rgbToHsv(this._r, this._g, this._b); 1088 return { 1089 h: hsv.h * 360, 1090 s: hsv.s, 1091 v: hsv.v, 1092 a: this._a 1093 }; 1094 }, 1095 toHsvString: function toHsvString() { 1096 var hsv = rgbToHsv(this._r, this._g, this._b); 1097 var h = Math.round(hsv.h * 360), 1098 s = Math.round(hsv.s * 100), 1099 v = Math.round(hsv.v * 100); 1100 return this._a == 1 ? "hsv(" + h + ", " + s + "%, " + v + "%)" : "hsva(" + h + ", " + s + "%, " + v + "%, " + this._roundA + ")"; 1101 }, 1102 toHsl: function toHsl() { 1103 var hsl = rgbToHsl(this._r, this._g, this._b); 1104 return { 1105 h: hsl.h * 360, 1106 s: hsl.s, 1107 l: hsl.l, 1108 a: this._a 1109 }; 1110 }, 1111 toHslString: function toHslString() { 1112 var hsl = rgbToHsl(this._r, this._g, this._b); 1113 var h = Math.round(hsl.h * 360), 1114 s = Math.round(hsl.s * 100), 1115 l = Math.round(hsl.l * 100); 1116 return this._a == 1 ? "hsl(" + h + ", " + s + "%, " + l + "%)" : "hsla(" + h + ", " + s + "%, " + l + "%, " + this._roundA + ")"; 1117 }, 1118 toHex: function toHex(allow3Char) { 1119 return rgbToHex(this._r, this._g, this._b, allow3Char); 1120 }, 1121 toHexString: function toHexString(allow3Char) { 1122 return "#" + this.toHex(allow3Char); 1123 }, 1124 toHex8: function toHex8(allow4Char) { 1125 return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char); 1126 }, 1127 toHex8String: function toHex8String(allow4Char) { 1128 return "#" + this.toHex8(allow4Char); 1129 }, 1130 toRgb: function toRgb() { 1131 return { 1132 r: Math.round(this._r), 1133 g: Math.round(this._g), 1134 b: Math.round(this._b), 1135 a: this._a 1136 }; 1137 }, 1138 toRgbString: function toRgbString() { 1139 return this._a == 1 ? "rgb(" + Math.round(this._r) + ", " + Math.round(this._g) + ", " + Math.round(this._b) + ")" : "rgba(" + Math.round(this._r) + ", " + Math.round(this._g) + ", " + Math.round(this._b) + ", " + this._roundA + ")"; 1140 }, 1141 toPercentageRgb: function toPercentageRgb() { 1142 return { 1143 r: Math.round(bound01(this._r, 255) * 100) + "%", 1144 g: Math.round(bound01(this._g, 255) * 100) + "%", 1145 b: Math.round(bound01(this._b, 255) * 100) + "%", 1146 a: this._a 1147 }; 1148 }, 1149 toPercentageRgbString: function toPercentageRgbString() { 1150 return this._a == 1 ? "rgb(" + Math.round(bound01(this._r, 255) * 100) + "%, " + Math.round(bound01(this._g, 255) * 100) + "%, " + Math.round(bound01(this._b, 255) * 100) + "%)" : "rgba(" + Math.round(bound01(this._r, 255) * 100) + "%, " + Math.round(bound01(this._g, 255) * 100) + "%, " + Math.round(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"; 1151 }, 1152 toName: function toName() { 1153 if (this._a === 0) { 1154 return "transparent"; 1155 } 1156 if (this._a < 1) { 1157 return false; 1158 } 1159 return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false; 1160 }, 1161 toFilter: function toFilter(secondColor) { 1162 var hex8String = "#" + rgbaToArgbHex(this._r, this._g, this._b, this._a); 1163 var secondHex8String = hex8String; 1164 var gradientType = this._gradientType ? "GradientType = 1, " : ""; 1165 if (secondColor) { 1166 var s = tinycolor(secondColor); 1167 secondHex8String = "#" + rgbaToArgbHex(s._r, s._g, s._b, s._a); 1168 } 1169 return "progid:DXImageTransform.Microsoft.gradient(" + gradientType + "startColorstr=" + hex8String + ",endColorstr=" + secondHex8String + ")"; 1170 }, 1171 toString: function toString(format) { 1172 var formatSet = !!format; 1173 format = format || this._format; 1174 var formattedString = false; 1175 var hasAlpha = this._a < 1 && this._a >= 0; 1176 var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name"); 1177 if (needsAlphaFormat) { 1178 // Special case for "transparent", all other non-alpha formats 1179 // will return rgba when there is transparency. 1180 if (format === "name" && this._a === 0) { 1181 return this.toName(); 1182 } 1183 return this.toRgbString(); 1184 } 1185 if (format === "rgb") { 1186 formattedString = this.toRgbString(); 1187 } 1188 if (format === "prgb") { 1189 formattedString = this.toPercentageRgbString(); 1190 } 1191 if (format === "hex" || format === "hex6") { 1192 formattedString = this.toHexString(); 1193 } 1194 if (format === "hex3") { 1195 formattedString = this.toHexString(true); 1196 } 1197 if (format === "hex4") { 1198 formattedString = this.toHex8String(true); 1199 } 1200 if (format === "hex8") { 1201 formattedString = this.toHex8String(); 1202 } 1203 if (format === "name") { 1204 formattedString = this.toName(); 1205 } 1206 if (format === "hsl") { 1207 formattedString = this.toHslString(); 1208 } 1209 if (format === "hsv") { 1210 formattedString = this.toHsvString(); 1211 } 1212 return formattedString || this.toHexString(); 1213 }, 1214 clone: function clone() { 1215 return tinycolor(this.toString()); 1216 }, 1217 _applyModification: function _applyModification(fn, args) { 1218 var color = fn.apply(null, [this].concat([].slice.call(args))); 1219 this._r = color._r; 1220 this._g = color._g; 1221 this._b = color._b; 1222 this.setAlpha(color._a); 1223 return this; 1224 }, 1225 lighten: function lighten() { 1226 return this._applyModification(_lighten, arguments); 1227 }, 1228 brighten: function brighten() { 1229 return this._applyModification(_brighten, arguments); 1230 }, 1231 darken: function darken() { 1232 return this._applyModification(_darken, arguments); 1233 }, 1234 desaturate: function desaturate() { 1235 return this._applyModification(_desaturate, arguments); 1236 }, 1237 saturate: function saturate() { 1238 return this._applyModification(_saturate, arguments); 1239 }, 1240 greyscale: function greyscale() { 1241 return this._applyModification(_greyscale, arguments); 1242 }, 1243 spin: function spin() { 1244 return this._applyModification(_spin, arguments); 1245 }, 1246 _applyCombination: function _applyCombination(fn, args) { 1247 return fn.apply(null, [this].concat([].slice.call(args))); 1248 }, 1249 analogous: function analogous() { 1250 return this._applyCombination(_analogous, arguments); 1251 }, 1252 complement: function complement() { 1253 return this._applyCombination(_complement, arguments); 1254 }, 1255 monochromatic: function monochromatic() { 1256 return this._applyCombination(_monochromatic, arguments); 1257 }, 1258 splitcomplement: function splitcomplement() { 1259 return this._applyCombination(_splitcomplement, arguments); 1260 }, 1261 // Disabled until https://github.com/bgrins/TinyColor/issues/254 1262 // polyad: function (number) { 1263 // return this._applyCombination(polyad, [number]); 1264 // }, 1265 triad: function triad() { 1266 return this._applyCombination(polyad, [3]); 1267 }, 1268 tetrad: function tetrad() { 1269 return this._applyCombination(polyad, [4]); 1270 } 1271}; 1272 1273// If input is an object, force 1 into "1.0" to handle ratios properly 1274// String input requires "1.0" as input, so 1 will be treated as 1 1275tinycolor.fromRatio = function (color, opts) { 1276 if (_typeof(color) == "object") { 1277 var newColor = {}; 1278 for (var i in color) { 1279 if (color.hasOwnProperty(i)) { 1280 if (i === "a") { 1281 newColor[i] = color[i]; 1282 } else { 1283 newColor[i] = convertToPercentage(color[i]); 1284 } 1285 } 1286 } 1287 color = newColor; 1288 } 1289 return tinycolor(color, opts); 1290}; 1291 1292// Given a string or object, convert that input to RGB 1293// Possible string inputs: 1294// 1295// "red" 1296// "#f00" or "f00" 1297// "#ff0000" or "ff0000" 1298// "#ff000000" or "ff000000" 1299// "rgb 255 0 0" or "rgb (255, 0, 0)" 1300// "rgb 1.0 0 0" or "rgb (1, 0, 0)" 1301// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" 1302// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" 1303// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" 1304// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" 1305// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" 1306// 1307function inputToRGB(color) { 1308 var rgb = { 1309 r: 0, 1310 g: 0, 1311 b: 0 1312 }; 1313 var a = 1; 1314 var s = null; 1315 var v = null; 1316 var l = null; 1317 var ok = false; 1318 var format = false; 1319 if (typeof color == "string") { 1320 color = stringInputToObject(color); 1321 } 1322 if (_typeof(color) == "object") { 1323 if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) { 1324 rgb = rgbToRgb(color.r, color.g, color.b); 1325 ok = true; 1326 format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; 1327 } else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) { 1328 s = convertToPercentage(color.s); 1329 v = convertToPercentage(color.v); 1330 rgb = hsvToRgb(color.h, s, v); 1331 ok = true; 1332 format = "hsv"; 1333 } else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) { 1334 s = convertToPercentage(color.s); 1335 l = convertToPercentage(color.l); 1336 rgb = hslToRgb(color.h, s, l); 1337 ok = true; 1338 format = "hsl"; 1339 } 1340 if (color.hasOwnProperty("a")) { 1341 a = color.a; 1342 } 1343 } 1344 a = boundAlpha(a); 1345 return { 1346 ok: ok, 1347 format: color.format || format, 1348 r: Math.min(255, Math.max(rgb.r, 0)), 1349 g: Math.min(255, Math.max(rgb.g, 0)), 1350 b: Math.min(255, Math.max(rgb.b, 0)), 1351 a: a 1352 }; 1353} 1354 1355// Conversion Functions 1356// -------------------- 1357 1358// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from: 1359// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript> 1360 1361// `rgbToRgb` 1362// Handle bounds / percentage checking to conform to CSS color spec 1363// <http://www.w3.org/TR/css3-color/> 1364// *Assumes:* r, g, b in [0, 255] or [0, 1] 1365// *Returns:* { r, g, b } in [0, 255] 1366function rgbToRgb(r, g, b) { 1367 return { 1368 r: bound01(r, 255) * 255, 1369 g: bound01(g, 255) * 255, 1370 b: bound01(b, 255) * 255 1371 }; 1372} 1373 1374// `rgbToHsl` 1375// Converts an RGB color value to HSL. 1376// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] 1377// *Returns:* { h, s, l } in [0,1] 1378function rgbToHsl(r, g, b) { 1379 r = bound01(r, 255); 1380 g = bound01(g, 255); 1381 b = bound01(b, 255); 1382 var max = Math.max(r, g, b), 1383 min = Math.min(r, g, b); 1384 var h, 1385 s, 1386 l = (max + min) / 2; 1387 if (max == min) { 1388 h = s = 0; // achromatic 1389 } else { 1390 var d = max - min; 1391 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 1392 switch (max) { 1393 case r: 1394 h = (g - b) / d + (g < b ? 6 : 0); 1395 break; 1396 case g: 1397 h = (b - r) / d + 2; 1398 break; 1399 case b: 1400 h = (r - g) / d + 4; 1401 break; 1402 } 1403 h /= 6; 1404 } 1405 return { 1406 h: h, 1407 s: s, 1408 l: l 1409 }; 1410} 1411 1412// `hslToRgb` 1413// Converts an HSL color value to RGB. 1414// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] 1415// *Returns:* { r, g, b } in the set [0, 255] 1416function hslToRgb(h, s, l) { 1417 var r, g, b; 1418 h = bound01(h, 360); 1419 s = bound01(s, 100); 1420 l = bound01(l, 100); 1421 function hue2rgb(p, q, t) { 1422 if (t < 0) t += 1; 1423 if (t > 1) t -= 1; 1424 if (t < 1 / 6) return p + (q - p) * 6 * t; 1425 if (t < 1 / 2) return q; 1426 if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; 1427 return p; 1428 } 1429 if (s === 0) { 1430 r = g = b = l; // achromatic 1431 } else { 1432 var q = l < 0.5 ? l * (1 + s) : l + s - l * s; 1433 var p = 2 * l - q; 1434 r = hue2rgb(p, q, h + 1 / 3); 1435 g = hue2rgb(p, q, h); 1436 b = hue2rgb(p, q, h - 1 / 3); 1437 } 1438 return { 1439 r: r * 255, 1440 g: g * 255, 1441 b: b * 255 1442 }; 1443} 1444 1445// `rgbToHsv` 1446// Converts an RGB color value to HSV 1447// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] 1448// *Returns:* { h, s, v } in [0,1] 1449function rgbToHsv(r, g, b) { 1450 r = bound01(r, 255); 1451 g = bound01(g, 255); 1452 b = bound01(b, 255); 1453 var max = Math.max(r, g, b), 1454 min = Math.min(r, g, b); 1455 var h, 1456 s, 1457 v = max; 1458 var d = max - min; 1459 s = max === 0 ? 0 : d / max; 1460 if (max == min) { 1461 h = 0; // achromatic 1462 } else { 1463 switch (max) { 1464 case r: 1465 h = (g - b) / d + (g < b ? 6 : 0); 1466 break; 1467 case g: 1468 h = (b - r) / d + 2; 1469 break; 1470 case b: 1471 h = (r - g) / d + 4; 1472 break; 1473 } 1474 h /= 6; 1475 } 1476 return { 1477 h: h, 1478 s: s, 1479 v: v 1480 }; 1481} 1482 1483// `hsvToRgb` 1484// Converts an HSV color value to RGB. 1485// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] 1486// *Returns:* { r, g, b } in the set [0, 255] 1487function hsvToRgb(h, s, v) { 1488 h = bound01(h, 360) * 6; 1489 s = bound01(s, 100); 1490 v = bound01(v, 100); 1491 var i = Math.floor(h), 1492 f = h - i, 1493 p = v * (1 - s), 1494 q = v * (1 - f * s), 1495 t = v * (1 - (1 - f) * s), 1496 mod = i % 6, 1497 r = [v, q, p, p, t, v][mod], 1498 g = [t, v, v, q, p, p][mod], 1499 b = [p, p, t, v, v, q][mod]; 1500 return { 1501 r: r * 255, 1502 g: g * 255, 1503 b: b * 255 1504 }; 1505} 1506 1507// `rgbToHex` 1508// Converts an RGB color to hex 1509// Assumes r, g, and b are contained in the set [0, 255] 1510// Returns a 3 or 6 character hex 1511function rgbToHex(r, g, b, allow3Char) { 1512 var hex = [pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16))]; 1513 1514 // Return a 3 character hex if possible 1515 if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { 1516 return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); 1517 } 1518 return hex.join(""); 1519} 1520 1521// `rgbaToHex` 1522// Converts an RGBA color plus alpha transparency to hex 1523// Assumes r, g, b are contained in the set [0, 255] and 1524// a in [0, 1]. Returns a 4 or 8 character rgba hex 1525function rgbaToHex(r, g, b, a, allow4Char) { 1526 var hex = [pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16)), pad2(convertDecimalToHex(a))]; 1527 1528 // Return a 4 character hex if possible 1529 if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) { 1530 return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0); 1531 } 1532 return hex.join(""); 1533} 1534 1535// `rgbaToArgbHex` 1536// Converts an RGBA color to an ARGB Hex8 string 1537// Rarely used, but required for "toFilter()" 1538function rgbaToArgbHex(r, g, b, a) { 1539 var hex = [pad2(convertDecimalToHex(a)), pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16))]; 1540 return hex.join(""); 1541} 1542 1543// `equals` 1544// Can be called with any tinycolor input 1545tinycolor.equals = function (color1, color2) { 1546 if (!color1 || !color2) return false; 1547 return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); 1548}; 1549tinycolor.random = function () { 1550 return tinycolor.fromRatio({ 1551 r: Math.random(), 1552 g: Math.random(), 1553 b: Math.random() 1554 }); 1555}; 1556 1557// Modification Functions 1558// ---------------------- 1559// Thanks to less.js for some of the basics here 1560// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js> 1561 1562function _desaturate(color, amount) { 1563 amount = amount === 0 ? 0 : amount || 10; 1564 var hsl = tinycolor(color).toHsl(); 1565 hsl.s -= amount / 100; 1566 hsl.s = clamp01(hsl.s); 1567 return tinycolor(hsl); 1568} 1569function _saturate(color, amount) { 1570 amount = amount === 0 ? 0 : amount || 10; 1571 var hsl = tinycolor(color).toHsl(); 1572 hsl.s += amount / 100; 1573 hsl.s = clamp01(hsl.s); 1574 return tinycolor(hsl); 1575} 1576function _greyscale(color) { 1577 return tinycolor(color).desaturate(100); 1578} 1579function _lighten(color, amount) { 1580 amount = amount === 0 ? 0 : amount || 10; 1581 var hsl = tinycolor(color).toHsl(); 1582 hsl.l += amount / 100; 1583 hsl.l = clamp01(hsl.l); 1584 return tinycolor(hsl); 1585} 1586function _brighten(color, amount) { 1587 amount = amount === 0 ? 0 : amount || 10; 1588 var rgb = tinycolor(color).toRgb(); 1589 rgb.r = Math.max(0, Math.min(255, rgb.r - Math.round(255 * -(amount / 100)))); 1590 rgb.g = Math.max(0, Math.min(255, rgb.g - Math.round(255 * -(amount / 100)))); 1591 rgb.b = Math.max(0, Math.min(255, rgb.b - Math.round(255 * -(amount / 100)))); 1592 return tinycolor(rgb); 1593} 1594function _darken(color, amount) { 1595 amount = amount === 0 ? 0 : amount || 10; 1596 var hsl = tinycolor(color).toHsl(); 1597 hsl.l -= amount / 100; 1598 hsl.l = clamp01(hsl.l); 1599 return tinycolor(hsl); 1600} 1601 1602// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue. 1603// Values outside of this range will be wrapped into this range. 1604function _spin(color, amount) { 1605 var hsl = tinycolor(color).toHsl(); 1606 var hue = (hsl.h + amount) % 360; 1607 hsl.h = hue < 0 ? 360 + hue : hue; 1608 return tinycolor(hsl); 1609} 1610 1611// Combination Functions 1612// --------------------- 1613// Thanks to jQuery xColor for some of the ideas behind these 1614// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js> 1615 1616function _complement(color) { 1617 var hsl = tinycolor(color).toHsl(); 1618 hsl.h = (hsl.h + 180) % 360; 1619 return tinycolor(hsl); 1620} 1621function polyad(color, number) { 1622 if (isNaN(number) || number <= 0) { 1623 throw new Error("Argument to polyad must be a positive number"); 1624 } 1625 var hsl = tinycolor(color).toHsl(); 1626 var result = [tinycolor(color)]; 1627 var step = 360 / number; 1628 for (var i = 1; i < number; i++) { 1629 result.push(tinycolor({ 1630 h: (hsl.h + i * step) % 360, 1631 s: hsl.s, 1632 l: hsl.l 1633 })); 1634 } 1635 return result; 1636} 1637function _splitcomplement(color) { 1638 var hsl = tinycolor(color).toHsl(); 1639 var h = hsl.h; 1640 return [tinycolor(color), tinycolor({ 1641 h: (h + 72) % 360, 1642 s: hsl.s, 1643 l: hsl.l 1644 }), tinycolor({ 1645 h: (h + 216) % 360, 1646 s: hsl.s, 1647 l: hsl.l 1648 })]; 1649} 1650function _analogous(color, results, slices) { 1651 results = results || 6; 1652 slices = slices || 30; 1653 var hsl = tinycolor(color).toHsl(); 1654 var part = 360 / slices; 1655 var ret = [tinycolor(color)]; 1656 for (hsl.h = (hsl.h - (part * results >> 1) + 720) % 360; --results;) { 1657 hsl.h = (hsl.h + part) % 360; 1658 ret.push(tinycolor(hsl)); 1659 } 1660 return ret; 1661} 1662function _monochromatic(color, results) { 1663 results = results || 6; 1664 var hsv = tinycolor(color).toHsv(); 1665 var h = hsv.h, 1666 s = hsv.s, 1667 v = hsv.v; 1668 var ret = []; 1669 var modification = 1 / results; 1670 while (results--) { 1671 ret.push(tinycolor({ 1672 h: h, 1673 s: s, 1674 v: v 1675 })); 1676 v = (v + modification) % 1; 1677 } 1678 return ret; 1679} 1680 1681// Utility Functions 1682// --------------------- 1683 1684tinycolor.mix = function (color1, color2, amount) { 1685 amount = amount === 0 ? 0 : amount || 50; 1686 var rgb1 = tinycolor(color1).toRgb(); 1687 var rgb2 = tinycolor(color2).toRgb(); 1688 var p = amount / 100; 1689 var rgba = { 1690 r: (rgb2.r - rgb1.r) * p + rgb1.r, 1691 g: (rgb2.g - rgb1.g) * p + rgb1.g, 1692 b: (rgb2.b - rgb1.b) * p + rgb1.b, 1693 a: (rgb2.a - rgb1.a) * p + rgb1.a 1694 }; 1695 return tinycolor(rgba); 1696}; 1697 1698// Readability Functions 1699// --------------------- 1700// <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2) 1701 1702// `contrast` 1703// Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2) 1704tinycolor.readability = function (color1, color2) { 1705 var c1 = tinycolor(color1); 1706 var c2 = tinycolor(color2); 1707 return (Math.max(c1.getLuminance(), c2.getLuminance()) + 0.05) / (Math.min(c1.getLuminance(), c2.getLuminance()) + 0.05); 1708}; 1709 1710// `isReadable` 1711// Ensure that foreground and background color combinations meet WCAG2 guidelines. 1712// The third argument is an optional Object. 1713// the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA'; 1714// the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'. 1715// If the entire object is absent, isReadable defaults to {level:"AA",size:"small"}. 1716 1717// *Example* 1718// tinycolor.isReadable("#000", "#111") => false 1719// tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false 1720tinycolor.isReadable = function (color1, color2, wcag2) { 1721 var readability = tinycolor.readability(color1, color2); 1722 var wcag2Parms, out; 1723 out = false; 1724 wcag2Parms = validateWCAG2Parms(wcag2); 1725 switch (wcag2Parms.level + wcag2Parms.size) { 1726 case "AAsmall": 1727 case "AAAlarge": 1728 out = readability >= 4.5; 1729 break; 1730 case "AAlarge": 1731 out = readability >= 3; 1732 break; 1733 case "AAAsmall": 1734 out = readability >= 7; 1735 break; 1736 } 1737 return out; 1738}; 1739 1740// `mostReadable` 1741// Given a base color and a list of possible foreground or background 1742// colors for that base, returns the most readable color. 1743// Optionally returns Black or White if the most readable color is unreadable. 1744// *Example* 1745// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255" 1746// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff" 1747// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3" 1748// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff" 1749tinycolor.mostReadable = function (baseColor, colorList, args) { 1750 var bestColor = null; 1751 var bestScore = 0; 1752 var readability; 1753 var includeFallbackColors, level, size; 1754 args = args || {}; 1755 includeFallbackColors = args.includeFallbackColors; 1756 level = args.level; 1757 size = args.size; 1758 for (var i = 0; i < colorList.length; i++) { 1759 readability = tinycolor.readability(baseColor, colorList[i]); 1760 if (readability > bestScore) { 1761 bestScore = readability; 1762 bestColor = tinycolor(colorList[i]); 1763 } 1764 } 1765 if (tinycolor.isReadable(baseColor, bestColor, { 1766 level: level, 1767 size: size 1768 }) || !includeFallbackColors) { 1769 return bestColor; 1770 } else { 1771 args.includeFallbackColors = false; 1772 return tinycolor.mostReadable(baseColor, ["#fff", "#000"], args); 1773 } 1774}; 1775 1776// Big List of Colors 1777// ------------------ 1778// <https://www.w3.org/TR/css-color-4/#named-colors> 1779var names = tinycolor.names = { 1780 aliceblue: "f0f8ff", 1781 antiquewhite: "faebd7", 1782 aqua: "0ff", 1783 aquamarine: "7fffd4", 1784 azure: "f0ffff", 1785 beige: "f5f5dc", 1786 bisque: "ffe4c4", 1787 black: "000", 1788 blanchedalmond: "ffebcd", 1789 blue: "00f", 1790 blueviolet: "8a2be2", 1791 brown: "a52a2a", 1792 burlywood: "deb887", 1793 burntsienna: "ea7e5d", 1794 cadetblue: "5f9ea0", 1795 chartreuse: "7fff00", 1796 chocolate: "d2691e", 1797 coral: "ff7f50", 1798 cornflowerblue: "6495ed", 1799 cornsilk: "fff8dc", 1800 crimson: "dc143c", 1801 cyan: "0ff", 1802 darkblue: "00008b", 1803 darkcyan: "008b8b", 1804 darkgoldenrod: "b8860b", 1805 darkgray: "a9a9a9", 1806 darkgreen: "006400", 1807 darkgrey: "a9a9a9", 1808 darkkhaki: "bdb76b", 1809 darkmagenta: "8b008b", 1810 darkolivegreen: "556b2f", 1811 darkorange: "ff8c00", 1812 darkorchid: "9932cc", 1813 darkred: "8b0000", 1814 darksalmon: "e9967a", 1815 darkseagreen: "8fbc8f", 1816 darkslateblue: "483d8b", 1817 darkslategray: "2f4f4f", 1818 darkslategrey: "2f4f4f", 1819 darkturquoise: "00ced1", 1820 darkviolet: "9400d3", 1821 deeppink: "ff1493", 1822 deepskyblue: "00bfff", 1823 dimgray: "696969", 1824 dimgrey: "696969", 1825 dodgerblue: "1e90ff", 1826 firebrick: "b22222", 1827 floralwhite: "fffaf0", 1828 forestgreen: "228b22", 1829 fuchsia: "f0f", 1830 gainsboro: "dcdcdc", 1831 ghostwhite: "f8f8ff", 1832 gold: "ffd700", 1833 goldenrod: "daa520", 1834 gray: "808080", 1835 green: "008000", 1836 greenyellow: "adff2f", 1837 grey: "808080", 1838 honeydew: "f0fff0", 1839 hotpink: "ff69b4", 1840 indianred: "cd5c5c", 1841 indigo: "4b0082", 1842 ivory: "fffff0", 1843 khaki: "f0e68c", 1844 lavender: "e6e6fa", 1845 lavenderblush: "fff0f5", 1846 lawngreen: "7cfc00", 1847 lemonchiffon: "fffacd", 1848 lightblue: "add8e6", 1849 lightcoral: "f08080", 1850 lightcyan: "e0ffff", 1851 lightgoldenrodyellow: "fafad2", 1852 lightgray: "d3d3d3", 1853 lightgreen: "90ee90", 1854 lightgrey: "d3d3d3", 1855 lightpink: "ffb6c1", 1856 lightsalmon: "ffa07a", 1857 lightseagreen: "20b2aa", 1858 lightskyblue: "87cefa", 1859 lightslategray: "789", 1860 lightslategrey: "789", 1861 lightsteelblue: "b0c4de", 1862 lightyellow: "ffffe0", 1863 lime: "0f0", 1864 limegreen: "32cd32", 1865 linen: "faf0e6", 1866 magenta: "f0f", 1867 maroon: "800000", 1868 mediumaquamarine: "66cdaa", 1869 mediumblue: "0000cd", 1870 mediumorchid: "ba55d3", 1871 mediumpurple: "9370db", 1872 mediumseagreen: "3cb371", 1873 mediumslateblue: "7b68ee", 1874 mediumspringgreen: "00fa9a", 1875 mediumturquoise: "48d1cc", 1876 mediumvioletred: "c71585", 1877 midnightblue: "191970", 1878 mintcream: "f5fffa", 1879 mistyrose: "ffe4e1", 1880 moccasin: "ffe4b5", 1881 navajowhite: "ffdead", 1882 navy: "000080", 1883 oldlace: "fdf5e6", 1884 olive: "808000", 1885 olivedrab: "6b8e23", 1886 orange: "ffa500", 1887 orangered: "ff4500", 1888 orchid: "da70d6", 1889 palegoldenrod: "eee8aa", 1890 palegreen: "98fb98", 1891 paleturquoise: "afeeee", 1892 palevioletred: "db7093", 1893 papayawhip: "ffefd5", 1894 peachpuff: "ffdab9", 1895 peru: "cd853f", 1896 pink: "ffc0cb", 1897 plum: "dda0dd", 1898 powderblue: "b0e0e6", 1899 purple: "800080", 1900 rebeccapurple: "663399", 1901 red: "f00", 1902 rosybrown: "bc8f8f", 1903 royalblue: "4169e1", 1904 saddlebrown: "8b4513", 1905 salmon: "fa8072", 1906 sandybrown: "f4a460", 1907 seagreen: "2e8b57", 1908 seashell: "fff5ee", 1909 sienna: "a0522d", 1910 silver: "c0c0c0", 1911 skyblue: "87ceeb", 1912 slateblue: "6a5acd", 1913 slategray: "708090", 1914 slategrey: "708090", 1915 snow: "fffafa", 1916 springgreen: "00ff7f", 1917 steelblue: "4682b4", 1918 tan: "d2b48c", 1919 teal: "008080", 1920 thistle: "d8bfd8", 1921 tomato: "ff6347", 1922 turquoise: "40e0d0", 1923 violet: "ee82ee", 1924 wheat: "f5deb3", 1925 white: "fff", 1926 whitesmoke: "f5f5f5", 1927 yellow: "ff0", 1928 yellowgreen: "9acd32" 1929}; 1930 1931// Make it easy to access colors via `hexNames[hex]` 1932var hexNames = tinycolor.hexNames = flip(names); 1933 1934// Utilities 1935// --------- 1936 1937// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }` 1938function flip(o) { 1939 var flipped = {}; 1940 for (var i in o) { 1941 if (o.hasOwnProperty(i)) { 1942 flipped[o[i]] = i; 1943 } 1944 } 1945 return flipped; 1946} 1947 1948// Return a valid alpha value [0,1] with all invalid values being set to 1 1949function boundAlpha(a) { 1950 a = parseFloat(a); 1951 if (isNaN(a) || a < 0 || a > 1) { 1952 a = 1; 1953 } 1954 return a; 1955} 1956 1957// Take input from [0, n] and return it as [0, 1] 1958function bound01(n, max) { 1959 if (isOnePointZero(n)) n = "100%"; 1960 var processPercent = isPercentage(n); 1961 n = Math.min(max, Math.max(0, parseFloat(n))); 1962 1963 // Automatically convert percentage into number 1964 if (processPercent) { 1965 n = parseInt(n * max, 10) / 100; 1966 } 1967 1968 // Handle floating point rounding errors 1969 if (Math.abs(n - max) < 0.000001) { 1970 return 1; 1971 } 1972 1973 // Convert into [0, 1] range if it isn't already 1974 return n % max / parseFloat(max); 1975} 1976 1977// Force a number between 0 and 1 1978function clamp01(val) { 1979 return Math.min(1, Math.max(0, val)); 1980} 1981 1982// Parse a base-16 hex value into a base-10 integer 1983function parseIntFromHex(val) { 1984 return parseInt(val, 16); 1985} 1986 1987// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 1988// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0> 1989function isOnePointZero(n) { 1990 return typeof n == "string" && n.indexOf(".") != -1 && parseFloat(n) === 1; 1991} 1992 1993// Check to see if string passed in is a percentage 1994function isPercentage(n) { 1995 return typeof n === "string" && n.indexOf("%") != -1; 1996} 1997 1998// Force a hex value to have 2 characters 1999function pad2(c) { 2000 return c.length == 1 ? "0" + c : "" + c; 2001} 2002 2003// Replace a decimal with it's percentage value 2004function convertToPercentage(n) { 2005 if (n <= 1) { 2006 n = n * 100 + "%"; 2007 } 2008 return n; 2009} 2010 2011// Converts a decimal to a hex value 2012function convertDecimalToHex(d) { 2013 return Math.round(parseFloat(d) * 255).toString(16); 2014} 2015// Converts a hex value to a decimal 2016function convertHexToDecimal(h) { 2017 return parseIntFromHex(h) / 255; 2018} 2019var matchers = function () { 2020 // <http://www.w3.org/TR/css3-values/#integers> 2021 var CSS_INTEGER = "[-\\+]?\\d+%?"; 2022 2023 // <http://www.w3.org/TR/css3-values/#number-value> 2024 var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; 2025 2026 // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. 2027 var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; 2028 2029 // Actual matching. 2030 // Parentheses and commas are optional, but not required. 2031 // Whitespace can take the place of commas or opening paren 2032 var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; 2033 var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; 2034 return { 2035 CSS_UNIT: new RegExp(CSS_UNIT), 2036 rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), 2037 rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), 2038 hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), 2039 hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), 2040 hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), 2041 hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), 2042 hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, 2043 hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, 2044 hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, 2045 hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ 2046 }; 2047}(); 2048 2049// `isValidCSSUnit` 2050// Take in a single string / number and check to see if it looks like a CSS unit 2051// (see `matchers` above for definition). 2052function isValidCSSUnit(color) { 2053 return !!matchers.CSS_UNIT.exec(color); 2054} 2055 2056// `stringInputToObject` 2057// Permissive string parsing. Take in a number of formats, and output an object 2058// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}` 2059function stringInputToObject(color) { 2060 color = color.replace(trimLeft, "").replace(trimRight, "").toLowerCase(); 2061 var named = false; 2062 if (names[color]) { 2063 color = names[color]; 2064 named = true; 2065 } else if (color == "transparent") { 2066 return { 2067 r: 0, 2068 g: 0, 2069 b: 0, 2070 a: 0, 2071 format: "name" 2072 }; 2073 } 2074 2075 // Try to match string input using regular expressions. 2076 // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] 2077 // Just return an object and let the conversion functions handle that. 2078 // This way the result will be the same whether the tinycolor is initialized with string or object. 2079 var match; 2080 if (match = matchers.rgb.exec(color)) { 2081 return { 2082 r: match[1], 2083 g: match[2], 2084 b: match[3] 2085 }; 2086 } 2087 if (match = matchers.rgba.exec(color)) { 2088 return { 2089 r: match[1], 2090 g: match[2], 2091 b: match[3], 2092 a: match[4] 2093 }; 2094 } 2095 if (match = matchers.hsl.exec(color)) { 2096 return { 2097 h: match[1], 2098 s: match[2], 2099 l: match[3] 2100 }; 2101 } 2102 if (match = matchers.hsla.exec(color)) { 2103 return { 2104 h: match[1], 2105 s: match[2], 2106 l: match[3], 2107 a: match[4] 2108 }; 2109 } 2110 if (match = matchers.hsv.exec(color)) { 2111 return { 2112 h: match[1], 2113 s: match[2], 2114 v: match[3] 2115 }; 2116 } 2117 if (match = matchers.hsva.exec(color)) { 2118 return { 2119 h: match[1], 2120 s: match[2], 2121 v: match[3], 2122 a: match[4] 2123 }; 2124 } 2125 if (match = matchers.hex8.exec(color)) { 2126 return { 2127 r: parseIntFromHex(match[1]), 2128 g: parseIntFromHex(match[2]), 2129 b: parseIntFromHex(match[3]), 2130 a: convertHexToDecimal(match[4]), 2131 format: named ? "name" : "hex8" 2132 }; 2133 } 2134 if (match = matchers.hex6.exec(color)) { 2135 return { 2136 r: parseIntFromHex(match[1]), 2137 g: parseIntFromHex(match[2]), 2138 b: parseIntFromHex(match[3]), 2139 format: named ? "name" : "hex" 2140 }; 2141 } 2142 if (match = matchers.hex4.exec(color)) { 2143 return { 2144 r: parseIntFromHex(match[1] + "" + match[1]), 2145 g: parseIntFromHex(match[2] + "" + match[2]), 2146 b: parseIntFromHex(match[3] + "" + match[3]), 2147 a: convertHexToDecimal(match[4] + "" + match[4]), 2148 format: named ? "name" : "hex8" 2149 }; 2150 } 2151 if (match = matchers.hex3.exec(color)) { 2152 return { 2153 r: parseIntFromHex(match[1] + "" + match[1]), 2154 g: parseIntFromHex(match[2] + "" + match[2]), 2155 b: parseIntFromHex(match[3] + "" + match[3]), 2156 format: named ? "name" : "hex" 2157 }; 2158 } 2159 return false; 2160} 2161function validateWCAG2Parms(parms) { 2162 // return valid WCAG2 parms for isReadable. 2163 // If input parms are invalid, return {"level":"AA", "size":"small"} 2164 var level, size; 2165 parms = parms || { 2166 level: "AA", 2167 size: "small" 2168 }; 2169 level = (parms.level || "AA").toUpperCase(); 2170 size = (parms.size || "small").toLowerCase(); 2171 if (level !== "AA" && level !== "AAA") { 2172 level = "AA"; 2173 } 2174 if (size !== "small" && size !== "large") { 2175 size = "small"; 2176 } 2177 return { 2178 level: level, 2179 size: size 2180 }; 2181} 2182
2183var ENV = /* @__PURE__ */ ((ENV2) => (ENV2[ENV2.WEBGL_LEGACY = 0] = "WEBGL_LEGACY", ENV2[ENV2.WEBGL = 1] = "WEBGL", ENV2[ENV2.WEBGL2 = 2] = "WEBGL2", ENV2))(ENV || {}), RENDERER_TYPE = /* @__PURE__ */ ((RENDERER_TYPE2) => (RENDERER_TYPE2[RENDERER_TYPE2.UNKNOWN = 0] = "UNKNOWN", RENDERER_TYPE2[RENDERER_TYPE2.WEBGL = 1] = "WEBGL", RENDERER_TYPE2[RENDERER_TYPE2.CANVAS = 2] = "CANVAS", RENDERER_TYPE2))(RENDERER_TYPE || {}), BUFFER_BITS = /* @__PURE__ */ ((BUFFER_BITS2) => (BUFFER_BITS2[BUFFER_BITS2.COLOR = 16384] = "COLOR", BUFFER_BITS2[BUFFER_BITS2.DEPTH = 256] = "DEPTH", BUFFER_BITS2[BUFFER_BITS2.STENCIL = 1024] = "STENCIL", BUFFER_BITS2))(BUFFER_BITS || {}), BLEND_MODES = /* @__PURE__ */ ((BLEND_MODES2) => (BLEND_MODES2[BLEND_MODES2.NORMAL = 0] = "NORMAL", BLEND_MODES2[BLEND_MODES2.ADD = 1] = "ADD", BLEND_MODES2[BLEND_MODES2.MULTIPLY = 2] = "MULTIPLY", BLEND_MODES2[BLEND_MODES2.SCREEN = 3] = "SCREEN", BLEND_MODES2[BLEND_MODES2.OVERLAY = 4] = "OVERLAY", BLEND_MODES2[BLEND_MODES2.DARKEN = 5] = "DARKEN", BLEND_MODES2[BLEND_MODES2.LIGHTEN = 6] = "LIGHTEN", BLEND_MODES2[BLEND_MODES2.COLOR_DODGE = 7] = "COLOR_DODGE", BLEND_MODES2[BLEND_MODES2.COLOR_BURN = 8] = "COLOR_BURN", BLEND_MODES2[BLEND_MODES2.HARD_LIGHT = 9] = "HARD_LIGHT", BLEND_MODES2[BLEND_MODES2.SOFT_LIGHT = 10] = "SOFT_LIGHT", BLEND_MODES2[BLEND_MODES2.DIFFERENCE = 11] = "DIFFERENCE", BLEND_MODES2[BLEND_MODES2.EXCLUSION = 12] = "EXCLUSION", BLEND_MODES2[BLEND_MODES2.HUE = 13] = "HUE", BLEND_MODES2[BLEND_MODES2.SATURATION = 14] = "SATURATION", BLEND_MODES2[BLEND_MODES2.COLOR = 15] = "COLOR", BLEND_MODES2[BLEND_MODES2.LUMINOSITY = 16] = "LUMINOSITY", BLEND_MODES2[BLEND_MODES2.NORMAL_NPM = 17] = "NORMAL_NPM", BLEND_MODES2[BLEND_MODES2.ADD_NPM = 18] = "ADD_NPM", BLEND_MODES2[BLEND_MODES2.SCREEN_NPM = 19] = "SCREEN_NPM", BLEND_MODES2[BLEND_MODES2.NONE = 20] = "NONE", BLEND_MODES2[BLEND_MODES2.SRC_OVER = 0] = "SRC_OVER", BLEND_MODES2[BLEND_MODES2.SRC_IN = 21] = "SRC_IN", BLEND_MODES2[BLEND_MODES2.SRC_OUT = 22] = "SRC_OUT", BLEND_MODES2[BLEND_MODES2.SRC_ATOP = 23] = "SRC_ATOP", BLEND_MODES2[BLEND_MODES2.DST_OVER = 24] = "DST_OVER", BLEND_MODES2[BLEND_MODES2.DST_IN = 25] = "DST_IN", BLEND_MODES2[BLEND_MODES2.DST_OUT = 26] = "DST_OUT", BLEND_MODES2[BLEND_MODES2.DST_ATOP = 27] = "DST_ATOP", BLEND_MODES2[BLEND_MODES2.ERASE = 26] = "ERASE", BLEND_MODES2[BLEND_MODES2.SUBTRACT = 28] = "SUBTRACT", BLEND_MODES2[BLEND_MODES2.XOR = 29] = "XOR", BLEND_MODES2))(BLEND_MODES || {}), DRAW_MODES = /* @__PURE__ */ ((DRAW_MODES2) => (DRAW_MODES2[DRAW_MODES2.POINTS = 0] = "POINTS", DRAW_MODES2[DRAW_MODES2.LINES = 1] = "LINES", DRAW_MODES2[DRAW_MODES2.LINE_LOOP = 2] = "LINE_LOOP", DRAW_MODES2[DRAW_MODES2.LINE_STRIP = 3] = "LINE_STRIP", DRAW_MODES2[DRAW_MODES2.TRIANGLES = 4] = "TRIANGLES", DRAW_MODES2[DRAW_MODES2.TRIANGLE_STRIP = 5] = "TRIANGLE_STRIP", DRAW_MODES2[DRAW_MODES2.TRIANGLE_FAN = 6] = "TRIANGLE_FAN", DRAW_MODES2))(DRAW_MODES || {}), FORMATS = /* @__PURE__ */ ((FORMATS2) => (FORMATS2[FORMATS2.RGBA = 6408] = "RGBA", FORMATS2[FORMATS2.RGB = 6407] = "RGB", FORMATS2[FORMATS2.RG = 33319] = "RG", FORMATS2[FORMATS2.RED = 6403] = "RED", FORMATS2[FORMATS2.RGBA_INTEGER = 36249] = "RGBA_INTEGER", FORMATS2[FORMATS2.RGB_INTEGER = 36248] = "RGB_INTEGER", FORMATS2[FORMATS2.RG_INTEGER = 33320] = "RG_INTEGER", FORMATS2[FORMATS2.RED_INTEGER = 36244] = "RED_INTEGER", FORMATS2[FORMATS2.ALPHA = 6406] = "ALPHA", FORMATS2[FORMATS2.LUMINANCE = 6409] = "LUMINANCE", FORMATS2[FORMATS2.LUMINANCE_ALPHA = 6410] = "LUMINANCE_ALPHA", FORMATS2[FORMATS2.DEPTH_COMPONENT = 6402] = "DEPTH_COMPONENT", FORMATS2[FORMATS2.DEPTH_STENCIL = 34041] = "DEPTH_STENCIL", FORMATS2))(FORMATS || {}), TARGETS = /* @__PURE__ */ ((TARGETS2) => (TARGETS2[TARGETS2.TEXTURE_2D = 3553] = "TEXTURE_2D", TARGETS2[TARGETS2.TEXTURE_CUBE_MAP = 34067] = "TEXTURE_CUBE_MAP", TARGETS2[TARGETS2.TEXTURE_2D_ARRAY = 35866] = "TEXTURE_2D_ARRAY", TARGETS2[TARGETS2.TEXTURE_CUBE_MAP_POSITIVE_X = 34069] = "TEXTURE_CUBE_MAP_POSITIVE_X", TARGETS2[TARGETS2.TEXTURE_CUBE_MAP_NEGATIVE_X = 34070] = "TEXTURE_CUBE_MAP_NEGATIVE_X", TARGETS2[TARGETS2.TEXTURE_CUBE_MAP_POSITIVE_Y = 34071] = "TEXTURE_CUBE_MAP_POSITIVE_Y", TARGETS2[TARGETS2.TEXTURE_CUBE_MAP_NEGATIVE_Y = 34072] = "TEXTURE_CUBE_MAP_NEGATIVE_Y", TARGETS2[TARGETS2.TEXTURE_CUBE_MAP_POSITIVE_Z = 34073] = "TEXTURE_CUBE_MAP_POSITIVE_Z", TARGETS2[TARGETS2.TEXTURE_CUBE_MAP_NEGATIVE_Z = 34074] = "TEXTURE_CUBE_MAP_NEGATIVE_Z", TARGETS2))(TARGETS || {}), TYPES = /* @__PURE__ */ ((TYPES2) => (TYPES2[TYPES2.UNSIGNED_BYTE = 5121] = "UNSIGNED_BYTE", TYPES2[TYPES2.UNSIGNED_SHORT = 5123] = "UNSIGNED_SHORT", TYPES2[TYPES2.UNSIGNED_SHORT_5_6_5 = 33635] = "UNSIGNED_SHORT_5_6_5", TYPES2[TYPES2.UNSIGNED_SHORT_4_4_4_4 = 32819] = "UNSIGNED_SHORT_4_4_4_4", TYPES2[TYPES2.UNSIGNED_SHORT_5_5_5_1 = 32820] = "UNSIGNED_SHORT_5_5_5_1", TYPES2[TYPES2.UNSIGNED_INT = 5125] = "UNSIGNED_INT", TYPES2[TYPES2.UNSIGNED_INT_10F_11F_11F_REV = 35899] = "UNSIGNED_INT_10F_11F_11F_REV", TYPES2[TYPES2.UNSIGNED_INT_2_10_10_10_REV = 33640] = "UNSIGNED_INT_2_10_10_10_REV", TYPES2[TYPES2.UNSIGNED_INT_24_8 = 34042] = "UNSIGNED_INT_24_8", TYPES2[TYPES2.UNSIGNED_INT_5_9_9_9_REV = 35902] = "UNSIGNED_INT_5_9_9_9_REV", TYPES2[TYPES2.BYTE = 5120] = "BYTE", TYPES2[TYPES2.SHORT = 5122] = "SHORT", TYPES2[TYPES2.INT = 5124] = "INT", TYPES2[TYPES2.FLOAT = 5126] = "FLOAT", TYPES2[TYPES2.FLOAT_32_UNSIGNED_INT_24_8_REV = 36269] = "FLOAT_32_UNSIGNED_INT_24_8_REV", TYPES2[TYPES2.HALF_FLOAT = 36193] = "HALF_FLOAT", TYPES2))(TYPES || {}), SAMPLER_TYPES = /* @__PURE__ */ ((SAMPLER_TYPES2) => (SAMPLER_TYPES2[SAMPLER_TYPES2.FLOAT = 0] = "FLOAT", SAMPLER_TYPES2[SAMPLER_TYPES2.INT = 1] = "INT", SAMPLER_TYPES2[SAMPLER_TYPES2.UINT = 2] = "UINT", SAMPLER_TYPES2))(SAMPLER_TYPES || {}), SCALE_MODES = /* @__PURE__ */ ((SCALE_MODES2) => (SCALE_MODES2[SCALE_MODES2.NEAREST = 0] = "NEAREST", SCALE_MODES2[SCALE_MODES2.LINEAR = 1] = "LINEAR", SCALE_MODES2))(SCALE_MODES || {}), WRAP_MODES = /* @__PURE__ */ ((WRAP_MODES2) => (WRAP_MODES2[WRAP_MODES2.CLAMP = 33071] = "CLAMP", WRAP_MODES2[WRAP_MODES2.REPEAT = 10497] = "REPEAT", WRAP_MODES2[WRAP_MODES2.MIRRORED_REPEAT = 33648] = "MIRRORED_REPEAT", WRAP_MODES2))(WRAP_MODES || {}), MIPMAP_MODES = /* @__PURE__ */ ((MIPMAP_MODES2) => (MIPMAP_MODES2[MIPMAP_MODES2.OFF = 0] = "OFF", MIPMAP_MODES2[MIPMAP_MODES2.POW2 = 1] = "POW2", MIPMAP_MODES2[MIPMAP_MODES2.ON = 2] = "ON", MIPMAP_MODES2[MIPMAP_MODES2.ON_MANUAL = 3] = "ON_MANUAL", MIPMAP_MODES2))(MIPMAP_MODES || {}), ALPHA_MODES = /* @__PURE__ */ ((ALPHA_MODES2) => (ALPHA_MODES2[ALPHA_MODES2.NPM = 0] = "NPM", ALPHA_MODES2[ALPHA_MODES2.UNPACK = 1] = "UNPACK", ALPHA_MODES2[ALPHA_MODES2.PMA = 2] = "PMA", ALPHA_MODES2[ALPHA_MODES2.NO_PREMULTIPLIED_ALPHA = 0] = "NO_PREMULTIPLIED_ALPHA", ALPHA_MODES2[ALPHA_MODES2.PREMULTIPLY_ON_UPLOAD = 1] = "PREMULTIPLY_ON_UPLOAD", ALPHA_MODES2[ALPHA_MODES2.PREMULTIPLIED_ALPHA = 2] = "PREMULTIPLIED_ALPHA", ALPHA_MODES2))(ALPHA_MODES || {}), CLEAR_MODES = /* @__PURE__ */ ((CLEAR_MODES2) => (CLEAR_MODES2[CLEAR_MODES2.NO = 0] = "NO", CLEAR_MODES2[CLEAR_MODES2.YES = 1] = "YES", CLEAR_MODES2[CLEAR_MODES2.AUTO = 2] = "AUTO", CLEAR_MODES2[CLEAR_MODES2.BLEND = 0] = "BLEND", CLEAR_MODES2[CLEAR_MODES2.CLEAR = 1] = "CLEAR", CLEAR_MODES2[CLEAR_MODES2.BLIT = 2] = "BLIT", CLEAR_MODES2))(CLEAR_MODES || {}), GC_MODES = /* @__PURE__ */ ((GC_MODES2) => (GC_MODES2[GC_MODES2.AUTO = 0] = "AUTO", GC_MODES2[GC_MODES2.MANUAL = 1] = "MANUAL", GC_MODES2))(GC_MODES || {}), PRECISION = /* @__PURE__ */ ((PRECISION2) => (PRECISION2.LOW = "lowp", PRECISION2.MEDIUM = "mediump", PRECISION2.HIGH = "highp", PRECISION2))(PRECISION || {}), MASK_TYPES = /* @__PURE__ */ ((MASK_TYPES2) => (MASK_TYPES2[MASK_TYPES2.NONE = 0] = "NONE", MASK_TYPES2[MASK_TYPES2.SCISSOR = 1] = "SCISSOR", MASK_TYPES2[MASK_TYPES2.STENCIL = 2] = "STENCIL", MASK_TYPES2[MASK_TYPES2.SPRITE = 3] = "SPRITE", MASK_TYPES2[MASK_TYPES2.COLOR = 4] = "COLOR", MASK_TYPES2))(MASK_TYPES || {}), MSAA_QUALITY = /* @__PURE__ */ ((MSAA_QUALITY2) => (MSAA_QUALITY2[MSAA_QUALITY2.NONE = 0] = "NONE", MSAA_QUALITY2[MSAA_QUALITY2.LOW = 2] = "LOW", MSAA_QUALITY2[MSAA_QUALITY2.MEDIUM = 4] = "MEDIUM", MSAA_QUALITY2[MSAA_QUALITY2.HIGH = 8] = "HIGH", MSAA_QUALITY2))(MSAA_QUALITY || {}), BUFFER_TYPE = /* @__PURE__ */ ((BUFFER_TYPE2) =>
2183 (BUFFER_TYPE2[BUFFER_TYPE2.ELEMENT_ARRAY_BUFFER = 34963] = "ELEMENT_ARRAY_BUFFER", BUFFER_TYPE2[BUFFER_TYPE2.ARRAY_BUFFER = 34962] = "ARRAY_BUFFER", BUFFER_TYPE2[BUFFER_TYPE2.UNIFORM_BUFFER = 35345] = "UNIFORM_BUFFER", BUFFER_TYPE2))(BUFFER_TYPE || {}); 2184 2185const BrowserAdapter = { 2186 /** 2187 * Creates a canvas element of the given size. 2188 * This canvas is created using the browser's native canvas element. 2189 * @param width - width of the canvas 2190 * @param height - height of the canvas 2191 */ 2192 createCanvas: (width, height) => { 2193 const canvas = document.createElement("canvas"); 2194 return canvas.width = width, canvas.height = height, canvas; 2195 }, 2196 getCanvasRenderingContext2D: () => CanvasRenderingContext2D, 2197 getWebGLRenderingContext: () => WebGLRenderingContext, 2198 getNavigator: () => navigator, 2199 getBaseUrl: () => document.baseURI ?? window.location.href, 2200 getFontFaceSet: () => document.fonts, 2201 fetch: (url, options) => fetch(url, options), 2202 parseXML: (xml) => new DOMParser().parseFromString(xml, "text/xml") 2203}; 2204 2205const settings = { 2206 /** 2207 * This adapter is used to call methods that are platform dependent. 2208 * For example `document.createElement` only runs on the web but fails in node environments. 2209 * This allows us to support more platforms by abstracting away specific implementations per platform. 2210 * 2211 * By default the adapter is set to work in the browser. However you can create your own 2212 * by implementing the `IAdapter` interface. See `IAdapter` for more information. 2213 * @name ADAPTER 2214 * @memberof PIXI.settings 2215 * @type {PIXI.IAdapter} 2216 * @default PIXI.BrowserAdapter 2217 */ 2218 ADAPTER: BrowserAdapter, 2219 /** 2220 * Default resolution / device pixel ratio of the renderer. 2221 * @static 2222 * @name RESOLUTION 2223 * @memberof PIXI.settings 2224 * @type {number} 2225 * @default 1 2226 */ 2227 RESOLUTION: 1, 2228 /** 2229 * Enables bitmap creation before image load. This feature is experimental. 2230 * @static 2231 * @name CREATE_IMAGE_BITMAP 2232 * @memberof PIXI.settings 2233 * @type {boolean} 2234 * @default false 2235 */ 2236 CREATE_IMAGE_BITMAP: !1, 2237 /** 2238 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 2239 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 2240 * The main disadvantage is movement of objects may appear less smooth. 2241 * @static 2242 * @memberof PIXI.settings 2243 * @type {boolean} 2244 * @default false 2245 */ 2246 ROUND_PIXELS: !1 2247}; 2248 2249var appleIphone = /iPhone/i; 2250var appleIpod = /iPod/i; 2251var appleTablet = /iPad/i; 2252var appleUniversal = /\biOS-universal(?:.+)Mac\b/i; 2253var androidPhone = /\bAndroid(?:.+)Mobile\b/i; 2254var androidTablet = /Android/i; 2255var amazonPhone = /(?:SD4930UR|\bSilk(?:.+)Mobile\b)/i; 2256var amazonTablet = /Silk/i; 2257var windowsPhone = /Windows Phone/i; 2258var windowsTablet = /\bWindows(?:.+)ARM\b/i; 2259var otherBlackBerry = /BlackBerry/i; 2260var otherBlackBerry10 = /BB10/i; 2261var otherOpera = /Opera Mini/i; 2262var otherChrome = /\b(CriOS|Chrome)(?:.+)Mobile/i; 2263var otherFirefox = /Mobile(?:.+)Firefox\b/i; 2264var isAppleTabletOnIos13 = function (navigator) { 2265 return (typeof navigator !== 'undefined' && 2266 navigator.platform === 'MacIntel' && 2267 typeof navigator.maxTouchPoints === 'number' && 2268 navigator.maxTouchPoints > 1 && 2269 typeof MSStream === 'undefined'); 2270}; 2271function createMatch(userAgent) { 2272 return function (regex) { return regex.test(userAgent); }; 2273} 2274function isMobile$1(param) { 2275 var nav = { 2276 userAgent: '', 2277 platform: '', 2278 maxTouchPoints: 0 2279 }; 2280 if (!param && typeof navigator !== 'undefined') { 2281 nav = { 2282 userAgent: navigator.userAgent, 2283 platform: navigator.platform, 2284 maxTouchPoints: navigator.maxTouchPoints || 0 2285 }; 2286 } 2287 else if (typeof param === 'string') { 2288 nav.userAgent = param; 2289 } 2290 else if (param && param.userAgent) { 2291 nav = { 2292 userAgent: param.userAgent, 2293 platform: param.platform, 2294 maxTouchPoints: param.maxTouchPoints || 0 2295 }; 2296 } 2297 var userAgent = nav.userAgent;
vendor: 7,631 bytes, lines 2298-2549
2298 var tmp = userAgent.split('[FBAN'); 2299 if (typeof tmp[1] !== 'undefined') { 2300 userAgent = tmp[0]; 2301 } 2302 tmp = userAgent.split('Twitter'); 2303 if (typeof tmp[1] !== 'undefined') { 2304 userAgent = tmp[0]; 2305 } 2306 var match = createMatch(userAgent); 2307 var result = { 2308 apple: { 2309 phone: match(appleIphone) && !match(windowsPhone), 2310 ipod: match(appleIpod), 2311 tablet: !match(appleIphone) && 2312 (match(appleTablet) || isAppleTabletOnIos13(nav)) && 2313 !match(windowsPhone), 2314 universal: match(appleUniversal), 2315 device: (match(appleIphone) || 2316 match(appleIpod) || 2317 match(appleTablet) || 2318 match(appleUniversal) || 2319 isAppleTabletOnIos13(nav)) && 2320 !match(windowsPhone) 2321 }, 2322 amazon: { 2323 phone: match(amazonPhone), 2324 tablet: !match(amazonPhone) && match(amazonTablet), 2325 device: match(amazonPhone) || match(amazonTablet) 2326 }, 2327 android: { 2328 phone: (!match(windowsPhone) && match(amazonPhone)) || 2329 (!match(windowsPhone) && match(androidPhone)), 2330 tablet: !match(windowsPhone) && 2331 !match(amazonPhone) && 2332 !match(androidPhone) && 2333 (match(amazonTablet) || match(androidTablet)), 2334 device: (!match(windowsPhone) && 2335 (match(amazonPhone) || 2336 match(amazonTablet) || 2337 match(androidPhone) || 2338 match(androidTablet))) || 2339 match(/\bokhttp\b/i) 2340 }, 2341 windows: { 2342 phone: match(windowsPhone), 2343 tablet: match(windowsTablet), 2344 device: match(windowsPhone) || match(windowsTablet) 2345 }, 2346 other: { 2347 blackberry: match(otherBlackBerry), 2348 blackberry10: match(otherBlackBerry10), 2349 opera: match(otherOpera), 2350 firefox: match(otherFirefox), 2351 chrome: match(otherChrome), 2352 device: match(otherBlackBerry) || 2353 match(otherBlackBerry10) || 2354 match(otherOpera) || 2355 match(otherFirefox) || 2356 match(otherChrome) 2357 }, 2358 any: false, 2359 phone: false, 2360 tablet: false 2361 }; 2362 result.any = 2363 result.apple.device || 2364 result.android.device || 2365 result.windows.device || 2366 result.other.device; 2367 result.phone = 2368 result.apple.phone || result.android.phone || result.windows.phone; 2369 result.tablet = 2370 result.apple.tablet || result.android.tablet || result.windows.tablet; 2371 return result; 2372} 2373 2374const isMobileCall = isMobile$1.default ?? isMobile$1, isMobile = isMobileCall(globalThis.navigator); 2375 2376settings.RETINA_PREFIX = /@([0-9\.]+)x/; 2377settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = !1; 2378 2379var eventemitter3 = {exports: {}}; 2380 2381(function (module) { 2382 2383 var has = Object.prototype.hasOwnProperty 2384 , prefix = '~'; 2385 2386 /** 2387 * Constructor to create a storage for our `EE` objects. 2388 * An `Events` instance is a plain object whose properties are event names. 2389 * 2390 * @constructor 2391 * @private 2392 */ 2393 function Events() {} 2394 2395 // 2396 // We try to not inherit from `Object.prototype`. In some engines creating an 2397 // instance in this way is faster than calling `Object.create(null)` directly. 2398 // If `Object.create(null)` is not supported we prefix the event names with a 2399 // character to make sure that the built-in object properties are not 2400 // overridden or used as an attack vector. 2401 // 2402 if (Object.create) { 2403 Events.prototype = Object.create(null); 2404 2405 // 2406 // This hack is needed because the `__proto__` property is still inherited in 2407 // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. 2408 // 2409 if (!new Events().__proto__) prefix = false; 2410 } 2411 2412 /** 2413 * Representation of a single event listener. 2414 * 2415 * @param {Function} fn The listener function. 2416 * @param {*} context The context to invoke the listener with. 2417 * @param {Boolean} [once=false] Specify if the listener is a one-time listener. 2418 * @constructor 2419 * @private 2420 */ 2421 function EE(fn, context, once) { 2422 this.fn = fn; 2423 this.context = context; 2424 this.once = once || false; 2425 } 2426 2427 /** 2428 * Add a listener for a given event. 2429 * 2430 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. 2431 * @param {(String|Symbol)} event The event name. 2432 * @param {Function} fn The listener function. 2433 * @param {*} context The context to invoke the listener with. 2434 * @param {Boolean} once Specify if the listener is a one-time listener. 2435 * @returns {EventEmitter} 2436 * @private 2437 */ 2438 function addListener(emitter, event, fn, context, once) { 2439 if (typeof fn !== 'function') { 2440 throw new TypeError('The listener must be a function'); 2441 } 2442 2443 var listener = new EE(fn, context || emitter, once) 2444 , evt = prefix ? prefix + event : event; 2445 2446 if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; 2447 else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); 2448 else emitter._events[evt] = [emitter._events[evt], listener]; 2449 2450 return emitter; 2451 } 2452 2453 /** 2454 * Clear event by name. 2455 * 2456 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. 2457 * @param {(String|Symbol)} evt The Event name. 2458 * @private 2459 */ 2460 function clearEvent(emitter, evt) { 2461 if (--emitter._eventsCount === 0) emitter._events = new Events(); 2462 else delete emitter._events[evt]; 2463 } 2464 2465 /** 2466 * Minimal `EventEmitter` interface that is molded against the Node.js 2467 * `EventEmitter` interface. 2468 * 2469 * @constructor 2470 * @public 2471 */ 2472 function EventEmitter() { 2473 this._events = new Events(); 2474 this._eventsCount = 0; 2475 } 2476 2477 /** 2478 * Return an array listing the events for which the emitter has registered 2479 * listeners. 2480 * 2481 * @returns {Array} 2482 * @public 2483 */ 2484 EventEmitter.prototype.eventNames = function eventNames() { 2485 var names = [] 2486 , events 2487 , name; 2488 2489 if (this._eventsCount === 0) return names; 2490 2491 for (name in (events = this._events)) { 2492 if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); 2493 } 2494 2495 if (Object.getOwnPropertySymbols) { 2496 return names.concat(Object.getOwnPropertySymbols(events)); 2497 } 2498 2499 return names; 2500 }; 2501 2502 /** 2503 * Return the listeners registered for a given event. 2504 * 2505 * @param {(String|Symbol)} event The event name. 2506 * @returns {Array} The registered listeners. 2507 * @public 2508 */ 2509 EventEmitter.prototype.listeners = function listeners(event) { 2510 var evt = prefix ? prefix + event : event 2511 , handlers = this._events[evt]; 2512 2513 if (!handlers) return []; 2514 if (handlers.fn) return [handlers.fn]; 2515 2516 for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { 2517 ee[i] = handlers[i].fn; 2518 } 2519 2520 return ee; 2521 }; 2522 2523 /** 2524 * Return the number of listeners listening to a given event. 2525 * 2526 * @param {(String|Symbol)} event The event name. 2527 * @returns {Number} The number of listeners. 2528 * @public 2529 */ 2530 EventEmitter.prototype.listenerCount = function listenerCount(event) { 2531 var evt = prefix ? prefix + event : event 2532 , listeners = this._events[evt]; 2533 2534 if (!listeners) return 0; 2535 if (listeners.fn) return 1; 2536 return listeners.length; 2537 }; 2538 2539 /** 2540 * Calls each of the listeners registered for a given event. 2541 * 2542 * @param {(String|Symbol)} event The event name. 2543 * @returns {Boolean} `true` if the event had listeners, else `false`. 2544 * @public 2545 */ 2546 EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { 2547 var evt = prefix ? prefix + event : event; 2548 2549 if (!this._events[evt]) return false;
2550 2551 var listeners = this._events[evt] 2552 , len = arguments.length 2553 , args 2554 , i; 2555 2556 if (listeners.fn) { 2557 if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); 2558 2559 switch (len) { 2560 case 1: return listeners.fn.call(listeners.context), true; 2561 case 2: return listeners.fn.call(listeners.context, a1), true; 2562 case 3: return listeners.fn.call(listeners.context, a1, a2), true; 2563 case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; 2564 case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; 2565 case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; 2566 } 2567 2568 for (i = 1, args = new Array(len -1); i < len; i++) { 2569 args[i - 1] = arguments[i]; 2570 } 2571 2572 listeners.fn.apply(listeners.context, args); 2573 } else { 2574 var length = listeners.length 2575 , j; 2576 2577 for (i = 0; i < length; i++) { 2578 if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); 2579 2580 switch (len) { 2581 case 1: listeners[i].fn.call(listeners[i].context); break; 2582 case 2: listeners[i].fn.call(listeners[i].context, a1); break; 2583 case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; 2584 case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; 2585 default: 2586 if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { 2587 args[j - 1] = arguments[j]; 2588 } 2589 2590 listeners[i].fn.apply(listeners[i].context, args); 2591 } 2592 } 2593 } 2594 2595 return true; 2596 }; 2597 2598 /** 2599 * Add a listener for a given event. 2600 * 2601 * @param {(String|Symbol)} event The event name. 2602 * @param {Function} fn The listener function. 2603 * @param {*} [context=this] The context to invoke the listener with. 2604 * @returns {EventEmitter} `this`. 2605 * @public 2606 */ 2607 EventEmitter.prototype.on = function on(event, fn, context) { 2608 return addListener(this, event, fn, context, false); 2609 }; 2610 2611 /** 2612 * Add a one-time listener for a given event. 2613 * 2614 * @param {(String|Symbol)} event The event name. 2615 * @param {Function} fn The listener function. 2616 * @param {*} [context=this] The context to invoke the listener with. 2617 * @returns {EventEmitter} `this`. 2618 * @public 2619 */ 2620 EventEmitter.prototype.once = function once(event, fn, context) { 2621 return addListener(this, event, fn, context, true); 2622 }; 2623 2624 /** 2625 * Remove the listeners of a given event. 2626 * 2627 * @param {(String|Symbol)} event The event name. 2628 * @param {Function} fn Only remove the listeners that match this function. 2629 * @param {*} context Only remove the listeners that have this context. 2630 * @param {Boolean} once Only remove one-time listeners. 2631 * @returns {EventEmitter} `this`. 2632 * @public 2633 */ 2634 EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { 2635 var evt = prefix ? prefix + event : event; 2636 2637 if (!this._events[evt]) return this; 2638 if (!fn) { 2639 clearEvent(this, evt); 2640 return this; 2641 } 2642 2643 var listeners = this._events[evt]; 2644 2645 if (listeners.fn) { 2646 if ( 2647 listeners.fn === fn && 2648 (!once || listeners.once) && 2649 (!context || listeners.context === context) 2650 ) { 2651 clearEvent(this, evt); 2652 } 2653 } else { 2654 for (var i = 0, events = [], length = listeners.length; i < length; i++) { 2655 if ( 2656 listeners[i].fn !== fn || 2657 (once && !listeners[i].once) || 2658 (context && listeners[i].context !== context) 2659 ) { 2660 events.push(listeners[i]); 2661 } 2662 } 2663 2664 // 2665 // Reset the array, or remove it completely if we have no more listeners. 2666 // 2667 if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; 2668 else clearEvent(this, evt); 2669 } 2670 2671 return this; 2672 }; 2673 2674 /** 2675 * Remove all listeners, or those of the specified event. 2676 * 2677 * @param {(String|Symbol)} [event] The event name. 2678 * @returns {EventEmitter} `this`. 2679 * @public 2680 */ 2681 EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { 2682 var evt; 2683 2684 if (event) { 2685 evt = prefix ? prefix + event : event; 2686 if (this._events[evt]) clearEvent(this, evt); 2687 } else { 2688 this._events = new Events(); 2689 this._eventsCount = 0; 2690 } 2691 2692 return this; 2693 }; 2694 2695 // 2696 // Alias methods names because people roll like that. 2697 // 2698 EventEmitter.prototype.off = EventEmitter.prototype.removeListener; 2699 EventEmitter.prototype.addListener = EventEmitter.prototype.on; 2700 2701 // 2702 // Expose the prefix. 2703 // 2704 EventEmitter.prefixed = prefix; 2705 2706 // 2707 // Allow `EventEmitter` to be imported as module namespace. 2708 // 2709 EventEmitter.EventEmitter = EventEmitter; 2710 2711 // 2712 // Expose the module. 2713 // 2714 { 2715 module.exports = EventEmitter; 2716 } 2717} (eventemitter3)); 2718 2719var eventemitter3Exports = eventemitter3.exports; 2720const EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports); 2721 2722var earcut$2 = {exports: {}}; 2723 2724earcut$2.exports = earcut; 2725earcut$2.exports.default = earcut; 2726 2727function earcut(data, holeIndices, dim) { 2728 2729 dim = dim || 2; 2730 2731 var hasHoles = holeIndices && holeIndices.length, 2732 outerLen = hasHoles ? holeIndices[0] * dim : data.length, 2733 outerNode = linkedList(data, 0, outerLen, dim, true), 2734 triangles = []; 2735 2736 if (!outerNode || outerNode.next === outerNode.prev) return triangles; 2737 2738 var minX, minY, maxX, maxY, x, y, invSize; 2739 2740 if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); 2741 2742 // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox 2743 if (data.length > 80 * dim) { 2744 minX = maxX = data[0]; 2745 minY = maxY = data[1]; 2746 2747 for (var i = dim; i < outerLen; i += dim) { 2748 x = data[i]; 2749 y = data[i + 1]; 2750 if (x < minX) minX = x; 2751 if (y < minY) minY = y; 2752 if (x > maxX) maxX = x; 2753 if (y > maxY) maxY = y; 2754 } 2755 2756 // minX, minY and invSize are later used to transform coords into integers for z-order calculation 2757 invSize = Math.max(maxX - minX, maxY - minY); 2758 invSize = invSize !== 0 ? 32767 / invSize : 0; 2759 } 2760 2761 earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0); 2762 2763 return triangles; 2764} 2765 2766// create a circular doubly linked list from polygon points in the specified winding order 2767function linkedList(data, start, end, dim, clockwise) { 2768 var i, last; 2769 2770 if (clockwise === (signedArea(data, start, end, dim) > 0)) { 2771 for (i = start; i < end;
vendor: 19,454 bytes, lines 2771-3411
2771 i += dim) last = insertNode(i, data[i], data[i + 1], last); 2772 } else { 2773 for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); 2774 } 2775 2776 if (last && equals(last, last.next)) { 2777 removeNode(last); 2778 last = last.next; 2779 } 2780 2781 return last; 2782} 2783 2784// eliminate colinear or duplicate points 2785function filterPoints(start, end) { 2786 if (!start) return start; 2787 if (!end) end = start; 2788 2789 var p = start, 2790 again; 2791 do { 2792 again = false; 2793 2794 if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { 2795 removeNode(p); 2796 p = end = p.prev; 2797 if (p === p.next) break; 2798 again = true; 2799 2800 } else { 2801 p = p.next; 2802 } 2803 } while (again || p !== end); 2804 2805 return end; 2806} 2807 2808// main ear slicing loop which triangulates a polygon (given as a linked list) 2809function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { 2810 if (!ear) return; 2811 2812 // interlink polygon nodes in z-order 2813 if (!pass && invSize) indexCurve(ear, minX, minY, invSize); 2814 2815 var stop = ear, 2816 prev, next; 2817 2818 // iterate through ears, slicing them one by one 2819 while (ear.prev !== ear.next) { 2820 prev = ear.prev; 2821 next = ear.next; 2822 2823 if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { 2824 // cut off the triangle 2825 triangles.push(prev.i / dim | 0); 2826 triangles.push(ear.i / dim | 0); 2827 triangles.push(next.i / dim | 0); 2828 2829 removeNode(ear); 2830 2831 // skipping the next vertex leads to less sliver triangles 2832 ear = next.next; 2833 stop = next.next; 2834 2835 continue; 2836 } 2837 2838 ear = next; 2839 2840 // if we looped through the whole remaining polygon and can't find any more ears 2841 if (ear === stop) { 2842 // try filtering points and slicing again 2843 if (!pass) { 2844 earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); 2845 2846 // if this didn't work, try curing all small self-intersections locally 2847 } else if (pass === 1) { 2848 ear = cureLocalIntersections(filterPoints(ear), triangles, dim); 2849 earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); 2850 2851 // as a last resort, try splitting the remaining polygon into two 2852 } else if (pass === 2) { 2853 splitEarcut(ear, triangles, dim, minX, minY, invSize); 2854 } 2855 2856 break; 2857 } 2858 } 2859} 2860 2861// check whether a polygon node forms a valid ear with adjacent nodes 2862function isEar(ear) { 2863 var a = ear.prev, 2864 b = ear, 2865 c = ear.next; 2866 2867 if (area(a, b, c) >= 0) return false; // reflex, can't be an ear 2868 2869 // now make sure we don't have other points inside the potential ear 2870 var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; 2871 2872 // triangle bbox; min & max are calculated like this for speed 2873 var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx), 2874 y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy), 2875 x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx), 2876 y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy); 2877 2878 var p = c.next; 2879 while (p !== a) { 2880 if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && 2881 pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && 2882 area(p.prev, p, p.next) >= 0) return false; 2883 p = p.next; 2884 } 2885 2886 return true; 2887} 2888 2889function isEarHashed(ear, minX, minY, invSize) { 2890 var a = ear.prev, 2891 b = ear, 2892 c = ear.next; 2893 2894 if (area(a, b, c) >= 0) return false; // reflex, can't be an ear 2895 2896 var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; 2897 2898 // triangle bbox; min & max are calculated like this for speed 2899 var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx), 2900 y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy), 2901 x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx), 2902 y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy); 2903 2904 // z-order range for the current triangle bbox; 2905 var minZ = zOrder(x0, y0, minX, minY, invSize), 2906 maxZ = zOrder(x1, y1, minX, minY, invSize); 2907 2908 var p = ear.prevZ, 2909 n = ear.nextZ; 2910 2911 // look for points inside the triangle in both directions 2912 while (p && p.z >= minZ && n && n.z <= maxZ) { 2913 if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && 2914 pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; 2915 p = p.prevZ; 2916 2917 if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && 2918 pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; 2919 n = n.nextZ; 2920 } 2921 2922 // look for remaining points in decreasing z-order 2923 while (p && p.z >= minZ) { 2924 if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && 2925 pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; 2926 p = p.prevZ; 2927 } 2928 2929 // look for remaining points in increasing z-order 2930 while (n && n.z <= maxZ) { 2931 if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && 2932 pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; 2933 n = n.nextZ; 2934 } 2935 2936 return true; 2937} 2938 2939// go through all polygon nodes and cure small local self-intersections 2940function cureLocalIntersections(start, triangles, dim) { 2941 var p = start; 2942 do { 2943 var a = p.prev, 2944 b = p.next.next; 2945 2946 if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { 2947 2948 triangles.push(a.i / dim | 0); 2949 triangles.push(p.i / dim | 0); 2950 triangles.push(b.i / dim | 0); 2951 2952 // remove two nodes involved 2953 removeNode(p); 2954 removeNode(p.next); 2955 2956 p = start = b; 2957 } 2958 p = p.next; 2959 } while (p !== start); 2960 2961 return filterPoints(p); 2962} 2963 2964// try splitting polygon into two and triangulate them independently 2965function splitEarcut(start, triangles, dim, minX, minY, invSize) { 2966 // look for a valid diagonal that divides the polygon into two 2967 var a = start; 2968 do { 2969 var b = a.next.next; 2970 while (b !== a.prev) { 2971 if (a.i !== b.i && isValidDiagonal(a, b)) { 2972 // split the polygon in two by the diagonal 2973 var c = splitPolygon(a, b); 2974 2975 // filter colinear points around the cuts 2976 a = filterPoints(a, a.next); 2977 c = filterPoints(c, c.next); 2978 2979 // run earcut on each half 2980 earcutLinked(a, triangles, dim, minX, minY, invSize, 0); 2981 earcutLinked(c, triangles, dim, minX, minY, invSize, 0); 2982 return; 2983 } 2984 b = b.next; 2985 } 2986 a = a.next; 2987 } while (a !== start); 2988} 2989 2990// link every hole into the outer loop, producing a single-ring polygon without holes 2991function eliminateHoles(data, holeIndices, outerNode, dim) { 2992 var queue = [], 2993 i, len, start, end, list; 2994 2995 for (i = 0, len = holeIndices.length; i < len; i++) { 2996 start = holeIndices[i] * dim; 2997 end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; 2998 list = linkedList(data, start, end, dim, false); 2999 if (list === list.next) list.steiner = true; 3000 queue.push(getLeftmost(list)); 3001 } 3002 3003 queue.sort(compareX); 3004 3005 // process holes from left to right 3006 for (i = 0; i < queue.length; i++) { 3007 outerNode = eliminateHole(queue[i], outerNode); 3008 } 3009 3010 return outerNode; 3011} 3012 3013function compareX(a, b) { 3014 return a.x - b.x; 3015} 3016 3017// find a bridge between vertices that connects hole with an outer ring and and link it 3018function eliminateHole(hole, outerNode) { 3019 var bridge = findHoleBridge(hole, outerNode); 3020 if (!bridge) { 3021 return outerNode; 3022 } 3023 3024 var bridgeReverse = splitPolygon(bridge, hole); 3025 3026 // filter collinear points around the cuts 3027 filterPoints(bridgeReverse, bridgeReverse.next); 3028 return filterPoints(bridge, bridge.next); 3029} 3030 3031// David Eberly's algorithm for finding a bridge between hole and outer polygon 3032function findHoleBridge(hole, outerNode) { 3033 var p = outerNode, 3034 hx = hole.x, 3035 hy = hole.y, 3036 qx = -Infinity, 3037 m; 3038 3039 // find a segment intersected by a ray from the hole's leftmost point to the left; 3040 // segment's endpoint with lesser x will be potential connection point 3041 do { 3042 if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { 3043 var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); 3044 if (x <= hx && x > qx) { 3045 qx = x; 3046 m = p.x < p.next.x ? p : p.next; 3047 if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint 3048 } 3049 } 3050 p = p.next; 3051 } while (p !== outerNode); 3052 3053 if (!m) return null; 3054 3055 // look for points inside the triangle of hole point, segment intersection and endpoint; 3056 // if there are no points found, we have a valid connection; 3057 // otherwise choose the point of the minimum angle with the ray as connection point 3058 3059 var stop = m, 3060 mx = m.x, 3061 my = m.y, 3062 tanMin = Infinity, 3063 tan; 3064 3065 p = m; 3066 3067 do { 3068 if (hx >= p.x && p.x >= mx && hx !== p.x && 3069 pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { 3070 3071 tan = Math.abs(hy - p.y) / (hx - p.x); // tangential 3072 3073 if (locallyInside(p, hole) && 3074 (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) { 3075 m = p; 3076 tanMin = tan; 3077 } 3078 } 3079 3080 p = p.next; 3081 } while (p !== stop); 3082 3083 return m; 3084} 3085 3086// whether sector in vertex m contains sector in vertex p in the same coordinates 3087function sectorContainsSector(m, p) { 3088 return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0; 3089} 3090 3091// interlink polygon nodes in z-order 3092function indexCurve(start, minX, minY, invSize) { 3093 var p = start; 3094 do { 3095 if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize); 3096 p.prevZ = p.prev; 3097 p.nextZ = p.next; 3098 p = p.next; 3099 } while (p !== start); 3100 3101 p.prevZ.nextZ = null; 3102 p.prevZ = null; 3103 3104 sortLinked(p); 3105} 3106 3107// Simon Tatham's linked list merge sort algorithm 3108// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html 3109function sortLinked(list) { 3110 var i, p, q, e, tail, numMerges, pSize, qSize, 3111 inSize = 1; 3112 3113 do { 3114 p = list; 3115 list = null; 3116 tail = null; 3117 numMerges = 0; 3118 3119 while (p) { 3120 numMerges++; 3121 q = p; 3122 pSize = 0; 3123 for (i = 0; i < inSize; i++) { 3124 pSize++; 3125 q = q.nextZ; 3126 if (!q) break; 3127 } 3128 qSize = inSize; 3129 3130 while (pSize > 0 || (qSize > 0 && q)) { 3131 3132 if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { 3133 e = p; 3134 p = p.nextZ; 3135 pSize--; 3136 } else { 3137 e = q; 3138 q = q.nextZ; 3139 qSize--; 3140 } 3141 3142 if (tail) tail.nextZ = e; 3143 else list = e; 3144 3145 e.prevZ = tail; 3146 tail = e; 3147 } 3148 3149 p = q; 3150 } 3151 3152 tail.nextZ = null; 3153 inSize *= 2; 3154 3155 } while (numMerges > 1); 3156 3157 return list; 3158} 3159 3160// z-order of a point given coords and inverse of the longer side of data bbox 3161function zOrder(x, y, minX, minY, invSize) { 3162 // coords are transformed into non-negative 15-bit integer range 3163 x = (x - minX) * invSize | 0; 3164 y = (y - minY) * invSize | 0; 3165 3166 x = (x | (x << 8)) & 0x00FF00FF; 3167 x = (x | (x << 4)) & 0x0F0F0F0F; 3168 x = (x | (x << 2)) & 0x33333333; 3169 x = (x | (x << 1)) & 0x55555555; 3170 3171 y = (y | (y << 8)) & 0x00FF00FF; 3172 y = (y | (y << 4)) & 0x0F0F0F0F; 3173 y = (y | (y << 2)) & 0x33333333; 3174 y = (y | (y << 1)) & 0x55555555; 3175 3176 return x | (y << 1); 3177} 3178 3179// find the leftmost node of a polygon ring 3180function getLeftmost(start) { 3181 var p = start, 3182 leftmost = start; 3183 do { 3184 if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p; 3185 p = p.next; 3186 } while (p !== start); 3187 3188 return leftmost; 3189} 3190 3191// check if a point lies within a convex triangle 3192function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { 3193 return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && 3194 (ax - px) * (by - py) >= (bx - px) * (ay - py) && 3195 (bx - px) * (cy - py) >= (cx - px) * (by - py); 3196} 3197 3198// check if a diagonal between two polygon nodes is valid (lies in polygon interior) 3199function isValidDiagonal(a, b) { 3200 return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges 3201 (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible 3202 (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors 3203 equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case 3204} 3205 3206// signed area of a triangle 3207function area(p, q, r) { 3208 return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); 3209} 3210 3211// check if two points are equal 3212function equals(p1, p2) { 3213 return p1.x === p2.x && p1.y === p2.y; 3214} 3215 3216// check if two segments intersect 3217function intersects(p1, q1, p2, q2) { 3218 var o1 = sign$1(area(p1, q1, p2)); 3219 var o2 = sign$1(area(p1, q1, q2)); 3220 var o3 = sign$1(area(p2, q2, p1)); 3221 var o4 = sign$1(area(p2, q2, q1)); 3222 3223 if (o1 !== o2 && o3 !== o4) return true; // general case 3224 3225 if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 3226 if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 3227 if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 3228 if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 3229 3230 return false; 3231} 3232 3233// for collinear points p, q, r, check if point q lies on segment pr 3234function onSegment(p, q, r) { 3235 return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y); 3236} 3237 3238function sign$1(num) { 3239 return num > 0 ? 1 : num < 0 ? -1 : 0; 3240} 3241 3242// check if a polygon diagonal intersects any polygon segments 3243function intersectsPolygon(a, b) { 3244 var p = a; 3245 do { 3246 if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && 3247 intersects(p, p.next, a, b)) return true; 3248 p = p.next; 3249 } while (p !== a); 3250 3251 return false; 3252} 3253 3254// check if a polygon diagonal is locally inside the polygon 3255function locallyInside(a, b) { 3256 return area(a.prev, a, a.next) < 0 ? 3257 area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : 3258 area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; 3259} 3260 3261// check if the middle point of a polygon diagonal is inside the polygon 3262function middleInside(a, b) { 3263 var p = a, 3264 inside = false, 3265 px = (a.x + b.x) / 2, 3266 py = (a.y + b.y) / 2; 3267 do { 3268 if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y && 3269 (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) 3270 inside = !inside; 3271 p = p.next; 3272 } while (p !== a); 3273 3274 return inside; 3275} 3276 3277// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; 3278// if one belongs to the outer ring and another to a hole, it merges it into a single ring 3279function splitPolygon(a, b) { 3280 var a2 = new Node(a.i, a.x, a.y), 3281 b2 = new Node(b.i, b.x, b.y), 3282 an = a.next, 3283 bp = b.prev; 3284 3285 a.next = b; 3286 b.prev = a; 3287 3288 a2.next = an; 3289 an.prev = a2; 3290 3291 b2.next = a2; 3292 a2.prev = b2; 3293 3294 bp.next = b2; 3295 b2.prev = bp; 3296 3297 return b2; 3298} 3299 3300// create a node and optionally link it with previous one (in a circular doubly linked list) 3301function insertNode(i, x, y, last) { 3302 var p = new Node(i, x, y); 3303 3304 if (!last) { 3305 p.prev = p; 3306 p.next = p; 3307 3308 } else { 3309 p.next = last.next; 3310 p.prev = last; 3311 last.next.prev = p; 3312 last.next = p; 3313 } 3314 return p; 3315} 3316 3317function removeNode(p) { 3318 p.next.prev = p.prev; 3319 p.prev.next = p.next; 3320 3321 if (p.prevZ) p.prevZ.nextZ = p.nextZ; 3322 if (p.nextZ) p.nextZ.prevZ = p.prevZ; 3323} 3324 3325function Node(i, x, y) { 3326 // vertex index in coordinates array 3327 this.i = i; 3328 3329 // vertex coordinates 3330 this.x = x; 3331 this.y = y; 3332 3333 // previous and next vertex nodes in a polygon ring 3334 this.prev = null; 3335 this.next = null; 3336 3337 // z-order curve value 3338 this.z = 0; 3339 3340 // previous and next nodes in z-order 3341 this.prevZ = null; 3342 this.nextZ = null; 3343 3344 // indicates whether this is a steiner point 3345 this.steiner = false; 3346} 3347 3348// return a percentage difference between the polygon area and its triangulation area; 3349// used to verify correctness of triangulation 3350earcut.deviation = function (data, holeIndices, dim, triangles) { 3351 var hasHoles = holeIndices && holeIndices.length; 3352 var outerLen = hasHoles ? holeIndices[0] * dim : data.length; 3353 3354 var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); 3355 if (hasHoles) { 3356 for (var i = 0, len = holeIndices.length; i < len; i++) { 3357 var start = holeIndices[i] * dim; 3358 var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; 3359 polygonArea -= Math.abs(signedArea(data, start, end, dim)); 3360 } 3361 } 3362 3363 var trianglesArea = 0; 3364 for (i = 0; i < triangles.length; i += 3) { 3365 var a = triangles[i] * dim; 3366 var b = triangles[i + 1] * dim; 3367 var c = triangles[i + 2] * dim; 3368 trianglesArea += Math.abs( 3369 (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - 3370 (data[a] - data[b]) * (data[c + 1] - data[a + 1])); 3371 } 3372 3373 return polygonArea === 0 && trianglesArea === 0 ? 0 : 3374 Math.abs((trianglesArea - polygonArea) / polygonArea); 3375}; 3376 3377function signedArea(data, start, end, dim) { 3378 var sum = 0; 3379 for (var i = start, j = end - dim; i < end; i += dim) { 3380 sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); 3381 j = i; 3382 } 3383 return sum; 3384} 3385 3386// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts 3387earcut.flatten = function (data) { 3388 var dim = data[0][0].length, 3389 result = {vertices: [], holes: [], dimensions: dim}, 3390 holeIndex = 0; 3391 3392 for (var i = 0; i < data.length; i++) { 3393 for (var j = 0; j < data[i].length; j++) { 3394 for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); 3395 } 3396 if (i > 0) { 3397 holeIndex += data[i - 1].length; 3398 result.holes.push(holeIndex); 3399 } 3400 } 3401 return result; 3402}; 3403 3404var earcutExports = earcut$2.exports; 3405const earcut$1 = /*@__PURE__*/getDefaultExportFromCjs(earcutExports); 3406 3407var punycode$1 = {exports: {}}; 3408 3409/*! https://mths.be/punycode v1.4.1 by @mathias */ 3410punycode$1.exports; 3411
vendor: 13,894 bytes, lines 3412-3897
3412(function (module, exports) { 3413(function(root) { 3414 3415 /** Detect free variables */ 3416 var freeExports = exports && 3417 !exports.nodeType && exports; 3418 var freeModule = module && 3419 !module.nodeType && module; 3420 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal; 3421 if ( 3422 freeGlobal.global === freeGlobal || 3423 freeGlobal.window === freeGlobal || 3424 freeGlobal.self === freeGlobal 3425 ) { 3426 root = freeGlobal; 3427 } 3428 3429 /** 3430 * The `punycode` object. 3431 * @name punycode 3432 * @type Object 3433 */ 3434 var punycode, 3435 3436 /** Highest positive signed 32-bit float value */ 3437 maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 3438 3439 /** Bootstring parameters */ 3440 base = 36, 3441 tMin = 1, 3442 tMax = 26, 3443 skew = 38, 3444 damp = 700, 3445 initialBias = 72, 3446 initialN = 128, // 0x80 3447 delimiter = '-', // '\x2D' 3448 3449 /** Regular expressions */ 3450 regexPunycode = /^xn--/, 3451 regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars 3452 regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators 3453 3454 /** Error messages */ 3455 errors = { 3456 'overflow': 'Overflow: input needs wider integers to process', 3457 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 3458 'invalid-input': 'Invalid input' 3459 }, 3460 3461 /** Convenience shortcuts */ 3462 baseMinusTMin = base - tMin, 3463 floor = Math.floor, 3464 stringFromCharCode = String.fromCharCode, 3465 3466 /** Temporary variable */ 3467 key; 3468 3469 /*--------------------------------------------------------------------------*/ 3470 3471 /** 3472 * A generic error utility function. 3473 * @private 3474 * @param {String} type The error type. 3475 * @returns {Error} Throws a `RangeError` with the applicable error message. 3476 */ 3477 function error(type) { 3478 throw new RangeError(errors[type]); 3479 } 3480 3481 /** 3482 * A generic `Array#map` utility function. 3483 * @private 3484 * @param {Array} array The array to iterate over. 3485 * @param {Function} callback The function that gets called for every array 3486 * item. 3487 * @returns {Array} A new array of values returned by the callback function. 3488 */ 3489 function map(array, fn) { 3490 var length = array.length; 3491 var result = []; 3492 while (length--) { 3493 result[length] = fn(array[length]); 3494 } 3495 return result; 3496 } 3497 3498 /** 3499 * A simple `Array#map`-like wrapper to work with domain name strings or email 3500 * addresses. 3501 * @private 3502 * @param {String} domain The domain name or email address. 3503 * @param {Function} callback The function that gets called for every 3504 * character. 3505 * @returns {Array} A new string of characters returned by the callback 3506 * function. 3507 */ 3508 function mapDomain(string, fn) { 3509 var parts = string.split('@'); 3510 var result = ''; 3511 if (parts.length > 1) { 3512 // In email addresses, only the domain name should be punycoded. Leave 3513 // the local part (i.e. everything up to `@`) intact. 3514 result = parts[0] + '@'; 3515 string = parts[1]; 3516 } 3517 // Avoid `split(regex)` for IE8 compatibility. See #17. 3518 string = string.replace(regexSeparators, '\x2E'); 3519 var labels = string.split('.'); 3520 var encoded = map(labels, fn).join('.'); 3521 return result + encoded; 3522 } 3523 3524 /** 3525 * Creates an array containing the numeric code points of each Unicode 3526 * character in the string. While JavaScript uses UCS-2 internally, 3527 * this function will convert a pair of surrogate halves (each of which 3528 * UCS-2 exposes as separate characters) into a single code point, 3529 * matching UTF-16. 3530 * @see `punycode.ucs2.encode` 3531 * @see <https://mathiasbynens.be/notes/javascript-encoding> 3532 * @memberOf punycode.ucs2 3533 * @name decode 3534 * @param {String} string The Unicode input string (UCS-2). 3535 * @returns {Array} The new array of code points. 3536 */ 3537 function ucs2decode(string) { 3538 var output = [], 3539 counter = 0, 3540 length = string.length, 3541 value, 3542 extra; 3543 while (counter < length) { 3544 value = string.charCodeAt(counter++); 3545 if (value >= 0xD800 && value <= 0xDBFF && counter < length) { 3546 // high surrogate, and there is a next character 3547 extra = string.charCodeAt(counter++); 3548 if ((extra & 0xFC00) == 0xDC00) { // low surrogate 3549 output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); 3550 } else { 3551 // unmatched surrogate; only append this code unit, in case the next 3552 // code unit is the high surrogate of a surrogate pair 3553 output.push(value); 3554 counter--; 3555 } 3556 } else { 3557 output.push(value); 3558 } 3559 } 3560 return output; 3561 } 3562 3563 /** 3564 * Creates a string based on an array of numeric code points. 3565 * @see `punycode.ucs2.decode` 3566 * @memberOf punycode.ucs2 3567 * @name encode 3568 * @param {Array} codePoints The array of numeric code points. 3569 * @returns {String} The new Unicode string (UCS-2). 3570 */ 3571 function ucs2encode(array) { 3572 return map(array, function(value) { 3573 var output = ''; 3574 if (value > 0xFFFF) { 3575 value -= 0x10000; 3576 output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); 3577 value = 0xDC00 | value & 0x3FF; 3578 } 3579 output += stringFromCharCode(value); 3580 return output; 3581 }).join(''); 3582 } 3583 3584 /** 3585 * Converts a basic code point into a digit/integer. 3586 * @see `digitToBasic()` 3587 * @private 3588 * @param {Number} codePoint The basic numeric code point value. 3589 * @returns {Number} The numeric value of a basic code point (for use in 3590 * representing integers) in the range `0` to `base - 1`, or `base` if 3591 * the code point does not represent a value. 3592 */ 3593 function basicToDigit(codePoint) { 3594 if (codePoint - 48 < 10) { 3595 return codePoint - 22; 3596 } 3597 if (codePoint - 65 < 26) { 3598 return codePoint - 65; 3599 } 3600 if (codePoint - 97 < 26) { 3601 return codePoint - 97; 3602 } 3603 return base; 3604 } 3605 3606 /** 3607 * Converts a digit/integer into a basic code point. 3608 * @see `basicToDigit()` 3609 * @private 3610 * @param {Number} digit The numeric value of a basic code point. 3611 * @returns {Number} The basic code point whose value (when used for 3612 * representing integers) is `digit`, which needs to be in the range 3613 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is 3614 * used; else, the lowercase form is used. The behavior is undefined 3615 * if `flag` is non-zero and `digit` has no uppercase form. 3616 */ 3617 function digitToBasic(digit, flag) { 3618 // 0..25 map to ASCII a..z or A..Z 3619 // 26..35 map to ASCII 0..9 3620 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); 3621 } 3622 3623 /** 3624 * Bias adaptation function as per section 3.4 of RFC 3492. 3625 * https://tools.ietf.org/html/rfc3492#section-3.4 3626 * @private 3627 */ 3628 function adapt(delta, numPoints, firstTime) { 3629 var k = 0; 3630 delta = firstTime ? floor(delta / damp) : delta >> 1; 3631 delta += floor(delta / numPoints); 3632 for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { 3633 delta = floor(delta / baseMinusTMin); 3634 } 3635 return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); 3636 } 3637 3638 /** 3639 * Converts a Punycode string of ASCII-only symbols to a string of Unicode 3640 * symbols. 3641 * @memberOf punycode 3642 * @param {String} input The Punycode string of ASCII-only symbols. 3643 * @returns {String} The resulting string of Unicode symbols. 3644 */ 3645 function decode(input) { 3646 // Don't use UCS-2 3647 var output = [], 3648 inputLength = input.length, 3649 out, 3650 i = 0, 3651 n = initialN, 3652 bias = initialBias, 3653 basic, 3654 j, 3655 index, 3656 oldi, 3657 w, 3658 k, 3659 digit, 3660 t, 3661 /** Cached calculation results */ 3662 baseMinusT; 3663 3664 // Handle the basic code points: let `basic` be the number of input code 3665 // points before the last delimiter, or `0` if there is none, then copy 3666 // the first basic code points to the output. 3667 3668 basic = input.lastIndexOf(delimiter); 3669 if (basic < 0) { 3670 basic = 0; 3671 } 3672 3673 for (j = 0; j < basic; ++j) { 3674 // if it's not a basic code point 3675 if (input.charCodeAt(j) >= 0x80) { 3676 error('not-basic'); 3677 } 3678 output.push(input.charCodeAt(j)); 3679 } 3680 3681 // Main decoding loop: start just after the last delimiter if any basic code 3682 // points were copied; start at the beginning otherwise. 3683 3684 for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { 3685 3686 // `index` is the index of the next character to be consumed. 3687 // Decode a generalized variable-length integer into `delta`, 3688 // which gets added to `i`. The overflow checking is easier 3689 // if we increase `i` as we go, then subtract off its starting 3690 // value at the end to obtain `delta`. 3691 for (oldi = i, w = 1, k = base; /* no condition */; k += base) { 3692 3693 if (index >= inputLength) { 3694 error('invalid-input'); 3695 } 3696 3697 digit = basicToDigit(input.charCodeAt(index++)); 3698 3699 if (digit >= base || digit > floor((maxInt - i) / w)) { 3700 error('overflow'); 3701 } 3702 3703 i += digit * w; 3704 t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); 3705 3706 if (digit < t) { 3707 break; 3708 } 3709 3710 baseMinusT = base - t; 3711 if (w > floor(maxInt / baseMinusT)) { 3712 error('overflow'); 3713 } 3714 3715 w *= baseMinusT; 3716 3717 } 3718 3719 out = output.length + 1; 3720 bias = adapt(i - oldi, out, oldi == 0); 3721 3722 // `i` was supposed to wrap around from `out` to `0`, 3723 // incrementing `n` each time, so we'll fix that now: 3724 if (floor(i / out) > maxInt - n) { 3725 error('overflow'); 3726 } 3727 3728 n += floor(i / out); 3729 i %= out; 3730 3731 // Insert `n` at position `i` of the output 3732 output.splice(i++, 0, n); 3733 3734 } 3735 3736 return ucs2encode(output); 3737 } 3738 3739 /** 3740 * Converts a string of Unicode symbols (e.g. a domain name label) to a 3741 * Punycode string of ASCII-only symbols. 3742 * @memberOf punycode 3743 * @param {String} input The string of Unicode symbols. 3744 * @returns {String} The resulting Punycode string of ASCII-only symbols. 3745 */ 3746 function encode(input) { 3747 var n, 3748 delta, 3749 handledCPCount, 3750 basicLength, 3751 bias, 3752 j, 3753 m, 3754 q, 3755 k, 3756 t, 3757 currentValue, 3758 output = [], 3759 /** `inputLength` will hold the number of code points in `input`. */ 3760 inputLength, 3761 /** Cached calculation results */ 3762 handledCPCountPlusOne, 3763 baseMinusT, 3764 qMinusT; 3765 3766 // Convert the input in UCS-2 to Unicode 3767 input = ucs2decode(input); 3768 3769 // Cache the length 3770 inputLength = input.length; 3771 3772 // Initialize the state 3773 n = initialN; 3774 delta = 0; 3775 bias = initialBias; 3776 3777 // Handle the basic code points 3778 for (j = 0; j < inputLength; ++j) { 3779 currentValue = input[j]; 3780 if (currentValue < 0x80) { 3781 output.push(stringFromCharCode(currentValue)); 3782 } 3783 } 3784 3785 handledCPCount = basicLength = output.length; 3786 3787 // `handledCPCount` is the number of code points that have been handled; 3788 // `basicLength` is the number of basic code points. 3789 3790 // Finish the basic string - if it is not empty - with a delimiter 3791 if (basicLength) { 3792 output.push(delimiter); 3793 } 3794 3795 // Main encoding loop: 3796 while (handledCPCount < inputLength) { 3797 3798 // All non-basic code points < n have been handled already. Find the next 3799 // larger one: 3800 for (m = maxInt, j = 0; j < inputLength; ++j) { 3801 currentValue = input[j]; 3802 if (currentValue >= n && currentValue < m) { 3803 m = currentValue; 3804 } 3805 } 3806 3807 // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>, 3808 // but guard against overflow 3809 handledCPCountPlusOne = handledCPCount + 1; 3810 if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { 3811 error('overflow'); 3812 } 3813 3814 delta += (m - n) * handledCPCountPlusOne; 3815 n = m; 3816 3817 for (j = 0; j < inputLength; ++j) { 3818 currentValue = input[j]; 3819 3820 if (currentValue < n && ++delta > maxInt) { 3821 error('overflow'); 3822 } 3823 3824 if (currentValue == n) { 3825 // Represent delta as a generalized variable-length integer 3826 for (q = delta, k = base; /* no condition */; k += base) { 3827 t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); 3828 if (q < t) { 3829 break; 3830 } 3831 qMinusT = q - t; 3832 baseMinusT = base - t; 3833 output.push( 3834 stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) 3835 ); 3836 q = floor(qMinusT / baseMinusT); 3837 } 3838 3839 output.push(stringFromCharCode(digitToBasic(q, 0))); 3840 bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); 3841 delta = 0; 3842 ++handledCPCount; 3843 } 3844 } 3845 3846 ++delta; 3847 ++n; 3848 3849 } 3850 return output.join(''); 3851 } 3852 3853 /** 3854 * Converts a Punycode string representing a domain name or an email address 3855 * to Unicode. Only the Punycoded parts of the input will be converted, i.e. 3856 * it doesn't matter if you call it on a string that has already been 3857 * converted to Unicode. 3858 * @memberOf punycode 3859 * @param {String} input The Punycoded domain name or email address to 3860 * convert to Unicode. 3861 * @returns {String} The Unicode representation of the given Punycode 3862 * string. 3863 */ 3864 function toUnicode(input) { 3865 return mapDomain(input, function(string) { 3866 return regexPunycode.test(string) 3867 ? decode(string.slice(4).toLowerCase()) 3868 : string; 3869 }); 3870 } 3871 3872 /** 3873 * Converts a Unicode string representing a domain name or an email address to 3874 * Punycode. Only the non-ASCII parts of the domain name will be converted, 3875 * i.e. it doesn't matter if you call it with a domain that's already in 3876 * ASCII. 3877 * @memberOf punycode 3878 * @param {String} input The domain name or email address to convert, as a 3879 * Unicode string. 3880 * @returns {String} The Punycode representation of the given domain name or 3881 * email address. 3882 */ 3883 function toASCII(input) { 3884 return mapDomain(input, function(string) { 3885 return regexNonASCII.test(string) 3886 ? 'xn--' + encode(string) 3887 : string; 3888 }); 3889 } 3890 3891 /*--------------------------------------------------------------------------*/ 3892 3893 /** Define the public API */ 3894 punycode = { 3895 /** 3896 * A string representing the current Punycode.js version number. 3897 * @memberOf punycode
3898 * @type String 3899 */ 3900 'version': '1.4.1', 3901 /** 3902 * An object of methods to convert from JavaScript's internal character 3903 * representation (UCS-2) to Unicode code points, and back. 3904 * @see <https://mathiasbynens.be/notes/javascript-encoding> 3905 * @memberOf punycode 3906 * @type Object 3907 */ 3908 'ucs2': { 3909 'decode': ucs2decode, 3910 'encode': ucs2encode 3911 }, 3912 'decode': decode, 3913 'encode': encode, 3914 'toASCII': toASCII, 3915 'toUnicode': toUnicode 3916 }; 3917 3918 /** Expose `punycode` */ 3919 // Some AMD build optimizers, like r.js, check for specific condition patterns 3920 // like the following: 3921 if (freeExports && freeModule) { 3922 if (module.exports == freeExports) { 3923 // in Node.js, io.js, or RingoJS v0.8.0+ 3924 freeModule.exports = punycode; 3925 } else { 3926 // in Narwhal or RingoJS v0.7.0- 3927 for (key in punycode) { 3928 punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); 3929 } 3930 } 3931 } else { 3932 // in Rhino or a web browser 3933 root.punycode = punycode; 3934 } 3935 3936 }(commonjsGlobal)); 3937} (punycode$1, punycode$1.exports)); 3938 3939var punycodeExports = punycode$1.exports; 3940 3941/* eslint complexity: [2, 18], max-statements: [2, 33] */ 3942var shams = function hasSymbols() { 3943 if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; } 3944 if (typeof Symbol.iterator === 'symbol') { return true; } 3945 3946 var obj = {}; 3947 var sym = Symbol('test'); 3948 var symObj = Object(sym); 3949 if (typeof sym === 'string') { return false; } 3950 3951 if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; } 3952 if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; } 3953 3954 // temp disabled per https://github.com/ljharb/object.assign/issues/17 3955 // if (sym instanceof Symbol) { return false; } 3956 // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4 3957 // if (!(symObj instanceof Symbol)) { return false; } 3958 3959 // if (typeof Symbol.prototype.toString !== 'function') { return false; } 3960 // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; } 3961 3962 var symVal = 42; 3963 obj[sym] = symVal; 3964 for (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop 3965 if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; } 3966 3967 if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; } 3968 3969 var syms = Object.getOwnPropertySymbols(obj); 3970 if (syms.length !== 1 || syms[0] !== sym) { return false; } 3971 3972 if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; } 3973 3974 if (typeof Object.getOwnPropertyDescriptor === 'function') { 3975 var descriptor = Object.getOwnPropertyDescriptor(obj, sym); 3976 if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; } 3977 } 3978 3979 return true; 3980}; 3981 3982var origSymbol = typeof Symbol !== 'undefined' && Symbol; 3983var hasSymbolSham = shams; 3984 3985var hasSymbols$1 = function hasNativeSymbols() { 3986 if (typeof origSymbol !== 'function') { return false; } 3987 if (typeof Symbol !== 'function') { return false; } 3988 if (typeof origSymbol('foo') !== 'symbol') { return false; } 3989 if (typeof Symbol('bar') !== 'symbol') { return false; } 3990 3991 return hasSymbolSham(); 3992}; 3993 3994var test = { 3995 foo: {} 3996}; 3997 3998var $Object = Object; 3999 4000var hasProto$1 = function hasProto() { 4001 return { __proto__: test }.foo === test.foo && !({ __proto__: null } instanceof $Object); 4002}; 4003 4004/* eslint no-invalid-this: 1 */ 4005 4006var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; 4007var toStr$1 = Object.prototype.toString; 4008var max = Math.max; 4009var funcType = '[object Function]'; 4010 4011var concatty = function concatty(a, b) { 4012 var arr = []; 4013 4014 for (var i = 0; i < a.length; i += 1) { 4015 arr[i] = a[i]; 4016 } 4017 for (var j = 0; j < b.length; j += 1) { 4018 arr[j + a.length] = b[j]; 4019 } 4020 4021 return arr; 4022}; 4023 4024var slicy = function slicy(arrLike, offset) { 4025 var arr = []; 4026 for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) { 4027 arr[j] = arrLike[i]; 4028 } 4029 return arr; 4030}; 4031 4032var joiny = function (arr, joiner) { 4033 var str = ''; 4034 for (var i = 0; i < arr.length; i += 1) { 4035 str += arr[i]; 4036 if (i + 1 < arr.length) { 4037 str += joiner; 4038 } 4039 } 4040 return str; 4041}; 4042 4043var implementation$1 = function bind(that) { 4044 var target = this; 4045 if (typeof target !== 'function' || toStr$1.apply(target) !== funcType) { 4046 throw new TypeError(ERROR_MESSAGE + target); 4047 } 4048 var args = slicy(arguments, 1); 4049 4050 var bound; 4051 var binder = function () { 4052 if (this instanceof bound) { 4053 var result = target.apply( 4054 this, 4055 concatty(args, arguments) 4056 ); 4057 if (Object(result) === result) { 4058 return result; 4059 } 4060 return this; 4061 } 4062 return target.apply( 4063 that, 4064 concatty(args, arguments) 4065 ); 4066 4067 }; 4068 4069 var boundLength = max(0, target.length - args.length); 4070 var boundArgs = []; 4071 for (var i = 0; i < boundLength; i++) { 4072 boundArgs[i] = '$' + i; 4073 } 4074 4075 bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder); 4076 4077 if (target.prototype) { 4078 var Empty = function Empty() {}; 4079 Empty.prototype = target.prototype; 4080 bound.prototype = new Empty(); 4081 Empty.prototype = null; 4082 } 4083 4084 return bound; 4085}; 4086 4087var implementation = implementation$1; 4088 4089var functionBind = Function.prototype.bind || implementation; 4090 4091var call = Function.prototype.call; 4092var $hasOwn = Object.prototype.hasOwnProperty;
vendor: 10,655 bytes, lines 4093-4351
4093var bind$5 = functionBind; 4094 4095/** @type {(o: {}, p: PropertyKey) => p is keyof o} */ 4096var hasown = bind$5.call(call, $hasOwn); 4097 4098var undefined$1; 4099 4100var $SyntaxError$1 = SyntaxError; 4101var $Function = Function; 4102var $TypeError$3 = TypeError; 4103 4104// eslint-disable-next-line consistent-return 4105var getEvalledConstructor = function (expressionSyntax) { 4106 try { 4107 return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')(); 4108 } catch (e) {} 4109}; 4110 4111var $gOPD$1 = Object.getOwnPropertyDescriptor; 4112if ($gOPD$1) { 4113 try { 4114 $gOPD$1({}, ''); 4115 } catch (e) { 4116 $gOPD$1 = null; // this is IE 8, which has a broken gOPD 4117 } 4118} 4119 4120var throwTypeError = function () { 4121 throw new $TypeError$3(); 4122}; 4123var ThrowTypeError = $gOPD$1 4124 ? (function () { 4125 try { 4126 // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties 4127 arguments.callee; // IE 8 does not throw here 4128 return throwTypeError; 4129 } catch (calleeThrows) { 4130 try { 4131 // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '') 4132 return $gOPD$1(arguments, 'callee').get; 4133 } catch (gOPDthrows) { 4134 return throwTypeError; 4135 } 4136 } 4137 }()) 4138 : throwTypeError; 4139 4140var hasSymbols = hasSymbols$1(); 4141var hasProto = hasProto$1(); 4142 4143var getProto = Object.getPrototypeOf || ( 4144 hasProto 4145 ? function (x) { return x.__proto__; } // eslint-disable-line no-proto 4146 : null 4147); 4148 4149var needsEval = {}; 4150 4151var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined$1 : getProto(Uint8Array); 4152 4153var INTRINSICS = { 4154 '%AggregateError%': typeof AggregateError === 'undefined' ? undefined$1 : AggregateError, 4155 '%Array%': Array, 4156 '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined$1 : ArrayBuffer, 4157 '%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined$1, 4158 '%AsyncFromSyncIteratorPrototype%': undefined$1, 4159 '%AsyncFunction%': needsEval, 4160 '%AsyncGenerator%': needsEval, 4161 '%AsyncGeneratorFunction%': needsEval, 4162 '%AsyncIteratorPrototype%': needsEval, 4163 '%Atomics%': typeof Atomics === 'undefined' ? undefined$1 : Atomics, 4164 '%BigInt%': typeof BigInt === 'undefined' ? undefined$1 : BigInt, 4165 '%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined$1 : BigInt64Array, 4166 '%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined$1 : BigUint64Array, 4167 '%Boolean%': Boolean, 4168 '%DataView%': typeof DataView === 'undefined' ? undefined$1 : DataView, 4169 '%Date%': Date, 4170 '%decodeURI%': decodeURI, 4171 '%decodeURIComponent%': decodeURIComponent, 4172 '%encodeURI%': encodeURI, 4173 '%encodeURIComponent%': encodeURIComponent, 4174 '%Error%': Error, 4175 '%eval%': eval, // eslint-disable-line no-eval 4176 '%EvalError%': EvalError, 4177 '%Float32Array%': typeof Float32Array === 'undefined' ? undefined$1 : Float32Array, 4178 '%Float64Array%': typeof Float64Array === 'undefined' ? undefined$1 : Float64Array, 4179 '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined$1 : FinalizationRegistry, 4180 '%Function%': $Function, 4181 '%GeneratorFunction%': needsEval, 4182 '%Int8Array%': typeof Int8Array === 'undefined' ? undefined$1 : Int8Array, 4183 '%Int16Array%': typeof Int16Array === 'undefined' ? undefined$1 : Int16Array, 4184 '%Int32Array%': typeof Int32Array === 'undefined' ? undefined$1 : Int32Array, 4185 '%isFinite%': isFinite, 4186 '%isNaN%': isNaN, 4187 '%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined$1, 4188 '%JSON%': typeof JSON === 'object' ? JSON : undefined$1, 4189 '%Map%': typeof Map === 'undefined' ? undefined$1 : Map, 4190 '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined$1 : getProto(new Map()[Symbol.iterator]()), 4191 '%Math%': Math, 4192 '%Number%': Number, 4193 '%Object%': Object, 4194 '%parseFloat%': parseFloat, 4195 '%parseInt%': parseInt, 4196 '%Promise%': typeof Promise === 'undefined' ? undefined$1 : Promise, 4197 '%Proxy%': typeof Proxy === 'undefined' ? undefined$1 : Proxy, 4198 '%RangeError%': RangeError, 4199 '%ReferenceError%': ReferenceError, 4200 '%Reflect%': typeof Reflect === 'undefined' ? undefined$1 : Reflect, 4201 '%RegExp%': RegExp, 4202 '%Set%': typeof Set === 'undefined' ? undefined$1 : Set, 4203 '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined$1 : getProto(new Set()[Symbol.iterator]()), 4204 '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined$1 : SharedArrayBuffer, 4205 '%String%': String, 4206 '%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined$1, 4207 '%Symbol%': hasSymbols ? Symbol : undefined$1, 4208 '%SyntaxError%': $SyntaxError$1, 4209 '%ThrowTypeError%': ThrowTypeError, 4210 '%TypedArray%': TypedArray, 4211 '%TypeError%': $TypeError$3, 4212 '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined$1 : Uint8Array, 4213 '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined$1 : Uint8ClampedArray, 4214 '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined$1 : Uint16Array, 4215 '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined$1 : Uint32Array, 4216 '%URIError%': URIError, 4217 '%WeakMap%': typeof WeakMap === 'undefined' ? undefined$1 : WeakMap, 4218 '%WeakRef%': typeof WeakRef === 'undefined' ? undefined$1 : WeakRef, 4219 '%WeakSet%': typeof WeakSet === 'undefined' ? undefined$1 : WeakSet 4220}; 4221 4222if (getProto) { 4223 try { 4224 null.error; // eslint-disable-line no-unused-expressions 4225 } catch (e) { 4226 // https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229 4227 var errorProto = getProto(getProto(e)); 4228 INTRINSICS['%Error.prototype%'] = errorProto; 4229 } 4230} 4231 4232var doEval = function doEval(name) { 4233 var value; 4234 if (name === '%AsyncFunction%') { 4235 value = getEvalledConstructor('async function () {}'); 4236 } else if (name === '%GeneratorFunction%') { 4237 value = getEvalledConstructor('function* () {}'); 4238 } else if (name === '%AsyncGeneratorFunction%') { 4239 value = getEvalledConstructor('async function* () {}'); 4240 } else if (name === '%AsyncGenerator%') { 4241 var fn = doEval('%AsyncGeneratorFunction%'); 4242 if (fn) { 4243 value = fn.prototype; 4244 } 4245 } else if (name === '%AsyncIteratorPrototype%') { 4246 var gen = doEval('%AsyncGenerator%'); 4247 if (gen && getProto) { 4248 value = getProto(gen.prototype); 4249 } 4250 } 4251 4252 INTRINSICS[name] = value; 4253 4254 return value; 4255}; 4256 4257var LEGACY_ALIASES = { 4258 '%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'], 4259 '%ArrayPrototype%': ['Array', 'prototype'], 4260 '%ArrayProto_entries%': ['Array', 'prototype', 'entries'], 4261 '%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'], 4262 '%ArrayProto_keys%': ['Array', 'prototype', 'keys'], 4263 '%ArrayProto_values%': ['Array', 'prototype', 'values'], 4264 '%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'], 4265 '%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'], 4266 '%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'], 4267 '%BooleanPrototype%': ['Boolean', 'prototype'], 4268 '%DataViewPrototype%': ['DataView', 'prototype'], 4269 '%DatePrototype%': ['Date', 'prototype'], 4270 '%ErrorPrototype%': ['Error', 'prototype'], 4271 '%EvalErrorPrototype%': ['EvalError', 'prototype'], 4272 '%Float32ArrayPrototype%': ['Float32Array', 'prototype'], 4273 '%Float64ArrayPrototype%': ['Float64Array', 'prototype'], 4274 '%FunctionPrototype%': ['Function', 'prototype'], 4275 '%Generator%': ['GeneratorFunction', 'prototype'], 4276 '%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'], 4277 '%Int8ArrayPrototype%': ['Int8Array', 'prototype'], 4278 '%Int16ArrayPrototype%': ['Int16Array', 'prototype'], 4279 '%Int32ArrayPrototype%': ['Int32Array', 'prototype'], 4280 '%JSONParse%': ['JSON', 'parse'], 4281 '%JSONStringify%': ['JSON', 'stringify'], 4282 '%MapPrototype%': ['Map', 'prototype'], 4283 '%NumberPrototype%': ['Number', 'prototype'], 4284 '%ObjectPrototype%': ['Object', 'prototype'], 4285 '%ObjProto_toString%': ['Object', 'prototype', 'toString'], 4286 '%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'], 4287 '%PromisePrototype%': ['Promise', 'prototype'], 4288 '%PromiseProto_then%': ['Promise', 'prototype', 'then'], 4289 '%Promise_all%': ['Promise', 'all'], 4290 '%Promise_reject%': ['Promise', 'reject'], 4291 '%Promise_resolve%': ['Promise', 'resolve'], 4292 '%RangeErrorPrototype%': ['RangeError', 'prototype'], 4293 '%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'], 4294 '%RegExpPrototype%': ['RegExp', 'prototype'], 4295 '%SetPrototype%': ['Set', 'prototype'], 4296 '%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'], 4297 '%StringPrototype%': ['String', 'prototype'], 4298 '%SymbolPrototype%': ['Symbol', 'prototype'], 4299 '%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'], 4300 '%TypedArrayPrototype%': ['TypedArray', 'prototype'], 4301 '%TypeErrorPrototype%': ['TypeError', 'prototype'], 4302 '%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'], 4303 '%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'], 4304 '%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'], 4305 '%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'], 4306 '%URIErrorPrototype%': ['URIError', 'prototype'], 4307 '%WeakMapPrototype%': ['WeakMap', 'prototype'], 4308 '%WeakSetPrototype%': ['WeakSet', 'prototype'] 4309}; 4310 4311var bind$4 = functionBind; 4312var hasOwn$1 = hasown; 4313var $concat$1 = bind$4.call(Function.call, Array.prototype.concat); 4314var $spliceApply = bind$4.call(Function.apply, Array.prototype.splice); 4315var $replace$1 = bind$4.call(Function.call, String.prototype.replace); 4316var $strSlice = bind$4.call(Function.call, String.prototype.slice); 4317var $exec = bind$4.call(Function.call, RegExp.prototype.exec); 4318 4319/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */ 4320var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; 4321var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */ 4322var stringToPath = function stringToPath(string) { 4323 var first = $strSlice(string, 0, 1); 4324 var last = $strSlice(string, -1); 4325 if (first === '%' && last !== '%') { 4326 throw new $SyntaxError$1('invalid intrinsic syntax, expected closing `%`'); 4327 } else if (last === '%' && first !== '%') { 4328 throw new $SyntaxError$1('invalid intrinsic syntax, expected opening `%`'); 4329 } 4330 var result = []; 4331 $replace$1(string, rePropName, function (match, number, quote, subString) { 4332 result[result.length] = quote ? $replace$1(subString, reEscapeChar, '$1') : number || match; 4333 }); 4334 return result; 4335}; 4336/* end adaptation */ 4337 4338var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) { 4339 var intrinsicName = name; 4340 var alias; 4341 if (hasOwn$1(LEGACY_ALIASES, intrinsicName)) { 4342 alias = LEGACY_ALIASES[intrinsicName]; 4343 intrinsicName = '%' + alias[0] + '%'; 4344 } 4345 4346 if (hasOwn$1(INTRINSICS, intrinsicName)) { 4347 var value = INTRINSICS[intrinsicName]; 4348 if (value === needsEval) { 4349 value = doEval(intrinsicName); 4350 } 4351 if (typeof value === 'undefined' && !allowMissing) {
4352 throw new $TypeError$3('intrinsic ' + name + ' exists, but is not available. Please file an issue!'); 4353 } 4354 4355 return { 4356 alias: alias, 4357 name: intrinsicName, 4358 value: value 4359 }; 4360 } 4361 4362 throw new $SyntaxError$1('intrinsic ' + name + ' does not exist!'); 4363}; 4364 4365var getIntrinsic = function GetIntrinsic(name, allowMissing) { 4366 if (typeof name !== 'string' || name.length === 0) { 4367 throw new $TypeError$3('intrinsic name must be a non-empty string'); 4368 } 4369 if (arguments.length > 1 && typeof allowMissing !== 'boolean') { 4370 throw new $TypeError$3('"allowMissing" argument must be a boolean'); 4371 } 4372 4373 if ($exec(/^%?[^%]*%?$/, name) === null) { 4374 throw new $SyntaxError$1('`%` may not be present anywhere but at the beginning and end of the intrinsic name'); 4375 } 4376 var parts = stringToPath(name); 4377 var intrinsicBaseName = parts.length > 0 ? parts[0] : ''; 4378 4379 var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing); 4380 var intrinsicRealName = intrinsic.name; 4381 var value = intrinsic.value; 4382 var skipFurtherCaching = false; 4383 4384 var alias = intrinsic.alias; 4385 if (alias) { 4386 intrinsicBaseName = alias[0]; 4387 $spliceApply(parts, $concat$1([0, 1], alias)); 4388 } 4389 4390 for (var i = 1, isOwn = true; i < parts.length; i += 1) { 4391 var part = parts[i]; 4392 var first = $strSlice(part, 0, 1); 4393 var last = $strSlice(part, -1); 4394 if ( 4395 ( 4396 (first === '"' || first === "'" || first === '`') 4397 || (last === '"' || last === "'" || last === '`') 4398 ) 4399 && first !== last 4400 ) { 4401 throw new $SyntaxError$1('property names with quotes must have matching quotes'); 4402 } 4403 if (part === 'constructor' || !isOwn) { 4404 skipFurtherCaching = true; 4405 } 4406 4407 intrinsicBaseName += '.' + part; 4408 intrinsicRealName = '%' + intrinsicBaseName + '%'; 4409 4410 if (hasOwn$1(INTRINSICS, intrinsicRealName)) { 4411 value = INTRINSICS[intrinsicRealName]; 4412 } else if (value != null) { 4413 if (!(part in value)) { 4414 if (!allowMissing) { 4415 throw new $TypeError$3('base intrinsic for ' + name + ' exists, but the property is not available.'); 4416 } 4417 return void undefined$1; 4418 } 4419 if ($gOPD$1 && (i + 1) >= parts.length) { 4420 var desc = $gOPD$1(value, part); 4421 isOwn = !!desc; 4422 4423 // By convention, when a data property is converted to an accessor 4424 // property to emulate a data property that does not suffer from 4425 // the override mistake, that accessor's getter is marked with 4426 // an `originalValue` property. Here, when we detect this, we 4427 // uphold the illusion by pretending to see that original data 4428 // property, i.e., returning the value rather than the getter 4429 // itself. 4430 if (isOwn && 'get' in desc && !('originalValue' in desc.get)) { 4431 value = desc.get; 4432 } else { 4433 value = value[part]; 4434 } 4435 } else { 4436 isOwn = hasOwn$1(value, part); 4437 value = value[part]; 4438 } 4439 4440 if (isOwn && !skipFurtherCaching) { 4441 INTRINSICS[intrinsicRealName] = value; 4442 } 4443 } 4444 } 4445 return value; 4446}; 4447 4448var callBind$1 = {exports: {}}; 4449 4450var GetIntrinsic$5 = getIntrinsic; 4451 4452var $defineProperty$1 = GetIntrinsic$5('%Object.defineProperty%', true); 4453 4454var hasPropertyDescriptors$1 = function hasPropertyDescriptors() { 4455 if ($defineProperty$1) { 4456 try { 4457 $defineProperty$1({}, 'a', { value: 1 }); 4458 return true; 4459 } catch (e) { 4460 // IE 8 has a broken defineProperty 4461 return false; 4462 } 4463 } 4464 return false; 4465}; 4466 4467hasPropertyDescriptors$1.hasArrayLengthDefineBug = function hasArrayLengthDefineBug() { 4468 // node v0.6 has a bug where array lengths can be Set but not Defined 4469 if (!hasPropertyDescriptors$1()) { 4470 return null; 4471 } 4472 try { 4473 return $defineProperty$1([], 'length', { value: 1 }).length !== 1; 4474 } catch (e) { 4475 // In Firefox 4-22, defining length on an array throws an exception. 4476 return true; 4477 } 4478}; 4479 4480var hasPropertyDescriptors_1 = hasPropertyDescriptors$1; 4481 4482var GetIntrinsic$4 = getIntrinsic; 4483 4484var $gOPD = GetIntrinsic$4('%Object.getOwnPropertyDescriptor%', true); 4485 4486if ($gOPD) { 4487 try { 4488 $gOPD([], 'length'); 4489 } catch (e) { 4490 // IE 8 has a broken gOPD 4491 $gOPD = null; 4492 } 4493} 4494 4495var gopd$1 = $gOPD; 4496 4497var hasPropertyDescriptors = hasPropertyDescriptors_1(); 4498 4499var GetIntrinsic$3 = getIntrinsic; 4500 4501var $defineProperty = hasPropertyDescriptors && GetIntrinsic$3('%Object.defineProperty%', true); 4502if ($defineProperty) { 4503 try { 4504 $defineProperty({}, 'a', { value: 1 }); 4505 } catch (e) { 4506 // IE 8 has a broken defineProperty 4507 $defineProperty = false;
4508 } 4509} 4510 4511var $SyntaxError = GetIntrinsic$3('%SyntaxError%'); 4512var $TypeError$2 = GetIntrinsic$3('%TypeError%'); 4513 4514var gopd = gopd$1; 4515 4516/** @type {(obj: Record<PropertyKey, unknown>, property: PropertyKey, value: unknown, nonEnumerable?: boolean | null, nonWritable?: boolean | null, nonConfigurable?: boolean | null, loose?: boolean) => void} */ 4517var defineDataProperty = function defineDataProperty( 4518 obj, 4519 property, 4520 value 4521) { 4522 if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { 4523 throw new $TypeError$2('`obj` must be an object or a function`'); 4524 } 4525 if (typeof property !== 'string' && typeof property !== 'symbol') { 4526 throw new $TypeError$2('`property` must be a string or a symbol`'); 4527 } 4528 if (arguments.length > 3 && typeof arguments[3] !== 'boolean' && arguments[3] !== null) { 4529 throw new $TypeError$2('`nonEnumerable`, if provided, must be a boolean or null'); 4530 } 4531 if (arguments.length > 4 && typeof arguments[4] !== 'boolean' && arguments[4] !== null) { 4532 throw new $TypeError$2('`nonWritable`, if provided, must be a boolean or null'); 4533 } 4534 if (arguments.length > 5 && typeof arguments[5] !== 'boolean' && arguments[5] !== null) { 4535 throw new $TypeError$2('`nonConfigurable`, if provided, must be a boolean or null'); 4536 } 4537 if (arguments.length > 6 && typeof arguments[6] !== 'boolean') { 4538 throw new $TypeError$2('`loose`, if provided, must be a boolean'); 4539 } 4540 4541 var nonEnumerable = arguments.length > 3 ? arguments[3] : null; 4542 var nonWritable = arguments.length > 4 ? arguments[4] : null; 4543 var nonConfigurable = arguments.length > 5 ? arguments[5] : null; 4544 var loose = arguments.length > 6 ? arguments[6] : false; 4545 4546 /* @type {false | TypedPropertyDescriptor<unknown>} */ 4547 var desc = !!gopd && gopd(obj, property); 4548 4549 if ($defineProperty) { 4550 $defineProperty(obj, property, { 4551 configurable: nonConfigurable === null && desc ? desc.configurable : !nonConfigurable, 4552 enumerable: nonEnumerable === null && desc ? desc.enumerable : !nonEnumerable, 4553 value: value, 4554 writable: nonWritable === null && desc ? desc.writable : !nonWritable 4555 }); 4556 } else if (loose || (!nonEnumerable && !nonWritable && !nonConfigurable)) { 4557 // must fall back to [[Set]], and was not explicitly asked to make non-enumerable, non-writable, or non-configurable 4558 obj[property] = value; // eslint-disable-line no-param-reassign 4559 } else { 4560 throw new $SyntaxError('This environment does not support defining a property as non-configurable, non-writable, or non-enumerable.'); 4561 } 4562}; 4563 4564var GetIntrinsic$2 = getIntrinsic; 4565var define = defineDataProperty; 4566var hasDescriptors = hasPropertyDescriptors_1(); 4567var gOPD = gopd$1; 4568 4569var $TypeError$1 = GetIntrinsic$2('%TypeError%'); 4570var $floor$1 = GetIntrinsic$2('%Math.floor%'); 4571 4572var setFunctionLength = function setFunctionLength(fn, length) { 4573 if (typeof fn !== 'function') { 4574 throw new $TypeError$1('`fn` is not a function'); 4575 } 4576 if (typeof length !== 'number' || length < 0 || length > 0xFFFFFFFF || $floor$1(length) !== length) { 4577 throw new $TypeError$1('`length` must be a positive 32-bit integer'); 4578 } 4579 4580 var loose = arguments.length > 2 && !!arguments[2]; 4581 4582 var functionLengthIsConfigurable = true; 4583 var functionLengthIsWritable = true; 4584 if ('length' in fn && gOPD) { 4585 var desc = gOPD(fn, 'length'); 4586 if (desc && !desc.configurable) { 4587 functionLengthIsConfigurable = false; 4588 } 4589 if (desc && !desc.writable) { 4590 functionLengthIsWritable = false; 4591 } 4592 } 4593 4594 if (functionLengthIsConfigurable || functionLengthIsWritable || !loose) { 4595 if (hasDescriptors) { 4596 define(fn, 'length', length, true, true); 4597 } else { 4598 define(fn, 'length', length); 4599 } 4600 } 4601 return fn; 4602}; 4603 4604(function (module) { 4605 4606 var bind = functionBind; 4607 var GetIntrinsic = getIntrinsic; 4608 var setFunctionLength$1 = setFunctionLength; 4609 4610 var $TypeError = GetIntrinsic('%TypeError%'); 4611 var $apply = GetIntrinsic('%Function.prototype.apply%'); 4612 var $call = GetIntrinsic('%Function.prototype.call%'); 4613 var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply); 4614 4615 var $defineProperty = GetIntrinsic('%Object.defineProperty%', true); 4616 var $max = GetIntrinsic('%Math.max%'); 4617 4618 if ($defineProperty) { 4619 try { 4620 $defineProperty({}, 'a', { value: 1 }); 4621 } catch (e) { 4622 // IE 8 has a broken defineProperty 4623 $defineProperty = null; 4624 } 4625 } 4626 4627 module.exports = function callBind(originalFunction) { 4628 if (typeof originalFunction !== 'function') { 4629 throw new $TypeError('a function is required'); 4630 }
vendor: 48,935 bytes, lines 4631-6140
4631 var func = $reflectApply(bind, $call, arguments); 4632 return setFunctionLength$1( 4633 func, 4634 1 + $max(0, originalFunction.length - (arguments.length - 1)), 4635 true 4636 ); 4637 }; 4638 4639 var applyBind = function applyBind() { 4640 return $reflectApply(bind, $apply, arguments); 4641 }; 4642 4643 if ($defineProperty) { 4644 $defineProperty(module.exports, 'apply', { value: applyBind }); 4645 } else { 4646 module.exports.apply = applyBind; 4647 } 4648} (callBind$1)); 4649 4650var callBindExports = callBind$1.exports; 4651 4652var GetIntrinsic$1 = getIntrinsic; 4653 4654var callBind = callBindExports; 4655 4656var $indexOf = callBind(GetIntrinsic$1('String.prototype.indexOf')); 4657 4658var callBound$1 = function callBoundIntrinsic(name, allowMissing) { 4659 var intrinsic = GetIntrinsic$1(name, !!allowMissing); 4660 if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) { 4661 return callBind(intrinsic); 4662 } 4663 return intrinsic; 4664}; 4665 4666const require$$0 = /*@__PURE__*/getAugmentedNamespace(__viteBrowserExternal); 4667 4668var hasMap = typeof Map === 'function' && Map.prototype; 4669var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null; 4670var mapSize$1 = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null; 4671var mapForEach = hasMap && Map.prototype.forEach; 4672var hasSet = typeof Set === 'function' && Set.prototype; 4673var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null; 4674var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null; 4675var setForEach = hasSet && Set.prototype.forEach; 4676var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype; 4677var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null; 4678var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype; 4679var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null; 4680var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype; 4681var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null; 4682var booleanValueOf = Boolean.prototype.valueOf; 4683var objectToString = Object.prototype.toString; 4684var functionToString = Function.prototype.toString; 4685var $match = String.prototype.match; 4686var $slice = String.prototype.slice; 4687var $replace = String.prototype.replace; 4688var $toUpperCase = String.prototype.toUpperCase; 4689var $toLowerCase = String.prototype.toLowerCase; 4690var $test = RegExp.prototype.test; 4691var $concat = Array.prototype.concat; 4692var $join = Array.prototype.join; 4693var $arrSlice = Array.prototype.slice; 4694var $floor = Math.floor; 4695var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null; 4696var gOPS = Object.getOwnPropertySymbols; 4697var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null; 4698var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object'; 4699// ie, `has-tostringtag/shams 4700var toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol') 4701 ? Symbol.toStringTag 4702 : null; 4703var isEnumerable = Object.prototype.propertyIsEnumerable; 4704 4705var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || ( 4706 [].__proto__ === Array.prototype // eslint-disable-line no-proto 4707 ? function (O) { 4708 return O.__proto__; // eslint-disable-line no-proto 4709 } 4710 : null 4711); 4712 4713function addNumericSeparator(num, str) { 4714 if ( 4715 num === Infinity 4716 || num === -Infinity 4717 || num !== num 4718 || (num && num > -1000 && num < 1000) 4719 || $test.call(/e/, str) 4720 ) { 4721 return str; 4722 } 4723 var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g; 4724 if (typeof num === 'number') { 4725 var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num) 4726 if (int !== num) { 4727 var intStr = String(int); 4728 var dec = $slice.call(str, intStr.length + 1); 4729 return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, ''); 4730 } 4731 } 4732 return $replace.call(str, sepRegex, '$&_'); 4733} 4734 4735var utilInspect = require$$0; 4736var inspectCustom = utilInspect.custom; 4737var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null; 4738 4739var objectInspect = function inspect_(obj, options, depth, seen) { 4740 var opts = options || {}; 4741 4742 if (has$3(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) { 4743 throw new TypeError('option "quoteStyle" must be "single" or "double"'); 4744 } 4745 if ( 4746 has$3(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number' 4747 ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity 4748 : opts.maxStringLength !== null 4749 ) 4750 ) { 4751 throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`'); 4752 } 4753 var customInspect = has$3(opts, 'customInspect') ? opts.customInspect : true; 4754 if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') { 4755 throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`'); 4756 } 4757 4758 if ( 4759 has$3(opts, 'indent') 4760 && opts.indent !== null 4761 && opts.indent !== '\t' 4762 && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0) 4763 ) { 4764 throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`'); 4765 } 4766 if (has$3(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') { 4767 throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`'); 4768 } 4769 var numericSeparator = opts.numericSeparator; 4770 4771 if (typeof obj === 'undefined') { 4772 return 'undefined'; 4773 } 4774 if (obj === null) { 4775 return 'null'; 4776 } 4777 if (typeof obj === 'boolean') { 4778 return obj ? 'true' : 'false'; 4779 } 4780 4781 if (typeof obj === 'string') { 4782 return inspectString(obj, opts); 4783 } 4784 if (typeof obj === 'number') { 4785 if (obj === 0) { 4786 return Infinity / obj > 0 ? '0' : '-0'; 4787 } 4788 var str = String(obj); 4789 return numericSeparator ? addNumericSeparator(obj, str) : str; 4790 } 4791 if (typeof obj === 'bigint') { 4792 var bigIntStr = String(obj) + 'n'; 4793 return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr; 4794 } 4795 4796 var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth; 4797 if (typeof depth === 'undefined') { depth = 0; } 4798 if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') { 4799 return isArray$3(obj) ? '[Array]' : '[Object]'; 4800 } 4801 4802 var indent = getIndent(opts, depth); 4803 4804 if (typeof seen === 'undefined') { 4805 seen = []; 4806 } else if (indexOf(seen, obj) >= 0) { 4807 return '[Circular]'; 4808 } 4809 4810 function inspect(value, from, noIndent) { 4811 if (from) { 4812 seen = $arrSlice.call(seen); 4813 seen.push(from); 4814 } 4815 if (noIndent) { 4816 var newOpts = { 4817 depth: opts.depth 4818 }; 4819 if (has$3(opts, 'quoteStyle')) { 4820 newOpts.quoteStyle = opts.quoteStyle; 4821 } 4822 return inspect_(value, newOpts, depth + 1, seen); 4823 } 4824 return inspect_(value, opts, depth + 1, seen); 4825 } 4826 4827 if (typeof obj === 'function' && !isRegExp$1(obj)) { // in older engines, regexes are callable 4828 var name = nameOf(obj); 4829 var keys = arrObjKeys(obj, inspect); 4830 return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : ''); 4831 } 4832 if (isSymbol(obj)) { 4833 var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj); 4834 return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString; 4835 } 4836 if (isElement(obj)) { 4837 var s = '<' + $toLowerCase.call(String(obj.nodeName)); 4838 var attrs = obj.attributes || []; 4839 for (var i = 0; i < attrs.length; i++) { 4840 s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts); 4841 } 4842 s += '>'; 4843 if (obj.childNodes && obj.childNodes.length) { s += '...'; } 4844 s += '</' + $toLowerCase.call(String(obj.nodeName)) + '>'; 4845 return s; 4846 } 4847 if (isArray$3(obj)) { 4848 if (obj.length === 0) { return '[]'; } 4849 var xs = arrObjKeys(obj, inspect); 4850 if (indent && !singleLineValues(xs)) { 4851 return '[' + indentedJoin(xs, indent) + ']'; 4852 } 4853 return '[ ' + $join.call(xs, ', ') + ' ]'; 4854 } 4855 if (isError(obj)) { 4856 var parts = arrObjKeys(obj, inspect); 4857 if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) { 4858 return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }'; 4859 } 4860 if (parts.length === 0) { return '[' + String(obj) + ']'; } 4861 return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }'; 4862 } 4863 if (typeof obj === 'object' && customInspect) { 4864 if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) { 4865 return utilInspect(obj, { depth: maxDepth - depth }); 4866 } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') { 4867 return obj.inspect(); 4868 } 4869 } 4870 if (isMap(obj)) { 4871 var mapParts = []; 4872 if (mapForEach) { 4873 mapForEach.call(obj, function (value, key) { 4874 mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj)); 4875 }); 4876 } 4877 return collectionOf('Map', mapSize$1.call(obj), mapParts, indent); 4878 } 4879 if (isSet(obj)) { 4880 var setParts = []; 4881 if (setForEach) { 4882 setForEach.call(obj, function (value) { 4883 setParts.push(inspect(value, obj)); 4884 }); 4885 } 4886 return collectionOf('Set', setSize.call(obj), setParts, indent); 4887 } 4888 if (isWeakMap(obj)) { 4889 return weakCollectionOf('WeakMap'); 4890 } 4891 if (isWeakSet(obj)) { 4892 return weakCollectionOf('WeakSet'); 4893 } 4894 if (isWeakRef(obj)) { 4895 return weakCollectionOf('WeakRef'); 4896 } 4897 if (isNumber(obj)) { 4898 return markBoxed(inspect(Number(obj))); 4899 } 4900 if (isBigInt(obj)) { 4901 return markBoxed(inspect(bigIntValueOf.call(obj))); 4902 } 4903 if (isBoolean(obj)) { 4904 return markBoxed(booleanValueOf.call(obj)); 4905 } 4906 if (isString(obj)) { 4907 return markBoxed(inspect(String(obj))); 4908 } 4909 // note: in IE 8, sometimes `global !== window` but both are the prototypes of each other 4910 /* eslint-env browser */ 4911 if (typeof window !== 'undefined' && obj === window) { 4912 return '{ [object Window] }'; 4913 } 4914 if (obj === commonjsGlobal) { 4915 return '{ [object globalThis] }'; 4916 } 4917 if (!isDate(obj) && !isRegExp$1(obj)) { 4918 var ys = arrObjKeys(obj, inspect); 4919 var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object; 4920 var protoTag = obj instanceof Object ? '' : 'null prototype'; 4921 var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : ''; 4922 var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : ''; 4923 var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : ''); 4924 if (ys.length === 0) { return tag + '{}'; } 4925 if (indent) { 4926 return tag + '{' + indentedJoin(ys, indent) + '}'; 4927 } 4928 return tag + '{ ' + $join.call(ys, ', ') + ' }'; 4929 } 4930 return String(obj); 4931}; 4932 4933function wrapQuotes(s, defaultStyle, opts) { 4934 var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '"' : "'"; 4935 return quoteChar + s + quoteChar; 4936} 4937 4938function quote(s) { 4939 return $replace.call(String(s), /"/g, '"'); 4940} 4941 4942function isArray$3(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } 4943function isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } 4944function isRegExp$1(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } 4945function isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } 4946function isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } 4947function isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } 4948function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); } 4949 4950// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives 4951function isSymbol(obj) { 4952 if (hasShammedSymbols) { 4953 return obj && typeof obj === 'object' && obj instanceof Symbol; 4954 } 4955 if (typeof obj === 'symbol') { 4956 return true; 4957 } 4958 if (!obj || typeof obj !== 'object' || !symToString) { 4959 return false; 4960 } 4961 try { 4962 symToString.call(obj); 4963 return true; 4964 } catch (e) {} 4965 return false; 4966} 4967 4968function isBigInt(obj) { 4969 if (!obj || typeof obj !== 'object' || !bigIntValueOf) { 4970 return false; 4971 } 4972 try { 4973 bigIntValueOf.call(obj); 4974 return true; 4975 } catch (e) {} 4976 return false; 4977} 4978 4979var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; }; 4980function has$3(obj, key) { 4981 return hasOwn.call(obj, key); 4982} 4983 4984function toStr(obj) { 4985 return objectToString.call(obj); 4986} 4987 4988function nameOf(f) { 4989 if (f.name) { return f.name; } 4990 var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/); 4991 if (m) { return m[1]; } 4992 return null; 4993} 4994 4995function indexOf(xs, x) { 4996 if (xs.indexOf) { return xs.indexOf(x); } 4997 for (var i = 0, l = xs.length; i < l; i++) { 4998 if (xs[i] === x) { return i; } 4999 } 5000 return -1; 5001} 5002 5003function isMap(x) { 5004 if (!mapSize$1 || !x || typeof x !== 'object') { 5005 return false; 5006 } 5007 try { 5008 mapSize$1.call(x); 5009 try { 5010 setSize.call(x); 5011 } catch (s) { 5012 return true; 5013 } 5014 return x instanceof Map; // core-js workaround, pre-v2.5.0 5015 } catch (e) {} 5016 return false; 5017} 5018 5019function isWeakMap(x) { 5020 if (!weakMapHas || !x || typeof x !== 'object') { 5021 return false; 5022 } 5023 try { 5024 weakMapHas.call(x, weakMapHas); 5025 try { 5026 weakSetHas.call(x, weakSetHas); 5027 } catch (s) { 5028 return true; 5029 } 5030 return x instanceof WeakMap; // core-js workaround, pre-v2.5.0 5031 } catch (e) {} 5032 return false; 5033} 5034 5035function isWeakRef(x) { 5036 if (!weakRefDeref || !x || typeof x !== 'object') { 5037 return false; 5038 } 5039 try { 5040 weakRefDeref.call(x); 5041 return true; 5042 } catch (e) {} 5043 return false; 5044} 5045 5046function isSet(x) { 5047 if (!setSize || !x || typeof x !== 'object') { 5048 return false; 5049 } 5050 try { 5051 setSize.call(x); 5052 try { 5053 mapSize$1.call(x); 5054 } catch (m) { 5055 return true; 5056 } 5057 return x instanceof Set; // core-js workaround, pre-v2.5.0 5058 } catch (e) {} 5059 return false; 5060} 5061 5062function isWeakSet(x) { 5063 if (!weakSetHas || !x || typeof x !== 'object') { 5064 return false; 5065 } 5066 try { 5067 weakSetHas.call(x, weakSetHas); 5068 try { 5069 weakMapHas.call(x, weakMapHas); 5070 } catch (s) { 5071 return true; 5072 } 5073 return x instanceof WeakSet; // core-js workaround, pre-v2.5.0 5074 } catch (e) {} 5075 return false; 5076} 5077 5078function isElement(x) { 5079 if (!x || typeof x !== 'object') { return false; } 5080 if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) { 5081 return true; 5082 } 5083 return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function'; 5084} 5085 5086function inspectString(str, opts) { 5087 if (str.length > opts.maxStringLength) { 5088 var remaining = str.length - opts.maxStringLength; 5089 var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : ''); 5090 return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer; 5091 } 5092 // eslint-disable-next-line no-control-regex 5093 var s = $replace.call($replace.call(str, /(['\\])/g, '\\$1'), /[\x00-\x1f]/g, lowbyte); 5094 return wrapQuotes(s, 'single', opts); 5095} 5096 5097function lowbyte(c) { 5098 var n = c.charCodeAt(0); 5099 var x = { 5100 8: 'b', 5101 9: 't', 5102 10: 'n', 5103 12: 'f', 5104 13: 'r' 5105 }[n]; 5106 if (x) { return '\\' + x; } 5107 return '\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16)); 5108} 5109 5110function markBoxed(str) { 5111 return 'Object(' + str + ')'; 5112} 5113 5114function weakCollectionOf(type) { 5115 return type + ' { ? }'; 5116} 5117 5118function collectionOf(type, size, entries, indent) { 5119 var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', '); 5120 return type + ' (' + size + ') {' + joinedEntries + '}'; 5121} 5122 5123function singleLineValues(xs) { 5124 for (var i = 0; i < xs.length; i++) { 5125 if (indexOf(xs[i], '\n') >= 0) { 5126 return false; 5127 } 5128 } 5129 return true; 5130} 5131 5132function getIndent(opts, depth) { 5133 var baseIndent; 5134 if (opts.indent === '\t') { 5135 baseIndent = '\t'; 5136 } else if (typeof opts.indent === 'number' && opts.indent > 0) { 5137 baseIndent = $join.call(Array(opts.indent + 1), ' '); 5138 } else { 5139 return null; 5140 } 5141 return { 5142 base: baseIndent, 5143 prev: $join.call(Array(depth + 1), baseIndent) 5144 }; 5145} 5146 5147function indentedJoin(xs, indent) { 5148 if (xs.length === 0) { return ''; } 5149 var lineJoiner = '\n' + indent.prev + indent.base; 5150 return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\n' + indent.prev; 5151} 5152 5153function arrObjKeys(obj, inspect) { 5154 var isArr = isArray$3(obj); 5155 var xs = []; 5156 if (isArr) { 5157 xs.length = obj.length; 5158 for (var i = 0; i < obj.length; i++) { 5159 xs[i] = has$3(obj, i) ? inspect(obj[i], obj) : ''; 5160 } 5161 } 5162 var syms = typeof gOPS === 'function' ? gOPS(obj) : []; 5163 var symMap; 5164 if (hasShammedSymbols) { 5165 symMap = {}; 5166 for (var k = 0; k < syms.length; k++) { 5167 symMap['$' + syms[k]] = syms[k]; 5168 } 5169 } 5170 5171 for (var key in obj) { // eslint-disable-line no-restricted-syntax 5172 if (!has$3(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue 5173 if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue 5174 if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) { 5175 // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section 5176 continue; // eslint-disable-line no-restricted-syntax, no-continue 5177 } else if ($test.call(/[^\w$]/, key)) { 5178 xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj)); 5179 } else { 5180 xs.push(key + ': ' + inspect(obj[key], obj)); 5181 } 5182 } 5183 if (typeof gOPS === 'function') { 5184 for (var j = 0; j < syms.length; j++) { 5185 if (isEnumerable.call(obj, syms[j])) { 5186 xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj)); 5187 } 5188 } 5189 } 5190 return xs; 5191} 5192 5193var GetIntrinsic = getIntrinsic; 5194var callBound = callBound$1; 5195var inspect = objectInspect; 5196 5197var $TypeError = GetIntrinsic('%TypeError%'); 5198var $WeakMap = GetIntrinsic('%WeakMap%', true); 5199var $Map = GetIntrinsic('%Map%', true); 5200 5201var $weakMapGet = callBound('WeakMap.prototype.get', true); 5202var $weakMapSet = callBound('WeakMap.prototype.set', true); 5203var $weakMapHas = callBound('WeakMap.prototype.has', true); 5204var $mapGet = callBound('Map.prototype.get', true); 5205var $mapSet = callBound('Map.prototype.set', true); 5206var $mapHas = callBound('Map.prototype.has', true); 5207 5208/* 5209 * This function traverses the list returning the node corresponding to the 5210 * given key. 5211 * 5212 * That node is also moved to the head of the list, so that if it's accessed 5213 * again we don't need to traverse the whole list. By doing so, all the recently 5214 * used nodes can be accessed relatively quickly. 5215 */ 5216var listGetNode = function (list, key) { // eslint-disable-line consistent-return 5217 for (var prev = list, curr; (curr = prev.next) !== null; prev = curr) { 5218 if (curr.key === key) { 5219 prev.next = curr.next; 5220 curr.next = list.next; 5221 list.next = curr; // eslint-disable-line no-param-reassign 5222 return curr; 5223 } 5224 } 5225}; 5226 5227var listGet = function (objects, key) { 5228 var node = listGetNode(objects, key); 5229 return node && node.value; 5230}; 5231var listSet = function (objects, key, value) { 5232 var node = listGetNode(objects, key); 5233 if (node) { 5234 node.value = value; 5235 } else { 5236 // Prepend the new node to the beginning of the list 5237 objects.next = { // eslint-disable-line no-param-reassign 5238 key: key, 5239 next: objects.next, 5240 value: value 5241 }; 5242 } 5243}; 5244var listHas = function (objects, key) { 5245 return !!listGetNode(objects, key); 5246}; 5247 5248var sideChannel = function getSideChannel() { 5249 var $wm; 5250 var $m; 5251 var $o; 5252 var channel = { 5253 assert: function (key) { 5254 if (!channel.has(key)) { 5255 throw new $TypeError('Side channel does not contain ' + inspect(key)); 5256 } 5257 }, 5258 get: function (key) { // eslint-disable-line consistent-return 5259 if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { 5260 if ($wm) { 5261 return $weakMapGet($wm, key); 5262 } 5263 } else if ($Map) { 5264 if ($m) { 5265 return $mapGet($m, key); 5266 } 5267 } else { 5268 if ($o) { // eslint-disable-line no-lonely-if 5269 return listGet($o, key); 5270 } 5271 } 5272 }, 5273 has: function (key) { 5274 if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { 5275 if ($wm) { 5276 return $weakMapHas($wm, key); 5277 } 5278 } else if ($Map) { 5279 if ($m) { 5280 return $mapHas($m, key); 5281 } 5282 } else { 5283 if ($o) { // eslint-disable-line no-lonely-if 5284 return listHas($o, key); 5285 } 5286 } 5287 return false; 5288 }, 5289 set: function (key, value) { 5290 if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { 5291 if (!$wm) { 5292 $wm = new $WeakMap(); 5293 } 5294 $weakMapSet($wm, key, value); 5295 } else if ($Map) { 5296 if (!$m) { 5297 $m = new $Map(); 5298 } 5299 $mapSet($m, key, value); 5300 } else { 5301 if (!$o) { 5302 /* 5303 * Initialize the linked list as an empty node, so that we don't have 5304 * to special-case handling of the first node: we can always refer to 5305 * it as (previous node).next, instead of something like (list).head 5306 */ 5307 $o = { key: {}, next: null }; 5308 } 5309 listSet($o, key, value); 5310 } 5311 } 5312 }; 5313 return channel; 5314}; 5315 5316var replace = String.prototype.replace; 5317var percentTwenties = /%20/g; 5318 5319var Format = { 5320 RFC1738: 'RFC1738', 5321 RFC3986: 'RFC3986' 5322}; 5323 5324var formats$4 = { 5325 'default': Format.RFC3986, 5326 formatters: { 5327 RFC1738: function (value) { 5328 return replace.call(value, percentTwenties, '+'); 5329 }, 5330 RFC3986: function (value) { 5331 return String(value); 5332 } 5333 }, 5334 RFC1738: Format.RFC1738, 5335 RFC3986: Format.RFC3986 5336}; 5337 5338var formats$3 = formats$4; 5339 5340var has$2 = Object.prototype.hasOwnProperty; 5341var isArray$2 = Array.isArray; 5342 5343var hexTable = (function () { 5344 var array = []; 5345 for (var i = 0; i < 256; ++i) { 5346 array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); 5347 } 5348 5349 return array; 5350}()); 5351 5352var compactQueue = function compactQueue(queue) { 5353 while (queue.length > 1) { 5354 var item = queue.pop(); 5355 var obj = item.obj[item.prop]; 5356 5357 if (isArray$2(obj)) { 5358 var compacted = []; 5359 5360 for (var j = 0; j < obj.length; ++j) { 5361 if (typeof obj[j] !== 'undefined') { 5362 compacted.push(obj[j]); 5363 } 5364 } 5365 5366 item.obj[item.prop] = compacted; 5367 } 5368 } 5369}; 5370 5371var arrayToObject = function arrayToObject(source, options) { 5372 var obj = options && options.plainObjects ? Object.create(null) : {}; 5373 for (var i = 0; i < source.length; ++i) { 5374 if (typeof source[i] !== 'undefined') { 5375 obj[i] = source[i]; 5376 } 5377 } 5378 5379 return obj; 5380}; 5381 5382var merge = function merge(target, source, options) { 5383 /* eslint no-param-reassign: 0 */ 5384 if (!source) { 5385 return target; 5386 } 5387 5388 if (typeof source !== 'object') { 5389 if (isArray$2(target)) { 5390 target.push(source); 5391 } else if (target && typeof target === 'object') { 5392 if ((options && (options.plainObjects || options.allowPrototypes)) || !has$2.call(Object.prototype, source)) { 5393 target[source] = true; 5394 } 5395 } else { 5396 return [target, source]; 5397 } 5398 5399 return target; 5400 } 5401 5402 if (!target || typeof target !== 'object') { 5403 return [target].concat(source); 5404 } 5405 5406 var mergeTarget = target; 5407 if (isArray$2(target) && !isArray$2(source)) { 5408 mergeTarget = arrayToObject(target, options); 5409 } 5410 5411 if (isArray$2(target) && isArray$2(source)) { 5412 source.forEach(function (item, i) { 5413 if (has$2.call(target, i)) { 5414 var targetItem = target[i]; 5415 if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') { 5416 target[i] = merge(targetItem, item, options); 5417 } else { 5418 target.push(item); 5419 } 5420 } else { 5421 target[i] = item; 5422 } 5423 }); 5424 return target; 5425 } 5426 5427 return Object.keys(source).reduce(function (acc, key) { 5428 var value = source[key]; 5429 5430 if (has$2.call(acc, key)) { 5431 acc[key] = merge(acc[key], value, options); 5432 } else { 5433 acc[key] = value; 5434 } 5435 return acc; 5436 }, mergeTarget); 5437}; 5438 5439var assign$1 = function assignSingleSource(target, source) { 5440 return Object.keys(source).reduce(function (acc, key) { 5441 acc[key] = source[key]; 5442 return acc; 5443 }, target); 5444}; 5445 5446var decode = function (str, decoder, charset) { 5447 var strWithoutPlus = str.replace(/\+/g, ' '); 5448 if (charset === 'iso-8859-1') { 5449 // unescape never throws, no try...catch needed: 5450 return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape); 5451 } 5452 // utf-8 5453 try { 5454 return decodeURIComponent(strWithoutPlus); 5455 } catch (e) { 5456 return strWithoutPlus; 5457 } 5458}; 5459 5460var encode = function encode(str, defaultEncoder, charset, kind, format) { 5461 // This code was originally written by Brian White (mscdex) for the io.js core querystring library. 5462 // It has been adapted here for stricter adherence to RFC 3986 5463 if (str.length === 0) { 5464 return str; 5465 } 5466 5467 var string = str; 5468 if (typeof str === 'symbol') { 5469 string = Symbol.prototype.toString.call(str); 5470 } else if (typeof str !== 'string') { 5471 string = String(str); 5472 } 5473 5474 if (charset === 'iso-8859-1') { 5475 return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { 5476 return '%26%23' + parseInt($0.slice(2), 16) + '%3B'; 5477 }); 5478 } 5479 5480 var out = ''; 5481 for (var i = 0; i < string.length; ++i) { 5482 var c = string.charCodeAt(i); 5483 5484 if ( 5485 c === 0x2D // - 5486 || c === 0x2E // . 5487 || c === 0x5F // _ 5488 || c === 0x7E // ~ 5489 || (c >= 0x30 && c <= 0x39) // 0-9 5490 || (c >= 0x41 && c <= 0x5A) // a-z 5491 || (c >= 0x61 && c <= 0x7A) // A-Z 5492 || (format === formats$3.RFC1738 && (c === 0x28 || c === 0x29)) // ( ) 5493 ) { 5494 out += string.charAt(i); 5495 continue; 5496 } 5497 5498 if (c < 0x80) { 5499 out = out + hexTable[c]; 5500 continue; 5501 } 5502 5503 if (c < 0x800) { 5504 out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); 5505 continue; 5506 } 5507 5508 if (c < 0xD800 || c >= 0xE000) { 5509 out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); 5510 continue; 5511 } 5512 5513 i += 1; 5514 c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); 5515 /* eslint operator-linebreak: [2, "before"] */ 5516 out += hexTable[0xF0 | (c >> 18)] 5517 + hexTable[0x80 | ((c >> 12) & 0x3F)] 5518 + hexTable[0x80 | ((c >> 6) & 0x3F)] 5519 + hexTable[0x80 | (c & 0x3F)]; 5520 } 5521 5522 return out; 5523}; 5524 5525var compact = function compact(value) { 5526 var queue = [{ obj: { o: value }, prop: 'o' }]; 5527 var refs = []; 5528 5529 for (var i = 0; i < queue.length; ++i) { 5530 var item = queue[i]; 5531 var obj = item.obj[item.prop]; 5532 5533 var keys = Object.keys(obj); 5534 for (var j = 0; j < keys.length; ++j) { 5535 var key = keys[j]; 5536 var val = obj[key]; 5537 if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { 5538 queue.push({ obj: obj, prop: key }); 5539 refs.push(val); 5540 } 5541 } 5542 } 5543 5544 compactQueue(queue); 5545 5546 return value; 5547}; 5548 5549var isRegExp = function isRegExp(obj) { 5550 return Object.prototype.toString.call(obj) === '[object RegExp]'; 5551}; 5552 5553var isBuffer = function isBuffer(obj) { 5554 if (!obj || typeof obj !== 'object') { 5555 return false; 5556 } 5557 5558 return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); 5559}; 5560 5561var combine = function combine(a, b) { 5562 return [].concat(a, b); 5563}; 5564 5565var maybeMap = function maybeMap(val, fn) { 5566 if (isArray$2(val)) { 5567 var mapped = []; 5568 for (var i = 0; i < val.length; i += 1) { 5569 mapped.push(fn(val[i])); 5570 } 5571 return mapped; 5572 } 5573 return fn(val); 5574}; 5575 5576var utils$2 = { 5577 arrayToObject: arrayToObject, 5578 assign: assign$1, 5579 combine: combine, 5580 compact: compact, 5581 decode: decode, 5582 encode: encode, 5583 isBuffer: isBuffer, 5584 isRegExp: isRegExp, 5585 maybeMap: maybeMap, 5586 merge: merge 5587}; 5588 5589var getSideChannel = sideChannel; 5590var utils$1 = utils$2; 5591var formats$2 = formats$4; 5592var has$1 = Object.prototype.hasOwnProperty; 5593 5594var arrayPrefixGenerators = { 5595 brackets: function brackets(prefix) { 5596 return prefix + '[]'; 5597 }, 5598 comma: 'comma', 5599 indices: function indices(prefix, key) { 5600 return prefix + '[' + key + ']'; 5601 }, 5602 repeat: function repeat(prefix) { 5603 return prefix; 5604 } 5605}; 5606 5607var isArray$1 = Array.isArray; 5608var push = Array.prototype.push; 5609var pushToArray = function (arr, valueOrArray) { 5610 push.apply(arr, isArray$1(valueOrArray) ? valueOrArray : [valueOrArray]); 5611}; 5612 5613var toISO = Date.prototype.toISOString; 5614 5615var defaultFormat = formats$2['default']; 5616var defaults$1 = { 5617 addQueryPrefix: false, 5618 allowDots: false, 5619 charset: 'utf-8', 5620 charsetSentinel: false, 5621 delimiter: '&', 5622 encode: true, 5623 encoder: utils$1.encode, 5624 encodeValuesOnly: false, 5625 format: defaultFormat, 5626 formatter: formats$2.formatters[defaultFormat], 5627 // deprecated 5628 indices: false, 5629 serializeDate: function serializeDate(date) { 5630 return toISO.call(date); 5631 }, 5632 skipNulls: false, 5633 strictNullHandling: false 5634}; 5635 5636var isNonNullishPrimitive = function isNonNullishPrimitive(v) { 5637 return typeof v === 'string' 5638 || typeof v === 'number' 5639 || typeof v === 'boolean' 5640 || typeof v === 'symbol' 5641 || typeof v === 'bigint'; 5642}; 5643 5644var sentinel = {}; 5645 5646var stringify$1 = function stringify( 5647 object, 5648 prefix, 5649 generateArrayPrefix, 5650 commaRoundTrip, 5651 strictNullHandling, 5652 skipNulls, 5653 encoder, 5654 filter, 5655 sort, 5656 allowDots, 5657 serializeDate, 5658 format, 5659 formatter, 5660 encodeValuesOnly, 5661 charset, 5662 sideChannel 5663) { 5664 var obj = object; 5665 5666 var tmpSc = sideChannel; 5667 var step = 0; 5668 var findFlag = false; 5669 while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) { 5670 // Where object last appeared in the ref tree 5671 var pos = tmpSc.get(object); 5672 step += 1; 5673 if (typeof pos !== 'undefined') { 5674 if (pos === step) { 5675 throw new RangeError('Cyclic object value'); 5676 } else { 5677 findFlag = true; // Break while 5678 } 5679 } 5680 if (typeof tmpSc.get(sentinel) === 'undefined') { 5681 step = 0; 5682 } 5683 } 5684 5685 if (typeof filter === 'function') { 5686 obj = filter(prefix, obj); 5687 } else if (obj instanceof Date) { 5688 obj = serializeDate(obj); 5689 } else if (generateArrayPrefix === 'comma' && isArray$1(obj)) { 5690 obj = utils$1.maybeMap(obj, function (value) { 5691 if (value instanceof Date) { 5692 return serializeDate(value); 5693 } 5694 return value; 5695 }); 5696 } 5697 5698 if (obj === null) { 5699 if (strictNullHandling) { 5700 return encoder && !encodeValuesOnly ? encoder(prefix, defaults$1.encoder, charset, 'key', format) : prefix; 5701 } 5702 5703 obj = ''; 5704 } 5705 5706 if (isNonNullishPrimitive(obj) || utils$1.isBuffer(obj)) { 5707 if (encoder) { 5708 var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults$1.encoder, charset, 'key', format); 5709 return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults$1.encoder, charset, 'value', format))]; 5710 } 5711 return [formatter(prefix) + '=' + formatter(String(obj))]; 5712 } 5713 5714 var values = []; 5715 5716 if (typeof obj === 'undefined') { 5717 return values; 5718 } 5719 5720 var objKeys; 5721 if (generateArrayPrefix === 'comma' && isArray$1(obj)) { 5722 // we need to join elements in 5723 if (encodeValuesOnly && encoder) { 5724 obj = utils$1.maybeMap(obj, encoder); 5725 } 5726 objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }]; 5727 } else if (isArray$1(filter)) { 5728 objKeys = filter; 5729 } else { 5730 var keys = Object.keys(obj); 5731 objKeys = sort ? keys.sort(sort) : keys; 5732 } 5733 5734 var adjustedPrefix = commaRoundTrip && isArray$1(obj) && obj.length === 1 ? prefix + '[]' : prefix; 5735 5736 for (var j = 0; j < objKeys.length; ++j) { 5737 var key = objKeys[j]; 5738 var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key]; 5739 5740 if (skipNulls && value === null) { 5741 continue; 5742 } 5743 5744 var keyPrefix = isArray$1(obj) 5745 ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, key) : adjustedPrefix 5746 : adjustedPrefix + (allowDots ? '.' + key : '[' + key + ']'); 5747 5748 sideChannel.set(object, step); 5749 var valueSideChannel = getSideChannel(); 5750 valueSideChannel.set(sentinel, sideChannel); 5751 pushToArray(values, stringify( 5752 value, 5753 keyPrefix, 5754 generateArrayPrefix, 5755 commaRoundTrip, 5756 strictNullHandling, 5757 skipNulls, 5758 generateArrayPrefix === 'comma' && encodeValuesOnly && isArray$1(obj) ? null : encoder, 5759 filter, 5760 sort, 5761 allowDots, 5762 serializeDate, 5763 format, 5764 formatter, 5765 encodeValuesOnly, 5766 charset, 5767 valueSideChannel 5768 )); 5769 } 5770 5771 return values; 5772}; 5773 5774var normalizeStringifyOptions = function normalizeStringifyOptions(opts) { 5775 if (!opts) { 5776 return defaults$1; 5777 } 5778 5779 if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') { 5780 throw new TypeError('Encoder has to be a function.'); 5781 } 5782 5783 var charset = opts.charset || defaults$1.charset; 5784 if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { 5785 throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); 5786 } 5787 5788 var format = formats$2['default']; 5789 if (typeof opts.format !== 'undefined') { 5790 if (!has$1.call(formats$2.formatters, opts.format)) { 5791 throw new TypeError('Unknown format option provided.'); 5792 } 5793 format = opts.format; 5794 } 5795 var formatter = formats$2.formatters[format]; 5796 5797 var filter = defaults$1.filter; 5798 if (typeof opts.filter === 'function' || isArray$1(opts.filter)) { 5799 filter = opts.filter; 5800 } 5801 5802 return { 5803 addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults$1.addQueryPrefix, 5804 allowDots: typeof opts.allowDots === 'undefined' ? defaults$1.allowDots : !!opts.allowDots, 5805 charset: charset, 5806 charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults$1.charsetSentinel, 5807 delimiter: typeof opts.delimiter === 'undefined' ? defaults$1.delimiter : opts.delimiter, 5808 encode: typeof opts.encode === 'boolean' ? opts.encode : defaults$1.encode, 5809 encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults$1.encoder, 5810 encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults$1.encodeValuesOnly, 5811 filter: filter, 5812 format: format, 5813 formatter: formatter, 5814 serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults$1.serializeDate, 5815 skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults$1.skipNulls, 5816 sort: typeof opts.sort === 'function' ? opts.sort : null, 5817 strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults$1.strictNullHandling 5818 }; 5819}; 5820 5821var stringify_1 = function (object, opts) { 5822 var obj = object; 5823 var options = normalizeStringifyOptions(opts); 5824 5825 var objKeys; 5826 var filter; 5827 5828 if (typeof options.filter === 'function') { 5829 filter = options.filter; 5830 obj = filter('', obj); 5831 } else if (isArray$1(options.filter)) { 5832 filter = options.filter; 5833 objKeys = filter; 5834 } 5835 5836 var keys = []; 5837 5838 if (typeof obj !== 'object' || obj === null) { 5839 return ''; 5840 } 5841 5842 var arrayFormat; 5843 if (opts && opts.arrayFormat in arrayPrefixGenerators) { 5844 arrayFormat = opts.arrayFormat; 5845 } else if (opts && 'indices' in opts) { 5846 arrayFormat = opts.indices ? 'indices' : 'repeat'; 5847 } else { 5848 arrayFormat = 'indices'; 5849 } 5850 5851 var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; 5852 if (opts && 'commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') { 5853 throw new TypeError('`commaRoundTrip` must be a boolean, or absent'); 5854 } 5855 var commaRoundTrip = generateArrayPrefix === 'comma' && opts && opts.commaRoundTrip; 5856 5857 if (!objKeys) { 5858 objKeys = Object.keys(obj); 5859 } 5860 5861 if (options.sort) { 5862 objKeys.sort(options.sort); 5863 } 5864 5865 var sideChannel = getSideChannel(); 5866 for (var i = 0; i < objKeys.length; ++i) { 5867 var key = objKeys[i]; 5868 5869 if (options.skipNulls && obj[key] === null) { 5870 continue; 5871 } 5872 pushToArray(keys, stringify$1( 5873 obj[key], 5874 key, 5875 generateArrayPrefix, 5876 commaRoundTrip, 5877 options.strictNullHandling, 5878 options.skipNulls, 5879 options.encode ? options.encoder : null, 5880 options.filter, 5881 options.sort, 5882 options.allowDots, 5883 options.serializeDate, 5884 options.format, 5885 options.formatter, 5886 options.encodeValuesOnly, 5887 options.charset, 5888 sideChannel 5889 )); 5890 } 5891 5892 var joined = keys.join(options.delimiter); 5893 var prefix = options.addQueryPrefix === true ? '?' : ''; 5894 5895 if (options.charsetSentinel) { 5896 if (options.charset === 'iso-8859-1') { 5897 // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark 5898 prefix += 'utf8=%26%2310003%3B&'; 5899 } else { 5900 // encodeURIComponent('✓') 5901 prefix += 'utf8=%E2%9C%93&'; 5902 } 5903 } 5904 5905 return joined.length > 0 ? prefix + joined : ''; 5906}; 5907 5908var utils = utils$2; 5909 5910var has = Object.prototype.hasOwnProperty; 5911var isArray = Array.isArray; 5912 5913var defaults = { 5914 allowDots: false, 5915 allowPrototypes: false, 5916 allowSparse: false, 5917 arrayLimit: 20, 5918 charset: 'utf-8', 5919 charsetSentinel: false, 5920 comma: false, 5921 decoder: utils.decode, 5922 delimiter: '&', 5923 depth: 5, 5924 ignoreQueryPrefix: false, 5925 interpretNumericEntities: false, 5926 parameterLimit: 1000, 5927 parseArrays: true, 5928 plainObjects: false, 5929 strictNullHandling: false 5930}; 5931 5932var interpretNumericEntities = function (str) { 5933 return str.replace(/&#(\d+);/g, function ($0, numberStr) { 5934 return String.fromCharCode(parseInt(numberStr, 10)); 5935 }); 5936}; 5937 5938var parseArrayValue = function (val, options) { 5939 if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) { 5940 return val.split(','); 5941 } 5942 5943 return val; 5944}; 5945 5946// This is what browsers will submit when the ✓ character occurs in an 5947// application/x-www-form-urlencoded body and the encoding of the page containing 5948// the form is iso-8859-1, or when the submitted form has an accept-charset 5949// attribute of iso-8859-1. Presumably also with other charsets that do not contain 5950// the ✓ character, such as us-ascii. 5951var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓') 5952 5953// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded. 5954var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓') 5955 5956var parseValues = function parseQueryStringValues(str, options) { 5957 var obj = { __proto__: null }; 5958 5959 var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str; 5960 var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit; 5961 var parts = cleanStr.split(options.delimiter, limit); 5962 var skipIndex = -1; // Keep track of where the utf8 sentinel was found 5963 var i; 5964 5965 var charset = options.charset; 5966 if (options.charsetSentinel) { 5967 for (i = 0; i < parts.length; ++i) { 5968 if (parts[i].indexOf('utf8=') === 0) { 5969 if (parts[i] === charsetSentinel) { 5970 charset = 'utf-8'; 5971 } else if (parts[i] === isoSentinel) { 5972 charset = 'iso-8859-1'; 5973 } 5974 skipIndex = i; 5975 i = parts.length; // The eslint settings do not allow break; 5976 } 5977 } 5978 } 5979 5980 for (i = 0; i < parts.length; ++i) { 5981 if (i === skipIndex) { 5982 continue; 5983 } 5984 var part = parts[i]; 5985 5986 var bracketEqualsPos = part.indexOf(']='); 5987 var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1; 5988 5989 var key, val; 5990 if (pos === -1) { 5991 key = options.decoder(part, defaults.decoder, charset, 'key'); 5992 val = options.strictNullHandling ? null : ''; 5993 } else { 5994 key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key'); 5995 val = utils.maybeMap( 5996 parseArrayValue(part.slice(pos + 1), options), 5997 function (encodedVal) { 5998 return options.decoder(encodedVal, defaults.decoder, charset, 'value'); 5999 } 6000 ); 6001 } 6002 6003 if (val && options.interpretNumericEntities && charset === 'iso-8859-1') { 6004 val = interpretNumericEntities(val); 6005 } 6006 6007 if (part.indexOf('[]=') > -1) { 6008 val = isArray(val) ? [val] : val; 6009 } 6010 6011 if (has.call(obj, key)) { 6012 obj[key] = utils.combine(obj[key], val); 6013 } else { 6014 obj[key] = val; 6015 } 6016 } 6017 6018 return obj; 6019}; 6020 6021var parseObject = function (chain, val, options, valuesParsed) { 6022 var leaf = valuesParsed ? val : parseArrayValue(val, options); 6023 6024 for (var i = chain.length - 1; i >= 0; --i) { 6025 var obj; 6026 var root = chain[i]; 6027 6028 if (root === '[]' && options.parseArrays) { 6029 obj = [].concat(leaf); 6030 } else { 6031 obj = options.plainObjects ? Object.create(null) : {}; 6032 var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root; 6033 var index = parseInt(cleanRoot, 10); 6034 if (!options.parseArrays && cleanRoot === '') { 6035 obj = { 0: leaf }; 6036 } else if ( 6037 !isNaN(index) 6038 && root !== cleanRoot 6039 && String(index) === cleanRoot 6040 && index >= 0 6041 && (options.parseArrays && index <= options.arrayLimit) 6042 ) { 6043 obj = []; 6044 obj[index] = leaf; 6045 } else if (cleanRoot !== '__proto__') { 6046 obj[cleanRoot] = leaf; 6047 } 6048 } 6049 6050 leaf = obj; 6051 } 6052 6053 return leaf; 6054}; 6055 6056var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) { 6057 if (!givenKey) { 6058 return; 6059 } 6060 6061 // Transform dot notation to bracket notation 6062 var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; 6063 6064 // The regex chunks 6065 6066 var brackets = /(\[[^[\]]*])/; 6067 var child = /(\[[^[\]]*])/g; 6068 6069 // Get the parent 6070 6071 var segment = options.depth > 0 && brackets.exec(key); 6072 var parent = segment ? key.slice(0, segment.index) : key; 6073 6074 // Stash the parent if it exists 6075 6076 var keys = []; 6077 if (parent) { 6078 // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties 6079 if (!options.plainObjects && has.call(Object.prototype, parent)) { 6080 if (!options.allowPrototypes) { 6081 return; 6082 } 6083 } 6084 6085 keys.push(parent); 6086 } 6087 6088 // Loop through children appending to the array until we hit depth 6089 6090 var i = 0; 6091 while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) { 6092 i += 1; 6093 if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) { 6094 if (!options.allowPrototypes) { 6095 return; 6096 } 6097 } 6098 keys.push(segment[1]); 6099 } 6100 6101 // If there's a remainder, just add whatever is left 6102 6103 if (segment) { 6104 keys.push('[' + key.slice(segment.index) + ']'); 6105 } 6106 6107 return parseObject(keys, val, options, valuesParsed); 6108}; 6109 6110var normalizeParseOptions = function normalizeParseOptions(opts) { 6111 if (!opts) { 6112 return defaults; 6113 } 6114 6115 if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') { 6116 throw new TypeError('Decoder has to be a function.'); 6117 } 6118 6119 if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { 6120 throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); 6121 } 6122 var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset; 6123 6124 return { 6125 allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots, 6126 allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes, 6127 allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse, 6128 arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit, 6129 charset: charset, 6130 charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, 6131 comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma, 6132 decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder, 6133 delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter, 6134 // eslint-disable-next-line no-implicit-coercion, no-extra-parens 6135 depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth, 6136 ignoreQueryPrefix: opts.ignoreQueryPrefix === true, 6137 interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities, 6138 parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit, 6139 parseArrays: opts.parseArrays !== false, 6140 plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
vendor: 6,406 bytes, lines 6141-6358
6141 strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling 6142 }; 6143}; 6144 6145var parse$1 = function (str, opts) { 6146 var options = normalizeParseOptions(opts); 6147 6148 if (str === '' || str === null || typeof str === 'undefined') { 6149 return options.plainObjects ? Object.create(null) : {}; 6150 } 6151 6152 var tempObj = typeof str === 'string' ? parseValues(str, options) : str; 6153 var obj = options.plainObjects ? Object.create(null) : {}; 6154 6155 // Iterate over the keys and setup the new object 6156 6157 var keys = Object.keys(tempObj); 6158 for (var i = 0; i < keys.length; ++i) { 6159 var key = keys[i]; 6160 var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string'); 6161 obj = utils.merge(obj, newObj, options); 6162 } 6163 6164 if (options.allowSparse === true) { 6165 return obj; 6166 } 6167 6168 return utils.compact(obj); 6169}; 6170 6171var stringify = stringify_1; 6172var parse = parse$1; 6173var formats$1 = formats$4; 6174 6175var lib = { 6176 formats: formats$1, 6177 parse: parse, 6178 stringify: stringify 6179}; 6180 6181/* 6182 * Copyright Joyent, Inc. and other Node contributors. 6183 * 6184 * Permission is hereby granted, free of charge, to any person obtaining a 6185 * copy of this software and associated documentation files (the 6186 * "Software"), to deal in the Software without restriction, including 6187 * without limitation the rights to use, copy, modify, merge, publish, 6188 * distribute, sublicense, and/or sell copies of the Software, and to permit 6189 * persons to whom the Software is furnished to do so, subject to the 6190 * following conditions: 6191 * 6192 * The above copyright notice and this permission notice shall be included 6193 * in all copies or substantial portions of the Software. 6194 * 6195 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 6196 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 6197 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 6198 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 6199 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 6200 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 6201 * USE OR OTHER DEALINGS IN THE SOFTWARE. 6202 */ 6203 6204var punycode = punycodeExports; 6205 6206function Url() { 6207 this.protocol = null; 6208 this.slashes = null; 6209 this.auth = null; 6210 this.host = null; 6211 this.port = null; 6212 this.hostname = null; 6213 this.hash = null; 6214 this.search = null; 6215 this.query = null; 6216 this.pathname = null; 6217 this.path = null; 6218 this.href = null; 6219} 6220 6221// Reference: RFC 3986, RFC 1808, RFC 2396 6222 6223/* 6224 * define these here so at least they only have to be 6225 * compiled once on the first module load. 6226 */ 6227var protocolPattern = /^([a-z0-9.+-]+:)/i, 6228 portPattern = /:[0-9]*$/, 6229 6230 // Special case for a simple path URL 6231 simplePathPattern = /^(\/\/?(?!\/)[^?\s]*)(\?[^\s]*)?$/, 6232 6233 /* 6234 * RFC 2396: characters reserved for delimiting URLs. 6235 * We actually just auto-escape these. 6236 */ 6237 delims = [ 6238 '<', '>', '"', '`', ' ', '\r', '\n', '\t' 6239 ], 6240 6241 // RFC 2396: characters not allowed for various reasons. 6242 unwise = [ 6243 '{', '}', '|', '\\', '^', '`' 6244 ].concat(delims), 6245 6246 // Allowed by RFCs, but cause of XSS attacks. Always escape these. 6247 autoEscape = ['\''].concat(unwise), 6248 /* 6249 * Characters that are never ever allowed in a hostname. 6250 * Note that any invalid chars are also handled, but these 6251 * are the ones that are *expected* to be seen, so we fast-path 6252 * them. 6253 */ 6254 nonHostChars = [ 6255 '%', '/', '?', ';', '#' 6256 ].concat(autoEscape), 6257 hostEndingChars = [ 6258 '/', '?', '#' 6259 ], 6260 hostnameMaxLen = 255, 6261 hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, 6262 hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, 6263 // protocols that can allow "unsafe" and "unwise" chars. 6264 unsafeProtocol = { 6265 javascript: true, 6266 'javascript:': true 6267 }, 6268 // protocols that never have a hostname. 6269 hostlessProtocol = { 6270 javascript: true, 6271 'javascript:': true 6272 }, 6273 // protocols that always contain a // bit. 6274 slashedProtocol = { 6275 http: true, 6276 https: true, 6277 ftp: true, 6278 gopher: true, 6279 file: true, 6280 'http:': true, 6281 'https:': true, 6282 'ftp:': true, 6283 'gopher:': true, 6284 'file:': true 6285 }, 6286 querystring = lib; 6287 6288function urlParse(url, parseQueryString, slashesDenoteHost) { 6289 if (url && typeof url === 'object' && url instanceof Url) { return url; } 6290 6291 var u = new Url(); 6292 u.parse(url, parseQueryString, slashesDenoteHost); 6293 return u; 6294} 6295 6296Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) { 6297 if (typeof url !== 'string') { 6298 throw new TypeError("Parameter 'url' must be a string, not " + typeof url); 6299 } 6300 6301 /* 6302 * Copy chrome, IE, opera backslash-handling behavior. 6303 * Back slashes before the query string get converted to forward slashes 6304 * See: https://code.google.com/p/chromium/issues/detail?id=25916 6305 */ 6306 var queryIndex = url.indexOf('?'), 6307 splitter = queryIndex !== -1 && queryIndex < url.indexOf('#') ? '?' : '#', 6308 uSplit = url.split(splitter), 6309 slashRegex = /\\/g; 6310 uSplit[0] = uSplit[0].replace(slashRegex, '/'); 6311 url = uSplit.join(splitter); 6312 6313 var rest = url; 6314 6315 /* 6316 * trim before proceeding. 6317 * This is to support parse stuff like " http://foo.com \n" 6318 */ 6319 rest = rest.trim(); 6320 6321 if (!slashesDenoteHost && url.split('#').length === 1) { 6322 // Try fast path regexp 6323 var simplePath = simplePathPattern.exec(rest); 6324 if (simplePath) { 6325 this.path = rest; 6326 this.href = rest; 6327 this.pathname = simplePath[1]; 6328 if (simplePath[2]) { 6329 this.search = simplePath[2]; 6330 if (parseQueryString) { 6331 this.query = querystring.parse(this.search.substr(1)); 6332 } else { 6333 this.query = this.search.substr(1); 6334 } 6335 } else if (parseQueryString) { 6336 this.search = ''; 6337 this.query = {}; 6338 } 6339 return this; 6340 } 6341 } 6342 6343 var proto = protocolPattern.exec(rest); 6344 if (proto) { 6345 proto = proto[0]; 6346 var lowerProto = proto.toLowerCase(); 6347 this.protocol = lowerProto; 6348 rest = rest.substr(proto.length); 6349 } 6350 6351 /* 6352 * figure out if it's got a host 6353 * user@server is *always* interpreted as a hostname, and url 6354 * resolution will treat //foo/bar as host=foo,path=bar because that's 6355 * how the browser resolves relative URLs. 6356 */ 6357 if (slashesDenoteHost || proto || rest.match(/^\/\/[^@/]+@[^@/]+/)) { 6358 var slashes = rest.substr(0, 2) === '//';
vendor: 5,579 bytes, lines 6359-6544
6359 if (slashes && !(proto && hostlessProtocol[proto])) { 6360 rest = rest.substr(2); 6361 this.slashes = true; 6362 } 6363 } 6364 6365 if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) { 6366 6367 /* 6368 * there's a hostname. 6369 * the first instance of /, ?, ;, or # ends the host. 6370 * 6371 * If there is an @ in the hostname, then non-host chars *are* allowed 6372 * to the left of the last @ sign, unless some host-ending character 6373 * comes *before* the @-sign. 6374 * URLs are obnoxious. 6375 * 6376 * ex: 6377 * http://a@b@c/ => user:a@b host:c 6378 * http://a@b?@c => user:a host:c path:/?@c 6379 */ 6380 6381 /* 6382 * v0.12 TODO(isaacs): This is not quite how Chrome does things. 6383 * Review our test case against browsers more comprehensively. 6384 */ 6385 6386 // find the first instance of any hostEndingChars 6387 var hostEnd = -1; 6388 for (var i = 0; i < hostEndingChars.length; i++) { 6389 var hec = rest.indexOf(hostEndingChars[i]); 6390 if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; } 6391 } 6392 6393 /* 6394 * at this point, either we have an explicit point where the 6395 * auth portion cannot go past, or the last @ char is the decider. 6396 */ 6397 var auth, atSign; 6398 if (hostEnd === -1) { 6399 // atSign can be anywhere. 6400 atSign = rest.lastIndexOf('@'); 6401 } else { 6402 /* 6403 * atSign must be in auth portion. 6404 * http://a@b/c@d => host:b auth:a path:/c@d 6405 */ 6406 atSign = rest.lastIndexOf('@', hostEnd); 6407 } 6408 6409 /* 6410 * Now we have a portion which is definitely the auth. 6411 * Pull that off. 6412 */ 6413 if (atSign !== -1) { 6414 auth = rest.slice(0, atSign); 6415 rest = rest.slice(atSign + 1); 6416 this.auth = decodeURIComponent(auth); 6417 } 6418 6419 // the host is the remaining to the left of the first non-host char 6420 hostEnd = -1; 6421 for (var i = 0; i < nonHostChars.length; i++) { 6422 var hec = rest.indexOf(nonHostChars[i]); 6423 if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; } 6424 } 6425 // if we still have not hit it, then the entire thing is a host. 6426 if (hostEnd === -1) { hostEnd = rest.length; } 6427 6428 this.host = rest.slice(0, hostEnd); 6429 rest = rest.slice(hostEnd); 6430 6431 // pull out port. 6432 this.parseHost(); 6433 6434 /* 6435 * we've indicated that there is a hostname, 6436 * so even if it's empty, it has to be present. 6437 */ 6438 this.hostname = this.hostname || ''; 6439 6440 /* 6441 * if hostname begins with [ and ends with ] 6442 * assume that it's an IPv6 address. 6443 */ 6444 var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']'; 6445 6446 // validate a little. 6447 if (!ipv6Hostname) { 6448 var hostparts = this.hostname.split(/\./); 6449 for (var i = 0, l = hostparts.length; i < l; i++) { 6450 var part = hostparts[i]; 6451 if (!part) { continue; } 6452 if (!part.match(hostnamePartPattern)) { 6453 var newpart = ''; 6454 for (var j = 0, k = part.length; j < k; j++) { 6455 if (part.charCodeAt(j) > 127) { 6456 /* 6457 * we replace non-ASCII char with a temporary placeholder 6458 * we need this to make sure size of hostname is not 6459 * broken by replacing non-ASCII by nothing 6460 */ 6461 newpart += 'x'; 6462 } else { 6463 newpart += part[j]; 6464 } 6465 } 6466 // we test again with ASCII char only 6467 if (!newpart.match(hostnamePartPattern)) { 6468 var validParts = hostparts.slice(0, i); 6469 var notHost = hostparts.slice(i + 1); 6470 var bit = part.match(hostnamePartStart); 6471 if (bit) { 6472 validParts.push(bit[1]); 6473 notHost.unshift(bit[2]); 6474 } 6475 if (notHost.length) { 6476 rest = '/' + notHost.join('.') + rest; 6477 } 6478 this.hostname = validParts.join('.'); 6479 break; 6480 } 6481 } 6482 } 6483 } 6484 6485 if (this.hostname.length > hostnameMaxLen) { 6486 this.hostname = ''; 6487 } else { 6488 // hostnames are always lower case. 6489 this.hostname = this.hostname.toLowerCase(); 6490 } 6491 6492 if (!ipv6Hostname) { 6493 /* 6494 * IDNA Support: Returns a punycoded representation of "domain". 6495 * It only converts parts of the domain name that 6496 * have non-ASCII characters, i.e. it doesn't matter if 6497 * you call it with a domain that already is ASCII-only. 6498 */ 6499 this.hostname = punycode.toASCII(this.hostname); 6500 } 6501 6502 var p = this.port ? ':' + this.port : ''; 6503 var h = this.hostname || ''; 6504 this.host = h + p; 6505 this.href += this.host; 6506 6507 /* 6508 * strip [ and ] from the hostname 6509 * the host field still retains them, though 6510 */ 6511 if (ipv6Hostname) { 6512 this.hostname = this.hostname.substr(1, this.hostname.length - 2); 6513 if (rest[0] !== '/') { 6514 rest = '/' + rest; 6515 } 6516 } 6517 } 6518 6519 /* 6520 * now rest is set to the post-host stuff. 6521 * chop off any delim chars. 6522 */ 6523 if (!unsafeProtocol[lowerProto]) { 6524 6525 /* 6526 * First, make 100% sure that any "autoEscape" chars get 6527 * escaped, even if encodeURIComponent doesn't think they 6528 * need to be. 6529 */ 6530 for (var i = 0, l = autoEscape.length; i < l; i++) { 6531 var ae = autoEscape[i]; 6532 if (rest.indexOf(ae) === -1) { continue; } 6533 var esc = encodeURIComponent(ae); 6534 if (esc === ae) { 6535 esc = escape(ae); 6536 } 6537 rest = rest.split(ae).join(esc); 6538 } 6539 } 6540 6541 // chop off from the tail first. 6542 var hash = rest.indexOf('#'); 6543 if (hash !== -1) { 6544 // got a fragment string.
vendor: 7,325 bytes, lines 6545-6773
6545 this.hash = rest.substr(hash); 6546 rest = rest.slice(0, hash); 6547 } 6548 var qm = rest.indexOf('?'); 6549 if (qm !== -1) { 6550 this.search = rest.substr(qm); 6551 this.query = rest.substr(qm + 1); 6552 if (parseQueryString) { 6553 this.query = querystring.parse(this.query); 6554 } 6555 rest = rest.slice(0, qm); 6556 } else if (parseQueryString) { 6557 // no query string, but parseQueryString still requested 6558 this.search = ''; 6559 this.query = {}; 6560 } 6561 if (rest) { this.pathname = rest; } 6562 if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { 6563 this.pathname = '/'; 6564 } 6565 6566 // to support http.request 6567 if (this.pathname || this.search) { 6568 var p = this.pathname || ''; 6569 var s = this.search || ''; 6570 this.path = p + s; 6571 } 6572 6573 // finally, reconstruct the href based on what has been validated. 6574 this.href = this.format(); 6575 return this; 6576}; 6577 6578Url.prototype.format = function () { 6579 var auth = this.auth || ''; 6580 if (auth) { 6581 auth = encodeURIComponent(auth); 6582 auth = auth.replace(/%3A/i, ':'); 6583 auth += '@'; 6584 } 6585 6586 var protocol = this.protocol || '', 6587 pathname = this.pathname || '', 6588 hash = this.hash || '', 6589 host = false, 6590 query = ''; 6591 6592 if (this.host) { 6593 host = auth + this.host; 6594 } else if (this.hostname) { 6595 host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); 6596 if (this.port) { 6597 host += ':' + this.port; 6598 } 6599 } 6600 6601 if (this.query && typeof this.query === 'object' && Object.keys(this.query).length) { 6602 query = querystring.stringify(this.query, { 6603 arrayFormat: 'repeat', 6604 addQueryPrefix: false 6605 }); 6606 } 6607 6608 var search = this.search || (query && ('?' + query)) || ''; 6609 6610 if (protocol && protocol.substr(-1) !== ':') { protocol += ':'; } 6611 6612 /* 6613 * only the slashedProtocols get the //. Not mailto:, xmpp:, etc. 6614 * unless they had them to begin with. 6615 */ 6616 if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { 6617 host = '//' + (host || ''); 6618 if (pathname && pathname.charAt(0) !== '/') { pathname = '/' + pathname; } 6619 } else if (!host) { 6620 host = ''; 6621 } 6622 6623 if (hash && hash.charAt(0) !== '#') { hash = '#' + hash; } 6624 if (search && search.charAt(0) !== '?') { search = '?' + search; } 6625 6626 pathname = pathname.replace(/[?#]/g, function (match) { 6627 return encodeURIComponent(match); 6628 }); 6629 search = search.replace('#', '%23'); 6630 6631 return protocol + host + pathname + search + hash; 6632}; 6633 6634Url.prototype.resolve = function (relative) { 6635 return this.resolveObject(urlParse(relative, false, true)).format(); 6636}; 6637 6638Url.prototype.resolveObject = function (relative) { 6639 if (typeof relative === 'string') { 6640 var rel = new Url(); 6641 rel.parse(relative, false, true); 6642 relative = rel; 6643 } 6644 6645 var result = new Url(); 6646 var tkeys = Object.keys(this); 6647 for (var tk = 0; tk < tkeys.length; tk++) { 6648 var tkey = tkeys[tk]; 6649 result[tkey] = this[tkey]; 6650 } 6651 6652 /* 6653 * hash is always overridden, no matter what. 6654 * even href="" will remove it. 6655 */ 6656 result.hash = relative.hash; 6657 6658 // if the relative url is empty, then there's nothing left to do here. 6659 if (relative.href === '') { 6660 result.href = result.format(); 6661 return result; 6662 } 6663 6664 // hrefs like //foo/bar always cut to the protocol. 6665 if (relative.slashes && !relative.protocol) { 6666 // take everything except the protocol from relative 6667 var rkeys = Object.keys(relative); 6668 for (var rk = 0; rk < rkeys.length; rk++) { 6669 var rkey = rkeys[rk]; 6670 if (rkey !== 'protocol') { result[rkey] = relative[rkey]; } 6671 } 6672 6673 // urlParse appends trailing / to urls like http://www.example.com 6674 if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { 6675 result.pathname = '/'; 6676 result.path = result.pathname; 6677 } 6678 6679 result.href = result.format(); 6680 return result; 6681 } 6682 6683 if (relative.protocol && relative.protocol !== result.protocol) { 6684 /* 6685 * if it's a known url protocol, then changing 6686 * the protocol does weird things 6687 * first, if it's not file:, then we MUST have a host, 6688 * and if there was a path 6689 * to begin with, then we MUST have a path. 6690 * if it is file:, then the host is dropped, 6691 * because that's known to be hostless. 6692 * anything else is assumed to be absolute. 6693 */ 6694 if (!slashedProtocol[relative.protocol]) { 6695 var keys = Object.keys(relative); 6696 for (var v = 0; v < keys.length; v++) { 6697 var k = keys[v]; 6698 result[k] = relative[k]; 6699 } 6700 result.href = result.format(); 6701 return result; 6702 } 6703 6704 result.protocol = relative.protocol; 6705 if (!relative.host && !hostlessProtocol[relative.protocol]) { 6706 var relPath = (relative.pathname || '').split('/'); 6707 while (relPath.length && !(relative.host = relPath.shift())) { } 6708 if (!relative.host) { relative.host = ''; } 6709 if (!relative.hostname) { relative.hostname = ''; } 6710 if (relPath[0] !== '') { relPath.unshift(''); } 6711 if (relPath.length < 2) { relPath.unshift(''); } 6712 result.pathname = relPath.join('/'); 6713 } else { 6714 result.pathname = relative.pathname; 6715 } 6716 result.search = relative.search; 6717 result.query = relative.query; 6718 result.host = relative.host || ''; 6719 result.auth = relative.auth; 6720 result.hostname = relative.hostname || relative.host; 6721 result.port = relative.port; 6722 // to support http.request 6723 if (result.pathname || result.search) { 6724 var p = result.pathname || ''; 6725 var s = result.search || ''; 6726 result.path = p + s; 6727 } 6728 result.slashes = result.slashes || relative.slashes; 6729 result.href = result.format(); 6730 return result; 6731 } 6732 6733 var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/', 6734 isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/', 6735 mustEndAbs = isRelAbs || isSourceAbs || (result.host && relative.pathname), 6736 removeAllDots = mustEndAbs, 6737 srcPath = result.pathname && result.pathname.split('/') || [], 6738 relPath = relative.pathname && relative.pathname.split('/') || [], 6739 psychotic = result.protocol && !slashedProtocol[result.protocol]; 6740 6741 /* 6742 * if the url is a non-slashed url, then relative 6743 * links like ../.. should be able 6744 * to crawl up to the hostname, as well. This is strange. 6745 * result.protocol has already been set by now. 6746 * Later on, put the first path part into the host field. 6747 */ 6748 if (psychotic) { 6749 result.hostname = ''; 6750 result.port = null; 6751 if (result.host) { 6752 if (srcPath[0] === '') { srcPath[0] = result.host; } else { srcPath.unshift(result.host); } 6753 } 6754 result.host = ''; 6755 if (relative.protocol) { 6756 relative.hostname = null; 6757 relative.port = null; 6758 if (relative.host) { 6759 if (relPath[0] === '') { relPath[0] = relative.host; } else { relPath.unshift(relative.host); } 6760 } 6761 relative.host = null; 6762 } 6763 mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); 6764 } 6765 6766 if (isRelAbs) { 6767 // it's absolute. 6768 result.host = relative.host || relative.host === '' ? relative.host : result.host; 6769 result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname; 6770 result.search = relative.search; 6771 result.query = relative.query; 6772 srcPath = relPath; 6773 // fall through to the dot-handling below.
6774 } else if (relPath.length) { 6775 /* 6776 * it's relative 6777 * throw away the existing file, and take the new path instead. 6778 */ 6779 if (!srcPath) { srcPath = []; } 6780 srcPath.pop(); 6781 srcPath = srcPath.concat(relPath); 6782 result.search = relative.search; 6783 result.query = relative.query; 6784 } else if (relative.search != null) { 6785 /* 6786 * just pull out the search. 6787 * like href='?foo'. 6788 * Put this after the other two cases because it simplifies the booleans 6789 */ 6790 if (psychotic) { 6791 result.host = srcPath.shift(); 6792 result.hostname = result.host; 6793 /* 6794 * occationaly the auth can get stuck only in host 6795 * this especially happens in cases like 6796 * url.resolveObject('mailto:local1@domain1', 'local2@domain2') 6797 */ 6798 var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; 6799 if (authInHost) { 6800 result.auth = authInHost.shift(); 6801 result.hostname = authInHost.shift(); 6802 result.host = result.hostname; 6803 } 6804 } 6805 result.search = relative.search; 6806 result.query = relative.query; 6807 // to support http.request 6808 if (result.pathname !== null || result.search !== null) { 6809 result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); 6810 } 6811 result.href = result.format(); 6812 return result; 6813 } 6814 6815 if (!srcPath.length) { 6816 /* 6817 * no path at all. easy. 6818 * we've already handled the other stuff above. 6819 */ 6820 result.pathname = null; 6821 // to support http.request 6822 if (result.search) { 6823 result.path = '/' + result.search; 6824 } else { 6825 result.path = null; 6826 } 6827 result.href = result.format(); 6828 return result; 6829 } 6830 6831 /* 6832 * if a url ENDs in . or .., then it must get a trailing slash. 6833 * however, if it ends in anything else non-slashy, 6834 * then it must NOT get a trailing slash. 6835 */ 6836 var last = srcPath.slice(-1)[0]; 6837 var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''; 6838 6839 /* 6840 * strip single dots, resolve double dots to parent dir 6841 * if the path tries to go above the root, `up` ends up > 0 6842 */ 6843 var up = 0; 6844 for (var i = srcPath.length; i >= 0; i--) { 6845 last = srcPath[i]; 6846 if (last === '.') { 6847 srcPath.splice(i, 1); 6848 } else if (last === '..') { 6849 srcPath.splice(i, 1); 6850 up++; 6851 } else if (up) { 6852 srcPath.splice(i, 1); 6853 up--; 6854 } 6855 } 6856 6857 // if the path is allowed to go above the root, restore leading ..s 6858 if (!mustEndAbs && !removeAllDots) { 6859 for (; up--; up) { 6860 srcPath.unshift('..'); 6861 } 6862 } 6863 6864 if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { 6865 srcPath.unshift(''); 6866 } 6867 6868 if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { 6869 srcPath.push(''); 6870 } 6871 6872 var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/'); 6873 6874 // put the host back 6875 if (psychotic) { 6876 result.hostname = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; 6877 result.host = result.hostname; 6878 /* 6879 * occationaly the auth can get stuck only in host 6880 * this especially happens in cases like 6881 * url.resolveObject('mailto:local1@domain1', 'local2@domain2') 6882 */ 6883 var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; 6884 if (authInHost) { 6885 result.auth = authInHost.shift(); 6886 result.hostname = authInHost.shift(); 6887 result.host = result.hostname; 6888 } 6889 } 6890 6891 mustEndAbs = mustEndAbs || (result.host && srcPath.length); 6892 6893 if (mustEndAbs && !isAbsolute) { 6894 srcPath.unshift(''); 6895 } 6896 6897 if (srcPath.length > 0) { 6898 result.pathname = srcPath.join('/'); 6899 } else { 6900 result.pathname = null; 6901 result.path = null; 6902 } 6903 6904 // to support request.http 6905 if (result.pathname !== null || result.search !== null) { 6906 result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); 6907 } 6908 result.auth = relative.auth || result.auth; 6909 result.slashes = result.slashes || relative.slashes; 6910 result.href = result.format(); 6911 return result; 6912}; 6913 6914Url.prototype.parseHost = function () { 6915 var host = this.host; 6916 var port = portPattern.exec(host); 6917 if (port) { 6918 port = port[0]; 6919 if (port !== ':') { 6920 this.port = port.substr(1); 6921 } 6922 host = host.substr(0, host.length - port.length); 6923 } 6924 if (host) { this.hostname = host; } 6925}; 6926 6927const warnings = {}; 6928function deprecation(version, message, ignoreDepth = 3) { 6929 if (warnings[message]) 6930 return; 6931 let stack = new Error().stack; 6932 typeof stack > "u" ? console.warn("PixiJS Deprecation Warning: ", `${message} 6933Deprecated since v${version}`) : (stack = stack.split(` 6934`).splice(ignoreDepth).join(` 6935`), console.groupCollapsed ? (console.groupCollapsed( 6936 "%cPixiJS Deprecation Warning: %c%s", 6937 "color:#614108;background:#fffbe6", 6938 "font-weight:normal;color:#614108;background:#fffbe6", 6939 `${message} 6940Deprecated since v${version}` 6941 ), console.warn(stack), console.groupEnd()) : (console.warn("PixiJS Deprecation Warning: ", `${message} 6942Deprecated since v${version}`), console.warn(stack))), warnings[message] = !0; 6943} 6944 6945function assertPath(path2) { 6946 if (typeof path2 != "string") 6947 throw new TypeError(`Path must be a string. Received ${JSON.stringify(path2)}`); 6948} 6949function removeUrlParams(url) { 6950 return url.split("?")[0].split("#")[0]; 6951} 6952function escapeRegExp(string) { 6953 return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); 6954} 6955function replaceAll(str, find, replace) { 6956 return str.replace(new RegExp(escapeRegExp(find), "g"), replace); 6957} 6958function normalizeStringPosix(path2, allowAboveRoot) { 6959 let res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, code = -1; 6960 for (let i = 0; i <= path2.length; ++i) { 6961 if (i < path2.length) 6962 code = path2.charCodeAt(i); 6963 else { 6964 if (code === 47) 6965 break; 6966 code = 47; 6967 } 6968 if (code === 47) { 6969 if (!(lastSlash === i - 1 || dots === 1)) 6970 if (lastSlash !== i - 1 && dots === 2) { 6971 if (res.length < 2 || lastSegmentLength !== 2 || res.charCo
vendor: 8,769 bytes, lines 6971-7193
6971deAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) { 6972 if (res.length > 2) { 6973 const lastSlashIndex = res.lastIndexOf("/"); 6974 if (lastSlashIndex !== res.length - 1) { 6975 lastSlashIndex === -1 ? (res = "", lastSegmentLength = 0) : (res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/")), lastSlash = i, dots = 0; 6976 continue; 6977 } 6978 } else if (res.length === 2 || res.length === 1) { 6979 res = "", lastSegmentLength = 0, lastSlash = i, dots = 0; 6980 continue; 6981 } 6982 } 6983 allowAboveRoot && (res.length > 0 ? res += "/.." : res = "..", lastSegmentLength = 2); 6984 } else 6985 res.length > 0 ? res += `/${path2.slice(lastSlash + 1, i)}` : res = path2.slice(lastSlash + 1, i), lastSegmentLength = i - lastSlash - 1; 6986 lastSlash = i, dots = 0; 6987 } else 6988 code === 46 && dots !== -1 ? ++dots : dots = -1; 6989 } 6990 return res; 6991} 6992const path = { 6993 /** 6994 * Converts a path to posix format. 6995 * @param path - The path to convert to posix 6996 */ 6997 toPosix(path2) { 6998 return replaceAll(path2, "\\", "/"); 6999 }, 7000 /** 7001 * Checks if the path is a URL e.g. http://, https:// 7002 * @param path - The path to check 7003 */ 7004 isUrl(path2) { 7005 return /^https?:/.test(this.toPosix(path2)); 7006 }, 7007 /** 7008 * Checks if the path is a data URL 7009 * @param path - The path to check 7010 */ 7011 isDataUrl(path2) { 7012 return /^data:([a-z]+\/[a-z0-9-+.]+(;[a-z0-9-.!#$%*+.{}|~`]+=[a-z0-9-.!#$%*+.{}()_|~`]+)*)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s<>]*?)$/i.test(path2); 7013 }, 7014 /** 7015 * Checks if the path is a blob URL 7016 * @param path - The path to check 7017 */ 7018 isBlobUrl(path2) { 7019 return path2.startsWith("blob:"); 7020 }, 7021 /** 7022 * Checks if the path has a protocol e.g. http://, https://, file:///, data:, blob:, C:/ 7023 * This will return true for windows file paths 7024 * @param path - The path to check 7025 */ 7026 hasProtocol(path2) { 7027 return /^[^/:]+:/.test(this.toPosix(path2)); 7028 }, 7029 /** 7030 * Returns the protocol of the path e.g. http://, https://, file:///, data:, blob:, C:/ 7031 * @param path - The path to get the protocol from 7032 */ 7033 getProtocol(path2) { 7034 assertPath(path2), path2 = this.toPosix(path2); 7035 const matchFile = /^file:\/\/\//.exec(path2); 7036 if (matchFile) 7037 return matchFile[0]; 7038 const matchProtocol = /^[^/:]+:\/{0,2}/.exec(path2); 7039 return matchProtocol ? matchProtocol[0] : ""; 7040 }, 7041 /** 7042 * Converts URL to an absolute path. 7043 * When loading from a Web Worker, we must use absolute paths. 7044 * If the URL is already absolute we return it as is 7045 * If it's not, we convert it 7046 * @param url - The URL to test 7047 * @param customBaseUrl - The base URL to use 7048 * @param customRootUrl - The root URL to use 7049 */ 7050 toAbsolute(url, customBaseUrl, customRootUrl) { 7051 if (assertPath(url), this.isDataUrl(url) || this.isBlobUrl(url)) 7052 return url; 7053 const baseUrl = removeUrlParams(this.toPosix(customBaseUrl ?? settings.ADAPTER.getBaseUrl())), rootUrl = removeUrlParams(this.toPosix(customRootUrl ?? this.rootname(baseUrl))); 7054 return url = this.toPosix(url), url.startsWith("/") ? path.join(rootUrl, url.slice(1)) : this.isAbsolute(url) ? url : this.join(baseUrl, url); 7055 }, 7056 /** 7057 * Normalizes the given path, resolving '..' and '.' segments 7058 * @param path - The path to normalize 7059 */ 7060 normalize(path2) { 7061 if (assertPath(path2), path2.length === 0) 7062 return "."; 7063 if (this.isDataUrl(path2) || this.isBlobUrl(path2)) 7064 return path2; 7065 path2 = this.toPosix(path2); 7066 let protocol = ""; 7067 const isAbsolute = path2.startsWith("/"); 7068 this.hasProtocol(path2) && (protocol = this.rootname(path2), path2 = path2.slice(protocol.length)); 7069 const trailingSeparator = path2.endsWith("/"); 7070 return path2 = normalizeStringPosix(path2, !1), path2.length > 0 && trailingSeparator && (path2 += "/"), isAbsolute ? `/${path2}` : protocol + path2; 7071 }, 7072 /** 7073 * Determines if path is an absolute path. 7074 * Absolute paths can be urls, data urls, or paths on disk 7075 * @param path - The path to test 7076 */ 7077 isAbsolute(path2) { 7078 return assertPath(path2), path2 = this.toPosix(path2), this.hasProtocol(path2) ? !0 : path2.startsWith("/"); 7079 }, 7080 /** 7081 * Joins all given path segments together using the platform-specific separator as a delimiter, 7082 * then normalizes the resulting path 7083 * @param segments - The segments of the path to join 7084 */ 7085 join(...segments) { 7086 if (segments.length === 0) 7087 return "."; 7088 let joined; 7089 for (let i = 0; i < segments.length; ++i) { 7090 const arg = segments[i]; 7091 if (assertPath(arg), arg.length > 0) 7092 if (joined === void 0) 7093 joined = arg; 7094 else { 7095 const prevArg = segments[i - 1] ?? ""; 7096 this.extname(prevArg) ? joined += `/../${arg}` : joined += `/${arg}`; 7097 } 7098 } 7099 return joined === void 0 ? "." : this.normalize(joined); 7100 }, 7101 /** 7102 * Returns the directory name of a path 7103 * @param path - The path to parse 7104 */ 7105 dirname(path2) { 7106 if (assertPath(path2), path2.length === 0) 7107 return "."; 7108 path2 = this.toPosix(path2); 7109 let code = path2.charCodeAt(0); 7110 const hasRoot = code === 47; 7111 let end = -1, matchedSlash = !0; 7112 const proto = this.getProtocol(path2), origpath = path2; 7113 path2 = path2.slice(proto.length); 7114 for (let i = path2.length - 1; i >= 1; --i) 7115 if (code = path2.charCodeAt(i), code === 47) { 7116 if (!matchedSlash) { 7117 end = i; 7118 break; 7119 } 7120 } else 7121 matchedSlash = !1; 7122 return end === -1 ? hasRoot ? "/" : this.isUrl(origpath) ? proto + path2 : proto : hasRoot && end === 1 ? "//" : proto + path2.slice(0, end); 7123 }, 7124 /** 7125 * Returns the root of the path e.g. /, C:/, file:///, http://domain.com/ 7126 * @param path - The path to parse 7127 */ 7128 rootname(path2) { 7129 assertPath(path2), path2 = this.toPosix(path2); 7130 let root = ""; 7131 if (path2.startsWith("/") ? root = "/" : root = this.getProtocol(path2), this.isUrl(path2)) { 7132 const index = path2.indexOf("/", root.length); 7133 index !== -1 ? root = path2.slice(0, index) : root = path2, root.endsWith("/") || (root += "/"); 7134 } 7135 return root; 7136 }, 7137 /** 7138 * Returns the last portion of a path 7139 * @param path - The path to test 7140 * @param ext - Optional extension to remove 7141 */ 7142 basename(path2, ext) { 7143 assertPath(path2), ext && assertPath(ext), path2 = removeUrlParams(this.toPosix(path2)); 7144 let start = 0, end = -1, matchedSlash = !0, i; 7145 if (ext !== void 0 && ext.length > 0 && ext.length <= path2.length) { 7146 if (ext.length === path2.length && ext === path2) 7147 return ""; 7148 let extIdx = ext.length - 1, firstNonSlashEnd = -1; 7149 for (i = path2.length - 1; i >= 0; --i) { 7150 const code = path2.charCodeAt(i); 7151 if (code === 47) { 7152 if (!matchedSlash) { 7153 start = i + 1; 7154 break; 7155 } 7156 } else 7157 firstNonSlashEnd === -1 && (matchedSlash = !1, firstNonSlashEnd = i + 1), extIdx >= 0 && (code === ext.charCodeAt(extIdx) ? --extIdx === -1 && (end = i) : (extIdx = -1, end = firstNonSlashEnd)); 7158 } 7159 return start === end ? end = firstNonSlashEnd : end === -1 && (end = path2.length), path2.slice(start, end); 7160 } 7161 for (i = path2.length - 1; i >= 0; --i) 7162 if (path2.charCodeAt(i) === 47) { 7163 if (!matchedSlash) { 7164 start = i + 1; 7165 break; 7166 } 7167 } else 7168 end === -1 && (matchedSlash = !1, end = i + 1); 7169 return end === -1 ? "" : path2.slice(start, end); 7170 }, 7171 /** 7172 * Returns the extension of the path, from the last occurrence of the . (period) character to end of string in the last 7173 * portion of the path. If there is no . in the last portion of the path, or if there are no . characters other than 7174 * the first character of the basename of path, an empty string is returned. 7175 * @param path - The path to parse 7176 */ 7177 extname(path2) { 7178 assertPath(path2), path2 = removeUrlParams(this.toPosix(path2)); 7179 let startDot = -1, startPart = 0, end = -1, matchedSlash = !0, preDotState = 0; 7180 for (let i = path2.length - 1; i >= 0; --i) { 7181 const code = path2.charCodeAt(i); 7182 if (code === 47) { 7183 if (!matchedSlash) { 7184 startPart = i + 1; 7185 break; 7186 } 7187 continue; 7188 } 7189 end === -1 && (matchedSlash = !1, end = i + 1), code === 46 ? startDot === -1 ? startDot = i : preDotState !== 1 && (preDotState = 1) : startDot !== -1 && (preDotState = -1); 7190 } 7191 return startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1 ? "" : path2.slice(startDot, end); 7192 }, 7193 /**
7194 * Parses a path into an object containing the 'root', `dir`, `base`, `ext`, and `name` properties. 7195 * @param path - The path to parse 7196 */ 7197 parse(path2) { 7198 assertPath(path2); 7199 const ret = { root: "", dir: "", base: "", ext: "", name: "" }; 7200 if (path2.length === 0) 7201 return ret; 7202 path2 = removeUrlParams(this.toPosix(path2)); 7203 let code = path2.charCodeAt(0); 7204 const isAbsolute = this.isAbsolute(path2); 7205 let start; 7206 ret.root = this.rootname(path2), isAbsolute || this.hasProtocol(path2) ? start = 1 : start = 0; 7207 let startDot = -1, startPart = 0, end = -1, matchedSlash = !0, i = path2.length - 1, preDotState = 0; 7208 for (; i >= start; --i) { 7209 if (code = path2.charCodeAt(i), code === 47) { 7210 if (!matchedSlash) { 7211 startPart = i + 1; 7212 break; 7213 } 7214 continue; 7215 } 7216 end === -1 && (matchedSlash = !1, end = i + 1), code === 46 ? startDot === -1 ? startDot = i : preDotState !== 1 && (preDotState = 1) : startDot !== -1 && (preDotState = -1); 7217 } 7218 return startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1 ? end !== -1 && (startPart === 0 && isAbsolute ? ret.base = ret.name = path2.slice(1, end) : ret.base = ret.name = path2.slice(startPart, end)) : (startPart === 0 && isAbsolute ? (ret.name = path2.slice(1, startDot), ret.base = path2.slice(1, end)) : (ret.name = path2.slice(startPart, startDot), ret.base = path2.slice(startPart, end)), ret.ext = path2.slice(startDot, end)), ret.dir = this.dirname(path2), ret; 7219 }, 7220 sep: "/", 7221 delimiter: ":" 7222}; 7223 7224let promise; 7225async function detectVideoAlphaMode() { 7226 return promise ?? (promise = (async () => { 7227 const gl = document.createElement("canvas").getContext("webgl"); 7228 if (!gl) 7229 return ALPHA_MODES.UNPACK; 7230 const video = await new Promise((resolve) => { 7231 const video2 = document.createElement("video"); 7232 video2.onloadeddata = () => resolve(video2), video2.onerror = () => resolve(null), video2.autoplay = !1, video2.crossOrigin = "anonymous", video2.preload = "auto", video2.src = "data:video/webm;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEAAAAAAAHTEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHGTbuMU6uEElTDZ1OsggEXTbuMU6uEHFO7a1OsggG97AEAAAAAAABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmoCrXsYMPQkBNgIRMYXZmV0GETGF2ZkSJiEBEAAAAAAAAFlSua8yuAQAAAAAAAEPXgQFzxYgAAAAAAAAAAZyBACK1nIN1bmSIgQCGhVZfVlA5g4EBI+ODhAJiWgDglLCBArqBApqBAlPAgQFVsIRVuYEBElTDZ9Vzc9JjwItjxYgAAAAAAAAAAWfInEWjh0VOQ09ERVJEh49MYXZjIGxpYnZweC12cDlnyKJFo4hEVVJBVElPTkSHlDAwOjAwOjAwLjA0MDAwMDAwMAAAH0O2dcfngQCgwqGggQAAAIJJg0IAABAAFgA4JBwYSgAAICAAEb///4r+AAB1oZ2mm+6BAaWWgkmDQgAAEAAWADgkHBhKAAAgIABIQBxTu2uRu4+zgQC3iveBAfGCAXHwgQM=", video2.load(); 7233 }); 7234 if (!video) 7235 return ALPHA_MODES.UNPACK; 7236 const texture = gl.createTexture(); 7237 gl.bindTexture(gl.TEXTURE_2D, texture); 7238 const framebuffer = gl.createFramebuffer(); 7239 gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer), gl.framebufferTexture2D( 7240 gl.FRAMEBUFFER, 7241 gl.COLOR_ATTACHMENT0, 7242 gl.TEXTURE_2D, 7243 texture, 7244 0 7245 ), gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !1), gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE), gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video); 7246 const pixel = new Uint8Array(4); 7247 return gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel), gl.deleteFramebuffer(framebuffer), gl.deleteTexture(texture), gl.getExtension("WEBGL_lose_context")?.loseContext(), pixel[0] <= pixel[3] ? ALPHA_MODES.PMA : ALPHA_MODES.UNPACK; 7248 })()), promise; 7249} 7250 7251let supported; 7252function isWebGLSupported() { 7253 return typeof supported > "u" && (supported = function() { 7254 const contextOptions = { 7255 stencil: !0, 7256 failIfMajorPerformanceCaveat: settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT 7257 }; 7258 try { 7259 if (!settings.ADAPTER.getWebGLRenderingContext()) 7260 return !1; 7261 const canvas = settings.ADAPTER.createCanvas(); 7262 let gl = canvas.getContext("webgl", contextOptions) || canvas.getContext("experimental-webgl", contextOptions); 7263 const success = !!gl?.getContextAttributes()?.stencil; 7264 if (gl) { 7265 const loseContext = gl.getExtension("WEBGL_lose_context"); 7266 loseContext && loseContext.loseContext(); 7267 } 7268 return gl = null, success; 7269 } catch { 7270 return !1; 7271 } 7272 }()), supported; 7273} 7274 7275var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return "string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},u=function(r){return (r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return {r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return {r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return {h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return {r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},g=function(r){return {h:u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},d=function(r){return {h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},f=function(r){return b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e;},c=function(r){return {h:(t=h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u;},l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\
vendor: 6,804 bytes, lines 7275-7277
7275s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,y={string:[[function(r){var t=i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=v.exec(r)||m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=l.exec(t)||p.exec(t);if(!n)return null;var e,u,a=g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return {h:u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return b(h)},"hsv"]]},N=function(r,t){for(var n=0;n<t.length;n++){var e=t[n][0](r);if(e)return [e,t[n][1]]}return [null,void 0]},x=function(r){return "string"==typeof r?N(r.trim(),y.string):"object"==typeof r&&null!==r?N(r,y.object):[null,void 0]},M=function(r,t){var n=c(r);return {h:n.h,s:e(n.s+100*t,0,100),l:n.l,a:n.a}},H=function(r){return (299*r.r+587*r.g+114*r.b)/1e3/255},$=function(r,t){var n=c(r);return {h:n.h,s:n.s,l:e(n.l+100*t,0,100),a:n.a}},j=function(){function r(r){this.parsed=x(r)[0],this.rgba=this.parsed||{r:0,g:0,b:0,a:1};}return r.prototype.isValid=function(){return null!==this.parsed},r.prototype.brightness=function(){return n(H(this.rgba),2)},r.prototype.isDark=function(){return H(this.rgba)<.5},r.prototype.isLight=function(){return H(this.rgba)>=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i;},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u;},r.prototype.toHsl=function(){return d(c(this.rgba))},r.prototype.toHslString=function(){return r=d(c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u;},r.prototype.toHsv=function(){return r=h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r;},r.prototype.invert=function(){return w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r;},r.prototype.saturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,-r))},r.prototype.grayscale=function(){return w(M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),w($(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),w($(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return "number"==typeof r?w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t;},r.prototype.hue=function(r){var t=c(this.rgba);return "number"==typeof r?w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===w(r).toHex()},r}(),w=function(r){return r instanceof j?r:new j(r)},S=[],k=function(r){r.forEach(function(r){S.indexOf(r)<0&&(r(j,y),S.push(r));});}; 7276 7277function namesPlugin(e,f){var a={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",s
7277andybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return "transparent";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b="black";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));u<t&&(t=u,b=g);}return b}};f.string.push([function(f){var r=f.toLowerCase(),d="transparent"===r?"#0000":a[r];return d?new e(d).toRgb():null},"name"]);} 7278 7279k([namesPlugin]); 7280const _Color = class _Color2 { 7281 /** 7282 * @param {PIXI.ColorSource} value - Optional value to use, if not provided, white is used. 7283 */ 7284 constructor(value = 16777215) { 7285 this._value = null, this._components = new Float32Array(4), this._components.fill(1), this._int = 16777215, this.value = value; 7286 } 7287 /** Get red component (0 - 1) */ 7288 get red() { 7289 return this._components[0]; 7290 } 7291 /** Get green component (0 - 1) */ 7292 get green() { 7293 return this._components[1]; 7294 } 7295 /** Get blue component (0 - 1) */ 7296 get blue() { 7297 return this._components[2]; 7298 } 7299 /** Get alpha component (0 - 1) */ 7300 get alpha() { 7301 return this._components[3]; 7302 } 7303 /** 7304 * Set the value, suitable for chaining 7305 * @param value
7306 * @see PIXI.Color.value 7307 */ 7308 setValue(value) { 7309 return this.value = value, this; 7310 } 7311 /** 7312 * The current color source. 7313 * 7314 * When setting: 7315 * - Setting to an instance of `Color` will copy its color source and components. 7316 * - Otherwise, `Color` will try to normalize the color source and set the components. 7317 * If the color source is invalid, an `Error` will be thrown and the `Color` will left unchanged. 7318 * 7319 * Note: The `null` in the setter's parameter type is added to match the TypeScript rule: return type of getter 7320 * must be assignable to its setter's parameter type. Setting `value` to `null` will throw an `Error`. 7321 * 7322 * When getting: 7323 * - A return value of `null` means the previous value was overridden (e.g., {@link PIXI.Color.multiply multiply}, 7324 * {@link PIXI.Color.premultiply premultiply} or {@link PIXI.Color.round round}). 7325 * - Otherwise, the color source used when setting is returned. 7326 * @type {PIXI.ColorSource} 7327 */ 7328 set value(value) { 7329 if (value instanceof _Color2) 7330 this._value = this.cloneSource(value._value), this._int = value._int, this._components.set(value._components); 7331 else { 7332 if (value === null) 7333 throw new Error("Cannot set PIXI.Color#value to null"); 7334 (this._value === null || !this.isSourceEqual(this._value, value)) && (this.normalize(value), this._value = this.cloneSource(value)); 7335 } 7336 } 7337 get value() { 7338 return this._value; 7339 } 7340 /** 7341 * Copy a color source internally. 7342 * @param value - Color source 7343 */ 7344 cloneSource(value) { 7345 return typeof value == "string" || typeof value == "number" || value instanceof Number || value === null ? value : Array.isArray(value) || ArrayBuffer.isView(value) ? value.slice(0) : typeof value == "object" && value !== null ? { ...value } : value; 7346 } 7347 /**
7348 * Equality check for color sources. 7349 * @param value1 - First color source 7350 * @param value2 - Second color source 7351 * @returns `true` if the color sources are equal, `false` otherwise. 7352 */ 7353 isSourceEqual(value1, value2) { 7354 const type1 = typeof value1; 7355 if (type1 !== typeof value2) 7356 return !1; 7357 if (type1 === "number" || type1 === "string" || value1 instanceof Number) 7358 return value1 === value2; 7359 if (Array.isArray(value1) && Array.isArray(value2) || ArrayBuffer.isView(value1) && ArrayBuffer.isView(value2)) 7360 return value1.length !== value2.length ? !1 : value1.every((v, i) => v === value2[i]); 7361 if (value1 !== null && value2 !== null) { 7362 const keys1 = Object.keys(value1), keys2 = Object.keys(value2); 7363 return keys1.length !== keys2.length ? !1 : keys1.every((key) => value1[key] === value2[key]); 7364 } 7365 return value1 === value2; 7366 } 7367 /** 7368 * Convert to a RGBA color object. 7369 * @example 7370 * import { Color } from 'pixi.js'; 7371 * new Color('white').toRgb(); // returns { r: 1, g: 1, b: 1, a: 1 } 7372 */ 7373 toRgba() { 7374 const [r, g, b, a] = this._components; 7375 return { r, g, b, a }; 7376 } 7377 /** 7378 * Convert to a RGB color object. 7379 * @example 7380 * import { Color } from 'pixi.js'; 7381 * new Color('white').toRgb(); // returns { r: 1, g: 1, b: 1 } 7382 */ 7383 toRgb() { 7384 const [r, g, b] = this._components; 7385 return { r, g, b }; 7386 } 7387 /** Convert to a CSS-style rgba string: `rgba(255,255,255,1.0)`. */ 7388 toRgbaString() { 7389 const [r, g, b] = this.toUint8RgbArray(); 7390 return `rgba(${r},${g},${b},${this.alpha})`; 7391 } 7392 toUint8RgbArray(out) { 7393 const [r, g, b] = this._components; 7394 return out = out ?? [], out[0] = Math.round(r * 255), out[1] = Math.round(g * 255), out[2] = Math.round(b * 255), out; 7395 } 7396 toRgbArray(out) { 7397 out = out ?? []; 7398 const [r, g, b] = this._components; 7399 return out[0] = r, out[1] = g, out[2] = b, out; 7400 } 7401 /** 7402 * Convert to a hexadecimal number. 7403 * @example 7404 * import { Color } from 'pixi.js'; 7405 * new Color('white').toNumber(); // returns 16777215 7406 */ 7407 toNumber() { 7408 return this._int; 7409 } 7410 /** 7411 * Convert to a hexadecimal number in little endian format (e.g., BBGGRR). 7412 * @example 7413 * import { Color } from 'pixi.js'; 7414 * new Color(0xffcc99).toLittleEndianNumber(); // returns 0x99ccff 7415 * @returns {number} - The color as a number in little endian format. 7416 */ 7417 toLittleEndianNumber() { 7418 const value = this._int; 7419 return (value >> 16) + (value & 65280) + ((value & 255) << 16); 7420 } 7421 /** 7422 * Multiply with another color. This action is destructive, and will 7423 * override the previous `value` property to be `null`. 7424 * @param {PIXI.ColorSource} value - The color to multiply by. 7425 */ 7426 multiply(value) { 7427 const [r, g, b, a] = _Color2.temp.setValue(value)._components; 7428 return this._components[0] *= r, this._components[1] *= g, this._components[2] *= b, this._components[3] *= a, this.refreshInt(), this._value = null, this; 7429 } 7430 /** 7431 * Converts color to a premultiplied alpha format. This action is destructive, and will 7432 * override the previous `value` property to be `null`. 7433 * @param alpha - The alpha to multiply by. 7434 * @param {boolean} [applyToRGB=true] - Whether to premultiply RGB channels. 7435 * @returns {PIXI.Color} - Itself. 7436 */ 7437 premultiply(alpha, applyToRGB = !0) { 7438 return applyToRGB && (this._components[0] *= alpha, this._components[1] *= alpha, this._components[2] *= alpha), this._components[3] = alpha, this.refreshInt(), this._value = null, this; 7439 } 7440 /** 7441 * Premultiplies alpha with current color. 7442 * @param {number} alpha - The alpha to multiply by. 7443 * @param {boolean} [applyToRGB=true] - Whether to premultiply RGB channels. 7444 * @returns {number} tint multiplied by alpha 7445 */ 7446 toPremultiplied(alpha, applyToRGB = !0) { 7447 if (alpha === 1) 7448 return (255 << 24) + this._int; 7449 if (alpha === 0) 7450 return applyToRGB ? 0 : this._int; 7451 let r = this._int >> 16 & 255, g = this._int >> 8 & 255, b = this._int & 255; 7452 return applyToRGB && (r = r * alpha + 0.5 | 0, g = g * alpha + 0.5 | 0, b = b * alpha + 0.5 | 0), (alpha * 255 << 24) + (r << 16) + (g << 8) + b; 7453 } 7454 /** 7455 * Convert to a hexidecimal string. 7456 * @example 7457 * import { Color } from 'pixi.js'; 7458 * new Color('white').toHex(); // returns "#ffffff" 7459 */ 7460 toHex() { 7461 const hexString = this._int.toString(16); 7462 return `#${"000000".substring(0, 6 - hexString.length) + hexString}`; 7463 } 7464 /** 7465 * Convert to a hexidecimal string with alpha. 7466 * @example 7467 * import { Color } from 'pixi.js'; 7468 * new Color('white').toHexa(); // returns "#ffffffff" 7469 */ 7470 toHexa() {
vendor: 11,510 bytes, lines 7471-7777
7471 const alphaString = Math.round(this._components[3] * 255).toString(16); 7472 return this.toHex() + "00".substring(0, 2 - alphaString.length) + alphaString; 7473 } 7474 /** 7475 * Set alpha, suitable for chaining. 7476 * @param alpha 7477 */ 7478 setAlpha(alpha) { 7479 return this._components[3] = this._clamp(alpha), this; 7480 } 7481 /** 7482 * Rounds the specified color according to the step. This action is destructive, and will 7483 * override the previous `value` property to be `null`. The alpha component is not rounded. 7484 * @param steps - Number of steps which will be used as a cap when rounding colors 7485 * @deprecated since 7.3.0 7486 */ 7487 round(steps) { 7488 const [r, g, b] = this._components; 7489 return this._components[0] = Math.round(r * steps) / steps, this._components[1] = Math.round(g * steps) / steps, this._components[2] = Math.round(b * steps) / steps, this.refreshInt(), this._value = null, this; 7490 } 7491 toArray(out) { 7492 out = out ?? []; 7493 const [r, g, b, a] = this._components; 7494 return out[0] = r, out[1] = g, out[2] = b, out[3] = a, out; 7495 } 7496 /** 7497 * Normalize the input value into rgba 7498 * @param value - Input value 7499 */ 7500 normalize(value) { 7501 let r, g, b, a; 7502 if ((typeof value == "number" || value instanceof Number) && value >= 0 && value <= 16777215) { 7503 const int = value; 7504 r = (int >> 16 & 255) / 255, g = (int >> 8 & 255) / 255, b = (int & 255) / 255, a = 1; 7505 } else if ((Array.isArray(value) || value instanceof Float32Array) && value.length >= 3 && value.length <= 4) 7506 value = this._clamp(value), [r, g, b, a = 1] = value; 7507 else if ((value instanceof Uint8Array || value instanceof Uint8ClampedArray) && value.length >= 3 && value.length <= 4) 7508 value = this._clamp(value, 0, 255), [r, g, b, a = 255] = value, r /= 255, g /= 255, b /= 255, a /= 255; 7509 else if (typeof value == "string" || typeof value == "object") { 7510 if (typeof value == "string") { 7511 const match = _Color2.HEX_PATTERN.exec(value); 7512 match && (value = `#${match[2]}`); 7513 } 7514 const color = w(value); 7515 color.isValid() && ({ r, g, b, a } = color.rgba, r /= 255, g /= 255, b /= 255); 7516 } 7517 if (r !== void 0) 7518 this._components[0] = r, this._components[1] = g, this._components[2] = b, this._components[3] = a, this.refreshInt(); 7519 else 7520 throw new Error(`Unable to convert color ${value}`); 7521 } 7522 /** Refresh the internal color rgb number */ 7523 refreshInt() { 7524 this._clamp(this._components); 7525 const [r, g, b] = this._components; 7526 this._int = (r * 255 << 16) + (g * 255 << 8) + (b * 255 | 0); 7527 } 7528 /** 7529 * Clamps values to a range. Will override original values 7530 * @param value - Value(s) to clamp 7531 * @param min - Minimum value 7532 * @param max - Maximum value 7533 */ 7534 _clamp(value, min = 0, max = 1) { 7535 return typeof value == "number" ? Math.min(Math.max(value, min), max) : (value.forEach((v, i) => { 7536 value[i] = Math.min(Math.max(v, min), max); 7537 }), value); 7538 } 7539}; 7540_Color.shared = new _Color(), /** 7541* Temporary Color object for static uses internally. 7542* As to not conflict with Color.shared. 7543* @ignore 7544*/ 7545_Color.temp = new _Color(), /** Pattern for hex strings */ 7546_Color.HEX_PATTERN = /^(#|0x)?(([a-f0-9]{3}){1,2}([a-f0-9]{2})?)$/i; 7547let Color = _Color; 7548 7549function hex2string(hex) { 7550 return deprecation("7.2.0", "utils.hex2string is deprecated, use Color#toHex instead"), Color.shared.setValue(hex).toHex(); 7551} 7552function rgb2hex(rgb) { 7553 return deprecation("7.2.0", "utils.rgb2hex is deprecated, use Color#toNumber instead"), Color.shared.setValue(rgb).toNumber(); 7554} 7555 7556function mapPremultipliedBlendModes() { 7557 const pm = [], npm = []; 7558 for (let i = 0; i < 32; i++) 7559 pm[i] = i, npm[i] = i; 7560 pm[BLEND_MODES.NORMAL_NPM] = BLEND_MODES.NORMAL, pm[BLEND_MODES.ADD_NPM] = BLEND_MODES.ADD, pm[BLEND_MODES.SCREEN_NPM] = BLEND_MODES.SCREEN, npm[BLEND_MODES.NORMAL] = BLEND_MODES.NORMAL_NPM, npm[BLEND_MODES.ADD] = BLEND_MODES.ADD_NPM, npm[BLEND_MODES.SCREEN] = BLEND_MODES.SCREEN_NPM; 7561 const array = []; 7562 return array.push(npm), array.push(pm), array; 7563} 7564const premultiplyBlendMode = mapPremultipliedBlendModes(); 7565function correctBlendMode(blendMode, premultiplied) { 7566 return premultiplyBlendMode[premultiplied ? 1 : 0][blendMode]; 7567} 7568 7569function createIndicesForQuads(size, outBuffer = null) { 7570 const totalIndices = size * 6; 7571 if (outBuffer = outBuffer || new Uint16Array(totalIndices), outBuffer.length !== totalIndices) 7572 throw new Error(`Out buffer length is incorrect, got ${outBuffer.length} and expected ${totalIndices}`); 7573 for (let i = 0, j = 0; i < totalIndices; i += 6, j += 4) 7574 outBuffer[i + 0] = j + 0, outBuffer[i + 1] = j + 1, outBuffer[i + 2] = j + 2, outBuffer[i + 3] = j + 0, outBuffer[i + 4] = j + 2, outBuffer[i + 5] = j + 3; 7575 return outBuffer; 7576} 7577 7578function getBufferType(array) { 7579 if (array.BYTES_PER_ELEMENT === 4) 7580 return array instanceof Float32Array ? "Float32Array" : array instanceof Uint32Array ? "Uint32Array" : "Int32Array"; 7581 if (array.BYTES_PER_ELEMENT === 2) { 7582 if (array instanceof Uint16Array) 7583 return "Uint16Array"; 7584 } else if (array.BYTES_PER_ELEMENT === 1 && array instanceof Uint8Array) 7585 return "Uint8Array"; 7586 return null; 7587} 7588 7589function nextPow2(v) { 7590 return v += v === 0 ? 1 : 0, --v, v |= v >>> 1, v |= v >>> 2, v |= v >>> 4, v |= v >>> 8, v |= v >>> 16, v + 1; 7591} 7592function isPow2(v) { 7593 return !(v & v - 1) && !!v; 7594} 7595function log2(v) { 7596 let r = (v > 65535 ? 1 : 0) << 4; 7597 v >>>= r; 7598 let shift = (v > 255 ? 1 : 0) << 3; 7599 return v >>>= shift, r |= shift, shift = (v > 15 ? 1 : 0) << 2, v >>>= shift, r |= shift, shift = (v > 3 ? 1 : 0) << 1, v >>>= shift, r |= shift, r | v >> 1; 7600} 7601 7602function removeItems(arr, startIdx, removeCount) { 7603 const length = arr.length; 7604 let i; 7605 if (startIdx >= length || removeCount === 0) 7606 return; 7607 removeCount = startIdx + removeCount > length ? length - startIdx : removeCount; 7608 const len = length - removeCount; 7609 for (i = startIdx; i < len; ++i) 7610 arr[i] = arr[i + removeCount]; 7611 arr.length = len; 7612} 7613 7614function sign(n) { 7615 return n === 0 ? 0 : n < 0 ? -1 : 1; 7616} 7617 7618let nextUid = 0; 7619function uid() { 7620 return ++nextUid; 7621} 7622 7623const _BoundingBox = class { 7624 /** 7625 * @param left - The left coordinate value of the bounding box. 7626 * @param top - The top coordinate value of the bounding box. 7627 * @param right - The right coordinate value of the bounding box. 7628 * @param bottom - The bottom coordinate value of the bounding box. 7629 */ 7630 constructor(left, top, right, bottom) { 7631 this.left = left, this.top = top, this.right = right, this.bottom = bottom; 7632 } 7633 /** The width of the bounding box. */ 7634 get width() { 7635 return this.right - this.left; 7636 } 7637 /** The height of the bounding box. */ 7638 get height() { 7639 return this.bottom - this.top; 7640 } 7641 /** Determines whether the BoundingBox is empty. */ 7642 isEmpty() { 7643 return this.left === this.right || this.top === this.bottom; 7644 } 7645}; 7646_BoundingBox.EMPTY = new _BoundingBox(0, 0, 0, 0); 7647let BoundingBox = _BoundingBox; 7648 7649const ProgramCache = {}, TextureCache = /* @__PURE__ */ Object.create(null), BaseTextureCache = /* @__PURE__ */ Object.create(null); 7650 7651class CanvasRenderTarget { 7652 /** 7653 * @param width - the width for the newly created canvas 7654 * @param height - the height for the newly created canvas 7655 * @param {number} [resolution=PIXI.settings.RESOLUTION] - The resolution / device pixel ratio of the canvas 7656 */ 7657 constructor(width, height, resolution) { 7658 this._canvas = settings.ADAPTER.createCanvas(), this._context = this._canvas.getContext("2d"), this.resolution = resolution || settings.RESOLUTION, this.resize(width, height); 7659 } 7660 /** 7661 * Clears the canvas that was created by the CanvasRenderTarget class. 7662 * @private 7663 */ 7664 clear() { 7665 this._checkDestroyed(), this._context.setTransform(1, 0, 0, 1, 0, 0), this._context.clearRect(0, 0, this._canvas.width, this._canvas.height); 7666 } 7667 /** 7668 * Resizes the canvas to the specified width and height. 7669 * @param desiredWidth - the desired width of the canvas 7670 * @param desiredHeight - the desired height of the canvas 7671 */ 7672 resize(desiredWidth, desiredHeight) { 7673 this._checkDestroyed(), this._canvas.width = Math.round(desiredWidth * this.resolution), this._canvas.height = Math.round(desiredHeight * this.resolution); 7674 } 7675 /** Destroys this canvas. */ 7676 destroy() { 7677 this._context = null, this._canvas = null; 7678 } 7679 /** 7680 * The width of the canvas buffer in pixels. 7681 * @member {number} 7682 */ 7683 get width() { 7684 return this._checkDestroyed(), this._canvas.width; 7685 } 7686 set width(val) { 7687 this._checkDestroyed(), this._canvas.width = Math.round(val); 7688 } 7689 /** 7690 * The height of the canvas buffer in pixels. 7691 * @member {number} 7692 */ 7693 get height() { 7694 return this._checkDestroyed(), this._canvas.height; 7695 } 7696 set height(val) { 7697 this._checkDestroyed(), this._canvas.height = Math.round(val); 7698 } 7699 /** The Canvas object that belongs to this CanvasRenderTarget. */ 7700 get canvas() { 7701 return this._checkDestroyed(), this._canvas; 7702 } 7703 /** A CanvasRenderingContext2D object representing a two-dimensional rendering context. */ 7704 get context() { 7705 return this._checkDestroyed(), this._context; 7706 } 7707 _checkDestroyed() { 7708 if (this._canvas === null) 7709 throw new TypeError("The CanvasRenderTarget has already been destroyed"); 7710 } 7711} 7712 7713function checkRow(data, width, y) { 7714 for (let x = 0, index = 4 * y * width; x < width; ++x, index += 4) 7715 if (data[index + 3] !== 0) 7716 return !1; 7717 return !0; 7718} 7719function checkColumn(data, width, x, top, bottom) { 7720 const stride = 4 * width; 7721 for (let y = top, index = top * stride + 4 * x; y <= bottom; ++y, index += stride) 7722 if (data[index + 3] !== 0) 7723 return !1; 7724 return !0; 7725} 7726function getCanvasBoundingBox(canvas) { 7727 const { width, height } = canvas, context = canvas.getContext("2d", { 7728 willReadFrequently: !0 7729 }); 7730 if (context === null) 7731 throw new TypeError("Failed to get canvas 2D context"); 7732 const data = context.getImageData(0, 0, width, height).data; 7733 let left = 0, top = 0, right = width - 1, bottom = height - 1; 7734 for (; top < height && checkRow(data, width, top); ) 7735 ++top; 7736 if (top === height) 7737 return BoundingBox.EMPTY; 7738 for (; checkRow(data, width, bottom); ) 7739 --bottom; 7740 for (; checkColumn(data, width, left, top, bottom); ) 7741 ++left; 7742 for (; checkColumn(data, width, right, top, bottom); ) 7743 --right; 7744 return ++right, ++bottom, new BoundingBox(left, top, right, bottom); 7745} 7746 7747function trimCanvas(canvas) { 7748 const boundingBox = getCanvasBoundingBox(canvas), { width, height } = boundingBox; 7749 let data = null; 7750 if (!boundingBox.isEmpty()) { 7751 const context = canvas.getContext("2d"); 7752 if (context === null) 7753 throw new TypeError("Failed to get canvas 2D context"); 7754 data = context.getImageData( 7755 boundingBox.left, 7756 boundingBox.top, 7757 width, 7758 height 7759 ); 7760 } 7761 return { width, height, data }; 7762} 7763 7764function determineCrossOrigin(url, loc = globalThis.location) { 7765 if (url.startsWith("data:")) 7766 return ""; 7767 loc = loc || globalThis.location; 7768 const parsedUrl = new URL(url, document.baseURI); 7769 return parsedUrl.hostname !== loc.hostname || parsedUrl.port !== loc.port || parsedUrl.protocol !== loc.protocol ? "anonymous" : ""; 7770} 7771 7772function getResolutionOfUrl(url, defaultValue = 1) { 7773 const resolution = settings.RETINA_PREFIX?.exec(url); 7774 return resolution ? parseFloat(resolution[1]) : defaultValue; 7775} 7776 7777var ExtensionType = /* @__PURE__ */ ((ExtensionType2) => (ExtensionType2.Renderer = "renderer", ExtensionType2.Application = "a
7777pplication", ExtensionType2.RendererSystem = "renderer-webgl-system", ExtensionType2.RendererPlugin = "renderer-webgl-plugin", ExtensionType2.CanvasRendererSystem = "renderer-canvas-system", ExtensionType2.CanvasRendererPlugin = "renderer-canvas-plugin", ExtensionType2.Asset = "asset", ExtensionType2.LoadParser = "load-parser", ExtensionType2.ResolveParser = "resolve-parser", ExtensionType2.CacheParser = "cache-parser", ExtensionType2.DetectionParser = "detection-parser", ExtensionType2))(ExtensionType || {}); 7778const normalizeExtension = (ext) => { 7779 if (typeof ext == "function" || typeof ext == "object" && ext.extension) { 7780 if (!ext.extension) 7781 throw new Error("Extension class must have an extension object"); 7782 ext = { ...typeof ext.extension != "object" ? { type: ext.extension } : ext.extension, ref: ext }; 7783 } 7784 if (typeof ext == "object") 7785 ext = { ...ext }; 7786 else 7787 throw new Error("Invalid extension type"); 7788 return typeof ext.type == "string" && (ext.type = [ext.type]), ext; 7789}, normalizePriority = (ext, defaultPriority) => normalizeExtension(ext).priority ?? defaultPriority, extensions$1 = { 7790 /** @ignore */ 7791 _addHandlers: {}, 7792 /** @ignore */ 7793 _removeHandlers: {}, 7794 /** @ignore */ 7795 _queue: {}, 7796 /** 7797 * Remove extensions from PixiJS. 7798 * @param extensions - Extensions to be removed. 7799 * @returns {PIXI.extensions} For chaining. 7800 */ 7801 remove(...extensions2) { 7802 return extensions2.map(normalizeExtension).forEach((ext) => { 7803 ext.type.forEach((type) => this._removeHandlers[type]?.(ext)); 7804 }), this; 7805 }, 7806 /** 7807 * Register new extensions with PixiJS. 7808 * @param extensions - The spread of extensions to add to PixiJS. 7809 * @returns {PIXI.extensions} For chaining. 7810 */ 7811 add(...extensions2) { 7812 return extensions2.map(normalizeExtension).forEach((ext) => { 7813 ext.type.forEach((type) => { 7814 const handlers = this._addHandlers, queue = this._queue; 7815 handlers[type] ? handlers[type](ext) : (queue[type] = queue[type] || [], queue[type].push(ext)); 7816 }); 7817 }), this; 7818 }, 7819 /** 7820 * Internal method to handle extensions by name. 7821 * @param type - The extension type. 7822 * @param onAdd - Function for handling when extensions are added/registered passes {@link PIXI.ExtensionFormat}. 7823 * @param onRemove - Function for handling when extensions are removed/unregistered passes {@link PIXI.ExtensionFormat}. 7824 * @returns {PIXI.extensions} For chaining. 7825 */ 7826 handle(type, onAdd, onRemove) { 7827 const addHandlers = this._addHandlers, removeHandlers = this._removeHandlers; 7828 if (addHandlers[type] || removeHandlers[type]) 7829 throw new Error(`Extension type ${type} already has a handler`); 7830 addHandlers[type] = onAdd, removeHandlers[type] = onRemove; 7831 const queue = this._queue; 7832 return queue[type] && (queue[type].forEach((ext) => onAdd(ext)), delete queue[type]), this; 7833 }, 7834 /** 7835 * Handle a type, but using a map by `name` property. 7836 * @param type - Type of extension to handle. 7837 * @param map - The object map of named extensions. 7838 * @returns {PIXI.extensions} For chaining. 7839 */ 7840 handleByMap(type, map) { 7841 return this.handle( 7842 type, 7843 (extension) => { 7844 map[extension.name] = extension.ref; 7845 }, 7846 (extension) => { 7847 delete map[extension.name]; 7848 } 7849 ); 7850 }, 7851 /** 7852 * Handle a type, but using a list of extensions. 7853 * @param type - Type of extension to handle. 7854 * @param list - The list of extensions. 7855 * @param defaultPriority - The default priority to use if none is specified. 7856 * @returns {PIXI.extensions} For chaining. 7857 */ 7858 handleByList(type, list, defaultPriority = -1) { 7859 return this.handle( 7860 type, 7861 (extension) => { 7862 list.includes(extension.ref) || (list.push(extension.ref), list.sort((a, b) => normalizePriority(b, defaultPriority) - normalizePriority(a, defaultPriority))); 7863 }, 7864 (extension) => { 7865 const index = list.indexOf(extension.ref); 7866 index !== -1 && list.splice(index, 1); 7867 } 7868 ); 7869 } 7870}; 7871 7872class ViewableBuffer { 7873 constructor(sizeOrBuffer) { 7874 typeof sizeOrBuffer == "number" ? this.rawBinaryData = new ArrayBuffer(sizeOrBuffer) : sizeOrBuffer instanceof Uint8Array ? this.rawBinaryData = sizeOrBuffer.buffer : this.rawBinaryData = sizeOrBuffer, this.uint32View = new Uint32Array(this.rawBinaryData), this.float32View = new Float32Array(this.rawBinaryData); 7875 } 7876 /** View on the raw binary data as a `Int8Array`. */ 7877 get int8View() { 7878 return this._int8View || (this._int8View = new Int8Array(this.rawBinaryData)), this._int8View; 7879 } 7880 /** View on the raw binary data as a `Uint8Array`. */ 7881 get uint8View() { 7882 return this._uint8View || (this._uint8View = new Uint8Array(this.rawBinaryData)), this._uint8View; 7883 } 7884 /** View on the raw binary data as a `Int16Array`. */ 7885 get int16View() { 7886 return this._int16View || (this._int16View = new Int16Array(this.rawBinaryData)), this._int16View; 7887 } 7888 /** View on the raw binary data as a `Uint16Array`. */ 7889 get uint16View() { 7890 return this._uint16View || (this._uint16View = new Uint16Array(this.rawBinaryData)), this._uint16View; 7891 } 7892 /** View on the raw binary data as a `Int32Array`. */ 7893 get int32View() { 7894 return this._int32View || (this._int32View = new Int32Array(this.rawBinaryData)), this._int32View; 7895 } 7896 /** 7897 * Returns the view of the given type. 7898 * @param type - One of `int8`, `uint8`, `int16`, 7899 * `uint16`, `int32`, `uint32`, and `float32`. 7900 * @returns - typed array of given type 7901 */ 7902 view(type) { 7903 return this[`${type}View`]; 7904 } 7905 /** Destroys all buffer references. Do not use after calling this. */ 7906 destroy() { 7907 this.rawBinaryData = null, this._int8View = null, this._uint8View = null, this._int16View = null, this._uint16View = null, this._int32View = null, this.uint32View = null, this.float32View = null; 7908 } 7909 static sizeOf(type) { 7910 switch (type) { 7911 case "int8": 7912 case "uint8": 7913 return 1; 7914 case "int16": 7915 case "uint16": 7916 return 2; 7917 case "int32": 7918 case "uint32": 7919 case "float32": 7920 return 4; 7921 default: 7922 throw new Error(`${type} isn't a valid view type`); 7923 } 7924 } 7925} 7926 7927const fragTemplate$1 = [ 7928 "precision mediump float;", 7929 "void main(void){", 7930 "float test = 0.1;", 7931 "%forloop%", 7932 "gl_FragColor = vec4(0.0);", 7933 "}" 7934].join(` 7935`); 7936function generateIfTestSrc(maxIfs) { 7937 let src = ""; 7938 for (let i = 0; i < maxIfs; ++i) 7939 i > 0 && (src += ` 7940else `), i < maxIfs - 1 && (src += `if(test == ${i}.0){}`); 7941 return src; 7942} 7943function checkMaxIfStatementsInShader(maxIfs, gl) { 7944 if (maxIfs === 0) 7945 throw new Error("Invalid value of `0` passed to `checkMaxIfStatementsInShader`"); 7946 const shader = gl.createShader(gl.FRAGMENT_SHADER); 7947 for (; ; ) { 7948 const fragmentSrc = fragTemplate$1.replace(/%forloop%/gi, generateIfTestSrc(maxIfs)); 7949 if (gl.shaderSource(shader, fragmentSrc), gl.compileShader(shader), !gl.getShaderParameter(shader, gl.COMPILE_STATUS)) 7950 maxIfs = maxIfs / 2 | 0; 7951 else 7952 break; 7953 }
vendor: 77,143 bytes, lines 7954-9845
7954 return maxIfs; 7955} 7956 7957const BLEND$1 = 0, OFFSET$1 = 1, CULLING$1 = 2, DEPTH_TEST$1 = 3, WINDING$1 = 4, DEPTH_MASK$1 = 5; 7958class State { 7959 constructor() { 7960 this.data = 0, this.blendMode = BLEND_MODES.NORMAL, this.polygonOffset = 0, this.blend = !0, this.depthMask = !0; 7961 } 7962 /** 7963 * Activates blending of the computed fragment color values. 7964 * @default true 7965 */ 7966 get blend() { 7967 return !!(this.data & 1 << BLEND$1); 7968 } 7969 set blend(value) { 7970 !!(this.data & 1 << BLEND$1) !== value && (this.data ^= 1 << BLEND$1); 7971 } 7972 /** 7973 * Activates adding an offset to depth values of polygon's fragments 7974 * @default false 7975 */ 7976 get offsets() { 7977 return !!(this.data & 1 << OFFSET$1); 7978 } 7979 set offsets(value) { 7980 !!(this.data & 1 << OFFSET$1) !== value && (this.data ^= 1 << OFFSET$1); 7981 } 7982 /** 7983 * Activates culling of polygons. 7984 * @default false 7985 */ 7986 get culling() { 7987 return !!(this.data & 1 << CULLING$1); 7988 } 7989 set culling(value) { 7990 !!(this.data & 1 << CULLING$1) !== value && (this.data ^= 1 << CULLING$1); 7991 } 7992 /** 7993 * Activates depth comparisons and updates to the depth buffer. 7994 * @default false 7995 */ 7996 get depthTest() { 7997 return !!(this.data & 1 << DEPTH_TEST$1); 7998 } 7999 set depthTest(value) { 8000 !!(this.data & 1 << DEPTH_TEST$1) !== value && (this.data ^= 1 << DEPTH_TEST$1); 8001 } 8002 /** 8003 * Enables or disables writing to the depth buffer. 8004 * @default true 8005 */ 8006 get depthMask() { 8007 return !!(this.data & 1 << DEPTH_MASK$1); 8008 } 8009 set depthMask(value) { 8010 !!(this.data & 1 << DEPTH_MASK$1) !== value && (this.data ^= 1 << DEPTH_MASK$1); 8011 } 8012 /** 8013 * Specifies whether or not front or back-facing polygons can be culled. 8014 * @default false 8015 */ 8016 get clockwiseFrontFace() { 8017 return !!(this.data & 1 << WINDING$1); 8018 } 8019 set clockwiseFrontFace(value) { 8020 !!(this.data & 1 << WINDING$1) !== value && (this.data ^= 1 << WINDING$1); 8021 } 8022 /** 8023 * The blend mode to be applied when this state is set. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. 8024 * Setting this mode to anything other than NO_BLEND will automatically switch blending on. 8025 * @default PIXI.BLEND_MODES.NORMAL 8026 */ 8027 get blendMode() { 8028 return this._blendMode; 8029 } 8030 set blendMode(value) { 8031 this.blend = value !== BLEND_MODES.NONE, this._blendMode = value; 8032 } 8033 /** 8034 * The polygon offset. Setting this property to anything other than 0 will automatically enable polygon offset fill. 8035 * @default 0 8036 */ 8037 get polygonOffset() { 8038 return this._polygonOffset; 8039 } 8040 set polygonOffset(value) { 8041 this.offsets = !!value, this._polygonOffset = value; 8042 } 8043 static for2d() { 8044 const state = new State(); 8045 return state.depthTest = !1, state.blend = !0, state; 8046 } 8047} 8048State.prototype.toString = function() { 8049 return `[@pixi/core:State blendMode=${this.blendMode} clockwiseFrontFace=${this.clockwiseFrontFace} culling=${this.culling} depthMask=${this.depthMask} polygonOffset=${this.polygonOffset}]`; 8050}; 8051 8052const INSTALLED = []; 8053function autoDetectResource(source, options) { 8054 if (!source) 8055 return null; 8056 let extension = ""; 8057 if (typeof source == "string") { 8058 const result = /\.(\w{3,4})(?:$|\?|#)/i.exec(source); 8059 result && (extension = result[1].toLowerCase()); 8060 } 8061 for (let i = INSTALLED.length - 1; i >= 0; --i) { 8062 const ResourcePlugin = INSTALLED[i]; 8063 if (ResourcePlugin.test && ResourcePlugin.test(source, extension)) 8064 return new ResourcePlugin(source, options); 8065 } 8066 throw new Error("Unrecognized source type to auto-detect Resource"); 8067} 8068 8069class Runner { 8070 /** 8071 * @param name - The function name that will be executed on the listeners added to this Runner. 8072 */ 8073 constructor(name) { 8074 this.items = [], this._name = name, this._aliasCount = 0; 8075 } 8076 /* eslint-disable jsdoc/require-param, jsdoc/check-param-names */ 8077 /** 8078 * Dispatch/Broadcast Runner to all listeners added to the queue. 8079 * @param {...any} params - (optional) parameters to pass to each listener 8080 */ 8081 /* eslint-enable jsdoc/require-param, jsdoc/check-param-names */ 8082 emit(a0, a1, a2, a3, a4, a5, a6, a7) { 8083 if (arguments.length > 8) 8084 throw new Error("max arguments reached"); 8085 const { name, items } = this; 8086 this._aliasCount++; 8087 for (let i = 0, len = items.length; i < len; i++) 8088 items[i][name](a0, a1, a2, a3, a4, a5, a6, a7); 8089 return items === this.items && this._aliasCount--, this; 8090 } 8091 ensureNonAliasedItems() { 8092 this._aliasCount > 0 && this.items.length > 1 && (this._aliasCount = 0, this.items = this.items.slice(0)); 8093 } 8094 /** 8095 * Add a listener to the Runner 8096 * 8097 * Runners do not need to have scope or functions passed to them. 8098 * All that is required is to pass the listening object and ensure that it has contains a function that has the same name 8099 * as the name provided to the Runner when it was created. 8100 * 8101 * E.g. A listener passed to this Runner will require a 'complete' function. 8102 * 8103 * ```js 8104 * import { Runner } from '@pixi/runner'; 8105 * 8106 * const complete = new Runner('complete'); 8107 * ``` 8108 * 8109 * The scope used will be the object itself. 8110 * @param {any} item - The object that will be listening. 8111 */ 8112 add(item) { 8113 return item[this._name] && (this.ensureNonAliasedItems(), this.remove(item), this.items.push(item)), this; 8114 } 8115 /** 8116 * Remove a single listener from the dispatch queue. 8117 * @param {any} item - The listener that you would like to remove. 8118 */ 8119 remove(item) { 8120 const index = this.items.indexOf(item); 8121 return index !== -1 && (this.ensureNonAliasedItems(), this.items.splice(index, 1)), this; 8122 } 8123 /** 8124 * Check to see if the listener is already in the Runner 8125 * @param {any} item - The listener that you would like to check. 8126 */ 8127 contains(item) { 8128 return this.items.includes(item); 8129 } 8130 /** Remove all listeners from the Runner */ 8131 removeAll() { 8132 return this.ensureNonAliasedItems(), this.items.length = 0, this; 8133 } 8134 /** Remove all references, don't use after this. */ 8135 destroy() { 8136 this.removeAll(), this.items = null, this._name = null; 8137 } 8138 /** 8139 * `true` if there are no this Runner contains no listeners 8140 * @readonly 8141 */ 8142 get empty() { 8143 return this.items.length === 0; 8144 } 8145 /** 8146 * The name of the runner. 8147 * @readonly 8148 */ 8149 get name() { 8150 return this._name; 8151 } 8152} 8153Object.defineProperties(Runner.prototype, { 8154 /** 8155 * Alias for `emit` 8156 * @memberof PIXI.Runner# 8157 * @method dispatch 8158 * @see PIXI.Runner#emit 8159 */ 8160 dispatch: { value: Runner.prototype.emit }, 8161 /** 8162 * Alias for `emit` 8163 * @memberof PIXI.Runner# 8164 * @method run 8165 * @see PIXI.Runner#emit 8166 */ 8167 run: { value: Runner.prototype.emit } 8168}); 8169 8170class Resource { 8171 /** 8172 * @param width - Width of the resource 8173 * @param height - Height of the resource 8174 */ 8175 constructor(width = 0, height = 0) { 8176 this._width = width, this._height = height, this.destroyed = !1, this.internal = !1, this.onResize = new Runner("setRealSize"), this.onUpdate = new Runner("update"), this.onError = new Runner("onError"); 8177 } 8178 /** 8179 * Bind to a parent BaseTexture 8180 * @param baseTexture - Parent texture 8181 */ 8182 bind(baseTexture) { 8183 this.onResize.add(baseTexture), this.onUpdate.add(baseTexture), this.onError.add(baseTexture), (this._width || this._height) && this.onResize.emit(this._width, this._height); 8184 } 8185 /** 8186 * Unbind to a parent BaseTexture 8187 * @param baseTexture - Parent texture 8188 */ 8189 unbind(baseTexture) { 8190 this.onResize.remove(baseTexture), this.onUpdate.remove(baseTexture), this.onError.remove(baseTexture); 8191 } 8192 /** 8193 * Trigger a resize event 8194 * @param width - X dimension 8195 * @param height - Y dimension 8196 */ 8197 resize(width, height) { 8198 (width !== this._width || height !== this._height) && (this._width = width, this._height = height, this.onResize.emit(width, height)); 8199 } 8200 /** 8201 * Has been validated 8202 * @readonly 8203 */ 8204 get valid() { 8205 return !!this._width && !!this._height; 8206 } 8207 /** Has been updated trigger event. */ 8208 update() { 8209 this.destroyed || this.onUpdate.emit(); 8210 } 8211 /** 8212 * This can be overridden to start preloading a resource 8213 * or do any other prepare step. 8214 * @protected 8215 * @returns Handle the validate event 8216 */ 8217 load() { 8218 return Promise.resolve(this); 8219 } 8220 /** 8221 * The width of the resource. 8222 * @readonly 8223 */ 8224 get width() { 8225 return this._width; 8226 } 8227 /** 8228 * The height of the resource. 8229 * @readonly 8230 */ 8231 get height() { 8232 return this._height; 8233 } 8234 /** 8235 * Set the style, optional to override 8236 * @param _renderer - yeah, renderer! 8237 * @param _baseTexture - the texture 8238 * @param _glTexture - texture instance for this webgl context 8239 * @returns - `true` is success 8240 */ 8241 style(_renderer, _baseTexture, _glTexture) { 8242 return !1; 8243 } 8244 /** Clean up anything, this happens when destroying is ready. */ 8245 dispose() { 8246 } 8247 /** 8248 * Call when destroying resource, unbind any BaseTexture object 8249 * before calling this method, as reference counts are maintained 8250 * internally. 8251 */ 8252 destroy() { 8253 this.destroyed || (this.destroyed = !0, this.dispose(), this.onError.removeAll(), this.onError = null, this.onResize.removeAll(), this.onResize = null, this.onUpdate.removeAll(), this.onUpdate = null); 8254 } 8255 /** 8256 * Abstract, used to auto-detect resource type. 8257 * @param {*} _source - The source object 8258 * @param {string} _extension - The extension of source, if set 8259 */ 8260 static test(_source, _extension) { 8261 return !1; 8262 } 8263} 8264 8265class BufferResource extends Resource { 8266 /** 8267 * @param source - Source buffer 8268 * @param options - Options 8269 * @param {number} options.width - Width of the texture 8270 * @param {number} options.height - Height of the texture 8271 * @param {1|2|4|8} [options.unpackAlignment=4] - The alignment of the pixel rows. 8272 */ 8273 constructor(source, options) { 8274 const { width, height } = options || {}; 8275 if (!width || !height) 8276 throw new Error("BufferResource width or height invalid"); 8277 super(width, height), this.data = source, this.unpackAlignment = options.unpackAlignment ?? 4; 8278 } 8279 /** 8280 * Upload the texture to the GPU. 8281 * @param renderer - Upload to the renderer 8282 * @param baseTexture - Reference to parent texture 8283 * @param glTexture - glTexture 8284 * @returns - true is success 8285 */ 8286 upload(renderer, baseTexture, glTexture) { 8287 const gl = renderer.gl; 8288 gl.pixelStorei(gl.UNPACK_ALIGNMENT, this.unpackAlignment), gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, baseTexture.alphaMode === ALPHA_MODES.UNPACK); 8289 const width = baseTexture.realWidth, height = baseTexture.realHeight; 8290 return glTexture.width === width && glTexture.height === height ? gl.texSubImage2D( 8291 baseTexture.target, 8292 0, 8293 0, 8294 0, 8295 width, 8296 height, 8297 baseTexture.format, 8298 glTexture.type, 8299 this.data 8300 ) : (glTexture.width = width, glTexture.height = height, gl.texImage2D( 8301 baseTexture.target, 8302 0, 8303 glTexture.internalFormat, 8304 width, 8305 height, 8306 0, 8307 baseTexture.format, 8308 glTexture.type, 8309 this.data 8310 )), !0; 8311 } 8312 /** Destroy and don't use after this. */ 8313 dispose() { 8314 this.data = null; 8315 } 8316 /** 8317 * Used to auto-detect the type of resource. 8318 * @param {*} source - The source object 8319 * @returns {boolean} `true` if buffer source 8320 */ 8321 static test(source) { 8322 return source === null || source instanceof Int8Array || source instanceof Uint8Array || source instanceof Uint8ClampedArray || source instanceof Int16Array || source instanceof Uint16Array || source instanceof Int32Array || source instanceof Uint32Array || source instanceof Float32Array; 8323 } 8324} 8325 8326const defaultBufferOptions = { 8327 scaleMode: SCALE_MODES.NEAREST, 8328 alphaMode: ALPHA_MODES.NPM 8329}, _BaseTexture = class _BaseTexture2 extends EventEmitter { 8330 /** 8331 * @param {PIXI.Resource|HTMLImageElement|HTMLVideoElement|ImageBitmap|ICanvas|string} [resource=null] - 8332 * The current resource to use, for things that aren't Resource objects, will be converted 8333 * into a Resource. 8334 * @param options - Collection of options, default options inherited from {@link PIXI.BaseTexture.defaultOptions}. 8335 * @param {PIXI.MIPMAP_MODES} [options.mipmap] - If mipmapping is enabled for texture 8336 * @param {number} [options.anisotropicLevel] - Anisotropic filtering level of texture 8337 * @param {PIXI.WRAP_MODES} [options.wrapMode] - Wrap mode for textures 8338 * @param {PIXI.SCALE_MODES} [options.scaleMode] - Default scale mode, linear, nearest 8339 * @param {PIXI.FORMATS} [options.format] - GL format type 8340 * @param {PIXI.TYPES} [options.type] - GL data type 8341 * @param {PIXI.TARGETS} [options.target] - GL texture target 8342 * @param {PIXI.ALPHA_MODES} [options.alphaMode] - Pre multiply the image alpha 8343 * @param {number} [options.width=0] - Width of the texture 8344 * @param {number} [options.height=0] - Height of the texture 8345 * @param {number} [options.resolution=PIXI.settings.RESOLUTION] - Resolution of the base texture 8346 * @param {object} [options.resourceOptions] - Optional resource options, 8347 * see {@link PIXI.autoDetectResource autoDetectResource} 8348 */ 8349 constructor(resource = null, options = null) { 8350 super(), options = Object.assign({}, _BaseTexture2.defaultOptions, options); 8351 const { 8352 alphaMode, 8353 mipmap, 8354 anisotropicLevel, 8355 scaleMode, 8356 width, 8357 height, 8358 wrapMode, 8359 format, 8360 type, 8361 target, 8362 resolution, 8363 resourceOptions 8364 } = options; 8365 resource && !(resource instanceof Resource) && (resource = autoDetectResource(resource, resourceOptions), resource.internal = !0), this.resolution = resolution || settings.RESOLUTION, this.width = Math.round((width || 0) * this.resolution) / this.resolution, this.height = Math.round((height || 0) * this.resolution) / this.resolution, this._mipmap = mipmap, this.anisotropicLevel = anisotropicLevel, this._wrapMode = wrapMode, this._scaleMode = scaleMode, this.format = format, this.type = type, this.target = target, this.alphaMode = alphaMode, this.uid = uid(), this.touched = 0, this.isPowerOfTwo = !1, this._refreshPOT(), this._glTextures = {}, this.dirtyId = 0, this.dirtyStyleId = 0, this.cacheId = null, this.valid = width > 0 && height > 0, this.textureCacheIds = [], this.destroyed = !1, this.resource = null, this._batchEnabled = 0, this._batchLocation = 0, this.parentTextureArray = null, this.setResource(resource); 8366 } 8367 /** 8368 * Pixel width of the source of this texture 8369 * @readonly 8370 */ 8371 get realWidth() { 8372 return Math.round(this.width * this.resolution); 8373 } 8374 /** 8375 * Pixel height of the source of this texture 8376 * @readonly 8377 */ 8378 get realHeight() { 8379 return Math.round(this.height * this.resolution); 8380 } 8381 /** 8382 * Mipmap mode of the texture, affects downscaled images 8383 * @default PIXI.MIPMAP_MODES.POW2 8384 */ 8385 get mipmap() { 8386 return this._mipmap; 8387 } 8388 set mipmap(value) { 8389 this._mipmap !== value && (this._mipmap = value, this.dirtyStyleId++); 8390 } 8391 /** 8392 * The scale mode to apply when scaling this texture 8393 * @default PIXI.SCALE_MODES.LINEAR 8394 */ 8395 get scaleMode() { 8396 return this._scaleMode; 8397 } 8398 set scaleMode(value) { 8399 this._scaleMode !== value && (this._scaleMode = value, this.dirtyStyleId++); 8400 } 8401 /** 8402 * How the texture wraps 8403 * @default PIXI.WRAP_MODES.CLAMP 8404 */ 8405 get wrapMode() { 8406 return this._wrapMode; 8407 } 8408 set wrapMode(value) { 8409 this._wrapMode !== value && (this._wrapMode = value, this.dirtyStyleId++); 8410 } 8411 /** 8412 * Changes style options of BaseTexture 8413 * @param scaleMode - Pixi scalemode 8414 * @param mipmap - enable mipmaps 8415 * @returns - this 8416 */ 8417 setStyle(scaleMode, mipmap) { 8418 let dirty; 8419 return scaleMode !== void 0 && scaleMode !== this.scaleMode && (this.scaleMode = scaleMode, dirty = !0), mipmap !== void 0 && mipmap !== this.mipmap && (this.mipmap = mipmap, dirty = !0), dirty && this.dirtyStyleId++, this; 8420 } 8421 /** 8422 * Changes w/h/resolution. Texture becomes valid if width and height are greater than zero. 8423 * @param desiredWidth - Desired visual width 8424 * @param desiredHeight - Desired visual height 8425 * @param resolution - Optionally set resolution 8426 * @returns - this 8427 */ 8428 setSize(desiredWidth, desiredHeight, resolution) { 8429 return resolution = resolution || this.resolution, this.setRealSize(desiredWidth * resolution, desiredHeight * resolution, resolution); 8430 } 8431 /** 8432 * Sets real size of baseTexture, preserves current resolution. 8433 * @param realWidth - Full rendered width 8434 * @param realHeight - Full rendered height 8435 * @param resolution - Optionally set resolution 8436 * @returns - this 8437 */ 8438 setRealSize(realWidth, realHeight, resolution) { 8439 return this.resolution = resolution || this.resolution, this.width = Math.round(realWidth) / this.resolution, this.height = Math.round(realHeight) / this.resolution, this._refreshPOT(), this.update(), this; 8440 } 8441 /** 8442 * Refresh check for isPowerOfTwo texture based on size 8443 * @private 8444 */ 8445 _refreshPOT() { 8446 this.isPowerOfTwo = isPow2(this.realWidth) && isPow2(this.realHeight); 8447 } 8448 /** 8449 * Changes resolution 8450 * @param resolution - res 8451 * @returns - this 8452 */ 8453 setResolution(resolution) { 8454 const oldResolution = this.resolution; 8455 return oldResolution === resolution ? this : (this.resolution = resolution, this.valid && (this.width = Math.round(this.width * oldResolution) / resolution, this.height = Math.round(this.height * oldResolution) / resolution, this.emit("update", this)), this._refreshPOT(), this); 8456 } 8457 /** 8458 * Sets the resource if it wasn't set. Throws error if resource already present 8459 * @param resource - that is managing this BaseTexture 8460 * @returns - this 8461 */ 8462 setResource(resource) { 8463 if (this.resource === resource) 8464 return this; 8465 if (this.resource) 8466 throw new Error("Resource can be set only once"); 8467 return resource.bind(this), this.resource = resource, this; 8468 } 8469 /** Invalidates the object. Texture becomes valid if width and height are greater than zero. */ 8470 update() { 8471 this.valid ? (this.dirtyId++, this.dirtyStyleId++, this.emit("update", this)) : this.width > 0 && this.height > 0 && (this.valid = !0, this.emit("loaded", this), this.emit("update", this)); 8472 } 8473 /** 8474 * Handle errors with resources. 8475 * @private 8476 * @param event - Error event emitted. 8477 */ 8478 onError(event) { 8479 this.emit("error", this, event); 8480 } 8481 /** 8482 * Destroys this base texture. 8483 * The method stops if resource doesn't want this texture to be destroyed. 8484 * Removes texture from all caches. 8485 * @fires PIXI.BaseTexture#destroyed 8486 */ 8487 destroy() { 8488 this.resource && (this.resource.unbind(this), this.resource.internal && this.resource.destroy(), this.resource = null), this.cacheId && (delete BaseTextureCache[this.cacheId], delete TextureCache[this.cacheId], this.cacheId = null), this.valid = !1, this.dispose(), _BaseTexture2.removeFromCache(this), this.textureCacheIds = null, this.destroyed = !0, this.emit("destroyed", this), this.removeAllListeners(); 8489 } 8490 /** 8491 * Frees the texture from WebGL memory without destroying this texture object. 8492 * This means you can still use the texture later which will upload it to GPU 8493 * memory again. 8494 * @fires PIXI.BaseTexture#dispose 8495 */ 8496 dispose() { 8497 this.emit("dispose", this); 8498 } 8499 /** Utility function for BaseTexture|Texture cast. */ 8500 castToBaseTexture() { 8501 return this; 8502 } 8503 /** 8504 * Helper function that creates a base texture based on the source you provide. 8505 * The source can be - image url, image element, canvas element. If the 8506 * source is an image url or an image element and not in the base texture 8507 * cache, it will be created and loaded. 8508 * @static 8509 * @param {HTMLImageElement|HTMLVideoElement|ImageBitmap|PIXI.ICanvas|string|string[]} source - The 8510 * source to create base texture from. 8511 * @param options - See {@link PIXI.BaseTexture}'s constructor for options. 8512 * @param {string} [options.pixiIdPrefix=pixiid] - If a source has no id, this is the prefix of the generated id 8513 * @param {boolean} [strict] - Enforce strict-mode, see {@link PIXI.settings.STRICT_TEXTURE_CACHE}. 8514 * @returns {PIXI.BaseTexture} The new base texture. 8515 */ 8516 static from(source, options, strict = settings.STRICT_TEXTURE_CACHE) { 8517 const isFrame = typeof source == "string"; 8518 let cacheId = null; 8519 if (isFrame) 8520 cacheId = source; 8521 else { 8522 if (!source._pixiId) { 8523 const prefix = options?.pixiIdPrefix || "pixiid"; 8524 source._pixiId = `${prefix}_${uid()}`; 8525 } 8526 cacheId = source._pixiId; 8527 } 8528 let baseTexture = BaseTextureCache[cacheId]; 8529 if (isFrame && strict && !baseTexture) 8530 throw new Error(`The cacheId "${cacheId}" does not exist in BaseTextureCache.`); 8531 return baseTexture || (baseTexture = new _BaseTexture2(source, options), baseTexture.cacheId = cacheId, _BaseTexture2.addToCache(baseTexture, cacheId)), baseTexture; 8532 } 8533 /** 8534 * Create a new Texture with a BufferResource from a typed array. 8535 * @param buffer - The optional array to use. If no data is provided, a new Float32Array is created. 8536 * @param width - Width of the resource 8537 * @param height - Height of the resource 8538 * @param options - See {@link PIXI.BaseTexture}'s constructor for options. 8539 * Default properties are different from the constructor's defaults. 8540 * @param {PIXI.FORMATS} [options.format] - The format is not given, the type is inferred from the 8541 * type of the buffer: `RGBA` if Float32Array, Int8Array, Uint8Array, or Uint8ClampedArray, 8542 * otherwise `RGBA_INTEGER`. 8543 * @param {PIXI.TYPES} [options.type] - The type is not given, the type is inferred from the 8544 * type of the buffer. Maps Float32Array to `FLOAT`, Int32Array to `INT`, Uint32Array to 8545 * `UNSIGNED_INT`, Int16Array to `SHORT`, Uint16Array to `UNSIGNED_SHORT`, Int8Array to `BYTE`, 8546 * Uint8Array/Uint8ClampedArray to `UNSIGNED_BYTE`. 8547 * @param {PIXI.ALPHA_MODES} [options.alphaMode=PIXI.ALPHA_MODES.NPM] 8548 * @param {PIXI.SCALE_MODES} [options.scaleMode=PIXI.SCALE_MODES.NEAREST] 8549 * @returns - The resulting new BaseTexture 8550 */ 8551 static fromBuffer(buffer, width, height, options) { 8552 buffer = buffer || new Float32Array(width * height * 4); 8553 const resource = new BufferResource(buffer, { width, height, ...options?.resourceOptions }); 8554 let format, type; 8555 return buffer instanceof Float32Array ? (format = FORMATS.RGBA, type = TYPES.FLOAT) : buffer instanceof Int32Array ? (format = FORMATS.RGBA_INTEGER, type = TYPES.INT) : buffer instanceof Uint32Array ? (format = FORMATS.RGBA_INTEGER, type = TYPES.UNSIGNED_INT) : buffer instanceof Int16Array ? (format = FORMATS.RGBA_INTEGER, type = TYPES.SHORT) : buffer instanceof Uint16Array ? (format = FORMATS.RGBA_INTEGER, type = TYPES.UNSIGNED_SHORT) : buffer instanceof Int8Array ? (format = FORMATS.RGBA, type = TYPES.BYTE) : (format = FORMATS.RGBA, type = TYPES.UNSIGNED_BYTE), resource.internal = !0, new _BaseTexture2(resource, Object.assign({}, defaultBufferOptions, { type, format }, options)); 8556 } 8557 /** 8558 * Adds a BaseTexture to the global BaseTextureCache. This cache is shared across the whole PIXI object. 8559 * @param {PIXI.BaseTexture} baseTexture - The BaseTexture to add to the cache. 8560 * @param {string} id - The id that the BaseTexture will be stored against. 8561 */ 8562 static addToCache(baseTexture, id) { 8563 id && (baseTexture.textureCacheIds.includes(id) || baseTexture.textureCacheIds.push(id), BaseTextureCache[id] && BaseTextureCache[id] !== baseTexture && console.warn(`BaseTexture added to the cache with an id [${id}] that already had an entry`), BaseTextureCache[id] = baseTexture); 8564 } 8565 /** 8566 * Remove a BaseTexture from the global BaseTextureCache. 8567 * @param {string|PIXI.BaseTexture} baseTexture - id of a BaseTexture to be removed, or a BaseTexture instance itself. 8568 * @returns {PIXI.BaseTexture|null} The BaseTexture that was removed. 8569 */ 8570 static removeFromCache(baseTexture) { 8571 if (typeof baseTexture == "string") { 8572 const baseTextureFromCache = BaseTextureCache[baseTexture]; 8573 if (baseTextureFromCache) { 8574 const index = baseTextureFromCache.textureCacheIds.indexOf(baseTexture); 8575 return index > -1 && baseTextureFromCache.textureCacheIds.splice(index, 1), delete BaseTextureCache[baseTexture], baseTextureFromCache; 8576 } 8577 } else if (baseTexture?.textureCacheIds) { 8578 for (let i = 0; i < baseTexture.textureCacheIds.length; ++i) 8579 delete BaseTextureCache[baseTexture.textureCacheIds[i]]; 8580 return baseTexture.textureCacheIds.length = 0, baseTexture; 8581 } 8582 return null; 8583 } 8584}; 8585_BaseTexture.defaultOptions = { 8586 /** 8587 * If mipmapping is enabled for texture. 8588 * @type {PIXI.MIPMAP_MODES} 8589 * @default PIXI.MIPMAP_MODES.POW2 8590 */ 8591 mipmap: MIPMAP_MODES.POW2, 8592 /** Anisotropic filtering level of texture */ 8593 anisotropicLevel: 0, 8594 /** 8595 * Default scale mode, linear, nearest. 8596 * @type {PIXI.SCALE_MODES} 8597 * @default PIXI.SCALE_MODES.LINEAR 8598 */ 8599 scaleMode: SCALE_MODES.LINEAR, 8600 /** 8601 * Wrap mode for textures. 8602 * @type {PIXI.WRAP_MODES} 8603 * @default PIXI.WRAP_MODES.CLAMP 8604 */ 8605 wrapMode: WRAP_MODES.CLAMP, 8606 /** 8607 * Pre multiply the image alpha 8608 * @type {PIXI.ALPHA_MODES} 8609 * @default PIXI.ALPHA_MODES.UNPACK 8610 */ 8611 alphaMode: ALPHA_MODES.UNPACK, 8612 /** 8613 * GL texture target 8614 * @type {PIXI.TARGETS} 8615 * @default PIXI.TARGETS.TEXTURE_2D 8616 */ 8617 target: TARGETS.TEXTURE_2D, 8618 /** 8619 * GL format type 8620 * @type {PIXI.FORMATS} 8621 * @default PIXI.FORMATS.RGBA 8622 */ 8623 format: FORMATS.RGBA, 8624 /** 8625 * GL data type 8626 * @type {PIXI.TYPES} 8627 * @default PIXI.TYPES.UNSIGNED_BYTE 8628 */ 8629 type: TYPES.UNSIGNED_BYTE 8630}, /** Global number of the texture batch, used by multi-texture renderers. */ 8631_BaseTexture._globalBatch = 0; 8632let BaseTexture = _BaseTexture; 8633 8634class BatchDrawCall { 8635 constructor() { 8636 this.texArray = null, this.blend = 0, this.type = DRAW_MODES.TRIANGLES, this.start = 0, this.size = 0, this.data = null; 8637 } 8638} 8639 8640let UID$4 = 0; 8641class Buffer { 8642 /** 8643 * @param {PIXI.IArrayBuffer} data - the data to store in the buffer. 8644 * @param _static - `true` for static buffer 8645 * @param index - `true` for index buffer 8646 */ 8647 constructor(data, _static = !0, index = !1) { 8648 this.data = data || new Float32Array(1), this._glBuffers = {}, this._updateID = 0, this.index = index, this.static = _static, this.id = UID$4++, this.disposeRunner = new Runner("disposeBuffer"); 8649 } 8650 // TODO could explore flagging only a partial upload? 8651 /** 8652 * Flags this buffer as requiring an upload to the GPU. 8653 * @param {PIXI.IArrayBuffer|number[]} [data] - the data to update in the buffer. 8654 */ 8655 update(data) { 8656 data instanceof Array && (data = new Float32Array(data)), this.data = data || this.data, this._updateID++; 8657 } 8658 /** Disposes WebGL resources that are connected to this geometry. */ 8659 dispose() { 8660 this.disposeRunner.emit(this, !1); 8661 } 8662 /** Destroys the buffer. */ 8663 destroy() { 8664 this.dispose(), this.data = null; 8665 } 8666 /** 8667 * Flags whether this is an index buffer. 8668 * 8669 * Index buffers are of type `ELEMENT_ARRAY_BUFFER`. Note that setting this property to false will make 8670 * the buffer of type `ARRAY_BUFFER`. 8671 * 8672 * For backwards compatibility. 8673 */ 8674 set index(value) { 8675 this.type = value ? BUFFER_TYPE.ELEMENT_ARRAY_BUFFER : BUFFER_TYPE.ARRAY_BUFFER; 8676 } 8677 get index() { 8678 return this.type === BUFFER_TYPE.ELEMENT_ARRAY_BUFFER; 8679 } 8680 /** 8681 * Helper function that creates a buffer based on an array or TypedArray 8682 * @param {ArrayBufferView | number[]} data - the TypedArray that the buffer will store. If this is a regular Array it will be converted to a Float32Array. 8683 * @returns - A new Buffer based on the data provided. 8684 */ 8685 static from(data) { 8686 return data instanceof Array && (data = new Float32Array(data)), new Buffer(data); 8687 } 8688} 8689 8690class Attribute { 8691 /** 8692 * @param buffer - the id of the buffer that this attribute will look for 8693 * @param size - the size of the attribute. If you have 2 floats per vertex (eg position x and y) this would be 2. 8694 * @param normalized - should the data be normalized. 8695 * @param {PIXI.TYPES} [type=PIXI.TYPES.FLOAT] - what type of number is the attribute. Check {@link PIXI.TYPES} to see the ones available 8696 * @param [stride=0] - How far apart, in bytes, the start of each value is. (used for interleaving data) 8697 * @param [start=0] - How far into the array to start reading values (used for interleaving data) 8698 * @param [instance=false] - Whether the geometry is instanced. 8699 * @param [divisor=1] - Divisor to use when doing instanced rendering 8700 */ 8701 constructor(buffer, size = 0, normalized = !1, type = TYPES.FLOAT, stride, start, instance, divisor = 1) { 8702 this.buffer = buffer, this.size = size, this.normalized = normalized, this.type = type, this.stride = stride, this.start = start, this.instance = instance, this.divisor = divisor; 8703 } 8704 /** Destroys the Attribute. */ 8705 destroy() { 8706 this.buffer = null; 8707 } 8708 /** 8709 * Helper function that creates an Attribute based on the information provided 8710 * @param buffer - the id of the buffer that this attribute will look for 8711 * @param [size=0] - the size of the attribute. If you have 2 floats per vertex (eg position x and y) this would be 2 8712 * @param [normalized=false] - should the data be normalized. 8713 * @param [type=PIXI.TYPES.FLOAT] - what type of number is the attribute. Check {@link PIXI.TYPES} to see the ones available 8714 * @param [stride=0] - How far apart, in bytes, the start of each value is. (used for interleaving data) 8715 * @returns - A new {@link PIXI.Attribute} based on the information provided 8716 */ 8717 static from(buffer, size, normalized, type, stride) { 8718 return new Attribute(buffer, size, normalized, type, stride); 8719 } 8720} 8721 8722const map$1 = { 8723 Float32Array, 8724 Uint32Array, 8725 Int32Array, 8726 Uint8Array 8727}; 8728function interleaveTypedArrays(arrays, sizes) { 8729 let outSize = 0, stride = 0; 8730 const views = {}; 8731 for (let i = 0; i < arrays.length; i++) 8732 stride += sizes[i], outSize += arrays[i].length; 8733 const buffer = new ArrayBuffer(outSize * 4); 8734 let out = null, littleOffset = 0; 8735 for (let i = 0; i < arrays.length; i++) { 8736 const size = sizes[i], array = arrays[i], type = getBufferType(array); 8737 views[type] || (views[type] = new map$1[type](buffer)), out = views[type]; 8738 for (let j = 0; j < array.length; j++) { 8739 const indexStart = (j / size | 0) * stride + littleOffset, index = j % size; 8740 out[indexStart + index] = array[j]; 8741 } 8742 littleOffset += size; 8743 } 8744 return new Float32Array(buffer); 8745} 8746 8747const byteSizeMap$1 = { 5126: 4, 5123: 2, 5121: 1 }; 8748let UID$3 = 0; 8749const map = { 8750 Float32Array, 8751 Uint32Array, 8752 Int32Array, 8753 Uint8Array, 8754 Uint16Array 8755}; 8756class Geometry { 8757 /** 8758 * @param buffers - An array of buffers. optional. 8759 * @param attributes - Of the geometry, optional structure of the attributes layout 8760 */ 8761 constructor(buffers = [], attributes = {}) { 8762 this.buffers = buffers, this.indexBuffer = null, this.attributes = attributes, this.glVertexArrayObjects = {}, this.id = UID$3++, this.instanced = !1, this.instanceCount = 1, this.disposeRunner = new Runner("disposeGeometry"), this.refCount = 0; 8763 } 8764 /** 8765 * 8766 * Adds an attribute to the geometry 8767 * Note: `stride` and `start` should be `undefined` if you dont know them, not 0! 8768 * @param id - the name of the attribute (matching up to a shader) 8769 * @param {PIXI.Buffer|number[]} buffer - the buffer that holds the data of the attribute . You can also provide an Array and a buffer will be created from it. 8770 * @param size - the size of the attribute. If you have 2 floats per vertex (eg position x and y) this would be 2 8771 * @param normalized - should the data be normalized. 8772 * @param [type=PIXI.TYPES.FLOAT] - what type of number is the attribute. Check {@link PIXI.TYPES} to see the ones available 8773 * @param [stride=0] - How far apart, in bytes, the start of each value is. (used for interleaving data) 8774 * @param [start=0] - How far into the array to start reading values (used for interleaving data) 8775 * @param instance - Instancing flag 8776 * @returns - Returns self, useful for chaining. 8777 */ 8778 addAttribute(id, buffer, size = 0, normalized = !1, type, stride, start, instance = !1) { 8779 if (!buffer) 8780 throw new Error("You must pass a buffer when creating an attribute"); 8781 buffer instanceof Buffer || (buffer instanceof Array && (buffer = new Float32Array(buffer)), buffer = new Buffer(buffer)); 8782 const ids = id.split("|"); 8783 if (ids.length > 1) { 8784 for (let i = 0; i < ids.length; i++) 8785 this.addAttribute(ids[i], buffer, size, normalized, type); 8786 return this; 8787 } 8788 let bufferIndex = this.buffers.indexOf(buffer); 8789 return bufferIndex === -1 && (this.buffers.push(buffer), bufferIndex = this.buffers.length - 1), this.attributes[id] = new Attribute(bufferIndex, size, normalized, type, stride, start, instance), this.instanced = this.instanced || instance, this; 8790 } 8791 /** 8792 * Returns the requested attribute. 8793 * @param id - The name of the attribute required 8794 * @returns - The attribute requested. 8795 */ 8796 getAttribute(id) { 8797 return this.attributes[id]; 8798 } 8799 /** 8800 * Returns the requested buffer. 8801 * @param id - The name of the buffer required. 8802 * @returns - The buffer requested. 8803 */ 8804 getBuffer(id) { 8805 return this.buffers[this.getAttribute(id).buffer]; 8806 } 8807 /** 8808 * 8809 * Adds an index buffer to the geometry 8810 * The index buffer contains integers, three for each triangle in the geometry, which reference the various attribute buffers (position, colour, UV coordinates, other UV coordinates, normal, …). There is only ONE index buffer. 8811 * @param {PIXI.Buffer|number[]} [buffer] - The buffer that holds the data of the index buffer. You can also provide an Array and a buffer will be created from it. 8812 * @returns - Returns self, useful for chaining. 8813 */ 8814 addIndex(buffer) { 8815 return buffer instanceof Buffer || (buffer instanceof Array && (buffer = new Uint16Array(buffer)), buffer = new Buffer(buffer)), buffer.type = BUFFER_TYPE.ELEMENT_ARRAY_BUFFER, this.indexBuffer = buffer, this.buffers.includes(buffer) || this.buffers.push(buffer), this; 8816 } 8817 /** 8818 * Returns the index buffer 8819 * @returns - The index buffer. 8820 */ 8821 getIndex() { 8822 return this.indexBuffer; 8823 } 8824 /** 8825 * This function modifies the structure so that all current attributes become interleaved into a single buffer 8826 * This can be useful if your model remains static as it offers a little performance boost 8827 * @returns - Returns self, useful for chaining. 8828 */ 8829 interleave() { 8830 if (this.buffers.length === 1 || this.buffers.length === 2 && this.indexBuffer) 8831 return this; 8832 const arrays = [], sizes = [], interleavedBuffer = new Buffer(); 8833 let i; 8834 for (i in this.attributes) { 8835 const attribute = this.attributes[i], buffer = this.buffers[attribute.buffer]; 8836 arrays.push(buffer.data), sizes.push(attribute.size * byteSizeMap$1[attribute.type] / 4), attribute.buffer = 0; 8837 } 8838 for (interleavedBuffer.data = interleaveTypedArrays(arrays, sizes), i = 0; i < this.buffers.length; i++) 8839 this.buffers[i] !== this.indexBuffer && this.buffers[i].destroy(); 8840 return this.buffers = [interleavedBuffer], this.indexBuffer && this.buffers.push(this.indexBuffer), this; 8841 } 8842 /** Get the size of the geometries, in vertices. */ 8843 getSize() { 8844 for (const i in this.attributes) { 8845 const attribute = this.attributes[i]; 8846 return this.buffers[attribute.buffer].data.length / (attribute.stride / 4 || attribute.size); 8847 } 8848 return 0; 8849 } 8850 /** Disposes WebGL resources that are connected to this geometry. */ 8851 dispose() { 8852 this.disposeRunner.emit(this, !1); 8853 } 8854 /** Destroys the geometry. */ 8855 destroy() { 8856 this.dispose(), this.buffers = null, this.indexBuffer = null, this.attributes = null; 8857 } 8858 /** 8859 * Returns a clone of the geometry. 8860 * @returns - A new clone of this geometry. 8861 */ 8862 clone() { 8863 const geometry = new Geometry(); 8864 for (let i = 0; i < this.buffers.length; i++) 8865 geometry.buffers[i] = new Buffer(this.buffers[i].data.slice(0)); 8866 for (const i in this.attributes) { 8867 const attrib = this.attributes[i]; 8868 geometry.attributes[i] = new Attribute( 8869 attrib.buffer, 8870 attrib.size, 8871 attrib.normalized, 8872 attrib.type, 8873 attrib.stride, 8874 attrib.start, 8875 attrib.instance 8876 ); 8877 } 8878 return this.indexBuffer && (geometry.indexBuffer = geometry.buffers[this.buffers.indexOf(this.indexBuffer)], geometry.indexBuffer.type = BUFFER_TYPE.ELEMENT_ARRAY_BUFFER), geometry; 8879 } 8880 /** 8881 * Merges an array of geometries into a new single one. 8882 * 8883 * Geometry attribute styles must match for this operation to work. 8884 * @param geometries - array of geometries to merge 8885 * @returns - Shiny new geometry! 8886 */ 8887 static merge(geometries) { 8888 const geometryOut = new Geometry(), arrays = [], sizes = [], offsets = []; 8889 let geometry; 8890 for (let i = 0; i < geometries.length; i++) { 8891 geometry = geometries[i]; 8892 for (let j = 0; j < geometry.buffers.length; j++) 8893 sizes[j] = sizes[j] || 0, sizes[j] += geometry.buffers[j].data.length, offsets[j] = 0; 8894 } 8895 for (let i = 0; i < geometry.buffers.length; i++) 8896 arrays[i] = new map[getBufferType(geometry.buffers[i].data)](sizes[i]), geometryOut.buffers[i] = new Buffer(arrays[i]); 8897 for (let i = 0; i < geometries.length; i++) { 8898 geometry = geometries[i]; 8899 for (let j = 0; j < geometry.buffers.length; j++) 8900 arrays[j].set(geometry.buffers[j].data, offsets[j]), offsets[j] += geometry.buffers[j].data.length; 8901 } 8902 if (geometryOut.attributes = geometry.attributes, geometry.indexBuffer) { 8903 geometryOut.indexBuffer = geometryOut.buffers[geometry.buffers.indexOf(geometry.indexBuffer)], geometryOut.indexBuffer.type = BUFFER_TYPE.ELEMENT_ARRAY_BUFFER; 8904 let offset = 0, stride = 0, offset2 = 0, bufferIndexToCount = 0; 8905 for (let i = 0; i < geometry.buffers.length; i++) 8906 if (geometry.buffers[i] !== geometry.indexBuffer) { 8907 bufferIndexToCount = i; 8908 break; 8909 } 8910 for (const i in geometry.attributes) { 8911 const attribute = geometry.attributes[i]; 8912 (attribute.buffer | 0) === bufferIndexToCount && (stride += attribute.size * byteSizeMap$1[attribute.type] / 4); 8913 } 8914 for (let i = 0; i < geometries.length; i++) { 8915 const indexBufferData = geometries[i].indexBuffer.data; 8916 for (let j = 0; j < indexBufferData.length; j++) 8917 geometryOut.indexBuffer.data[j + offset2] += offset; 8918 offset += geometries[i].buffers[bufferIndexToCount].data.length / stride, offset2 += indexBufferData.length; 8919 } 8920 } 8921 return geometryOut; 8922 } 8923} 8924 8925class BatchGeometry extends Geometry { 8926 /** 8927 * @param {boolean} [_static=false] - Optimization flag, where `false` 8928 * is updated every frame, `true` doesn't change frame-to-frame. 8929 */ 8930 constructor(_static = !1) { 8931 super(), this._buffer = new Buffer(null, _static, !1), this._indexBuffer = new Buffer(null, _static, !0), this.addAttribute("aVertexPosition", this._buffer, 2, !1, TYPES.FLOAT).addAttribute("aTextureCoord", this._buffer, 2, !1, TYPES.FLOAT).addAttribute("aColor", this._buffer, 4, !0, TYPES.UNSIGNED_BYTE).addAttribute("aTextureId", this._buffer, 1, !0, TYPES.FLOAT).addIndex(this._indexBuffer); 8932 } 8933} 8934 8935const PI_2 = Math.PI * 2, RAD_TO_DEG = 180 / Math.PI, DEG_TO_RAD = Math.PI / 180; 8936var SHAPES = /* @__PURE__ */ ((SHAPES2) => (SHAPES2[SHAPES2.POLY = 0] = "POLY", SHAPES2[SHAPES2.RECT = 1] = "RECT", SHAPES2[SHAPES2.CIRC = 2] = "CIRC", SHAPES2[SHAPES2.ELIP = 3] = "ELIP", SHAPES2[SHAPES2.RREC = 4] = "RREC", SHAPES2))(SHAPES || {}); 8937 8938class Point { 8939 /** 8940 * Creates a new `Point` 8941 * @param {number} [x=0] - position of the point on the x axis 8942 * @param {number} [y=0] - position of the point on the y axis 8943 */ 8944 constructor(x = 0, y = 0) { 8945 this.x = 0, this.y = 0, this.x = x, this.y = y; 8946 } 8947 /** 8948 * Creates a clone of this point 8949 * @returns A clone of this point 8950 */ 8951 clone() { 8952 return new Point(this.x, this.y); 8953 } 8954 /** 8955 * Copies `x` and `y` from the given point into this point 8956 * @param p - The point to copy from 8957 * @returns The point instance itself 8958 */ 8959 copyFrom(p) { 8960 return this.set(p.x, p.y), this; 8961 } 8962 /** 8963 * Copies this point's x and y into the given point (`p`). 8964 * @param p - The point to copy to. Can be any of type that is or extends `IPointData` 8965 * @returns The point (`p`) with values updated 8966 */ 8967 copyTo(p) { 8968 return p.set(this.x, this.y), p; 8969 } 8970 /** 8971 * Accepts another point (`p`) and returns `true` if the given point is equal to this point 8972 * @param p - The point to check 8973 * @returns Returns `true` if both `x` and `y` are equal 8974 */ 8975 equals(p) { 8976 return p.x === this.x && p.y === this.y; 8977 } 8978 /** 8979 * Sets the point to a new `x` and `y` position. 8980 * If `y` is omitted, both `x` and `y` will be set to `x`. 8981 * @param {number} [x=0] - position of the point on the `x` axis 8982 * @param {number} [y=x] - position of the point on the `y` axis 8983 * @returns The point instance itself 8984 */ 8985 set(x = 0, y = x) { 8986 return this.x = x, this.y = y, this; 8987 } 8988} 8989Point.prototype.toString = function() { 8990 return `[@pixi/math:Point x=${this.x} y=${this.y}]`; 8991}; 8992 8993const tempPoints$1 = [new Point(), new Point(), new Point(), new Point()]; 8994class Rectangle { 8995 /** 8996 * @param x - The X coordinate of the upper-left corner of the rectangle 8997 * @param y - The Y coordinate of the upper-left corner of the rectangle 8998 * @param width - The overall width of the rectangle 8999 * @param height - The overall height of the rectangle 9000 */ 9001 constructor(x = 0, y = 0, width = 0, height = 0) { 9002 this.x = Number(x), this.y = Number(y), this.width = Number(width), this.height = Number(height), this.type = SHAPES.RECT; 9003 } 9004 /** Returns the left edge of the rectangle. */ 9005 get left() { 9006 return this.x; 9007 } 9008 /** Returns the right edge of the rectangle. */ 9009 get right() { 9010 return this.x + this.width; 9011 } 9012 /** Returns the top edge of the rectangle. */ 9013 get top() { 9014 return this.y; 9015 } 9016 /** Returns the bottom edge of the rectangle. */ 9017 get bottom() { 9018 return this.y + this.height; 9019 } 9020 /** A constant empty rectangle. */ 9021 static get EMPTY() { 9022 return new Rectangle(0, 0, 0, 0); 9023 } 9024 /** 9025 * Creates a clone of this Rectangle 9026 * @returns a copy of the rectangle 9027 */ 9028 clone() { 9029 return new Rectangle(this.x, this.y, this.width, this.height); 9030 } 9031 /** 9032 * Copies another rectangle to this one. 9033 * @param rectangle - The rectangle to copy from. 9034 * @returns Returns itself. 9035 */ 9036 copyFrom(rectangle) { 9037 return this.x = rectangle.x, this.y = rectangle.y, this.width = rectangle.width, this.height = rectangle.height, this; 9038 } 9039 /** 9040 * Copies this rectangle to another one. 9041 * @param rectangle - The rectangle to copy to. 9042 * @returns Returns given parameter. 9043 */ 9044 copyTo(rectangle) { 9045 return rectangle.x = this.x, rectangle.y = this.y, rectangle.width = this.width, rectangle.height = this.height, rectangle; 9046 } 9047 /** 9048 * Checks whether the x and y coordinates given are contained within this Rectangle 9049 * @param x - The X coordinate of the point to test 9050 * @param y - The Y coordinate of the point to test 9051 * @returns Whether the x/y coordinates are within this Rectangle 9052 */ 9053 contains(x, y) { 9054 return this.width <= 0 || this.height <= 0 ? !1 : x >= this.x && x < this.x + this.width && y >= this.y && y < this.y + this.height; 9055 } 9056 /** 9057 * Determines whether the `other` Rectangle transformed by `transform` intersects with `this` Rectangle object. 9058 * Returns true only if the area of the intersection is >0, this means that Rectangles 9059 * sharing a side are not overlapping. Another side effect is that an arealess rectangle 9060 * (width or height equal to zero) can't intersect any other rectangle. 9061 * @param {Rectangle} other - The Rectangle to intersect with `this`. 9062 * @param {Matrix} transform - The transformation matrix of `other`. 9063 * @returns {boolean} A value of `true` if the transformed `other` Rectangle intersects with `this`; otherwise `false`. 9064 */ 9065 intersects(other, transform) { 9066 if (!transform) { 9067 const x02 = this.x < other.x ? other.x : this.x; 9068 if ((this.right > other.right ? other.right : this.right) <= x02) 9069 return !1; 9070 const y02 = this.y < other.y ? other.y : this.y; 9071 return (this.bottom > other.bottom ? other.bottom : this.bottom) > y02; 9072 } 9073 const x0 = this.left, x1 = this.right, y0 = this.top, y1 = this.bottom; 9074 if (x1 <= x0 || y1 <= y0) 9075 return !1; 9076 const lt = tempPoints$1[0].set(other.left, other.top), lb = tempPoints$1[1].set(other.left, other.bottom), rt = tempPoints$1[2].set(other.right, other.top), rb = tempPoints$1[3].set(other.right, other.bottom); 9077 if (rt.x <= lt.x || lb.y <= lt.y) 9078 return !1; 9079 const s = Math.sign(transform.a * transform.d - transform.b * transform.c); 9080 if (s === 0 || (transform.apply(lt, lt), transform.apply(lb, lb), transform.apply(rt, rt), transform.apply(rb, rb), Math.max(lt.x, lb.x, rt.x, rb.x) <= x0 || Math.min(lt.x, lb.x, rt.x, rb.x) >= x1 || Math.max(lt.y, lb.y, rt.y, rb.y) <= y0 || Math.min(lt.y, lb.y, rt.y, rb.y) >= y1)) 9081 return !1; 9082 const nx = s * (lb.y - lt.y), ny = s * (lt.x - lb.x), n00 = nx * x0 + ny * y0, n10 = nx * x1 + ny * y0, n01 = nx * x0 + ny * y1, n11 = nx * x1 + ny * y1; 9083 if (Math.max(n00, n10, n01, n11) <= nx * lt.x + ny * lt.y || Math.min(n00, n10, n01, n11) >= nx * rb.x + ny * rb.y) 9084 return !1; 9085 const mx = s * (lt.y - rt.y), my = s * (rt.x - lt.x), m00 = mx * x0 + my * y0, m10 = mx * x1 + my * y0, m01 = mx * x0 + my * y1, m11 = mx * x1 + my * y1; 9086 return !(Math.max(m00, m10, m01, m11) <= mx * lt.x + my * lt.y || Math.min(m00, m10, m01, m11) >= mx * rb.x + my * rb.y); 9087 } 9088 /** 9089 * Pads the rectangle making it grow in all directions. 9090 * If paddingY is omitted, both paddingX and paddingY will be set to paddingX. 9091 * @param paddingX - The horizontal padding amount. 9092 * @param paddingY - The vertical padding amount. 9093 * @returns Returns itself. 9094 */ 9095 pad(paddingX = 0, paddingY = paddingX) { 9096 return this.x -= paddingX, this.y -= paddingY, this.width += paddingX * 2, this.height += paddingY * 2, this; 9097 } 9098 /** 9099 * Fits this rectangle around the passed one. 9100 * @param rectangle - The rectangle to fit. 9101 * @returns Returns itself. 9102 */ 9103 fit(rectangle) { 9104 const x1 = Math.max(this.x, rectangle.x), x2 = Math.min(this.x + this.width, rectangle.x + rectangle.width), y1 = Math.max(this.y, rectangle.y), y2 = Math.min(this.y + this.height, rectangle.y + rectangle.height); 9105 return this.x = x1, this.width = Math.max(x2 - x1, 0), this.y = y1, this.height = Math.max(y2 - y1, 0), this; 9106 } 9107 /** 9108 * Enlarges rectangle that way its corners lie on grid 9109 * @param resolution - resolution 9110 * @param eps - precision 9111 * @returns Returns itself. 9112 */ 9113 ceil(resolution = 1, eps = 1e-3) { 9114 const x2 = Math.ceil((this.x + this.width - eps) * resolution) / resolution, y2 = Math.ceil((this.y + this.height - eps) * resolution) / resolution; 9115 return this.x = Math.floor((this.x + eps) * resolution) / resolution, this.y = Math.floor((this.y + eps) * resolution) / resolution, this.width = x2 - this.x, this.height = y2 - this.y, this; 9116 } 9117 /** 9118 * Enlarges this rectangle to include the passed rectangle. 9119 * @param rectangle - The rectangle to include. 9120 * @returns Returns itself. 9121 */ 9122 enlarge(rectangle) { 9123 const x1 = Math.min(this.x, rectangle.x), x2 = Math.max(this.x + this.width, rectangle.x + rectangle.width), y1 = Math.min(this.y, rectangle.y), y2 = Math.max(this.y + this.height, rectangle.y + rectangle.height); 9124 return this.x = x1, this.width = x2 - x1, this.y = y1, this.height = y2 - y1, this; 9125 } 9126} 9127Rectangle.prototype.toString = function() { 9128 return `[@pixi/math:Rectangle x=${this.x} y=${this.y} width=${this.width} height=${this.height}]`; 9129}; 9130 9131class Circle { 9132 /** 9133 * @param x - The X coordinate of the center of this circle 9134 * @param y - The Y coordinate of the center of this circle 9135 * @param radius - The radius of the circle 9136 */ 9137 constructor(x = 0, y = 0, radius = 0) { 9138 this.x = x, this.y = y, this.radius = radius, this.type = SHAPES.CIRC; 9139 } 9140 /** 9141 * Creates a clone of this Circle instance 9142 * @returns A copy of the Circle 9143 */ 9144 clone() { 9145 return new Circle(this.x, this.y, this.radius); 9146 } 9147 /** 9148 * Checks whether the x and y coordinates given are contained within this circle 9149 * @param x - The X coordinate of the point to test 9150 * @param y - The Y coordinate of the point to test 9151 * @returns Whether the x/y coordinates are within this Circle 9152 */ 9153 contains(x, y) { 9154 if (this.radius <= 0) 9155 return !1; 9156 const r2 = this.radius * this.radius; 9157 let dx = this.x - x, dy = this.y - y; 9158 return dx *= dx, dy *= dy, dx + dy <= r2; 9159 } 9160 /** 9161 * Returns the framing rectangle of the circle as a Rectangle object 9162 * @returns The framing rectangle 9163 */ 9164 getBounds() { 9165 return new Rectangle(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2); 9166 } 9167} 9168Circle.prototype.toString = function() { 9169 return `[@pixi/math:Circle x=${this.x} y=${this.y} radius=${this.radius}]`; 9170}; 9171 9172class Ellipse { 9173 /** 9174 * @param x - The X coordinate of the center of this ellipse 9175 * @param y - The Y coordinate of the center of this ellipse 9176 * @param halfWidth - The half width of this ellipse 9177 * @param halfHeight - The half height of this ellipse 9178 */ 9179 constructor(x = 0, y = 0, halfWidth = 0, halfHeight = 0) { 9180 this.x = x, this.y = y, this.width = halfWidth, this.height = halfHeight, this.type = SHAPES.ELIP; 9181 } 9182 /** 9183 * Creates a clone of this Ellipse instance 9184 * @returns {PIXI.Ellipse} A copy of the ellipse 9185 */ 9186 clone() { 9187 return new Ellipse(this.x, this.y, this.width, this.height); 9188 } 9189 /** 9190 * Checks whether the x and y coordinates given are contained within this ellipse 9191 * @param x - The X coordinate of the point to test 9192 * @param y - The Y coordinate of the point to test 9193 * @returns Whether the x/y coords are within this ellipse 9194 */ 9195 contains(x, y) { 9196 if (this.width <= 0 || this.height <= 0) 9197 return !1; 9198 let normx = (x - this.x) / this.width, normy = (y - this.y) / this.height; 9199 return normx *= normx, normy *= normy, normx + normy <= 1; 9200 } 9201 /** 9202 * Returns the framing rectangle of the ellipse as a Rectangle object 9203 * @returns The framing rectangle 9204 */ 9205 getBounds() { 9206 return new Rectangle(this.x - this.width, this.y - this.height, this.width, this.height); 9207 } 9208} 9209Ellipse.prototype.toString = function() { 9210 return `[@pixi/math:Ellipse x=${this.x} y=${this.y} width=${this.width} height=${this.height}]`; 9211}; 9212 9213class Polygon { 9214 /** 9215 * @param {PIXI.IPointData[]|number[]} points - This can be an array of Points 9216 * that form the polygon, a flat array of numbers that will be interpreted as [x,y, x,y, ...], or 9217 * the arguments passed can be all the points of the polygon e.g. 9218 * `new Polygon(new Point(), new Point(), ...)`, or the arguments passed can be flat 9219 * x,y values e.g. `new Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers. 9220 */ 9221 constructor(...points) { 9222 let flat = Array.isArray(points[0]) ? points[0] : points; 9223 if (typeof flat[0] != "number") { 9224 const p = []; 9225 for (let i = 0, il = flat.length; i < il; i++) 9226 p.push(flat[i].x, flat[i].y); 9227 flat = p; 9228 } 9229 this.points = flat, this.type = SHAPES.POLY, this.closeStroke = !0; 9230 } 9231 /** 9232 * Creates a clone of this polygon. 9233 * @returns - A copy of the polygon. 9234 */ 9235 clone() { 9236 const points = this.points.slice(), polygon = new Polygon(points); 9237 return polygon.closeStroke = this.closeStroke, polygon; 9238 } 9239 /** 9240 * Checks whether the x and y coordinates passed to this function are contained within this polygon. 9241 * @param x - The X coordinate of the point to test. 9242 * @param y - The Y coordinate of the point to test. 9243 * @returns - Whether the x/y coordinates are within this polygon. 9244 */ 9245 contains(x, y) { 9246 let inside = !1; 9247 const length = this.points.length / 2; 9248 for (let i = 0, j = length - 1; i < length; j = i++) { 9249 const xi = this.points[i * 2], yi = this.points[i * 2 + 1], xj = this.points[j * 2], yj = this.points[j * 2 + 1]; 9250 yi > y != yj > y && x < (xj - xi) * ((y - yi) / (yj - yi)) + xi && (inside = !inside); 9251 } 9252 return inside; 9253 } 9254} 9255Polygon.prototype.toString = function() { 9256 return `[@pixi/math:PolygoncloseStroke=${this.closeStroke}points=${this.points.reduce((pointsDesc, currentPoint) => `${pointsDesc}, ${currentPoint}`, "")}]`; 9257}; 9258 9259class RoundedRectangle { 9260 /** 9261 * @param x - The X coordinate of the upper-left corner of the rounded rectangle 9262 * @param y - The Y coordinate of the upper-left corner of the rounded rectangle 9263 * @param width - The overall width of this rounded rectangle 9264 * @param height - The overall height of this rounded rectangle 9265 * @param radius - Controls the radius of the rounded corners 9266 */ 9267 constructor(x = 0, y = 0, width = 0, height = 0, radius = 20) { 9268 this.x = x, this.y = y, this.width = width, this.height = height, this.radius = radius, this.type = SHAPES.RREC; 9269 } 9270 /** 9271 * Creates a clone of this Rounded Rectangle. 9272 * @returns - A copy of the rounded rectangle. 9273 */ 9274 clone() { 9275 return new RoundedRectangle(this.x, this.y, this.width, this.height, this.radius); 9276 } 9277 /** 9278 * Checks whether the x and y coordinates given are contained within this Rounded Rectangle 9279 * @param x - The X coordinate of the point to test. 9280 * @param y - The Y coordinate of the point to test. 9281 * @returns - Whether the x/y coordinates are within this Rounded Rectangle. 9282 */ 9283 contains(x, y) { 9284 if (this.width <= 0 || this.height <= 0) 9285 return !1; 9286 if (x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height) { 9287 const radius = Math.max(0, Math.min(this.radius, Math.min(this.width, this.height) / 2)); 9288 if (y >= this.y + radius && y <= this.y + this.height - radius || x >= this.x + radius && x <= this.x + this.width - radius) 9289 return !0; 9290 let dx = x - (this.x + radius), dy = y - (this.y + radius); 9291 const radius2 = radius * radius; 9292 if (dx * dx + dy * dy <= radius2 || (dx = x - (this.x + this.width - radius), dx * dx + dy * dy <= radius2) || (dy = y - (this.y + this.height - radius), dx * dx + dy * dy <= radius2) || (dx = x - (this.x + radius), dx * dx + dy * dy <= radius2)) 9293 return !0; 9294 } 9295 return !1; 9296 } 9297} 9298RoundedRectangle.prototype.toString = function() { 9299 return `[@pixi/math:RoundedRectangle x=${this.x} y=${this.y}width=${this.width} height=${this.height} radius=${this.radius}]`; 9300}; 9301 9302class Matrix { 9303 /** 9304 * @param a - x scale 9305 * @param b - y skew 9306 * @param c - x skew 9307 * @param d - y scale 9308 * @param tx - x translation 9309 * @param ty - y translation 9310 */ 9311 constructor(a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0) { 9312 this.array = null, this.a = a, this.b = b, this.c = c, this.d = d, this.tx = tx, this.ty = ty; 9313 } 9314 /** 9315 * Creates a Matrix object based on the given array. The Element to Matrix mapping order is as follows: 9316 * 9317 * a = array[0] 9318 * b = array[1] 9319 * c = array[3] 9320 * d = array[4] 9321 * tx = array[2] 9322 * ty = array[5] 9323 * @param array - The array that the matrix will be populated from. 9324 */ 9325 fromArray(array) { 9326 this.a = array[0], this.b = array[1], this.c = array[3], this.d = array[4], this.tx = array[2], this.ty = array[5]; 9327 } 9328 /** 9329 * Sets the matrix properties. 9330 * @param a - Matrix component 9331 * @param b - Matrix component 9332 * @param c - Matrix component 9333 * @param d - Matrix component 9334 * @param tx - Matrix component 9335 * @param ty - Matrix component 9336 * @returns This matrix. Good for chaining method calls. 9337 */ 9338 set(a, b, c, d, tx, ty) { 9339 return this.a = a, this.b = b, this.c = c, this.d = d, this.tx = tx, this.ty = ty, this; 9340 } 9341 /** 9342 * Creates an array from the current Matrix object. 9343 * @param transpose - Whether we need to transpose the matrix or not 9344 * @param [out=new Float32Array(9)] - If provided the array will be assigned to out 9345 * @returns The newly created array which contains the matrix 9346 */ 9347 toArray(transpose, out) { 9348 this.array || (this.array = new Float32Array(9)); 9349 const array = out || this.array; 9350 return transpose ? (array[0] = this.a, array[1] = this.b, array[2] = 0, array[3] = this.c, array[4] = this.d, array[5] = 0, array[6] = this.tx, array[7] = this.ty, array[8] = 1) : (array[0] = this.a, array[1] = this.c, array[2] = this.tx, array[3] = this.b, array[4] = this.d, array[5] = this.ty, array[6] = 0, array[7] = 0, array[8] = 1), array; 9351 } 9352 /** 9353 * Get a new position with the current transformation applied. 9354 * Can be used to go from a child's coordinate space to the world coordinate space. (e.g. rendering) 9355 * @param pos - The origin 9356 * @param {PIXI.Point} [newPos] - The point that the new position is assigned to (allowed to be same as input) 9357 * @returns {PIXI.Point} The new point, transformed through this matrix 9358 */ 9359 apply(pos, newPos) { 9360 newPos = newPos || new Point(); 9361 const x = pos.x, y = pos.y; 9362 return newPos.x = this.a * x + this.c * y + this.tx, newPos.y = this.b * x + this.d * y + this.ty, newPos; 9363 } 9364 /** 9365 * Get a new position with the inverse of the current transformation applied. 9366 * Can be used to go from the world coordinate space to a child's coordinate space. (e.g. input) 9367 * @param pos - The origin 9368 * @param {PIXI.Point} [newPos] - The point that the new position is assigned to (allowed to be same as input) 9369 * @returns {PIXI.Point} The new point, inverse-transformed through this matrix 9370 */ 9371 applyInverse(pos, newPos) { 9372 newPos = newPos || new Point(); 9373 const id = 1 / (this.a * this.d + this.c * -this.b), x = pos.x, y = pos.y; 9374 return newPos.x = this.d * id * x + -this.c * id * y + (this.ty * this.c - this.tx * this.d) * id, newPos.y = this.a * id * y + -this.b * id * x + (-this.ty * this.a + this.tx * this.b) * id, newPos; 9375 } 9376 /** 9377 * Translates the matrix on the x and y. 9378 * @param x - How much to translate x by 9379 * @param y - How much to translate y by 9380 * @returns This matrix. Good for chaining method calls. 9381 */ 9382 translate(x, y) { 9383 return this.tx += x, this.ty += y, this; 9384 } 9385 /** 9386 * Applies a scale transformation to the matrix. 9387 * @param x - The amount to scale horizontally 9388 * @param y - The amount to scale vertically 9389 * @returns This matrix. Good for chaining method calls. 9390 */ 9391 scale(x, y) { 9392 return this.a *= x, this.d *= y, this.c *= x, this.b *= y, this.tx *= x, this.ty *= y, this; 9393 } 9394 /** 9395 * Applies a rotation transformation to the matrix. 9396 * @param angle - The angle in radians. 9397 * @returns This matrix. Good for chaining method calls. 9398 */ 9399 rotate(angle) { 9400 const cos = Math.cos(angle), sin = Math.sin(angle), a1 = this.a, c1 = this.c, tx1 = this.tx; 9401 return this.a = a1 * cos - this.b * sin, this.b = a1 * sin + this.b * cos, this.c = c1 * cos - this.d * sin, this.d = c1 * sin + this.d * cos, this.tx = tx1 * cos - this.ty * sin, this.ty = tx1 * sin + this.ty * cos, this; 9402 } 9403 /** 9404 * Appends the given Matrix to this Matrix. 9405 * @param matrix - The matrix to append. 9406 * @returns This matrix. Good for chaining method calls. 9407 */ 9408 append(matrix) { 9409 const a1 = this.a, b1 = this.b, c1 = this.c, d1 = this.d; 9410 return this.a = matrix.a * a1 + matrix.b * c1, this.b = matrix.a * b1 + matrix.b * d1, this.c = matrix.c * a1 + matrix.d * c1, this.d = matrix.c * b1 + matrix.d * d1, this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx, this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty, this; 9411 } 9412 /** 9413 * Sets the matrix based on all the available properties 9414 * @param x - Position on the x axis 9415 * @param y - Position on the y axis 9416 * @param pivotX - Pivot on the x axis 9417 * @param pivotY - Pivot on the y axis 9418 * @param scaleX - Scale on the x axis 9419 * @param scaleY - Scale on the y axis 9420 * @param rotation - Rotation in radians 9421 * @param skewX - Skew on the x axis 9422 * @param skewY - Skew on the y axis 9423 * @returns This matrix. Good for chaining method calls. 9424 */ 9425 setTransform(x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) { 9426 return this.a = Math.cos(rotation + skewY) * scaleX, this.b = Math.sin(rotation + skewY) * scaleX, this.c = -Math.sin(rotation - skewX) * scaleY, this.d = Math.cos(rotation - skewX) * scaleY, this.tx = x - (pivotX * this.a + pivotY * this.c), this.ty = y - (pivotX * this.b + pivotY * this.d), this; 9427 } 9428 /** 9429 * Prepends the given Matrix to this Matrix. 9430 * @param matrix - The matrix to prepend 9431 * @returns This matrix. Good for chaining method calls. 9432 */ 9433 prepend(matrix) { 9434 const tx1 = this.tx; 9435 if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { 9436 const a1 = this.a, c1 = this.c; 9437 this.a = a1 * matrix.a + this.b * matrix.c, this.b = a1 * matrix.b + this.b * matrix.d, this.c = c1 * matrix.a + this.d * matrix.c, this.d = c1 * matrix.b + this.d * matrix.d; 9438 } 9439 return this.tx = tx1 * matrix.a + this.ty * matrix.c + matrix.tx, this.ty = tx1 * matrix.b + this.ty * matrix.d + matrix.ty, this; 9440 } 9441 /** 9442 * Decomposes the matrix (x, y, scaleX, scaleY, and rotation) and sets the properties on to a transform. 9443 * @param transform - The transform to apply the properties to. 9444 * @returns The transform with the newly applied properties 9445 */ 9446 decompose(transform) { 9447 const a = this.a, b = this.b, c = this.c, d = this.d, pivot = transform.pivot, skewX = -Math.atan2(-c, d), skewY = Math.atan2(b, a), delta = Math.abs(skewX + skewY); 9448 return delta < 1e-5 || Math.abs(PI_2 - delta) < 1e-5 ? (transform.rotation = skewY, transform.skew.x = transform.skew.y = 0) : (transform.rotation = 0, transform.skew.x = skewX, transform.skew.y = skewY), transform.scale.x = Math.sqrt(a * a + b * b), transform.scale.y = Math.sqrt(c * c + d * d), transform.position.x = this.tx + (pivot.x * a + pivot.y * c), transform.position.y = this.ty + (pivot.x * b + pivot.y * d), transform; 9449 } 9450 /** 9451 * Inverts this matrix 9452 * @returns This matrix. Good for chaining method calls. 9453 */ 9454 invert() { 9455 const a1 = this.a, b1 = this.b, c1 = this.c, d1 = this.d, tx1 = this.tx, n = a1 * d1 - b1 * c1; 9456 return this.a = d1 / n, this.b = -b1 / n, this.c = -c1 / n, this.d = a1 / n, this.tx = (c1 * this.ty - d1 * tx1) / n, this.ty = -(a1 * this.ty - b1 * tx1) / n, this; 9457 } 9458 /** 9459 * Resets this Matrix to an identity (default) matrix. 9460 * @returns This matrix. Good for chaining method calls. 9461 */ 9462 identity() { 9463 return this.a = 1, this.b = 0, this.c = 0, this.d = 1, this.tx = 0, this.ty = 0, this; 9464 } 9465 /** 9466 * Creates a new Matrix object with the same values as this one. 9467 * @returns A copy of this matrix. Good for chaining method calls. 9468 */ 9469 clone() { 9470 const matrix = new Matrix(); 9471 return matrix.a = this.a, matrix.b = this.b, matrix.c = this.c, matrix.d = this.d, matrix.tx = this.tx, matrix.ty = this.ty, matrix; 9472 } 9473 /** 9474 * Changes the values of the given matrix to be the same as the ones in this matrix 9475 * @param matrix - The matrix to copy to. 9476 * @returns The matrix given in parameter with its values updated. 9477 */ 9478 copyTo(matrix) { 9479 return matrix.a = this.a, matrix.b = this.b, matrix.c = this.c, matrix.d = this.d, matrix.tx = this.tx, matrix.ty = this.ty, matrix; 9480 } 9481 /** 9482 * Changes the values of the matrix to be the same as the ones in given matrix 9483 * @param {PIXI.Matrix} matrix - The matrix to copy from. 9484 * @returns {PIXI.Matrix} this 9485 */ 9486 copyFrom(matrix) { 9487 return this.a = matrix.a, this.b = matrix.b, this.c = matrix.c, this.d = matrix.d, this.tx = matrix.tx, this.ty = matrix.ty, this; 9488 } 9489 /** 9490 * A default (identity) matrix 9491 * @readonly 9492 */ 9493 static get IDENTITY() { 9494 return new Matrix(); 9495 } 9496 /** 9497 * A temp matrix 9498 * @readonly 9499 */ 9500 static get TEMP_MATRIX() { 9501 return new Matrix(); 9502 } 9503} 9504Matrix.prototype.toString = function() { 9505 return `[@pixi/math:Matrix a=${this.a} b=${this.b} c=${this.c} d=${this.d} tx=${this.tx} ty=${this.ty}]`; 9506}; 9507 9508const ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1], uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1], vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1], vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1], rotationCayley = [], rotationMatrices = [], signum = Math.sign; 9509function init$f() { 9510 for (let i = 0; i < 16; i++) { 9511 const row = []; 9512 rotationCayley.push(row); 9513 for (let j = 0; j < 16; j++) { 9514 const _ux = signum(ux[i] * ux[j] + vx[i] * uy[j]), _uy = signum(uy[i] * ux[j] + vy[i] * uy[j]), _vx = signum(ux[i] * vx[j] + vx[i] * vy[j]), _vy = signum(uy[i] * vx[j] + vy[i] * vy[j]); 9515 for (let k = 0; k < 16; k++) 9516 if (ux[k] === _ux && uy[k] === _uy && vx[k] === _vx && vy[k] === _vy) { 9517 row.push(k); 9518 break; 9519 } 9520 } 9521 } 9522 for (let i = 0; i < 16; i++) { 9523 const mat = new Matrix(); 9524 mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0), rotationMatrices.push(mat); 9525 } 9526} 9527init$f(); 9528const groupD8 = { 9529 /** 9530 * | Rotation | Direction | 9531 * |----------|-----------| 9532 * | 0° | East | 9533 * @readonly 9534 */ 9535 E: 0, 9536 /** 9537 * | Rotation | Direction | 9538 * |----------|-----------| 9539 * | 45°↻ | Southeast | 9540 * @readonly 9541 */ 9542 SE: 1, 9543 /** 9544 * | Rotation | Direction | 9545 * |----------|-----------| 9546 * | 90°↻ | South | 9547 * @readonly 9548 */ 9549 S: 2, 9550 /** 9551 * | Rotation | Direction | 9552 * |----------|-----------| 9553 * | 135°↻ | Southwest | 9554 * @readonly 9555 */ 9556 SW: 3, 9557 /** 9558 * | Rotation | Direction | 9559 * |----------|-----------| 9560 * | 180° | West | 9561 * @readonly 9562 */ 9563 W: 4, 9564 /** 9565 * | Rotation | Direction | 9566 * |-------------|--------------| 9567 * | -135°/225°↻ | Northwest | 9568 * @readonly 9569 */ 9570 NW: 5, 9571 /** 9572 * | Rotation | Direction | 9573 * |-------------|--------------| 9574 * | -90°/270°↻ | North | 9575 * @readonly 9576 */ 9577 N: 6, 9578 /** 9579 * | Rotation | Direction | 9580 * |-------------|--------------| 9581 * | -45°/315°↻ | Northeast | 9582 * @readonly 9583 */ 9584 NE: 7, 9585 /** 9586 * Reflection about Y-axis. 9587 * @readonly 9588 */ 9589 MIRROR_VERTICAL: 8, 9590 /** 9591 * Reflection about the main diagonal. 9592 * @readonly 9593 */ 9594 MAIN_DIAGONAL: 10, 9595 /** 9596 * Reflection about X-axis. 9597 * @readonly 9598 */ 9599 MIRROR_HORIZONTAL: 12, 9600 /** 9601 * Reflection about reverse diagonal. 9602 * @readonly 9603 */ 9604 REVERSE_DIAGONAL: 14, 9605 /** 9606 * @param {PIXI.GD8Symmetry} ind - sprite rotation angle. 9607 * @returns {PIXI.GD8Symmetry} The X-component of the U-axis 9608 * after rotating the axes. 9609 */ 9610 uX: (ind) => ux[ind], 9611 /** 9612 * @param {PIXI.GD8Symmetry} ind - sprite rotation angle. 9613 * @returns {PIXI.GD8Symmetry} The Y-component of the U-axis 9614 * after rotating the axes. 9615 */ 9616 uY: (ind) => uy[ind], 9617 /** 9618 * @param {PIXI.GD8Symmetry} ind - sprite rotation angle. 9619 * @returns {PIXI.GD8Symmetry} The X-component of the V-axis 9620 * after rotating the axes. 9621 */ 9622 vX: (ind) => vx[ind], 9623 /** 9624 * @param {PIXI.GD8Symmetry} ind - sprite rotation angle. 9625 * @returns {PIXI.GD8Symmetry} The Y-component of the V-axis 9626 * after rotating the axes. 9627 */ 9628 vY: (ind) => vy[ind], 9629 /** 9630 * @param {PIXI.GD8Symmetry} rotation - symmetry whose opposite 9631 * is needed. Only rotations have opposite symmetries while 9632 * reflections don't. 9633 * @returns {PIXI.GD8Symmetry} The opposite symmetry of `rotation` 9634 */ 9635 inv: (rotation) => rotation & 8 ? rotation & 15 : -rotation & 7, 9636 /** 9637 * Composes the two D8 operations. 9638 * 9639 * Taking `^` as reflection: 9640 * 9641 * | | E=0 | S=2 | W=4 | N=6 | E^=8 | S^=10 | W^=12 | N^=14 | 9642 * |-------|-----|-----|-----|-----|------|-------|-------|-------| 9643 * | E=0 | E | S | W | N | E^ | S^ | W^ | N^ | 9644 * | S=2 | S | W | N | E | S^ | W^ | N^ | E^ | 9645 * | W=4 | W | N | E | S | W^ | N^ | E^ | S^ | 9646 * | N=6 | N | E | S | W | N^ | E^ | S^ | W^ | 9647 * | E^=8 | E^ | N^ | W^ | S^ | E | N | W | S | 9648 * | S^=10 | S^ | E^ | N^ | W^ | S | E | N | W | 9649 * | W^=12 | W^ | S^ | E^ | N^ | W | S | E | N | 9650 * | N^=14 | N^ | W^ | S^ | E^ | N | W | S | E | 9651 * 9652 * [This is a Cayley table]{@link https://en.wikipedia.org/wiki/Cayley_table} 9653 * @param {PIXI.GD8Symmetry} rotationSecond - Second operation, which 9654 * is the row in the above cayley table. 9655 * @param {PIXI.GD8Symmetry} rotationFirst - First operation, which 9656 * is the column in the above cayley table. 9657 * @returns {PIXI.GD8Symmetry} Composed operation 9658 */ 9659 add: (rotationSecond, rotationFirst) => rotationCayley[rotationSecond][rotationFirst], 9660 /** 9661 * Reverse of `add`. 9662 * @param {PIXI.GD8Symmetry} rotationSecond - Second operation 9663 * @param {PIXI.GD8Symmetry} rotationFirst - First operation 9664 * @returns {PIXI.GD8Symmetry} Result 9665 */ 9666 sub: (rotationSecond, rotationFirst) => rotationCayley[rotationSecond][groupD8.inv(rotationFirst)], 9667 /** 9668 * Adds 180 degrees to rotation, which is a commutative 9669 * operation. 9670 * @param {number} rotation - The number to rotate. 9671 * @returns {number} Rotated number 9672 */ 9673 rotate180: (rotation) => rotation ^ 4, 9674 /** 9675 * Checks if the rotation angle is vertical, i.e. south 9676 * or north. It doesn't work for reflections. 9677 * @param {PIXI.GD8Symmetry} rotation - The number to check. 9678 * @returns {boolean} Whether or not the direction is vertical 9679 */ 9680 isVertical: (rotation) => (rotation & 3) === 2, 9681 // rotation % 4 === 2 9682 /** 9683 * Approximates the vector `V(dx,dy)` into one of the 9684 * eight directions provided by `groupD8`. 9685 * @param {number} dx - X-component of the vector 9686 * @param {number} dy - Y-component of the vector 9687 * @returns {PIXI.GD8Symmetry} Approximation of the vector into 9688 * one of the eight symmetries. 9689 */ 9690 byDirection: (dx, dy) => Math.abs(dx) * 2 <= Math.abs(dy) ? dy >= 0 ? groupD8.S : groupD8.N : Math.abs(dy) * 2 <= Math.abs(dx) ? dx > 0 ? groupD8.E : groupD8.W : dy > 0 ? dx > 0 ? groupD8.SE : groupD8.SW : dx > 0 ? groupD8.NE : groupD8.NW, 9691 /** 9692 * Helps sprite to compensate texture packer rotation. 9693 * @param {PIXI.Matrix} matrix - sprite world matrix 9694 * @param {PIXI.GD8Symmetry} rotation - The rotation factor to use. 9695 * @param {number} tx - sprite anchoring 9696 * @param {number} ty - sprite anchoring 9697 */ 9698 matrixAppendRotationInv: (matrix, rotation, tx = 0, ty = 0) => { 9699 const mat = rotationMatrices[groupD8.inv(rotation)]; 9700 mat.tx = tx, mat.ty = ty, matrix.append(mat); 9701 } 9702}; 9703 9704class ObservablePoint { 9705 /** 9706 * Creates a new `ObservablePoint` 9707 * @param cb - callback function triggered when `x` and/or `y` are changed 9708 * @param scope - owner of callback 9709 * @param {number} [x=0] - position of the point on the x axis 9710 * @param {number} [y=0] - position of the point on the y axis 9711 */ 9712 constructor(cb, scope, x = 0, y = 0) { 9713 this._x = x, this._y = y, this.cb = cb, this.scope = scope; 9714 } 9715 /** 9716 * Creates a clone of this point. 9717 * The callback and scope params can be overridden otherwise they will default 9718 * to the clone object's values. 9719 * @override 9720 * @param cb - The callback function triggered when `x` and/or `y` are changed 9721 * @param scope - The owner of the callback 9722 * @returns a copy of this observable point 9723 */ 9724 clone(cb = this.cb, scope = this.scope) { 9725 return new ObservablePoint(cb, scope, this._x, this._y); 9726 } 9727 /** 9728 * Sets the point to a new `x` and `y` position. 9729 * If `y` is omitted, both `x` and `y` will be set to `x`. 9730 * @param {number} [x=0] - position of the point on the x axis 9731 * @param {number} [y=x] - position of the point on the y axis 9732 * @returns The observable point instance itself 9733 */ 9734 set(x = 0, y = x) { 9735 return (this._x !== x || this._y !== y) && (this._x = x, this._y = y, this.cb.call(this.scope)), this; 9736 } 9737 /** 9738 * Copies x and y from the given point (`p`) 9739 * @param p - The point to copy from. Can be any of type that is or extends `IPointData` 9740 * @returns The observable point instance itself 9741 */ 9742 copyFrom(p) { 9743 return (this._x !== p.x || this._y !== p.y) && (this._x = p.x, this._y = p.y, this.cb.call(this.scope)), this; 9744 } 9745 /** 9746 * Copies this point's x and y into that of the given point (`p`) 9747 * @param p - The point to copy to. Can be any of type that is or extends `IPointData` 9748 * @returns The point (`p`) with values updated 9749 */ 9750 copyTo(p) { 9751 return p.set(this._x, this._y), p; 9752 } 9753 /** 9754 * Accepts another point (`p`) and returns `true` if the given point is equal to this point 9755 * @param p - The point to check 9756 * @returns Returns `true` if both `x` and `y` are equal 9757 */ 9758 equals(p) { 9759 return p.x === this._x && p.y === this._y; 9760 } 9761 /** Position of the observable point on the x axis. */ 9762 get x() { 9763 return this._x; 9764 } 9765 set x(value) { 9766 this._x !== value && (this._x = value, this.cb.call(this.scope)); 9767 } 9768 /** Position of the observable point on the y axis. */ 9769 get y() { 9770 return this._y; 9771 } 9772 set y(value) { 9773 this._y !== value && (this._y = value, this.cb.call(this.scope)); 9774 } 9775} 9776ObservablePoint.prototype.toString = function() { 9777 return `[@pixi/math:ObservablePoint x=${this.x} y=${this.y} scope=${this.scope}]`; 9778}; 9779 9780const _Transform = class { 9781 constructor() { 9782 this.worldTransform = new Matrix(), this.localTransform = new Matrix(), this.position = new ObservablePoint(this.onChange, this, 0, 0), this.scale = new ObservablePoint(this.onChange, this, 1, 1), this.pivot = new ObservablePoint(this.onChange, this, 0, 0), this.skew = new ObservablePoint(this.updateSkew, this, 0, 0), this._rotation = 0, this._cx = 1, this._sx = 0, this._cy = 0, this._sy = 1, this._localID = 0, this._currentLocalID = 0, this._worldID = 0, this._parentID = 0; 9783 } 9784 /** Called when a value changes. */ 9785 onChange() { 9786 this._localID++; 9787 } 9788 /** Called when the skew or the rotation changes. */ 9789 updateSkew() { 9790 this._cx = Math.cos(this._rotation + this.skew.y), this._sx = Math.sin(this._rotation + this.skew.y), this._cy = -Math.sin(this._rotation - this.skew.x), this._sy = Math.cos(this._rotation - this.skew.x), this._localID++; 9791 } 9792 /** Updates the local transformation matrix. */ 9793 updateLocalTransform() { 9794 const lt = this.localTransform; 9795 this._localID !== this._currentLocalID && (lt.a = this._cx * this.scale.x, lt.b = this._sx * this.scale.x, lt.c = this._cy * this.scale.y, lt.d = this._sy * this.scale.y, lt.tx = this.position.x - (this.pivot.x * lt.a + this.pivot.y * lt.c), lt.ty = this.position.y - (this.pivot.x * lt.b + this.pivot.y * lt.d), this._currentLocalID = this._localID, this._parentID = -1); 9796 } 9797 /** 9798 * Updates the local and the world transformation matrices. 9799 * @param parentTransform - The parent transform 9800 */ 9801 updateTransform(parentTransform) { 9802 const lt = this.localTransform; 9803 if (this._localID !== this._currentLocalID && (lt.a = this._cx * this.scale.x, lt.b = this._sx * this.scale.x, lt.c = this._cy * this.scale.y, lt.d = this._sy * this.scale.y, lt.tx = this.position.x - (this.pivot.x * lt.a + this.pivot.y * lt.c), lt.ty = this.position.y - (this.pivot.x * lt.b + this.pivot.y * lt.d), this._currentLocalID = this._localID, this._parentID = -1), this._parentID !== parentTransform._worldID) { 9804 const pt = parentTransform.worldTransform, wt = this.worldTransform; 9805 wt.a = lt.a * pt.a + lt.b * pt.c, wt.b = lt.a * pt.b + lt.b * pt.d, wt.c = lt.c * pt.a + lt.d * pt.c, wt.d = lt.c * pt.b + lt.d * pt.d, wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx, wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty, this._parentID = parentTransform._worldID, this._worldID++; 9806 } 9807 } 9808 /** 9809 * Decomposes a matrix and sets the transforms properties based on it. 9810 * @param matrix - The matrix to decompose 9811 */ 9812 setFromMatrix(matrix) { 9813 matrix.decompose(this), this._localID++; 9814 } 9815 /** The rotation of the object in radians. */ 9816 get rotation() { 9817 return this._rotation; 9818 } 9819 set rotation(value) { 9820 this._rotation !== value && (this._rotation = value, this.updateSkew()); 9821 } 9822}; 9823_Transform.IDENTITY = new _Transform(); 9824let Transform = _Transform; 9825Transform.prototype.toString = function() { 9826 return `[@pixi/math:Transform position=(${this.position.x}, ${this.position.y}) rotation=${this.rotation} scale=(${this.scale.x}, ${this.scale.y}) skew=(${this.skew.x}, ${this.skew.y}) ]`; 9827}; 9828 9829var defaultFragment$2 = `varying vec2 vTextureCoord; 9830 9831uniform sampler2D uSampler; 9832 9833void main(void){ 9834 gl_FragColor *= texture2D(uSampler, vTextureCoord); 9835}`; 9836 9837var defaultVertex$3 = `attribute vec2 aVertexPosition; 9838attribute vec2 aTextureCoord; 9839 9840uniform mat3 projectionMatrix; 9841 9842varying vec2 vTextureCoord; 9843 9844void main(void){ 9845 gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0
9845)).xy, 0.0, 1.0); 9846 vTextureCoord = aTextureCoord; 9847} 9848`; 9849 9850function compileShader(gl, type, src) { 9851 const shader = gl.createShader(type); 9852 return gl.shaderSource(shader, src), gl.compileShader(shader), shader; 9853} 9854 9855function booleanArray(size) { 9856 const array = new Array(size); 9857 for (let i = 0; i < array.length; i++) 9858 array[i] = !1; 9859 return array; 9860} 9861function defaultValue(type, size) { 9862 switch (type) { 9863 case "float": 9864 return 0; 9865 case "vec2": 9866 return new Float32Array(2 * size); 9867 case "vec3": 9868 return new Float32Array(3 * size); 9869 case "vec4": 9870 return new Float32Array(4 * size); 9871 case "int": 9872 case "uint": 9873 case "sampler2D": 9874 case "sampler2DArray": 9875 return 0; 9876 case "ivec2": 9877 return new Int32Array(2 * size); 9878 case "ivec3": 9879 return new Int32Array(3 * size); 9880 case "ivec4": 9881 return new Int32Array(4 * size); 9882 case "uvec2": 9883 return new Uint32Array(2 * size); 9884 case "uvec3": 9885 return new Uint32Array(3 * size); 9886 case "uvec4": 9887 return new Uint32Array(4 * size); 9888 case "bool": 9889 return !1; 9890 case "bvec2": 9891 return booleanArray(2 * size); 9892 case "bvec3": 9893 return booleanArray(3 * size); 9894 case "bvec4": 9895 return booleanArray(4 * size); 9896 case "mat2": 9897 return new Float32Array([ 9898 1, 9899 0, 9900 0, 9901 1 9902 ]); 9903 case "mat3": 9904 return new Float32Array([ 9905 1, 9906 0, 9907 0, 9908 0, 9909 1, 9910 0, 9911 0, 9912 0, 9913 1 9914 ]); 9915 case "mat4": 9916 return new Float32Array([ 9917 1, 9918 0, 9919 0, 9920 0, 9921 0, 9922 1, 9923 0, 9924 0, 9925 0, 9926 0, 9927 1, 9928 0, 9929 0, 9930 0, 9931 0, 9932 1 9933 ]); 9934 } 9935 return null; 9936} 9937 9938const uniformParsers = [ 9939 // a float cache layer 9940 { 9941 test: (data) => data.type === "float" && data.size === 1 && !data.isArray, 9942 code: (name) => ` 9943 if(uv["${name}"] !== ud["${name}"].value) 9944 { 9945 ud["${name}"].value = uv["${name}"] 9946 gl.uniform1f(ud["${name}"].location, uv["${name}"]) 9947 } 9948 ` 9949 }, 9950 // handling samplers 9951 { 9952 test: (data, uniform) => ( 9953 // eslint-disable-next-line max-len,no-eq-null,eqeqeq 9954 (data.type === "sampler2D" || data.type === "samplerCube" || data.type === "sampler2DArray") && data.size === 1 && !data.isArray && (uniform == null || uniform.castToBaseTexture !== void 0) 9955 ), 9956 code: (name) => `t = syncData.textureCount++; 9957 9958 renderer.texture.bind(uv["${name}"], t); 9959 9960 if(ud["${name}"].value !== t) 9961 { 9962 ud["${name}"].value = t; 9963 gl.uniform1i(ud["${name}"].location, t); 9964; // eslint-disable-line max-len 9965 }` 9966 }, 9967 // uploading pixi matrix object to mat3 9968 { 9969 test: (data, uniform) => data.type === "mat3" && data.size === 1 && !data.isArray && uniform.a !== void 0, 9970 code: (name) => ( 9971 // TODO and some smart caching dirty ids here! 9972 ` 9973 gl.uniformMatrix3fv(ud["${name}"].location, false, uv["${name}"].toArray(true)); 9974 ` 9975 ), 9976 codeUbo: (name) => ` 9977 var ${name}_matrix = uv.${name}.toArray(true); 9978 9979 data[offset] = ${name}_matrix[0]; 9980 data[offset+1] = ${name}_matrix[1]; 9981 data[offset+2] = ${name}_matrix[2]; 9982 9983 data[offset + 4] = ${name}_matrix[3]; 9984 data[offset + 5] = ${name}_matrix[4]; 9985 data[offset + 6] = ${name}_matrix[5]; 9986 9987 data[offset + 8] = ${name}_matrix[6]; 9988 data[offset + 9] = ${name}_matrix[7]; 9989 data[offset + 10] = ${name}_matrix[8]; 9990 ` 9991 }, 9992 // uploading a pixi point as a vec2 with caching layer 9993 { 9994 test: (data, uniform) => data.type === "vec2" && data.size === 1 && !data.isArray && uniform.x !== void 0, 9995 code: (name) => ` 9996 cv = ud["${name}"].value; 9997 v = uv["${name}"]; 9998 9999 if(cv[0] !== v.x || cv[1] !== v.y) 10000 { 10001 cv[0] = v.x; 10002 cv[1] = v.y; 10003 gl.uniform2f(ud["${name}"].location, v.x, v.y); 10004 }`, 10005 codeUbo: (name) => ` 10006 v = uv.${name}; 10007 10008 data[offset] = v.x; 10009 data[offset+1] = v.y; 10010 ` 10011 }, 10012 // caching layer for a vec2 10013 { 10014 test: (data) => data.type === "vec2" && data.size === 1 && !data.isArray, 10015 code: (name) => ` 10016 cv = ud["${name}"].value; 10017 v = uv["${name}"]; 10018 10019 if(cv[0] !== v[0] || cv[1] !== v[1]) 10020 { 10021 cv[0] = v[0]; 10022 cv[1] = v[1]; 10023 gl.uniform2f(ud["${name}"].location, v[0], v[1]); 10024 } 10025 ` 10026 }, 10027 // upload a pixi rectangle as a vec4 with caching layer 10028 { 10029 test: (data, uniform) => data.type === "vec4" && data.size === 1 && !data.isArray && uniform.width !== void 0, 10030 code: (name) => ` 10031 cv = ud["${name}"].value; 10032 v = uv["${name}"]; 10033 10034 if(cv[0] !== v.x || cv[1] !== v.y || cv[2] !== v.width || cv[3] !== v.height) 10035 { 10036 cv[0] = v.x; 10037 cv[1] = v.y; 10038 cv[2] = v.width; 10039 cv[3] = v.height; 10040 gl.uniform4f(ud["${name}"].location, v.x, v.y, v.width, v.height) 10041 }`, 10042 codeUbo: (name) => ` 10043 v = uv.${name}; 10044 10045 data[offset] = v.x; 10046 data[offset+1] = v.y; 10047 data[offset+2] = v.width; 10048 data[offset+3] = v.height; 10049 ` 10050 }, 10051 // upload a pixi color as vec4 with caching layer 10052 { 10053 test: (data, uniform) => data.type === "vec4" && data.size === 1 && !data.isArray && uniform.red !== void 0, 10054 code: (name) => ` 10055 cv = ud["${name}"].value; 10056 v = uv["${name}"]; 10057 10058 if(cv[0] !== v.red || cv[1] !== v.green || cv[2] !== v.blue || cv[3] !== v.alpha) 10059 { 10060 cv[0] = v.red; 10061 cv[1] = v.green; 10062 cv[2] = v.blue; 10063 cv[3] = v.alpha; 10064 gl.uniform4f(ud["${name}"].location, v.red, v.green, v.blue, v.alpha) 10065 }`, 10066 codeUbo: (name) => ` 10067 v = uv.${name}; 10068 10069 data[offset] = v.red; 10070 data[offset+1] = v.green; 10071 data[offset+2] = v.blue; 10072 data[offset+3] = v.alpha; 10073 ` 10074 }, 10075 // upload a pixi color as a vec3 with caching layer 10076 { 10077 test: (data, uniform) => data.type === "vec3" && data.size === 1 && !data.isArray && uniform.red !== void 0, 10078 code: (name) => ` 10079 cv = ud["${name}"].value; 10080 v = uv["${name}"]; 10081 10082 if(cv[0] !== v.red || cv[1] !== v.green || cv[2] !== v.blue || cv[3] !== v.a) 10083 { 10084 cv[0] = v.red; 10085 cv[1] = v.green; 10086 cv[2] = v.blue; 10087 10088 gl.uniform3f(ud["${name}"].location, v.red, v.green, v.blue) 10089 }`, 10090 codeUbo: (name) => ` 10091 v = uv.${name}; 10092 10093 data[offset] = v.red; 10094 data[offset+1] = v.green; 10095 data[offset+2] = v.blue; 10096 ` 10097 }, 10098 // a caching layer for vec4 uploading 10099 { 10100 test: (data) => data.type === "vec4" && data.size === 1 && !data.isArray, 10101 code: (name) => ` 10102 cv = ud["${name}"].value; 10103 v = uv["${name}"]; 10104 10105 if(cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) 10106 { 10107 cv[0] = v[0]; 10108 cv[1] = v[1]; 10109 cv[2] = v[2]; 10110 cv[3] = v[3]; 10111 10112 gl.uniform4f(ud["${name}"].location, v[0], v[1], v[2], v[3]) 10113 }` 10114 } 10115]; 10116 10117const GLSL_TO_SINGLE_SETTERS_CACHED = { 10118 float: ` 10119 if (cv !== v) 10120 { 10121 cu.value = v; 10122 gl.uniform1f(location, v); 10123 }`, 10124 vec2: ` 10125 if (cv[0] !== v[0] || cv[1] !== v[1]) 10126 { 10127 cv[0] = v[0]; 10128 cv[1] = v[1]; 10129 10130 gl.uniform2f(location, v[0], v[1]) 10131 }`, 10132 vec3: ` 10133 if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) 10134 { 10135 cv[0] = v[0]; 10136 cv[1] = v[1]; 10137 cv[2] = v[2]; 10138 10139 gl.uniform3f(location, v[0], v[1], v[2]) 10140 }`, 10141 vec4: ` 10142 if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) 10143 { 10144 cv[0] = v[0]; 10145 cv[1] = v[1]; 10146 cv[2] = v[2]; 10147 cv[3] = v[3]; 10148 10149 gl.uniform4f(location, v[0], v[1], v[2], v[3]); 10150 }`, 10151 int: `
10152 if (cv !== v) 10153 { 10154 cu.value = v; 10155 10156 gl.uniform1i(location, v); 10157 }`, 10158 ivec2: ` 10159 if (cv[0] !== v[0] || cv[1] !== v[1]) 10160 { 10161 cv[0] = v[0]; 10162 cv[1] = v[1]; 10163 10164 gl.uniform2i(location, v[0], v[1]); 10165 }`, 10166 ivec3: ` 10167 if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) 10168 { 10169 cv[0] = v[0]; 10170 cv[1] = v[1]; 10171 cv[2] = v[2]; 10172 10173 gl.uniform3i(location, v[0], v[1], v[2]); 10174 }`, 10175 ivec4: ` 10176 if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) 10177 { 10178 cv[0] = v[0]; 10179 cv[1] = v[1]; 10180 cv[2] = v[2]; 10181 cv[3] = v[3]; 10182 10183 gl.uniform4i(location, v[0], v[1], v[2], v[3]); 10184 }`, 10185 uint: ` 10186 if (cv !== v) 10187 { 10188 cu.value = v; 10189 10190 gl.uniform1ui(location, v); 10191 }`, 10192 uvec2: ` 10193 if (cv[0] !== v[0] || cv[1] !== v[1]) 10194 { 10195 cv[0] = v[0]; 10196 cv[1] = v[1]; 10197 10198 gl.uniform2ui(location, v[0], v[1]); 10199 }`, 10200 uvec3: ` 10201 if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) 10202 { 10203 cv[0] = v[0]; 10204 cv[1] = v[1]; 10205 cv[2] = v[2]; 10206 10207 gl.uniform3ui(location, v[0], v[1], v[2]); 10208 }`, 10209 uvec4: ` 10210 if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) 10211 { 10212 cv[0] = v[0]; 10213 cv[1] = v[1]; 10214 cv[2] = v[2]; 10215 cv[3] = v[3]; 10216 10217 gl.uniform4ui(location, v[0], v[1], v[2], v[3]); 10218 }`, 10219 bool: ` 10220 if (cv !== v) 10221 { 10222 cu.value = v; 10223 gl.uniform1i(location, v); 10224 }`, 10225 bvec2: ` 10226 if (cv[0] != v[0] || cv[1] != v[1]) 10227 { 10228 cv[0] = v[0]; 10229 cv[1] = v[1]; 10230 10231 gl.uniform2i(location, v[0], v[1]); 10232 }`, 10233 bvec3: ` 10234 if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) 10235 { 10236 cv[0] = v[0]; 10237 cv[1] = v[1]; 10238 cv[2] = v[2]; 10239 10240 gl.uniform3i(location, v[0], v[1], v[2]); 10241 }`, 10242 bvec4: ` 10243 if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) 10244 { 10245 cv[0] = v[0]; 10246 cv[1] = v[1]; 10247 cv[2] = v[2]; 10248 cv[3] = v[3]; 10249 10250 gl.uniform4i(location, v[0], v[1], v[2], v[3]); 10251 }`, 10252 mat2: "gl.uniformMatrix2fv(location, false, v)", 10253 mat3: "gl.uniformMatrix3fv(location, false, v)", 10254 mat4: "gl.uniformMatrix4fv(location, false, v)", 10255 sampler2D: ` 10256 if (cv !== v) 10257 { 10258 cu.value = v; 10259 10260 gl.uniform1i(location, v); 10261 }`, 10262 samplerCube: ` 10263 if (cv !== v) 10264 { 10265 cu.value = v; 10266 10267 gl.uniform1i(location, v); 10268 }`, 10269 sampler2DArray: ` 10270 if (cv !== v) 10271 { 10272 cu.value = v; 10273 10274 gl.uniform1i(location, v); 10275 }` 10276}, GLSL_TO_ARRAY_SETTERS = { 10277 float: "gl.uniform1fv(location, v)", 10278 vec2: "gl.uniform2fv(location, v)", 10279 vec3: "gl.uniform3fv(location, v)", 10280 vec4: "gl.uniform4fv(location, v)", 10281 mat4: "gl.uniformMatrix4fv(location, false, v)", 10282 mat3: "gl.uniformMatrix3fv(location, false, v)", 10283 mat2: "gl.uniformMatrix2fv(location, false, v)", 10284 int: "gl.uniform1iv(location, v)", 10285 ivec2: "gl.uniform2iv(location, v)", 10286 ivec3: "gl.uniform3iv(location, v)", 10287 ivec4: "gl.uniform4iv(location, v)", 10288 uint: "gl.uniform1uiv(location, v)", 10289 uvec2: "gl.uniform2uiv(location, v)", 10290 uvec3: "gl.uniform3uiv(location, v)", 10291 uvec4: "gl.uniform4uiv(location, v)", 10292 bool: "gl.uniform1iv(location, v)", 10293 bvec2: "gl.uniform2iv(location, v)", 10294 bvec3: "gl.uniform3iv(location, v)", 10295 bvec4: "gl.uniform4iv(location, v)", 10296 sampler2D: "gl.uniform1iv(location, v)", 10297 samplerCube: "gl.uniform1iv(location, v)", 10298 sampler2DArray: "gl.uniform1iv(location, v)" 10299}; 10300function generateUniformsSync(group, uniformData) { 10301 const funcFragments = [` 10302 var v = null; 10303 var cv = null; 10304 var cu = null; 10305 var t = 0; 10306 var gl = renderer.gl; 10307 `]; 10308 for (const i in group.uniforms) { 10309 const data = uniformData[i]; 10310 if (!data) { 10311 group.uniforms[i]?.group === !0 && (group.uniforms[i].ubo ? funcFragments.push(` 10312 renderer.shader.syncUniformBufferGroup(uv.${i}, '${i}'); 10313 `) : funcFragments.push(` 10314 renderer.shader.syncUniformGroup(uv.${i}, syncData); 10315 `)); 10316 continue; 10317 } 10318 const uniform = group.uniforms[i]; 10319 let parsed = !1; 10320 for (let j = 0; j < uniformParsers.length; j++) 10321 if (uniformParsers[j].test(data, uniform)) { 10322 funcFragments.push(uniformParsers[j].code(i, uniform)), parsed = !0; 10323 break; 10324 } 10325 if (!parsed) { 10326 const template = (data.size === 1 && !data.isArray ? GLSL_TO_SINGLE_SETTERS_CACHED : GLSL_TO_ARRAY_SETTERS)[data.type].replace("location", `ud["${i}"].location`); 10327 funcFragments.push(` 10328 cu = ud["${i}"]; 10329 cv = cu.value; 10330 v = uv["${i}"]; 10331 ${template};`); 10332 } 10333 } 10334 return new Function("ud", "uv", "renderer", "syncData", funcFragments.join(` 10335`)); 10336} 10337 10338const unknownContext = {}; 10339let context = unknownContext; 10340function getTestContext() { 10341 if (context === unknownContext || context?.isContextLost()) { 10342 const canvas = settings.ADAPTER.createCanvas(); 10343 let gl; 10344 settings.PREFER_ENV >= ENV.WEBGL2 && (gl = canvas.getContext("webgl2", {})), gl || (gl = canvas.getContext("webgl", {}) || canvas.getContext("experimental-webgl", {}), gl ? gl.getExtension("WEBGL_draw_buffers") : gl = null), context = gl; 10345 } 10346 return context; 10347} 10348 10349let maxFragmentPrecision; 10350function getMaxFragmentPrecision() { 10351 if (!maxFragmentPrecision) { 10352 maxFragmentPrecision = PRECISION.MEDIUM; 10353 const gl = getTestContext(); 10354 if (gl && gl.getShaderPrecisionFormat) { 10355 const shaderFragment = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT); 10356 shaderFragment && (maxFragmentPrecision = shaderFragment.precision ? PRECISION.HIGH : PRECISION.MEDIUM); 10357 } 10358 } 10359 return maxFragmentPrecision; 10360} 10361 10362function logPrettyShaderError(gl, shader) { 10363 const shaderSrc = gl.getShaderSource(shader).split(` 10364`).map((line, index) => `${index}: ${line}`), shaderLog = gl.getShaderInfoLog(shader), splitShader = shaderLog.split(` 10365`), dedupe = {}, lineNumbers = splitShader.map((line) =>
vendor: 12,994 bytes, lines 10365-10739
10365 parseFloat(line.replace(/^ERROR\: 0\:([\d]+)\:.*$/, "$1"))).filter((n) => n && !dedupe[n] ? (dedupe[n] = !0, !0) : !1), logArgs = [""]; 10366 lineNumbers.forEach((number) => { 10367 shaderSrc[number - 1] = `%c${shaderSrc[number - 1]}%c`, logArgs.push("background: #FF0000; color:#FFFFFF; font-size: 10px", "font-size: 10px"); 10368 }); 10369 const fragmentSourceToLog = shaderSrc.join(` 10370`); 10371 logArgs[0] = fragmentSourceToLog, console.error(shaderLog), console.groupCollapsed("click to view full shader code"), console.warn(...logArgs), console.groupEnd(); 10372} 10373function logProgramError(gl, program, vertexShader, fragmentShader) { 10374 gl.getProgramParameter(program, gl.LINK_STATUS) || (gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) || logPrettyShaderError(gl, vertexShader), gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) || logPrettyShaderError(gl, fragmentShader), console.error("PixiJS Error: Could not initialize shader."), gl.getProgramInfoLog(program) !== "" && console.warn("PixiJS Warning: gl.getProgramInfoLog()", gl.getProgramInfoLog(program))); 10375} 10376 10377const GLSL_TO_SIZE = { 10378 float: 1, 10379 vec2: 2, 10380 vec3: 3, 10381 vec4: 4, 10382 int: 1, 10383 ivec2: 2, 10384 ivec3: 3, 10385 ivec4: 4, 10386 uint: 1, 10387 uvec2: 2, 10388 uvec3: 3, 10389 uvec4: 4, 10390 bool: 1, 10391 bvec2: 2, 10392 bvec3: 3, 10393 bvec4: 4, 10394 mat2: 4, 10395 mat3: 9, 10396 mat4: 16, 10397 sampler2D: 1 10398}; 10399function mapSize(type) { 10400 return GLSL_TO_SIZE[type]; 10401} 10402 10403let GL_TABLE = null; 10404const GL_TO_GLSL_TYPES = { 10405 FLOAT: "float", 10406 FLOAT_VEC2: "vec2", 10407 FLOAT_VEC3: "vec3", 10408 FLOAT_VEC4: "vec4", 10409 INT: "int", 10410 INT_VEC2: "ivec2", 10411 INT_VEC3: "ivec3", 10412 INT_VEC4: "ivec4", 10413 UNSIGNED_INT: "uint", 10414 UNSIGNED_INT_VEC2: "uvec2", 10415 UNSIGNED_INT_VEC3: "uvec3", 10416 UNSIGNED_INT_VEC4: "uvec4", 10417 BOOL: "bool", 10418 BOOL_VEC2: "bvec2", 10419 BOOL_VEC3: "bvec3", 10420 BOOL_VEC4: "bvec4", 10421 FLOAT_MAT2: "mat2", 10422 FLOAT_MAT3: "mat3", 10423 FLOAT_MAT4: "mat4", 10424 SAMPLER_2D: "sampler2D", 10425 INT_SAMPLER_2D: "sampler2D", 10426 UNSIGNED_INT_SAMPLER_2D: "sampler2D", 10427 SAMPLER_CUBE: "samplerCube", 10428 INT_SAMPLER_CUBE: "samplerCube", 10429 UNSIGNED_INT_SAMPLER_CUBE: "samplerCube", 10430 SAMPLER_2D_ARRAY: "sampler2DArray", 10431 INT_SAMPLER_2D_ARRAY: "sampler2DArray", 10432 UNSIGNED_INT_SAMPLER_2D_ARRAY: "sampler2DArray" 10433}; 10434function mapType(gl, type) { 10435 if (!GL_TABLE) { 10436 const typeNames = Object.keys(GL_TO_GLSL_TYPES); 10437 GL_TABLE = {}; 10438 for (let i = 0; i < typeNames.length; ++i) { 10439 const tn = typeNames[i]; 10440 GL_TABLE[gl[tn]] = GL_TO_GLSL_TYPES[tn]; 10441 } 10442 } 10443 return GL_TABLE[type]; 10444} 10445 10446function setPrecision(src, requestedPrecision, maxSupportedPrecision) { 10447 if (src.substring(0, 9) !== "precision") { 10448 let precision = requestedPrecision; 10449 return requestedPrecision === PRECISION.HIGH && maxSupportedPrecision !== PRECISION.HIGH && (precision = PRECISION.MEDIUM), `precision ${precision} float; 10450${src}`; 10451 } else if (maxSupportedPrecision !== PRECISION.HIGH && src.substring(0, 15) === "precision highp") 10452 return src.replace("precision highp", "precision mediump"); 10453 return src; 10454} 10455 10456let unsafeEval; 10457function unsafeEvalSupported() { 10458 if (typeof unsafeEval == "boolean") 10459 return unsafeEval; 10460 try { 10461 unsafeEval = new Function("param1", "param2", "param3", "return param1[param2] === param3;")({ a: "b" }, "a", "b") === !0; 10462 } catch { 10463 unsafeEval = !1; 10464 } 10465 return unsafeEval; 10466} 10467 10468let UID$2 = 0; 10469const nameCache = {}, _Program = class _Program2 { 10470 /** 10471 * @param vertexSrc - The source of the vertex shader. 10472 * @param fragmentSrc - The source of the fragment shader. 10473 * @param name - Name for shader 10474 * @param extra - Extra data for shader 10475 */ 10476 constructor(vertexSrc, fragmentSrc, name = "pixi-shader", extra = {}) { 10477 this.extra = {}, this.id = UID$2++, this.vertexSrc = vertexSrc || _Program2.defaultVertexSrc, this.fragmentSrc = fragmentSrc || _Program2.defaultFragmentSrc, this.vertexSrc = this.vertexSrc.trim(), this.fragmentSrc = this.fragmentSrc.trim(), this.extra = extra, this.vertexSrc.substring(0, 8) !== "#version" && (name = name.replace(/\s+/g, "-"), nameCache[name] ? (nameCache[name]++, name += `-${nameCache[name]}`) : nameCache[name] = 1, this.vertexSrc = `#define SHADER_NAME ${name} 10478${this.vertexSrc}`, this.fragmentSrc = `#define SHADER_NAME ${name} 10479${this.fragmentSrc}`, this.vertexSrc = setPrecision( 10480 this.vertexSrc, 10481 _Program2.defaultVertexPrecision, 10482 PRECISION.HIGH 10483 ), this.fragmentSrc = setPrecision( 10484 this.fragmentSrc, 10485 _Program2.defaultFragmentPrecision, 10486 getMaxFragmentPrecision() 10487 )), this.glPrograms = {}, this.syncUniforms = null; 10488 } 10489 /** 10490 * The default vertex shader source. 10491 * @readonly 10492 */ 10493 static get defaultVertexSrc() { 10494 return defaultVertex$3; 10495 } 10496 /** 10497 * The default fragment shader source. 10498 * @readonly 10499 */ 10500 static get defaultFragmentSrc() { 10501 return defaultFragment$2; 10502 } 10503 /** 10504 * A short hand function to create a program based of a vertex and fragment shader. 10505 * 10506 * This method will also check to see if there is a cached program. 10507 * @param vertexSrc - The source of the vertex shader. 10508 * @param fragmentSrc - The source of the fragment shader. 10509 * @param name - Name for shader 10510 * @returns A shiny new PixiJS shader program! 10511 */ 10512 static from(vertexSrc, fragmentSrc, name) { 10513 const key = vertexSrc + fragmentSrc; 10514 let program = ProgramCache[key]; 10515 return program || (ProgramCache[key] = program = new _Program2(vertexSrc, fragmentSrc, name)), program; 10516 } 10517}; 10518_Program.defaultVertexPrecision = PRECISION.HIGH, /** 10519* Default specify float precision in fragment shader. 10520* iOS is best set at highp due to https://github.com/pixijs/pixijs/issues/3742 10521* @static 10522* @type {PIXI.PRECISION} 10523* @default PIXI.PRECISION.MEDIUM 10524*/ 10525_Program.defaultFragmentPrecision = isMobile.apple.device ? PRECISION.HIGH : PRECISION.MEDIUM; 10526let Program = _Program; 10527 10528let UID$1 = 0; 10529class UniformGroup { 10530 /** 10531 * @param {object | Buffer} [uniforms] - Custom uniforms to use to augment the built-in ones. Or a pixi buffer. 10532 * @param isStatic - Uniforms wont be changed after creation. 10533 * @param isUbo - If true, will treat this uniform group as a uniform buffer object. 10534 */ 10535 constructor(uniforms, isStatic, isUbo) { 10536 this.group = !0, this.syncUniforms = {}, this.dirtyId = 0, this.id = UID$1++, this.static = !!isStatic, this.ubo = !!isUbo, uniforms instanceof Buffer ? (this.buffer = uniforms, this.buffer.type = BUFFER_TYPE.UNIFORM_BUFFER, this.autoManage = !1, this.ubo = !0) : (this.uniforms = uniforms, this.ubo && (this.buffer = new Buffer(new Float32Array(1)), this.buffer.type = BUFFER_TYPE.UNIFORM_BUFFER, this.autoManage = !0)); 10537 } 10538 update() { 10539 this.dirtyId++, !this.autoManage && this.buffer && this.buffer.update(); 10540 } 10541 add(name, uniforms, _static) { 10542 if (!this.ubo) 10543 this.uniforms[name] = new UniformGroup(uniforms, _static); 10544 else 10545 throw new Error("[UniformGroup] uniform groups in ubo mode cannot be modified, or have uniform groups nested in them"); 10546 } 10547 static from(uniforms, _static, _ubo) { 10548 return new UniformGroup(uniforms, _static, _ubo); 10549 } 10550 /** 10551 * A short hand function for creating a static UBO UniformGroup. 10552 * @param uniforms - the ubo item 10553 * @param _static - should this be updated each time it is used? defaults to true here! 10554 */ 10555 static uboFrom(uniforms, _static) { 10556 return new UniformGroup(uniforms, _static ?? !0, !0); 10557 } 10558} 10559 10560class Shader { 10561 /** 10562 * @param program - The program the shader will use. 10563 * @param uniforms - Custom uniforms to use to augment the built-in ones. 10564 */ 10565 constructor(program, uniforms) { 10566 this.uniformBindCount = 0, this.program = program, uniforms ? uniforms instanceof UniformGroup ? this.uniformGroup = uniforms : this.uniformGroup = new UniformGroup(uniforms) : this.uniformGroup = new UniformGroup({}), this.disposeRunner = new Runner("disposeShader"); 10567 } 10568 // TODO move to shader system.. 10569 checkUniformExists(name, group) { 10570 if (group.uniforms[name]) 10571 return !0; 10572 for (const i in group.uniforms) { 10573 const uniform = group.uniforms[i]; 10574 if (uniform.group === !0 && this.checkUniformExists(name, uniform)) 10575 return !0; 10576 } 10577 return !1; 10578 } 10579 destroy() { 10580 this.uniformGroup = null, this.disposeRunner.emit(this), this.disposeRunner.destroy(); 10581 } 10582 /** 10583 * Shader uniform values, shortcut for `uniformGroup.uniforms`. 10584 * @readonly 10585 */ 10586 get uniforms() { 10587 return this.uniformGroup.uniforms; 10588 } 10589 /** 10590 * A short hand function to create a shader based of a vertex and fragment shader. 10591 * @param vertexSrc - The source of the vertex shader. 10592 * @param fragmentSrc - The source of the fragment shader. 10593 * @param uniforms - Custom uniforms to use to augment the built-in ones. 10594 * @returns A shiny new PixiJS shader! 10595 */ 10596 static from(vertexSrc, fragmentSrc, uniforms) { 10597 const program = Program.from(vertexSrc, fragmentSrc); 10598 return new Shader(program, uniforms); 10599 } 10600} 10601 10602class BatchShaderGenerator { 10603 /** 10604 * @param vertexSrc - Vertex shader 10605 * @param fragTemplate - Fragment shader template 10606 */ 10607 constructor(vertexSrc, fragTemplate) { 10608 if (this.vertexSrc = vertexSrc, this.fragTemplate = fragTemplate, this.programCache = {}, this.defaultGroupCache = {}, !fragTemplate.includes("%count%")) 10609 throw new Error('Fragment template must contain "%count%".'); 10610 if (!fragTemplate.includes("%forloop%")) 10611 throw new Error('Fragment template must contain "%forloop%".'); 10612 } 10613 generateShader(maxTextures) { 10614 if (!this.programCache[maxTextures]) { 10615 const sampleValues = new Int32Array(maxTextures); 10616 for (let i = 0; i < maxTextures; i++) 10617 sampleValues[i] = i; 10618 this.defaultGroupCache[maxTextures] = UniformGroup.from({ uSamplers: sampleValues }, !0); 10619 let fragmentSrc = this.fragTemplate; 10620 fragmentSrc = fragmentSrc.replace(/%count%/gi, `${maxTextures}`), fragmentSrc = fragmentSrc.replace(/%forloop%/gi, this.generateSampleSrc(maxTextures)), this.programCache[maxTextures] = new Program(this.vertexSrc, fragmentSrc); 10621 } 10622 const uniforms = { 10623 tint: new Float32Array([1, 1, 1, 1]), 10624 translationMatrix: new Matrix(), 10625 default: this.defaultGroupCache[maxTextures] 10626 }; 10627 return new Shader(this.programCache[maxTextures], uniforms); 10628 } 10629 generateSampleSrc(maxTextures) { 10630 let src = ""; 10631 src += ` 10632`, src += ` 10633`; 10634 for (let i = 0; i < maxTextures; i++) 10635 i > 0 && (src += ` 10636else `), i < maxTextures - 1 && (src += `if(vTextureId < ${i}.5)`), src += ` 10637{`, src += ` 10638 color = texture2D(uSamplers[${i}], vTextureCoord);`, src += ` 10639}`; 10640 return src += ` 10641`, src += ` 10642`, src; 10643 } 10644} 10645 10646class BatchTextureArray { 10647 constructor() { 10648 this.elements = [], this.ids = [], this.count = 0; 10649 } 10650 clear() { 10651 for (let i = 0; i < this.count; i++) 10652 this.elements[i] = null; 10653 this.count = 0; 10654 } 10655} 10656 10657function canUploadSameBuffer() { 10658 return !isMobile.apple.device; 10659} 10660 10661function maxRecommendedTextures(max) { 10662 let allowMax = !0; 10663 const navigator = settings.ADAPTER.getNavigator(); 10664 if (isMobile.tablet || isMobile.phone) { 10665 if (isMobile.apple.device) { 10666 const match = navigator.userAgent.match(/OS (\d+)_(\d+)?/); 10667 match && parseInt(match[1], 10) < 11 && (allowMax = !1); 10668 } 10669 if (isMobile.android.device) { 10670 const match = navigator.userAgent.match(/Android\s([0-9.]*)/); 10671 match && parseInt(match[1], 10) < 7 && (allowMax = !1); 10672 } 10673 } 10674 return allowMax ? max : 4; 10675} 10676 10677class ObjectRenderer { 10678 /** 10679 * @param renderer - The renderer this manager works for. 10680 */ 10681 constructor(renderer) { 10682 this.renderer = renderer; 10683 } 10684 /** Stub method that should be used to empty the current batch by rendering objects now. */ 10685 flush() { 10686 } 10687 /** Generic destruction method that frees all resources. This should be called by subclasses. */ 10688 destroy() { 10689 this.renderer = null; 10690 } 10691 /** 10692 * Stub method that initializes any state required before 10693 * rendering starts. It is different from the `prerender` 10694 * signal, which occurs every frame, in that it is called 10695 * whenever an object requests _this_ renderer specifically. 10696 */ 10697 start() { 10698 } 10699 /** Stops the renderer. It should free up any state and become dormant. */ 10700 stop() { 10701 this.flush(); 10702 } 10703 /** 10704 * Keeps the object to render. It doesn't have to be 10705 * rendered immediately. 10706 * @param {PIXI.DisplayObject} _object - The object to render. 10707 */ 10708 render(_object) { 10709 } 10710} 10711 10712var defaultFragment$1 = `varying vec2 vTextureCoord; 10713varying vec4 vColor; 10714varying float vTextureId; 10715uniform sampler2D uSamplers[%count%]; 10716 10717void main(void){ 10718 vec4 color; 10719 %forloop% 10720 gl_FragColor = color * vColor; 10721} 10722`; 10723 10724var defaultVertex$2 = `precision highp float; 10725attribute vec2 aVertexPosition; 10726attribute vec2 aTextureCoord; 10727attribute vec4 aColor; 10728attribute float aTextureId; 10729 10730uniform mat3 projectionMatrix; 10731uniform mat3 translationMatrix; 10732uniform vec4 tint; 10733 10734varying vec2 vTextureCoord; 10735varying vec4 vColor; 10736varying float vTextureId; 10737 10738void main(void){ 10739 gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0
10739)).xy, 0.0, 1.0); 10740 10741 vTextureCoord = aTextureCoord; 10742 vTextureId = aTextureId; 10743 vColor = aColor * tint; 10744} 10745`; 10746 10747const _BatchRenderer = class _BatchRenderer2 extends ObjectRenderer { 10748 /** 10749 * This will hook onto the renderer's `contextChange` 10750 * and `prerender` signals. 10751 * @param {PIXI.Renderer} renderer - The renderer this works for. 10752 */ 10753 constructor(renderer) { 10754 super(renderer), this.setShaderGenerator(), this.geometryClass = BatchGeometry, this.vertexSize = 6, this.state = State.for2d(), this.size = _BatchRenderer2.defaultBatchSize * 4, this._vertexCount = 0, this._indexCount = 0, this._bufferedElements = [], this._bufferedTextures = [], this._bufferSize = 0, this._shader = null, this._packedGeometries = [], this._packedGeometryPoolSize = 2, this._flushId = 0, this._aBuffers = {}, this._iBuffers = {}, this.maxTextures = 1, this.renderer.on("prerender", this.onPrerender, this), renderer.runners.contextChange.add(this), this._dcIndex = 0, this._aIndex = 0, this._iIndex = 0, this._attributeBuffer = null, this._indexBuffer = null, this._tempBoundTextures = []; 10755 } 10756 /** 10757 * The maximum textures that this device supports. 10758 * @static 10759 * @default 32 10760 */ 10761 static get defaultMaxTextures() { 10762 return this._defaultMaxTextures = this._defaultMaxTextures ?? maxRecommendedTextures(32), this._defaultMaxTextures; 10763 } 10764 static set defaultMaxTextures(value) { 10765 this._defaultMaxTextures = value; 10766 } 10767 /** 10768 * Can we upload the same buffer in a single frame? 10769 * @static 10770 */ 10771 static get canUploadSameBuffer() { 10772 return this._canUploadSameBuffer = this._canUploadSameBuffer ?? c
vendor: 12,484 bytes, lines 10772-11027
10772anUploadSameBuffer(), this._canUploadSameBuffer; 10773 } 10774 static set canUploadSameBuffer(value) { 10775 this._canUploadSameBuffer = value; 10776 } 10777 /** 10778 * @see PIXI.BatchRenderer#maxTextures 10779 * @deprecated since 7.1.0 10780 * @readonly 10781 */ 10782 get MAX_TEXTURES() { 10783 return deprecation("7.1.0", "BatchRenderer#MAX_TEXTURES renamed to BatchRenderer#maxTextures"), this.maxTextures; 10784 } 10785 /** 10786 * The default vertex shader source 10787 * @readonly 10788 */ 10789 static get defaultVertexSrc() { 10790 return defaultVertex$2; 10791 } 10792 /** 10793 * The default fragment shader source 10794 * @readonly 10795 */ 10796 static get defaultFragmentTemplate() { 10797 return defaultFragment$1; 10798 } 10799 /** 10800 * Set the shader generator. 10801 * @param {object} [options] 10802 * @param {string} [options.vertex=PIXI.BatchRenderer.defaultVertexSrc] - Vertex shader source 10803 * @param {string} [options.fragment=PIXI.BatchRenderer.defaultFragmentTemplate] - Fragment shader template 10804 */ 10805 setShaderGenerator({ 10806 vertex = _BatchRenderer2.defaultVertexSrc, 10807 fragment = _BatchRenderer2.defaultFragmentTemplate 10808 } = {}) { 10809 this.shaderGenerator = new BatchShaderGenerator(vertex, fragment); 10810 } 10811 /** 10812 * Handles the `contextChange` signal. 10813 * 10814 * It calculates `this.maxTextures` and allocating the packed-geometry object pool. 10815 */ 10816 contextChange() { 10817 const gl = this.renderer.gl; 10818 settings.PREFER_ENV === ENV.WEBGL_LEGACY ? this.maxTextures = 1 : (this.maxTextures = Math.min( 10819 gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 10820 _BatchRenderer2.defaultMaxTextures 10821 ), this.maxTextures = checkMaxIfStatementsInShader( 10822 this.maxTextures, 10823 gl 10824 )), this._shader = this.shaderGenerator.generateShader(this.maxTextures); 10825 for (let i = 0; i < this._packedGeometryPoolSize; i++) 10826 this._packedGeometries[i] = new this.geometryClass(); 10827 this.initFlushBuffers(); 10828 } 10829 /** Makes sure that static and dynamic flush pooled objects have correct dimensions. */ 10830 initFlushBuffers() { 10831 const { 10832 _drawCallPool, 10833 _textureArrayPool 10834 } = _BatchRenderer2, MAX_SPRITES = this.size / 4, MAX_TA = Math.floor(MAX_SPRITES / this.maxTextures) + 1; 10835 for (; _drawCallPool.length < MAX_SPRITES; ) 10836 _drawCallPool.push(new BatchDrawCall()); 10837 for (; _textureArrayPool.length < MAX_TA; ) 10838 _textureArrayPool.push(new BatchTextureArray()); 10839 for (let i = 0; i < this.maxTextures; i++) 10840 this._tempBoundTextures[i] = null; 10841 } 10842 /** Handles the `prerender` signal. It ensures that flushes start from the first geometry object again. */ 10843 onPrerender() { 10844 this._flushId = 0; 10845 } 10846 /** 10847 * Buffers the "batchable" object. It need not be rendered immediately. 10848 * @param {PIXI.DisplayObject} element - the element to render when 10849 * using this renderer 10850 */ 10851 render(element) { 10852 element._texture.valid && (this._vertexCount + element.vertexData.length / 2 > this.size && this.flush(), this._vertexCount += element.vertexData.length / 2, this._indexCount += element.indices.length, this._bufferedTextures[this._bufferSize] = element._texture.baseTexture, this._bufferedElements[this._bufferSize++] = element); 10853 } 10854 buildTexturesAndDrawCalls() { 10855 const { 10856 _bufferedTextures: textures, 10857 maxTextures 10858 } = this, textureArrays = _BatchRenderer2._textureArrayPool, batch = this.renderer.batch, boundTextures = this._tempBoundTextures, touch = this.renderer.textureGC.count; 10859 let TICK = ++BaseTexture._globalBatch, countTexArrays = 0, texArray = textureArrays[0], start = 0; 10860 batch.copyBoundTextures(boundTextures, maxTextures); 10861 for (let i = 0; i < this._bufferSize; ++i) { 10862 const tex = textures[i]; 10863 textures[i] = null, tex._batchEnabled !== TICK && (texArray.count >= maxTextures && (batch.boundArray(texArray, boundTextures, TICK, maxTextures), this.buildDrawCalls(texArray, start, i), start = i, texArray = textureArrays[++countTexArrays], ++TICK), tex._batchEnabled = TICK, tex.touched = touch, texArray.elements[texArray.count++] = tex); 10864 } 10865 texArray.count > 0 && (batch.boundArray(texArray, boundTextures, TICK, maxTextures), this.buildDrawCalls(texArray, start, this._bufferSize), ++countTexArrays, ++TICK); 10866 for (let i = 0; i < boundTextures.length; i++) 10867 boundTextures[i] = null; 10868 BaseTexture._globalBatch = TICK; 10869 } 10870 /** 10871 * Populating drawcalls for rendering 10872 * @param texArray 10873 * @param start 10874 * @param finish 10875 */ 10876 buildDrawCalls(texArray, start, finish) { 10877 const { 10878 _bufferedElements: elements, 10879 _attributeBuffer, 10880 _indexBuffer, 10881 vertexSize 10882 } = this, drawCalls = _BatchRenderer2._drawCallPool; 10883 let dcIndex = this._dcIndex, aIndex = this._aIndex, iIndex = this._iIndex, drawCall = drawCalls[dcIndex]; 10884 drawCall.start = this._iIndex, drawCall.texArray = texArray; 10885 for (let i = start; i < finish; ++i) { 10886 const sprite = elements[i], tex = sprite._texture.baseTexture, spriteBlendMode = premultiplyBlendMode[tex.alphaMode ? 1 : 0][sprite.blendMode]; 10887 elements[i] = null, start < i && drawCall.blend !== spriteBlendMode && (drawCall.size = iIndex - drawCall.start, start = i, drawCall = drawCalls[++dcIndex], drawCall.texArray = texArray, drawCall.start = iIndex), this.packInterleavedGeometry(sprite, _attributeBuffer, _indexBuffer, aIndex, iIndex), aIndex += sprite.vertexData.length / 2 * vertexSize, iIndex += sprite.indices.length, drawCall.blend = spriteBlendMode; 10888 } 10889 start < finish && (drawCall.size = iIndex - drawCall.start, ++dcIndex), this._dcIndex = dcIndex, this._aIndex = aIndex, this._iIndex = iIndex; 10890 } 10891 /** 10892 * Bind textures for current rendering 10893 * @param texArray 10894 */ 10895 bindAndClearTexArray(texArray) { 10896 const textureSystem = this.renderer.texture; 10897 for (let j = 0; j < texArray.count; j++) 10898 textureSystem.bind(texArray.elements[j], texArray.ids[j]), texArray.elements[j] = null; 10899 texArray.count = 0; 10900 } 10901 updateGeometry() { 10902 const { 10903 _packedGeometries: packedGeometries, 10904 _attributeBuffer: attributeBuffer, 10905 _indexBuffer: indexBuffer 10906 } = this; 10907 _BatchRenderer2.canUploadSameBuffer ? (packedGeometries[this._flushId]._buffer.update(attributeBuffer.rawBinaryData), packedGeometries[this._flushId]._indexBuffer.update(indexBuffer), this.renderer.geometry.updateBuffers()) : (this._packedGeometryPoolSize <= this._flushId && (this._packedGeometryPoolSize++, packedGeometries[this._flushId] = new this.geometryClass()), packedGeometries[this._flushId]._buffer.update(attributeBuffer.rawBinaryData), packedGeometries[this._flushId]._indexBuffer.update(indexBuffer), this.renderer.geometry.bind(packedGeometries[this._flushId]), this.renderer.geometry.updateBuffers(), this._flushId++); 10908 } 10909 drawBatches() { 10910 const dcCount = this._dcIndex, { gl, state: stateSystem } = this.renderer, drawCalls = _BatchRenderer2._drawCallPool; 10911 let curTexArray = null; 10912 for (let i = 0; i < dcCount; i++) { 10913 const { texArray, type, size, start, blend } = drawCalls[i]; 10914 curTexArray !== texArray && (curTexArray = texArray, this.bindAndClearTexArray(texArray)), this.state.blendMode = blend, stateSystem.set(this.state), gl.drawElements(type, size, gl.UNSIGNED_SHORT, start * 2); 10915 } 10916 } 10917 /** Renders the content _now_ and empties the current batch. */ 10918 flush() { 10919 this._vertexCount !== 0 && (this._attributeBuffer = this.getAttributeBuffer(this._vertexCount), this._indexBuffer = this.getIndexBuffer(this._indexCount), this._aIndex = 0, this._iIndex = 0, this._dcIndex = 0, this.buildTexturesAndDrawCalls(), this.updateGeometry(), this.drawBatches(), this._bufferSize = 0, this._vertexCount = 0, this._indexCount = 0); 10920 } 10921 /** Starts a new sprite batch. */ 10922 start() { 10923 this.renderer.state.set(this.state), this.renderer.texture.ensureSamplerType(this.maxTextures), this.renderer.shader.bind(this._shader), _BatchRenderer2.canUploadSameBuffer && this.renderer.geometry.bind(this._packedGeometries[this._flushId]); 10924 } 10925 /** Stops and flushes the current batch. */ 10926 stop() { 10927 this.flush(); 10928 } 10929 /** Destroys this `BatchRenderer`. It cannot be used again. */ 10930 destroy() { 10931 for (let i = 0; i < this._packedGeometryPoolSize; i++) 10932 this._packedGeometries[i] && this._packedGeometries[i].destroy(); 10933 this.renderer.off("prerender", this.onPrerender, this), this._aBuffers = null, this._iBuffers = null, this._packedGeometries = null, this._attributeBuffer = null, this._indexBuffer = null, this._shader && (this._shader.destroy(), this._shader = null), super.destroy(); 10934 } 10935 /** 10936 * Fetches an attribute buffer from `this._aBuffers` that can hold atleast `size` floats. 10937 * @param size - minimum capacity required 10938 * @returns - buffer than can hold atleast `size` floats 10939 */ 10940 getAttributeBuffer(size) { 10941 const roundedP2 = nextPow2(Math.ceil(size / 8)), roundedSizeIndex = log2(roundedP2), roundedSize = roundedP2 * 8; 10942 this._aBuffers.length <= roundedSizeIndex && (this._iBuffers.length = roundedSizeIndex + 1); 10943 let buffer = this._aBuffers[roundedSize]; 10944 return buffer || (this._aBuffers[roundedSize] = buffer = new ViewableBuffer(roundedSize * this.vertexSize * 4)), buffer; 10945 } 10946 /** 10947 * Fetches an index buffer from `this._iBuffers` that can 10948 * have at least `size` capacity. 10949 * @param size - minimum required capacity 10950 * @returns - buffer that can fit `size` indices. 10951 */ 10952 getIndexBuffer(size) { 10953 const roundedP2 = nextPow2(Math.ceil(size / 12)), roundedSizeIndex = log2(roundedP2), roundedSize = roundedP2 * 12; 10954 this._iBuffers.length <= roundedSizeIndex && (this._iBuffers.length = roundedSizeIndex + 1); 10955 let buffer = this._iBuffers[roundedSizeIndex]; 10956 return buffer || (this._iBuffers[roundedSizeIndex] = buffer = new Uint16Array(roundedSize)), buffer; 10957 } 10958 /** 10959 * Takes the four batching parameters of `element`, interleaves 10960 * and pushes them into the batching attribute/index buffers given. 10961 * 10962 * It uses these properties: `vertexData` `uvs`, `textureId` and 10963 * `indicies`. It also uses the "tint" of the base-texture, if 10964 * present. 10965 * @param {PIXI.DisplayObject} element - element being rendered 10966 * @param attributeBuffer - attribute buffer. 10967 * @param indexBuffer - index buffer 10968 * @param aIndex - number of floats already in the attribute buffer 10969 * @param iIndex - number of indices already in `indexBuffer` 10970 */ 10971 packInterleavedGeometry(element, attributeBuffer, indexBuffer, aIndex, iIndex) { 10972 const { 10973 uint32View, 10974 float32View 10975 } = attributeBuffer, packedVertices = aIndex / this.vertexSize, uvs = element.uvs, indicies = element.indices, vertexData = element.vertexData, textureId = element._texture.baseTexture._batchLocation, alpha = Math.min(element.worldAlpha, 1), argb = Color.shared.setValue(element._tintRGB).toPremultiplied(alpha, element._texture.baseTexture.alphaMode > 0); 10976 for (let i = 0; i < vertexData.length; i += 2) 10977 float32View[aIndex++] = vertexData[i], float32View[aIndex++] = vertexData[i + 1], float32View[aIndex++] = uvs[i], float32View[aIndex++] = uvs[i + 1], uint32View[aIndex++] = argb, float32View[aIndex++] = textureId; 10978 for (let i = 0; i < indicies.length; i++) 10979 indexBuffer[iIndex++] = packedVertices + indicies[i]; 10980 } 10981}; 10982_BatchRenderer.defaultBatchSize = 4096, /** @ignore */ 10983_BatchRenderer.extension = { 10984 name: "batch", 10985 type: ExtensionType.RendererPlugin 10986}, /** 10987* Pool of `BatchDrawCall` objects that `flush` used 10988* to create "batches" of the objects being rendered. 10989* 10990* These are never re-allocated again. 10991* Shared between all batch renderers because it can be only one "flush" working at the moment. 10992* @member {PIXI.BatchDrawCall[]} 10993*/ 10994_BatchRenderer._drawCallPool = [], /** 10995* Pool of `BatchDrawCall` objects that `flush` used 10996* to create "batches" of the objects being rendered. 10997* 10998* These are never re-allocated again. 10999* Shared between all batch renderers because it can be only one "flush" working at the moment. 11000* @member {PIXI.BatchTextureArray[]} 11001*/ 11002_BatchRenderer._textureArrayPool = []; 11003let BatchRenderer = _BatchRenderer; 11004extensions$1.add(BatchRenderer); 11005 11006var defaultFragment = `varying vec2 vTextureCoord; 11007 11008uniform sampler2D uSampler; 11009 11010void main(void){ 11011 gl_FragColor = texture2D(uSampler, vTextureCoord); 11012} 11013`; 11014 11015var defaultVertex$1 = `attribute vec2 aVertexPosition; 11016 11017uniform mat3 projectionMatrix; 11018 11019varying vec2 vTextureCoord; 11020 11021uniform vec4 inputSize; 11022uniform vec4 outputFrame; 11023 11024vec4 filterVertexPosition( void ) 11025{ 11026 vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy; 11027
11028 return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0); 11029} 11030 11031vec2 filterTextureCoord( void ) 11032{ 11033 return aVertexPosition * (outputFrame.zw * inputSize.zw); 11034} 11035 11036void main(void) 11037{ 11038 gl_Position = filterVertexPosition(); 11039 vTextureCoord = filterTextureCoord(); 11040} 11041`; 11042 11043const _Filter = class _Filter2 extends Shader { 11044 /** 11045 * @param vertexSrc - The source of the vertex shader. 11046 * @param fragmentSrc - The source of the fragment shader. 11047 * @param uniforms - Custom uniforms to use to augment the built-in ones. 11048 */ 11049 constructor(vertexSrc, fragmentSrc, uniforms) { 11050 const program = Program.from( 11051 vertexSrc || _Filter2.defaultVertexSrc, 11052 fragmentSrc || _Filter2.defaultFragmentSrc 11053 ); 11054 super(program, uniforms), this.padding = 0, this.resolution = _Filter2.defaultResolution, this.multisample = _Filter2.defaultMultisample, this.enabled = !0, this.autoFit = !0, this.state = new State(); 11055 } 11056 /** 11057 * Applies the filter 11058 * @param {PIXI.FilterSystem} filterManager - The renderer to retrieve the filter from 11059 * @param {PIXI.RenderTexture} input - The input render target. 11060 * @param {PIXI.RenderTexture} output - The target to output to. 11061 * @param {PIXI.CLEAR_MODES} [clearMode] - Should the output be cleared before rendering to it. 11062 * @param {object} [_currentState] - It's current state of filter. 11063 * There are some useful properties in the currentState : 11064 * target, filters, sourceFrame, destinationFrame, renderTarget, resolution 11065 */ 11066 apply(filterManager, input, output, clearMode, _currentState) { 11067 filterManager.applyFilter(this, input, output, clearMode); 11068 } 11069 /** 11070 * Sets the blend mode of the filter. 11071 * @default PIXI.BLEND_MODES.NORMAL 11072 */ 11073 get blendMode() { 11074 return this.state.blendMode; 11075 } 11076 set blendMode(value) { 11077 this.state.blendMode = value; 11078 } 11079 /** 11080 * The resolution of the filter. Setting this to be lower will lower the quality but 11081 * increase the performance of the filter. 11082 * If set to `null` or `0`, the resolution of the current render target is used. 11083 * @default PIXI.Filter.defaultResolution 11084 */ 11085 get resolution() { 11086 return this._resolution; 11087 } 11088 set resolution(value) { 11089 this._resolution = value; 11090 } 11091 /** 11092 * The default vertex shader source 11093 * @readonly 11094 */ 11095 static get defaultVertexSrc() { 11096 return defaultVertex$1; 11097 } 11098 /** 11099 * The default fragment shader source 11100 * @readonly 11101 */ 11102 static get defaultFragmentSrc() { 11103 return defaultFragment; 11104 } 11105}; 11106_Filter.defaultResolution = 1, /** 11107* Default filter samples for any filter. 11108* @static 11109* @type {PIXI.MSAA_QUALITY|null} 11110* @default PIXI.MSAA_QUALITY.NONE 11111*/ 11112_Filter.defaultMultisample = MSAA_QUALITY.NONE; 11113let Filter = _Filter; 11114 11115class BackgroundSystem { 11116 constructor() { 11117 this.clearBeforeRender = !0, this._backgroundColor = new Color(0), this.alpha = 1; 11118 } 11119 /** 11120 * initiates the background system 11121 * @param {PIXI.IRendererOptions} options - the options for the background colors 11122 */ 11123 init(options) { 11124 this.clearBeforeRender = options.clearBeforeRender; 11125 const { backgroundColor, background, backgroundAlpha } = options, color = background ?? backgroundColor; 11126 color !== void 0 && (this.color = color), this.alpha = backgroundAlpha; 11127 } 11128 /** 11129 * The background color to fill if not transparent. 11130 * @member {PIXI.ColorSource} 11131 */ 11132 get color() { 11133 return this._backgroundColor.value; 11134 } 11135 set color(value) { 11136 this._backgroundColor.setValue(value); 11137 } 11138 /** 11139 * The background color alpha. Setting this to 0 will make the canvas transparent. 11140 * @member {number} 11141 */ 11142 get alpha() { 11143 return this._backgroundColor.alpha; 11144 } 11145 set alpha(value) { 11146 this._backgroundColor.setAlpha(value); 11147 } 11148 /** The background color object. */ 11149 get backgroundColor() { 11150 return this._backgroundColor; 11151 } 11152 destroy() { 11153 } 11154} 11155BackgroundSystem.defaultOptions = { 11156 /** 11157 * {@link PIXI.IRendererOptions.backgroundAlpha} 11158 * @default 1 11159 * @memberof PIXI.settings.RENDER_OPTIONS 11160 */ 11161 backgroundAlpha: 1, 11162 /** 11163 * {@link PIXI.IRendererOptions.backgroundColor} 11164 * @default 0x000000 11165 * @memberof PIXI.settings.RENDER_OPTIONS 11166 */ 11167 backgroundColor: 0, 11168 /** 11169 * {@link PIXI.IRendererOptions.clearBeforeRender} 11170 * @default true 11171 * @memberof PIXI.settings.RENDER_OPTIONS 11172 */ 11173 clearBeforeRender: !0 11174}, /** @ignore */
vendor: 13,590 bytes, lines 11175-11522
11175BackgroundSystem.extension = { 11176 type: [ 11177 ExtensionType.RendererSystem, 11178 ExtensionType.CanvasRendererSystem 11179 ], 11180 name: "background" 11181}; 11182extensions$1.add(BackgroundSystem); 11183 11184class BatchSystem { 11185 /** 11186 * @param renderer - The renderer this System works for. 11187 */ 11188 constructor(renderer) { 11189 this.renderer = renderer, this.emptyRenderer = new ObjectRenderer(renderer), this.currentRenderer = this.emptyRenderer; 11190 } 11191 /** 11192 * Changes the current renderer to the one given in parameter 11193 * @param objectRenderer - The object renderer to use. 11194 */ 11195 setObjectRenderer(objectRenderer) { 11196 this.currentRenderer !== objectRenderer && (this.currentRenderer.stop(), this.currentRenderer = objectRenderer, this.currentRenderer.start()); 11197 } 11198 /** 11199 * This should be called if you wish to do some custom rendering 11200 * It will basically render anything that may be batched up such as sprites 11201 */ 11202 flush() { 11203 this.setObjectRenderer(this.emptyRenderer); 11204 } 11205 /** Reset the system to an empty renderer */ 11206 reset() { 11207 this.setObjectRenderer(this.emptyRenderer); 11208 } 11209 /** 11210 * Handy function for batch renderers: copies bound textures in first maxTextures locations to array 11211 * sets actual _batchLocation for them 11212 * @param arr - arr copy destination 11213 * @param maxTextures - number of copied elements 11214 */ 11215 copyBoundTextures(arr, maxTextures) { 11216 const { boundTextures } = this.renderer.texture; 11217 for (let i = maxTextures - 1; i >= 0; --i) 11218 arr[i] = boundTextures[i] || null, arr[i] && (arr[i]._batchLocation = i); 11219 } 11220 /** 11221 * Assigns batch locations to textures in array based on boundTextures state. 11222 * All textures in texArray should have `_batchEnabled = _batchId`, 11223 * and their count should be less than `maxTextures`. 11224 * @param texArray - textures to bound 11225 * @param boundTextures - current state of bound textures 11226 * @param batchId - marker for _batchEnabled param of textures in texArray 11227 * @param maxTextures - number of texture locations to manipulate 11228 */ 11229 boundArray(texArray, boundTextures, batchId, maxTextures) { 11230 const { elements, ids, count } = texArray; 11231 let j = 0; 11232 for (let i = 0; i < count; i++) { 11233 const tex = elements[i], loc = tex._batchLocation; 11234 if (loc >= 0 && loc < maxTextures && boundTextures[loc] === tex) { 11235 ids[i] = loc; 11236 continue; 11237 } 11238 for (; j < maxTextures; ) { 11239 const bound = boundTextures[j]; 11240 if (bound && bound._batchEnabled === batchId && bound._batchLocation === j) { 11241 j++; 11242 continue; 11243 } 11244 ids[i] = j, tex._batchLocation = j, boundTextures[j] = tex; 11245 break; 11246 } 11247 } 11248 } 11249 /** 11250 * @ignore 11251 */ 11252 destroy() { 11253 this.renderer = null; 11254 } 11255} 11256BatchSystem.extension = { 11257 type: ExtensionType.RendererSystem, 11258 name: "batch" 11259}; 11260extensions$1.add(BatchSystem); 11261 11262let CONTEXT_UID_COUNTER = 0; 11263class ContextSystem { 11264 /** @param renderer - The renderer this System works for. */ 11265 constructor(renderer) { 11266 this.renderer = renderer, this.webGLVersion = 1, this.extensions = {}, this.supports = { 11267 uint32Indices: !1 11268 }, this.handleContextLost = this.handleContextLost.bind(this), this.handleContextRestored = this.handleContextRestored.bind(this); 11269 } 11270 /** 11271 * `true` if the context is lost 11272 * @readonly 11273 */ 11274 get isLost() { 11275 return !this.gl || this.gl.isContextLost(); 11276 } 11277 /** 11278 * Handles the context change event. 11279 * @param {WebGLRenderingContext} gl - New WebGL context. 11280 */ 11281 contextChange(gl) { 11282 this.gl = gl, this.renderer.gl = gl, this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++; 11283 } 11284 init(options) { 11285 if (options.context) 11286 this.initFromContext(options.context); 11287 else { 11288 const alpha = this.renderer.background.alpha < 1, premultipliedAlpha = options.premultipliedAlpha; 11289 this.preserveDrawingBuffer = options.preserveDrawingBuffer, this.useContextAlpha = options.useContextAlpha, this.powerPreference = options.powerPreference, this.initFromOptions({ 11290 alpha, 11291 premultipliedAlpha, 11292 antialias: options.antialias, 11293 stencil: !0, 11294 preserveDrawingBuffer: options.preserveDrawingBuffer, 11295 powerPreference: options.powerPreference 11296 }); 11297 } 11298 } 11299 /** 11300 * Initializes the context. 11301 * @protected 11302 * @param {WebGLRenderingContext} gl - WebGL context 11303 */ 11304 initFromContext(gl) { 11305 this.gl = gl, this.validateContext(gl), this.renderer.gl = gl, this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++, this.renderer.runners.contextChange.emit(gl); 11306 const view = this.renderer.view; 11307 view.addEventListener !== void 0 && (view.addEventListener("webglcontextlost", this.handleContextLost, !1), view.addEventListener("webglcontextrestored", this.handleContextRestored, !1)); 11308 } 11309 /** 11310 * Initialize from context options 11311 * @protected 11312 * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext 11313 * @param {object} options - context attributes 11314 */ 11315 initFromOptions(options) { 11316 const gl = this.createContext(this.renderer.view, options); 11317 this.initFromContext(gl); 11318 } 11319 /** 11320 * Helper class to create a WebGL Context 11321 * @param canvas - the canvas element that we will get the context from 11322 * @param options - An options object that gets passed in to the canvas element containing the 11323 * context attributes 11324 * @see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext 11325 * @returns {WebGLRenderingContext} the WebGL context 11326 */ 11327 createContext(canvas, options) { 11328 let gl; 11329 if (settings.PREFER_ENV >= ENV.WEBGL2 && (gl = canvas.getContext("webgl2", options)), gl) 11330 this.webGLVersion = 2; 11331 else if (this.webGLVersion = 1, gl = canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options), !gl) 11332 throw new Error("This browser does not support WebGL. Try using the canvas renderer"); 11333 return this.gl = gl, this.getExtensions(), this.gl; 11334 } 11335 /** Auto-populate the {@link PIXI.ContextSystem.extensions extensions}. */ 11336 getExtensions() { 11337 const { gl } = this, common = { 11338 loseContext: gl.getExtension("WEBGL_lose_context"), 11339 anisotropicFiltering: gl.getExtension("EXT_texture_filter_anisotropic"), 11340 floatTextureLinear: gl.getExtension("OES_texture_float_linear"), 11341 s3tc: gl.getExtension("WEBGL_compressed_texture_s3tc"), 11342 s3tc_sRGB: gl.getExtension("WEBGL_compressed_texture_s3tc_srgb"), 11343 // eslint-disable-line camelcase 11344 etc: gl.getExtension("WEBGL_compressed_texture_etc"), 11345 etc1: gl.getExtension("WEBGL_compressed_texture_etc1"), 11346 pvrtc: gl.getExtension("WEBGL_compressed_texture_pvrtc") || gl.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"), 11347 atc: gl.getExtension("WEBGL_compressed_texture_atc"), 11348 astc: gl.getExtension("WEBGL_compressed_texture_astc") 11349 }; 11350 this.webGLVersion === 1 ? Object.assign(this.extensions, common, { 11351 drawBuffers: gl.getExtension("WEBGL_draw_buffers"), 11352 depthTexture: gl.getExtension("WEBGL_depth_texture"), 11353 vertexArrayObject: gl.getExtension("OES_vertex_array_object") || gl.getExtension("MOZ_OES_vertex_array_object") || gl.getExtension("WEBKIT_OES_vertex_array_object"), 11354 uint32ElementIndex: gl.getExtension("OES_element_index_uint"), 11355 // Floats and half-floats 11356 floatTexture: gl.getExtension("OES_texture_float"), 11357 floatTextureLinear: gl.getExtension("OES_texture_float_linear"), 11358 textureHalfFloat: gl.getExtension("OES_texture_half_float"), 11359 textureHalfFloatLinear: gl.getExtension("OES_texture_half_float_linear") 11360 }) : this.webGLVersion === 2 && Object.assign(this.extensions, common, { 11361 // Floats and half-floats 11362 colorBufferFloat: gl.getExtension("EXT_color_buffer_float") 11363 }); 11364 } 11365 /** 11366 * Handles a lost webgl context 11367 * @param {WebGLContextEvent} event - The context lost event. 11368 */ 11369 handleContextLost(event) { 11370 event.preventDefault(), setTimeout(() => { 11371 this.gl.isContextLost() && this.extensions.loseContext && this.extensions.loseContext.restoreContext(); 11372 }, 0); 11373 } 11374 /** Handles a restored webgl context. */ 11375 handleContextRestored() { 11376 this.renderer.runners.contextChange.emit(this.gl); 11377 } 11378 destroy() { 11379 const view = this.renderer.view; 11380 this.renderer = null, view.removeEventListener !== void 0 && (view.removeEventListener("webglcontextlost", this.handleContextLost), view.removeEventListener("webglcontextrestored", this.handleContextRestored)), this.gl.useProgram(null), this.extensions.loseContext && this.extensions.loseContext.loseContext(); 11381 } 11382 /** Handle the post-render runner event. */ 11383 postrender() { 11384 this.renderer.objectRenderer.renderingToScreen && this.gl.flush(); 11385 } 11386 /** 11387 * Validate context. 11388 * @param {WebGLRenderingContext} gl - Render context. 11389 */ 11390 validateContext(gl) { 11391 const attributes = gl.getContextAttributes(), isWebGl2 = "WebGL2RenderingContext" in globalThis && gl instanceof globalThis.WebGL2RenderingContext; 11392 isWebGl2 && (this.webGLVersion = 2), attributes && !attributes.stencil && console.warn("Provided WebGL context does not have a stencil buffer, masks may not render correctly"); 11393 const hasuint32 = isWebGl2 || !!gl.getExtension("OES_element_index_uint"); 11394 this.supports.uint32Indices = hasuint32, hasuint32 || console.warn("Provided WebGL context does not support 32 index buffer, complex graphics may not render correctly"); 11395 } 11396} 11397ContextSystem.defaultOptions = { 11398 /** 11399 * {@link PIXI.IRendererOptions.context} 11400 * @default null 11401 * @memberof PIXI.settings.RENDER_OPTIONS 11402 */ 11403 context: null, 11404 /** 11405 * {@link PIXI.IRendererOptions.antialias} 11406 * @default false 11407 * @memberof PIXI.settings.RENDER_OPTIONS 11408 */ 11409 antialias: !1, 11410 /** 11411 * {@link PIXI.IRendererOptions.premultipliedAlpha} 11412 * @default true 11413 * @memberof PIXI.settings.RENDER_OPTIONS 11414 */ 11415 premultipliedAlpha: !0, 11416 /** 11417 * {@link PIXI.IRendererOptions.preserveDrawingBuffer} 11418 * @default false 11419 * @memberof PIXI.settings.RENDER_OPTIONS 11420 */ 11421 preserveDrawingBuffer: !1, 11422 /** 11423 * {@link PIXI.IRendererOptions.powerPreference} 11424 * @default default 11425 * @memberof PIXI.settings.RENDER_OPTIONS 11426 */ 11427 powerPreference: "default" 11428}, /** @ignore */ 11429ContextSystem.extension = { 11430 type: ExtensionType.RendererSystem, 11431 name: "context" 11432}; 11433extensions$1.add(ContextSystem); 11434 11435class Framebuffer { 11436 /** 11437 * @param width - Width of the frame buffer 11438 * @param height - Height of the frame buffer 11439 */ 11440 constructor(width, height) { 11441 if (this.width = Math.round(width), this.height = Math.round(height), !this.width || !this.height) 11442 throw new Error("Framebuffer width or height is zero"); 11443 this.stencil = !1, this.depth = !1, this.dirtyId = 0, this.dirtyFormat = 0, this.dirtySize = 0, this.depthTexture = null, this.colorTextures = [], this.glFramebuffers = {}, this.disposeRunner = new Runner("disposeFramebuffer"), this.multisample = MSAA_QUALITY.NONE; 11444 } 11445 /** 11446 * Reference to the colorTexture. 11447 * @readonly 11448 */ 11449 get colorTexture() { 11450 return this.colorTextures[0]; 11451 } 11452 /** 11453 * Add texture to the colorTexture array. 11454 * @param index - Index of the array to add the texture to 11455 * @param texture - Texture to add to the array 11456 */ 11457 addColorTexture(index = 0, texture) { 11458 return this.colorTextures[index] = texture || new BaseTexture(null, { 11459 scaleMode: SCALE_MODES.NEAREST, 11460 resolution: 1, 11461 mipmap: MIPMAP_MODES.OFF, 11462 width: this.width, 11463 height: this.height 11464 }), this.dirtyId++, this.dirtyFormat++, this; 11465 } 11466 /** 11467 * Add a depth texture to the frame buffer. 11468 * @param texture - Texture to add. 11469 */ 11470 addDepthTexture(texture) { 11471 return this.depthTexture = texture || new BaseTexture(null, { 11472 scaleMode: SCALE_MODES.NEAREST, 11473 resolution: 1, 11474 width: this.width, 11475 height: this.height, 11476 mipmap: MIPMAP_MODES.OFF, 11477 format: FORMATS.DEPTH_COMPONENT, 11478 type: TYPES.UNSIGNED_SHORT 11479 }), this.dirtyId++, this.dirtyFormat++, this; 11480 } 11481 /** Enable depth on the frame buffer. */ 11482 enableDepth() { 11483 return this.depth = !0, this.dirtyId++, this.dirtyFormat++, this; 11484 } 11485 /** Enable stencil on the frame buffer. */ 11486 enableStencil() { 11487 return this.stencil = !0, this.dirtyId++, this.dirtyFormat++, this; 11488 } 11489 /** 11490 * Resize the frame buffer 11491 * @param width - Width of the frame buffer to resize to 11492 * @param height - Height of the frame buffer to resize to 11493 */ 11494 resize(width, height) { 11495 if (width = Math.round(width), height = Math.round(height), !width || !height) 11496 throw new Error("Framebuffer width and height must not be zero"); 11497 if (!(width === this.width && height === this.height)) { 11498 this.width = width, this.height = height, this.dirtyId++, this.dirtySize++; 11499 for (let i = 0; i < this.colorTextures.length; i++) { 11500 const texture = this.colorTextures[i], resolution = texture.resolution; 11501 texture.setSize(width / resolution, height / resolution); 11502 } 11503 if (this.depthTexture) { 11504 const resolution = this.depthTexture.resolution; 11505 this.depthTexture.setSize(width / resolution, height / resolution); 11506 } 11507 } 11508 } 11509 /** Disposes WebGL resources that are connected to this geometry. */ 11510 dispose() { 11511 this.disposeRunner.emit(this, !1); 11512 } 11513 /** Destroys and removes the depth texture added to this framebuffer. */ 11514 destroyDepthTexture() { 11515 this.depthTexture && (this.depthTexture.destroy(), this.depthTexture = null, ++this.dirtyId, ++this.dirtyFormat); 11516 } 11517} 11518 11519class BaseRenderTexture extends BaseTexture { 11520 /** 11521 * @param options 11522 * @param {number}
11522 [options.width=100] - The width of the base render texture. 11523 * @param {number} [options.height=100] - The height of the base render texture. 11524 * @param {PIXI.SCALE_MODES} [options.scaleMode=PIXI.BaseTexture.defaultOptions.scaleMode] - See {@link PIXI.SCALE_MODES} 11525 * for possible values. 11526 * @param {number} [options.resolution=PIXI.settings.RESOLUTION] - The resolution / device pixel ratio 11527 * of the texture being generated. 11528 * @param {PIXI.MSAA_QUALITY} [options.multisample=PIXI.MSAA_QUALITY.NONE] - The number of samples of the frame buffer. 11529 */ 11530 constructor(options = {}) { 11531 if (typeof options == "number") { 11532 const width = arguments[0], height = arguments[1], scaleMode = arguments[2], resolution = arguments[3]; 11533 options = { width, height, scaleMode, resolution }; 11534 } 11535 options.width = options.width ?? 100, options.height = options.height ?? 100, options.multisample ?? (options.multisample = MSAA_QUALITY.NONE), super(null, options), this.mipmap = MIPMAP_MODES.OFF, this.valid = !0, this._clear = new Color([0, 0, 0, 0]), this.framebuffer = new Framebuffer(this.realWidth, this.realHeight).addColorTexture(0, this), this.framebuffer.multisample = options.multisample, this.maskStack = [], this.filterStack = [{}]; 11536 } 11537 /** Color when clearning the texture. */ 11538 set clearColor(value) { 11539 this._clear.setValue(value); 11540 } 11541 get clearColor() { 11542 return this._clear.value; 11543 } 11544 /** 11545 * Color object when clearning the texture. 11546 * @readonly 11547 * @since 7.2.0 11548 */ 11549 get clear() { 11550 return this._clear; 11551 } 11552 /** 11553 * Shortcut to `this.framebuffer.multisample`. 11554 * @default PIXI.MSAA_QUALITY.NONE 11555 */ 11556 get multisample() { 11557 return this.framebuffer.multisample; 11558 } 11559 set multisample(value) { 11560 this.framebuffer.multisample = value; 11561 } 11562 /** 11563 * Resizes the BaseRenderTexture. 11564 * @param desiredWidth - The desired width to resize to. 11565 * @param desiredHeight - The desired height to resize to. 11566 */ 11567 resize(desiredWidth, desiredHeight) { 11568 this.framebuffer.resize(desiredWidth * this.resolution, desiredHeight * this.resolution), this.setRealSize(this.framebuffer.width, this.framebuffer.height); 11569 } 11570 /** 11571 * Frees the texture and framebuffer from WebGL memory without destroying this texture object. 11572 * This means you can still use the texture later which will upload it to GPU 11573 * memory again. 11574 * @fires PIXI.BaseTexture#dispose 11575 */ 11576 dispose() { 11577 this.framebuffer.dispose(), super.dispose(); 11578 } 11579 /** Destroys this texture. */ 11580 destroy() { 11581 super.destroy(), this.framebuffer.destroyDepthTexture(), this.framebuffer = null; 11582 } 11583} 11584 11585class BaseImageResource extends Resource { 11586 /** 11587 * @param {HTMLImageElement|HTMLVideoElement|ImageBitmap|PIXI.ICanvas} source 11588 */ 11589 constructor(source) { 11590 const sourceAny = source, width = sourceAny.naturalWidth || sourceAny.videoWidth || sourceAny.width, height = sourceAny.naturalHeight || sourceAny.videoHeight || sourceAny.height; 11591 super(width, height), this.source = source, this.noSubImage = !1; 11592 } 11593 /** 11594 * Set cross origin based detecting the url and the crossorigin 11595 * @param element - Element to apply crossOrigin 11596 * @param url - URL to check 11597 * @param crossorigin - Cross origin value to use 11598 */ 11599 static crossOrigin(element, url, crossorigin) { 11600 crossorigin === void 0 && !url.startsWith("data:") ? element.crossOrigin = determineCrossOrigin(url) : crossorigin !== !1 && (element.crossOrigin = typeof crossorigin == "string" ? crossorigin : "anonymous"); 11601 } 11602 /** 11603 * Upload the texture to the GPU. 11604 * @param renderer - Upload to the renderer 11605 * @param baseTexture - Reference to parent texture 11606 * @param glTexture 11607 * @param {HTMLImageElement|HTMLVideoElement|ImageBitmap|PIXI.ICanvas} [source] - (optional) 11608 * @returns - true is success 11609 */ 11610 upload(renderer, baseTexture, glTexture, source) { 11611 const gl = renderer.gl, width = baseTexture.realWidth, height = baseTexture.realHeight; 11612 if (source = source || this.source, typeof HTMLImageElement < "u" && source instanceof HTMLImageElement) {
vendor: 43,329 bytes, lines 11613-12455
11613 if (!source.complete || source.naturalWidth === 0) 11614 return !1; 11615 } else if (typeof HTMLVideoElement < "u" && source instanceof HTMLVideoElement && source.readyState <= 1) 11616 return !1; 11617 return gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, baseTexture.alphaMode === ALPHA_MODES.UNPACK), !this.noSubImage && baseTexture.target === gl.TEXTURE_2D && glTexture.width === width && glTexture.height === height ? gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, baseTexture.format, glTexture.type, source) : (glTexture.width = width, glTexture.height = height, gl.texImage2D(baseTexture.target, 0, glTexture.internalFormat, baseTexture.format, glTexture.type, source)), !0; 11618 } 11619 /** 11620 * Checks if source width/height was changed, resize can cause extra baseTexture update. 11621 * Triggers one update in any case. 11622 */ 11623 update() { 11624 if (this.destroyed) 11625 return; 11626 const source = this.source, width = source.naturalWidth || source.videoWidth || source.width, height = source.naturalHeight || source.videoHeight || source.height; 11627 this.resize(width, height), super.update(); 11628 } 11629 /** Destroy this {@link PIXI.BaseImageResource} */ 11630 dispose() { 11631 this.source = null; 11632 } 11633} 11634 11635class ImageResource extends BaseImageResource { 11636 /** 11637 * @param source - image source or URL 11638 * @param options 11639 * @param {boolean} [options.autoLoad=true] - start loading process 11640 * @param {boolean} [options.createBitmap=PIXI.settings.CREATE_IMAGE_BITMAP] - whether its required to create 11641 * a bitmap before upload 11642 * @param {boolean} [options.crossorigin=true] - Load image using cross origin 11643 * @param {PIXI.ALPHA_MODES} [options.alphaMode=PIXI.ALPHA_MODES.UNPACK] - Premultiply image alpha in bitmap 11644 */ 11645 constructor(source, options) { 11646 if (options = options || {}, typeof source == "string") { 11647 const imageElement = new Image(); 11648 BaseImageResource.crossOrigin(imageElement, source, options.crossorigin), imageElement.src = source, source = imageElement; 11649 } 11650 super(source), !source.complete && this._width && this._height && (this._width = 0, this._height = 0), this.url = source.src, this._process = null, this.preserveBitmap = !1, this.createBitmap = (options.createBitmap ?? settings.CREATE_IMAGE_BITMAP) && !!globalThis.createImageBitmap, this.alphaMode = typeof options.alphaMode == "number" ? options.alphaMode : null, this.bitmap = null, this._load = null, options.autoLoad !== !1 && this.load(); 11651 } 11652 /** 11653 * Returns a promise when image will be loaded and processed. 11654 * @param createBitmap - whether process image into bitmap 11655 */ 11656 load(createBitmap) { 11657 return this._load ? this._load : (createBitmap !== void 0 && (this.createBitmap = createBitmap), this._load = new Promise((resolve, reject) => { 11658 const source = this.source; 11659 this.url = source.src; 11660 const completed = () => { 11661 this.destroyed || (source.onload = null, source.onerror = null, this.update(), this._load = null, this.createBitmap ? resolve(this.process()) : resolve(this)); 11662 }; 11663 source.complete && source.src ? completed() : (source.onload = completed, source.onerror = (event) => { 11664 reject(event), this.onError.emit(event); 11665 }); 11666 }), this._load); 11667 } 11668 /** 11669 * Called when we need to convert image into BitmapImage. 11670 * Can be called multiple times, real promise is cached inside. 11671 * @returns - Cached promise to fill that bitmap 11672 */ 11673 process() { 11674 const source = this.source; 11675 if (this._process !== null) 11676 return this._process; 11677 if (this.bitmap !== null || !globalThis.createImageBitmap) 11678 return Promise.resolve(this); 11679 const createImageBitmap = globalThis.createImageBitmap, cors = !source.crossOrigin || source.crossOrigin === "anonymous"; 11680 return this._process = fetch( 11681 source.src, 11682 { 11683 mode: cors ? "cors" : "no-cors" 11684 } 11685 ).then((r) => r.blob()).then((blob) => createImageBitmap( 11686 blob, 11687 0, 11688 0, 11689 source.width, 11690 source.height, 11691 { 11692 premultiplyAlpha: this.alphaMode === null || this.alphaMode === ALPHA_MODES.UNPACK ? "premultiply" : "none" 11693 } 11694 )).then((bitmap) => this.destroyed ? Promise.reject() : (this.bitmap = bitmap, this.update(), this._process = null, Promise.resolve(this))), this._process; 11695 } 11696 /** 11697 * Upload the image resource to GPU. 11698 * @param renderer - Renderer to upload to 11699 * @param baseTexture - BaseTexture for this resource 11700 * @param glTexture - GLTexture to use 11701 * @returns {boolean} true is success 11702 */ 11703 upload(renderer, baseTexture, glTexture) { 11704 if (typeof this.alphaMode == "number" && (baseTexture.alphaMode = this.alphaMode), !this.createBitmap) 11705 return super.upload(renderer, baseTexture, glTexture); 11706 if (!this.bitmap && (this.process(), !this.bitmap)) 11707 return !1; 11708 if (super.upload(renderer, baseTexture, glTexture, this.bitmap), !this.preserveBitmap) { 11709 let flag = !0; 11710 const glTextures = baseTexture._glTextures; 11711 for (const key in glTextures) { 11712 const otherTex = glTextures[key]; 11713 if (otherTex !== glTexture && otherTex.dirtyId !== baseTexture.dirtyId) { 11714 flag = !1; 11715 break; 11716 } 11717 } 11718 flag && (this.bitmap.close && this.bitmap.close(), this.bitmap = null); 11719 } 11720 return !0; 11721 } 11722 /** Destroys this resource. */ 11723 dispose() { 11724 this.source.onload = null, this.source.onerror = null, super.dispose(), this.bitmap && (this.bitmap.close(), this.bitmap = null), this._process = null, this._load = null; 11725 } 11726 /** 11727 * Used to auto-detect the type of resource. 11728 * @param {*} source - The source object 11729 * @returns {boolean} `true` if current environment support HTMLImageElement, and source is string or HTMLImageElement 11730 */ 11731 static test(source) { 11732 return typeof HTMLImageElement < "u" && (typeof source == "string" || source instanceof HTMLImageElement); 11733 } 11734} 11735 11736class TextureUvs { 11737 constructor() { 11738 this.x0 = 0, this.y0 = 0, this.x1 = 1, this.y1 = 0, this.x2 = 1, this.y2 = 1, this.x3 = 0, this.y3 = 1, this.uvsFloat32 = new Float32Array(8); 11739 } 11740 /** 11741 * Sets the texture Uvs based on the given frame information. 11742 * @protected 11743 * @param frame - The frame of the texture 11744 * @param baseFrame - The base frame of the texture 11745 * @param rotate - Rotation of frame, see {@link PIXI.groupD8} 11746 */ 11747 set(frame, baseFrame, rotate) { 11748 const tw = baseFrame.width, th = baseFrame.height; 11749 if (rotate) { 11750 const w2 = frame.width / 2 / tw, h2 = frame.height / 2 / th, cX = frame.x / tw + w2, cY = frame.y / th + h2; 11751 rotate = groupD8.add(rotate, groupD8.NW), this.x0 = cX + w2 * groupD8.uX(rotate), this.y0 = cY + h2 * groupD8.uY(rotate), rotate = groupD8.add(rotate, 2), this.x1 = cX + w2 * groupD8.uX(rotate), this.y1 = cY + h2 * groupD8.uY(rotate), rotate = groupD8.add(rotate, 2), this.x2 = cX + w2 * groupD8.uX(rotate), this.y2 = cY + h2 * groupD8.uY(rotate), rotate = groupD8.add(rotate, 2), this.x3 = cX + w2 * groupD8.uX(rotate), this.y3 = cY + h2 * groupD8.uY(rotate); 11752 } else 11753 this.x0 = frame.x / tw, this.y0 = frame.y / th, this.x1 = (frame.x + frame.width) / tw, this.y1 = frame.y / th, this.x2 = (frame.x + frame.width) / tw, this.y2 = (frame.y + frame.height) / th, this.x3 = frame.x / tw, this.y3 = (frame.y + frame.height) / th; 11754 this.uvsFloat32[0] = this.x0, this.uvsFloat32[1] = this.y0, this.uvsFloat32[2] = this.x1, this.uvsFloat32[3] = this.y1, this.uvsFloat32[4] = this.x2, this.uvsFloat32[5] = this.y2, this.uvsFloat32[6] = this.x3, this.uvsFloat32[7] = this.y3; 11755 } 11756} 11757TextureUvs.prototype.toString = function() { 11758 return `[@pixi/core:TextureUvs x0=${this.x0} y0=${this.y0} x1=${this.x1} y1=${this.y1} x2=${this.x2} y2=${this.y2} x3=${this.x3} y3=${this.y3}]`; 11759}; 11760 11761const DEFAULT_UVS = new TextureUvs(); 11762function removeAllHandlers(tex) { 11763 tex.destroy = function() { 11764 }, tex.on = function() { 11765 }, tex.once = function() { 11766 }, tex.emit = function() { 11767 }; 11768} 11769class Texture extends EventEmitter { 11770 /** 11771 * @param baseTexture - The base texture source to create the texture from 11772 * @param frame - The rectangle frame of the texture to show 11773 * @param orig - The area of original texture 11774 * @param trim - Trimmed rectangle of original texture 11775 * @param rotate - indicates how the texture was rotated by texture packer. See {@link PIXI.groupD8} 11776 * @param anchor - Default anchor point used for sprite placement / rotation 11777 * @param borders - Default borders used for 9-slice scaling. See {@link PIXI.NineSlicePlane} 11778 */ 11779 constructor(baseTexture, frame, orig, trim, rotate, anchor, borders) { 11780 if (super(), this.noFrame = !1, frame || (this.noFrame = !0, frame = new Rectangle(0, 0, 1, 1)), baseTexture instanceof Texture && (baseTexture = baseTexture.baseTexture), this.baseTexture = baseTexture, this._frame = frame, this.trim = trim, this.valid = !1, this.destroyed = !1, this._uvs = DEFAULT_UVS, this.uvMatrix = null, this.orig = orig || frame, this._rotate = Number(rotate || 0), rotate === !0) 11781 this._rotate = 2; 11782 else if (this._rotate % 2 !== 0) 11783 throw new Error("attempt to use diamond-shaped UVs. If you are sure, set rotation manually"); 11784 this.defaultAnchor = anchor ? new Point(anchor.x, anchor.y) : new Point(0, 0), this.defaultBorders = borders, this._updateID = 0, this.textureCacheIds = [], baseTexture.valid ? this.noFrame ? baseTexture.valid && this.onBaseTextureUpdated(baseTexture) : this.frame = frame : baseTexture.once("loaded", this.onBaseTextureUpdated, this), this.noFrame && baseTexture.on("update", this.onBaseTextureUpdated, this); 11785 } 11786 /** 11787 * Updates this texture on the gpu. 11788 * 11789 * Calls the TextureResource update. 11790 * 11791 * If you adjusted `frame` manually, please call `updateUvs()` instead. 11792 */ 11793 update() { 11794 this.baseTexture.resource && this.baseTexture.resource.update(); 11795 } 11796 /** 11797 * Called when the base texture is updated 11798 * @protected 11799 * @param baseTexture - The base texture. 11800 */ 11801 onBaseTextureUpdated(baseTexture) { 11802 if (this.noFrame) { 11803 if (!this.baseTexture.valid) 11804 return; 11805 this._frame.width = baseTexture.width, this._frame.height = baseTexture.height, this.valid = !0, this.updateUvs(); 11806 } else 11807 this.frame = this._frame; 11808 this.emit("update", this); 11809 } 11810 /** 11811 * Destroys this texture 11812 * @param [destroyBase=false] - Whether to destroy the base texture as well 11813 * @fires PIXI.Texture#destroyed 11814 */ 11815 destroy(destroyBase) { 11816 if (this.baseTexture) { 11817 if (destroyBase) { 11818 const { resource } = this.baseTexture; 11819 resource?.url && TextureCache[resource.url] && Texture.removeFromCache(resource.url), this.baseTexture.destroy(); 11820 } 11821 this.baseTexture.off("loaded", this.onBaseTextureUpdated, this), this.baseTexture.off("update", this.onBaseTextureUpdated, this), this.baseTexture = null; 11822 } 11823 this._frame = null, this._uvs = null, this.trim = null, this.orig = null, this.valid = !1, Texture.removeFromCache(this), this.textureCacheIds = null, this.destroyed = !0, this.emit("destroyed", this), this.removeAllListeners(); 11824 } 11825 /** 11826 * Creates a new texture object that acts the same as this one. 11827 * @returns - The new texture 11828 */ 11829 clone() { 11830 const clonedFrame = this._frame.clone(), clonedOrig = this._frame === this.orig ? clonedFrame : this.orig.clone(), clonedTexture = new Texture( 11831 this.baseTexture, 11832 !this.noFrame && clonedFrame, 11833 clonedOrig, 11834 this.trim?.clone(), 11835 this.rotate, 11836 this.defaultAnchor, 11837 this.defaultBorders 11838 ); 11839 return this.noFrame && (clonedTexture._frame = clonedFrame), clonedTexture; 11840 } 11841 /** 11842 * Updates the internal WebGL UV cache. Use it after you change `frame` or `trim` of the texture. 11843 * Call it after changing the frame 11844 */ 11845 updateUvs() { 11846 this._uvs === DEFAULT_UVS && (this._uvs = new TextureUvs()), this._uvs.set(this._frame, this.baseTexture, this.rotate), this._updateID++; 11847 } 11848 /** 11849 * Helper function that creates a new Texture based on the source you provide. 11850 * The source can be - frame id, image url, video url, canvas element, video element, base texture 11851 * @param {string|PIXI.BaseTexture|HTMLImageElement|HTMLVideoElement|ImageBitmap|PIXI.ICanvas} source - 11852 * Source or array of sources to create texture from 11853 * @param options - See {@link PIXI.BaseTexture}'s constructor for options. 11854 * @param {string} [options.pixiIdPrefix=pixiid] - If a source has no id, this is the prefix of the generated id 11855 * @param {boolean} [strict] - Enforce strict-mode, see {@link PIXI.settings.STRICT_TEXTURE_CACHE}. 11856 * @returns {PIXI.Texture} The newly created texture 11857 */ 11858 static from(source, options = {}, strict = settings.STRICT_TEXTURE_CACHE) { 11859 const isFrame = typeof source == "string"; 11860 let cacheId = null; 11861 if (isFrame) 11862 cacheId = source; 11863 else if (source instanceof BaseTexture) { 11864 if (!source.cacheId) { 11865 const prefix = options?.pixiIdPrefix || "pixiid"; 11866 source.cacheId = `${prefix}-${uid()}`, BaseTexture.addToCache(source, source.cacheId); 11867 } 11868 cacheId = source.cacheId; 11869 } else { 11870 if (!source._pixiId) { 11871 const prefix = options?.pixiIdPrefix || "pixiid"; 11872 source._pixiId = `${prefix}_${uid()}`; 11873 } 11874 cacheId = source._pixiId; 11875 } 11876 let texture = TextureCache[cacheId]; 11877 if (isFrame && strict && !texture) 11878 throw new Error(`The cacheId "${cacheId}" does not exist in TextureCache.`); 11879 return !texture && !(source instanceof BaseTexture) ? (options.resolution || (options.resolution = getResolutionOfUrl(source)), texture = new Texture(new BaseTexture(source, options)), texture.baseTexture.cacheId = cacheId, BaseTexture.addToCache(texture.baseTexture, cacheId), Texture.addToCache(texture, cacheId)) : !texture && source instanceof BaseTexture && (texture = new Texture(source), Texture.addToCache(texture, cacheId)), texture; 11880 } 11881 /** 11882 * Useful for loading textures via URLs. Use instead of `Texture.from` because 11883 * it does a better job of handling failed URLs more effectively. This also ignores 11884 * `PIXI.settings.STRICT_TEXTURE_CACHE`. Works for Videos, SVGs, Images. 11885 * @param url - The remote URL or array of URLs to load. 11886 * @param options - Optional options to include 11887 * @returns - A Promise that resolves to a Texture. 11888 */ 11889 static fromURL(url, options) { 11890 const resourceOptions = Object.assign({ autoLoad: !1 }, options?.resourceOptions), texture = Texture.from(url, Object.assign({ resourceOptions }, options), !1), resource = texture.baseTexture.resource; 11891 return texture.baseTexture.valid ? Promise.resolve(texture) : resource.load().then(() => Promise.resolve(texture)); 11892 } 11893 /** 11894 * Create a new Texture with a BufferResource from a typed array. 11895 * @param buffer - The optional array to use. If no data is provided, a new Float32Array is created. 11896 * @param width - Width of the resource 11897 * @param height - Height of the resource 11898 * @param options - See {@link PIXI.BaseTexture}'s constructor for options. 11899 * Default properties are different from the constructor's defaults. 11900 * @param {PIXI.FORMATS} [options.format] - The format is not given, the type is inferred from the 11901 * type of the buffer: `RGBA` if Float32Array, Int8Array, Uint8Array, or Uint8ClampedArray, 11902 * otherwise `RGBA_INTEGER`. 11903 * @param {PIXI.TYPES} [options.type] - The type is not given, the type is inferred from the 11904 * type of the buffer. Maps Float32Array to `FLOAT`, Int32Array to `INT`, Uint32Array to 11905 * `UNSIGNED_INT`, Int16Array to `SHORT`, Uint16Array to `UNSIGNED_SHORT`, Int8Array to `BYTE`, 11906 * Uint8Array/Uint8ClampedArray to `UNSIGNED_BYTE`. 11907 * @param {PIXI.ALPHA_MODES} [options.alphaMode=PIXI.ALPHA_MODES.NPM] 11908 * @param {PIXI.SCALE_MODES} [options.scaleMode=PIXI.SCALE_MODES.NEAREST] 11909 * @returns - The resulting new BaseTexture 11910 */ 11911 static fromBuffer(buffer, width, height, options) { 11912 return new Texture(BaseTexture.fromBuffer(buffer, width, height, options)); 11913 } 11914 /** 11915 * Create a texture from a source and add to the cache. 11916 * @param {HTMLImageElement|HTMLVideoElement|ImageBitmap|PIXI.ICanvas|string} source - The input source. 11917 * @param imageUrl - File name of texture, for cache and resolving resolution. 11918 * @param name - Human readable name for the texture cache. If no name is 11919 * specified, only `imageUrl` will be used as the cache ID. 11920 * @param options 11921 * @returns - Output texture 11922 */ 11923 static fromLoader(source, imageUrl, name, options) { 11924 const baseTexture = new BaseTexture(source, Object.assign({ 11925 scaleMode: BaseTexture.defaultOptions.scaleMode, 11926 resolution: getResolutionOfUrl(imageUrl) 11927 }, options)), { resource } = baseTexture; 11928 resource instanceof ImageResource && (resource.url = imageUrl); 11929 const texture = new Texture(baseTexture); 11930 return name || (name = imageUrl), BaseTexture.addToCache(texture.baseTexture, name), Texture.addToCache(texture, name), name !== imageUrl && (BaseTexture.addToCache(texture.baseTexture, imageUrl), Texture.addToCache(texture, imageUrl)), texture.baseTexture.valid ? Promise.resolve(texture) : new Promise((resolve) => { 11931 texture.baseTexture.once("loaded", () => resolve(texture)); 11932 }); 11933 } 11934 /** 11935 * Adds a Texture to the global TextureCache. This cache is shared across the whole PIXI object. 11936 * @param texture - The Texture to add to the cache. 11937 * @param id - The id that the Texture will be stored against. 11938 */ 11939 static addToCache(texture, id) { 11940 id && (texture.textureCacheIds.includes(id) || texture.textureCacheIds.push(id), TextureCache[id] && TextureCache[id] !== texture && console.warn(`Texture added to the cache with an id [${id}] that already had an entry`), TextureCache[id] = texture); 11941 } 11942 /** 11943 * Remove a Texture from the global TextureCache. 11944 * @param texture - id of a Texture to be removed, or a Texture instance itself 11945 * @returns - The Texture that was removed 11946 */ 11947 static removeFromCache(texture) { 11948 if (typeof texture == "string") { 11949 const textureFromCache = TextureCache[texture]; 11950 if (textureFromCache) { 11951 const index = textureFromCache.textureCacheIds.indexOf(texture); 11952 return index > -1 && textureFromCache.textureCacheIds.splice(index, 1), delete TextureCache[texture], textureFromCache; 11953 } 11954 } else if (texture?.textureCacheIds) { 11955 for (let i = 0; i < texture.textureCacheIds.length; ++i) 11956 TextureCache[texture.textureCacheIds[i]] === texture && delete TextureCache[texture.textureCacheIds[i]]; 11957 return texture.textureCacheIds.length = 0, texture; 11958 } 11959 return null; 11960 } 11961 /** 11962 * Returns resolution of baseTexture 11963 * @readonly 11964 */ 11965 get resolution() { 11966 return this.baseTexture.resolution; 11967 } 11968 /** 11969 * The frame specifies the region of the base texture that this texture uses. 11970 * Please call `updateUvs()` after you change coordinates of `frame` manually. 11971 */ 11972 get frame() { 11973 return this._frame; 11974 } 11975 set frame(frame) { 11976 this._frame = frame, this.noFrame = !1; 11977 const { x, y, width, height } = frame, xNotFit = x + width > this.baseTexture.width, yNotFit = y + height > this.baseTexture.height; 11978 if (xNotFit || yNotFit) { 11979 const relationship = xNotFit && yNotFit ? "and" : "or", errorX = `X: ${x} + ${width} = ${x + width} > ${this.baseTexture.width}`, errorY = `Y: ${y} + ${height} = ${y + height} > ${this.baseTexture.height}`; 11980 throw new Error(`Texture Error: frame does not fit inside the base Texture dimensions: ${errorX} ${relationship} ${errorY}`); 11981 } 11982 this.valid = width && height && this.baseTexture.valid, !this.trim && !this.rotate && (this.orig = frame), this.valid && this.updateUvs(); 11983 } 11984 /** 11985 * Indicates whether the texture is rotated inside the atlas 11986 * set to 2 to compensate for texture packer rotation 11987 * set to 6 to compensate for spine packer rotation 11988 * can be used to rotate or mirror sprites 11989 * See {@link PIXI.groupD8} for explanation 11990 */ 11991 get rotate() { 11992 return this._rotate; 11993 } 11994 set rotate(rotate) { 11995 this._rotate = rotate, this.valid && this.updateUvs(); 11996 } 11997 /** The width of the Texture in pixels. */ 11998 get width() { 11999 return this.orig.width; 12000 } 12001 /** The height of the Texture in pixels. */ 12002 get height() { 12003 return this.orig.height; 12004 } 12005 /** Utility function for BaseTexture|Texture cast. */ 12006 castToBaseTexture() { 12007 return this.baseTexture; 12008 } 12009 /** An empty texture, used often to not have to create multiple empty textures. Can not be destroyed. */ 12010 static get EMPTY() { 12011 return Texture._EMPTY || (Texture._EMPTY = new Texture(new BaseTexture()), removeAllHandlers(Texture._EMPTY), removeAllHandlers(Texture._EMPTY.baseTexture)), Texture._EMPTY; 12012 } 12013 /** A white texture of 16x16 size, used for graphics and other things Can not be destroyed. */ 12014 static get WHITE() { 12015 if (!Texture._WHITE) { 12016 const canvas = settings.ADAPTER.createCanvas(16, 16), context = canvas.getContext("2d"); 12017 canvas.width = 16, canvas.height = 16, context.fillStyle = "white", context.fillRect(0, 0, 16, 16), Texture._WHITE = new Texture(BaseTexture.from(canvas)), removeAllHandlers(Texture._WHITE), removeAllHandlers(Texture._WHITE.baseTexture); 12018 } 12019 return Texture._WHITE; 12020 } 12021} 12022 12023class RenderTexture extends Texture { 12024 /** 12025 * @param baseRenderTexture - The base texture object that this texture uses. 12026 * @param frame - The rectangle frame of the texture to show. 12027 */ 12028 constructor(baseRenderTexture, frame) { 12029 super(baseRenderTexture, frame), this.valid = !0, this.filterFrame = null, this.filterPoolKey = null, this.updateUvs(); 12030 } 12031 /** 12032 * Shortcut to `this.baseTexture.framebuffer`, saves baseTexture cast. 12033 * @readonly 12034 */ 12035 get framebuffer() { 12036 return this.baseTexture.framebuffer; 12037 } 12038 /** 12039 * Shortcut to `this.framebuffer.multisample`. 12040 * @default PIXI.MSAA_QUALITY.NONE 12041 */ 12042 get multisample() { 12043 return this.framebuffer.multisample; 12044 } 12045 set multisample(value) { 12046 this.framebuffer.multisample = value; 12047 } 12048 /** 12049 * Resizes the RenderTexture. 12050 * @param desiredWidth - The desired width to resize to. 12051 * @param desiredHeight - The desired height to resize to. 12052 * @param resizeBaseTexture - Should the baseTexture.width and height values be resized as well? 12053 */ 12054 resize(desiredWidth, desiredHeight, resizeBaseTexture = !0) { 12055 const resolution = this.baseTexture.resolution, width = Math.round(desiredWidth * resolution) / resolution, height = Math.round(desiredHeight * resolution) / resolution; 12056 this.valid = width > 0 && height > 0, this._frame.width = this.orig.width = width, this._frame.height = this.orig.height = height, resizeBaseTexture && this.baseTexture.resize(width, height), this.updateUvs(); 12057 } 12058 /** 12059 * Changes the resolution of baseTexture, but does not change framebuffer size. 12060 * @param resolution - The new resolution to apply to RenderTexture 12061 */ 12062 setResolution(resolution) { 12063 const { baseTexture } = this; 12064 baseTexture.resolution !== resolution && (baseTexture.setResolution(resolution), this.resize(baseTexture.width, baseTexture.height, !1)); 12065 } 12066 /** 12067 * A short hand way of creating a render texture. 12068 * @param options - Options 12069 * @param {number} [options.width=100] - The width of the render texture 12070 * @param {number} [options.height=100] - The height of the render texture 12071 * @param {PIXI.SCALE_MODES} [options.scaleMode=PIXI.BaseTexture.defaultOptions.scaleMode] - See {@link PIXI.SCALE_MODES} 12072 * for possible values 12073 * @param {number} [options.resolution=PIXI.settings.RESOLUTION] - The resolution / device pixel ratio of the texture 12074 * being generated 12075 * @param {PIXI.MSAA_QUALITY} [options.multisample=PIXI.MSAA_QUALITY.NONE] - The number of samples of the frame buffer 12076 * @returns The new render texture 12077 */ 12078 static create(options) { 12079 return new RenderTexture(new BaseRenderTexture(options)); 12080 } 12081} 12082 12083class RenderTexturePool { 12084 /** 12085 * @param textureOptions - options that will be passed to BaseRenderTexture constructor 12086 * @param {PIXI.SCALE_MODES} [textureOptions.scaleMode] - See {@link PIXI.SCALE_MODES} for possible values. 12087 */ 12088 constructor(textureOptions) { 12089 this.texturePool = {}, this.textureOptions = textureOptions || {}, this.enableFullScreen = !1, this._pixelsWidth = 0, this._pixelsHeight = 0; 12090 } 12091 /** 12092 * Creates texture with params that were specified in pool constructor. 12093 * @param realWidth - Width of texture in pixels. 12094 * @param realHeight - Height of texture in pixels. 12095 * @param multisample - Number of samples of the framebuffer. 12096 */ 12097 createTexture(realWidth, realHeight, multisample = MSAA_QUALITY.NONE) { 12098 const baseRenderTexture = new BaseRenderTexture(Object.assign({ 12099 width: realWidth, 12100 height: realHeight, 12101 resolution: 1, 12102 multisample 12103 }, this.textureOptions)); 12104 return new RenderTexture(baseRenderTexture); 12105 } 12106 /** 12107 * Gets a Power-of-Two render texture or fullScreen texture 12108 * @param minWidth - The minimum width of the render texture. 12109 * @param minHeight - The minimum height of the render texture. 12110 * @param resolution - The resolution of the render texture. 12111 * @param multisample - Number of samples of the render texture. 12112 * @returns The new render texture. 12113 */ 12114 getOptimalTexture(minWidth, minHeight, resolution = 1, multisample = MSAA_QUALITY.NONE) { 12115 let key; 12116 minWidth = Math.max(Math.ceil(minWidth * resolution - 1e-6), 1), minHeight = Math.max(Math.ceil(minHeight * resolution - 1e-6), 1), !this.enableFullScreen || minWidth !== this._pixelsWidth || minHeight !== this._pixelsHeight ? (minWidth = nextPow2(minWidth), minHeight = nextPow2(minHeight), key = ((minWidth & 65535) << 16 | minHeight & 65535) >>> 0, multisample > 1 && (key += multisample * 4294967296)) : key = multisample > 1 ? -multisample : -1, this.texturePool[key] || (this.texturePool[key] = []); 12117 let renderTexture = this.texturePool[key].pop(); 12118 return renderTexture || (renderTexture = this.createTexture(minWidth, minHeight, multisample)), renderTexture.filterPoolKey = key, renderTexture.setResolution(resolution), renderTexture; 12119 } 12120 /** 12121 * Gets extra texture of the same size as input renderTexture 12122 * 12123 * `getFilterTexture(input, 0.5)` or `getFilterTexture(0.5, input)` 12124 * @param input - renderTexture from which size and resolution will be copied 12125 * @param resolution - override resolution of the renderTexture 12126 * It overrides, it does not multiply 12127 * @param multisample - number of samples of the renderTexture 12128 */ 12129 getFilterTexture(input, resolution, multisample) { 12130 const filterTexture = this.getOptimalTexture( 12131 input.width, 12132 input.height, 12133 resolution || input.resolution, 12134 multisample || MSAA_QUALITY.NONE 12135 ); 12136 return filterTexture.filterFrame = input.filterFrame, filterTexture; 12137 } 12138 /** 12139 * Place a render texture back into the pool. 12140 * @param renderTexture - The renderTexture to free 12141 */ 12142 returnTexture(renderTexture) { 12143 const key = renderTexture.filterPoolKey; 12144 renderTexture.filterFrame = null, this.texturePool[key].push(renderTexture); 12145 } 12146 /** 12147 * Alias for returnTexture, to be compliant with FilterSystem interface. 12148 * @param renderTexture - The renderTexture to free 12149 */ 12150 returnFilterTexture(renderTexture) { 12151 this.returnTexture(renderTexture); 12152 } 12153 /** 12154 * Clears the pool. 12155 * @param destroyTextures - Destroy all stored textures. 12156 */ 12157 clear(destroyTextures) { 12158 if (destroyTextures = destroyTextures !== !1, destroyTextures) 12159 for (const i in this.texturePool) { 12160 const textures = this.texturePool[i]; 12161 if (textures) 12162 for (let j = 0; j < textures.length; j++) 12163 textures[j].destroy(!0); 12164 } 12165 this.texturePool = {}; 12166 } 12167 /** 12168 * If screen size was changed, drops all screen-sized textures, 12169 * sets new screen size, sets `enableFullScreen` to true 12170 * 12171 * Size is measured in pixels, `renderer.view` can be passed here, not `renderer.screen` 12172 * @param size - Initial size of screen. 12173 */ 12174 setScreenSize(size) { 12175 if (!(size.width === this._pixelsWidth && size.height === this._pixelsHeight)) { 12176 this.enableFullScreen = size.width > 0 && size.height > 0; 12177 for (const i in this.texturePool) { 12178 if (!(Number(i) < 0)) 12179 continue; 12180 const textures = this.texturePool[i]; 12181 if (textures) 12182 for (let j = 0; j < textures.length; j++) 12183 textures[j].destroy(!0); 12184 this.texturePool[i] = []; 12185 } 12186 this._pixelsWidth = size.width, this._pixelsHeight = size.height; 12187 } 12188 } 12189} 12190RenderTexturePool.SCREEN_KEY = -1; 12191 12192class Quad extends Geometry { 12193 constructor() { 12194 super(), this.addAttribute("aVertexPosition", new Float32Array([ 12195 0, 12196 0, 12197 1, 12198 0, 12199 1, 12200 1, 12201 0, 12202 1 12203 ])).addIndex([0, 1, 3, 2]); 12204 } 12205} 12206 12207class QuadUv extends Geometry { 12208 constructor() { 12209 super(), this.vertices = new Float32Array([ 12210 -1, 12211 -1, 12212 1, 12213 -1, 12214 1, 12215 1, 12216 -1, 12217 1 12218 ]), this.uvs = new Float32Array([ 12219 0, 12220 0, 12221 1, 12222 0, 12223 1, 12224 1, 12225 0, 12226 1 12227 ]), this.vertexBuffer = new Buffer(this.vertices), this.uvBuffer = new Buffer(this.uvs), this.addAttribute("aVertexPosition", this.vertexBuffer).addAttribute("aTextureCoord", this.uvBuffer).addIndex([0, 1, 2, 0, 2, 3]); 12228 } 12229 /** 12230 * Maps two Rectangle to the quad. 12231 * @param targetTextureFrame - The first rectangle 12232 * @param destinationFrame - The second rectangle 12233 * @returns - Returns itself. 12234 */ 12235 map(targetTextureFrame, destinationFrame) { 12236 let x = 0, y = 0; 12237 return this.uvs[0] = x, this.uvs[1] = y, this.uvs[2] = x + destinationFrame.width / targetTextureFrame.width, this.uvs[3] = y, this.uvs[4] = x + destinationFrame.width / targetTextureFrame.width, this.uvs[5] = y + destinationFrame.height / targetTextureFrame.height, this.uvs[6] = x, this.uvs[7] = y + destinationFrame.height / targetTextureFrame.height, x = destinationFrame.x, y = destinationFrame.y, this.vertices[0] = x, this.vertices[1] = y, this.vertices[2] = x + destinationFrame.width, this.vertices[3] = y, this.vertices[4] = x + destinationFrame.width, this.vertices[5] = y + destinationFrame.height, this.vertices[6] = x, this.vertices[7] = y + destinationFrame.height, this.invalidate(), this; 12238 } 12239 /** 12240 * Legacy upload method, just marks buffers dirty. 12241 * @returns - Returns itself. 12242 */ 12243 invalidate() { 12244 return this.vertexBuffer._updateID++, this.uvBuffer._updateID++, this; 12245 } 12246} 12247 12248class FilterState { 12249 constructor() { 12250 this.renderTexture = null, this.target = null, this.legacy = !1, this.resolution = 1, this.multisample = MSAA_QUALITY.NONE, this.sourceFrame = new Rectangle(), this.destinationFrame = new Rectangle(), this.bindingSourceFrame = new Rectangle(), this.bindingDestinationFrame = new Rectangle(), this.filters = [], this.transform = null; 12251 } 12252 /** Clears the state */ 12253 clear() { 12254 this.target = null, this.filters = null, this.renderTexture = null; 12255 } 12256} 12257 12258const tempPoints = [new Point(), new Point(), new Point(), new Point()], tempMatrix$2 = new Matrix(); 12259class FilterSystem { 12260 /** 12261 * @param renderer - The renderer this System works for. 12262 */ 12263 constructor(renderer) { 12264 this.renderer = renderer, this.defaultFilterStack = [{}], this.texturePool = new RenderTexturePool(), this.statePool = [], this.quad = new Quad(), this.quadUv = new QuadUv(), this.tempRect = new Rectangle(), this.activeState = {}, this.globalUniforms = new UniformGroup({ 12265 outputFrame: new Rectangle(), 12266 inputSize: new Float32Array(4), 12267 inputPixel: new Float32Array(4), 12268 inputClamp: new Float32Array(4), 12269 resolution: 1, 12270 // legacy variables 12271 filterArea: new Float32Array(4), 12272 filterClamp: new Float32Array(4) 12273 }, !0), this.forceClear = !1, this.useMaxPadding = !1; 12274 } 12275 init() { 12276 this.texturePool.setScreenSize(this.renderer.view); 12277 } 12278 /** 12279 * Pushes a set of filters to be applied later to the system. This will redirect further rendering into an 12280 * input render-texture for the rest of the filtering pipeline. 12281 * @param {PIXI.DisplayObject} target - The target of the filter to render. 12282 * @param filters - The filters to apply. 12283 */ 12284 push(target, filters) { 12285 const renderer = this.renderer, filterStack = this.defaultFilterStack, state = this.statePool.pop() || new FilterState(), renderTextureSystem = renderer.renderTexture; 12286 let currentResolution, currentMultisample; 12287 if (renderTextureSystem.current) { 12288 const renderTexture = renderTextureSystem.current; 12289 currentResolution = renderTexture.resolution, currentMultisample = renderTexture.multisample; 12290 } else 12291 currentResolution = renderer.resolution, currentMultisample = renderer.multisample; 12292 let resolution = filters[0].resolution || currentResolution, multisample = filters[0].multisample ?? currentMultisample, padding = filters[0].padding, autoFit = filters[0].autoFit, legacy = filters[0].legacy ?? !0; 12293 for (let i = 1; i < filters.length; i++) { 12294 const filter = filters[i]; 12295 resolution = Math.min(resolution, filter.resolution || currentResolution), multisample = Math.min(multisample, filter.multisample ?? currentMultisample), padding = this.useMaxPadding ? Math.max(padding, filter.padding) : padding + filter.padding, autoFit = autoFit && filter.autoFit, legacy = legacy || (filter.legacy ?? !0); 12296 } 12297 filterStack.length === 1 && (this.defaultFilterStack[0].renderTexture = renderTextureSystem.current), filterStack.push(state), state.resolution = resolution, state.multisample = multisample, state.legacy = legacy, state.target = target, state.sourceFrame.copyFrom(target.filterArea || target.getBounds(!0)), state.sourceFrame.pad(padding); 12298 const sourceFrameProjected = this.tempRect.copyFrom(renderTextureSystem.sourceFrame); 12299 renderer.projection.transform && this.transformAABB( 12300 tempMatrix$2.copyFrom(renderer.projection.transform).invert(), 12301 sourceFrameProjected 12302 ), autoFit ? (state.sourceFrame.fit(sourceFrameProjected), (state.sourceFrame.width <= 0 || state.sourceFrame.height <= 0) && (state.sourceFrame.width = 0, state.sourceFrame.height = 0)) : state.sourceFrame.intersects(sourceFrameProjected) || (state.sourceFrame.width = 0, state.sourceFrame.height = 0), this.roundFrame( 12303 state.sourceFrame, 12304 renderTextureSystem.current ? renderTextureSystem.current.resolution : renderer.resolution, 12305 renderTextureSystem.sourceFrame, 12306 renderTextureSystem.destinationFrame, 12307 renderer.projection.transform 12308 ), state.renderTexture = this.getOptimalFilterTexture( 12309 state.sourceFrame.width, 12310 state.sourceFrame.height, 12311 resolution, 12312 multisample 12313 ), state.filters = filters, state.destinationFrame.width = state.renderTexture.width, state.destinationFrame.height = state.renderTexture.height; 12314 const destinationFrame = this.tempRect; 12315 destinationFrame.x = 0, destinationFrame.y = 0, destinationFrame.width = state.sourceFrame.width, destinationFrame.height = state.sourceFrame.height, state.renderTexture.filterFrame = state.sourceFrame, state.bindingSourceFrame.copyFrom(renderTextureSystem.sourceFrame), state.bindingDestinationFrame.copyFrom(renderTextureSystem.destinationFrame), state.transform = renderer.projection.transform, renderer.projection.transform = null, renderTextureSystem.bind(state.renderTexture, state.sourceFrame, destinationFrame), renderer.framebuffer.clear(0, 0, 0, 0); 12316 } 12317 /** Pops off the filter and applies it. */ 12318 pop() { 12319 const filterStack = this.defaultFilterStack, state = filterStack.pop(), filters = state.filters; 12320 this.activeState = state; 12321 const globalUniforms = this.globalUniforms.uniforms; 12322 globalUniforms.outputFrame = state.sourceFrame, globalUniforms.resolution = state.resolution; 12323 const inputSize = globalUniforms.inputSize, inputPixel = globalUniforms.inputPixel, inputClamp = globalUniforms.inputClamp; 12324 if (inputSize[0] = state.destinationFrame.width, inputSize[1] = state.destinationFrame.height, inputSize[2] = 1 / inputSize[0], inputSize[3] = 1 / inputSize[1], inputPixel[0] = Math.round(inputSize[0] * state.resolution), inputPixel[1] = Math.round(inputSize[1] * state.resolution), inputPixel[2] = 1 / inputPixel[0], inputPixel[3] = 1 / inputPixel[1], inputClamp[0] = 0.5 * inputPixel[2], inputClamp[1] = 0.5 * inputPixel[3], inputClamp[2] = state.sourceFrame.width * inputSize[2] - 0.5 * inputPixel[2], inputClamp[3] = state.sourceFrame.height * inputSize[3] - 0.5 * inputPixel[3], state.legacy) { 12325 const filterArea = globalUniforms.filterArea; 12326 filterArea[0] = state.destinationFrame.width, filterArea[1] = state.destinationFrame.height, filterArea[2] = state.sourceFrame.x, filterArea[3] = state.sourceFrame.y, globalUniforms.filterClamp = globalUniforms.inputClamp; 12327 } 12328 this.globalUniforms.update(); 12329 const lastState = filterStack[filterStack.length - 1]; 12330 if (this.renderer.framebuffer.blit(), filters.length === 1) 12331 filters[0].apply(this, state.renderTexture, lastState.renderTexture, CLEAR_MODES.BLEND, state), this.returnFilterTexture(state.renderTexture); 12332 else { 12333 let flip = state.renderTexture, flop = this.getOptimalFilterTexture( 12334 flip.width, 12335 flip.height, 12336 state.resolution 12337 ); 12338 flop.filterFrame = flip.filterFrame; 12339 let i = 0; 12340 for (i = 0; i < filters.length - 1; ++i) { 12341 i === 1 && state.multisample > 1 && (flop = this.getOptimalFilterTexture( 12342 flip.width, 12343 flip.height, 12344 state.resolution 12345 ), flop.filterFrame = flip.filterFrame), filters[i].apply(this, flip, flop, CLEAR_MODES.CLEAR, state); 12346 const t = flip; 12347 flip = flop, flop = t; 12348 } 12349 filters[i].apply(this, flip, lastState.renderTexture, CLEAR_MODES.BLEND, state), i > 1 && state.multisample > 1 && this.returnFilterTexture(state.renderTexture), this.returnFilterTexture(flip), this.returnFilterTexture(flop); 12350 } 12351 state.clear(), this.statePool.push(state); 12352 } 12353 /** 12354 * Binds a renderTexture with corresponding `filterFrame`, clears it if mode corresponds. 12355 * @param filterTexture - renderTexture to bind, should belong to filter pool or filter stack 12356 * @param clearMode - clearMode, by default its CLEAR/YES. See {@link PIXI.CLEAR_MODES} 12357 */ 12358 bindAndClear(filterTexture, clearMode = CLEAR_MODES.CLEAR) { 12359 const { 12360 renderTexture: renderTextureSystem, 12361 state: stateSystem 12362 } = this.renderer; 12363 if (filterTexture === this.defaultFilterStack[this.defaultFilterStack.length - 1].renderTexture ? this.renderer.projection.transform = this.activeState.transform : this.renderer.projection.transform = null, filterTexture?.filterFrame) { 12364 const destinationFrame = this.tempRect; 12365 destinationFrame.x = 0, destinationFrame.y = 0, destinationFrame.width = filterTexture.filterFrame.width, destinationFrame.height = filterTexture.filterFrame.height, renderTextureSystem.bind(filterTexture, filterTexture.filterFrame, destinationFrame); 12366 } else 12367 filterTexture !== this.defaultFilterStack[this.defaultFilterStack.length - 1].renderTexture ? renderTextureSystem.bind(filterTexture) : this.renderer.renderTexture.bind( 12368 filterTexture, 12369 this.activeState.bindingSourceFrame, 12370 this.activeState.bindingDestinationFrame 12371 ); 12372 const autoClear = stateSystem.stateId & 1 || this.forceClear; 12373 (clearMode === CLEAR_MODES.CLEAR || clearMode === CLEAR_MODES.BLIT && autoClear) && this.renderer.framebuffer.clear(0, 0, 0, 0); 12374 } 12375 /** 12376 * Draws a filter using the default rendering process. 12377 * 12378 * This should be called only by {@link PIXI.Filter#apply}. 12379 * @param filter - The filter to draw. 12380 * @param input - The input render target. 12381 * @param output - The target to output to. 12382 * @param clearMode - Should the output be cleared before rendering to it 12383 */ 12384 applyFilter(filter, input, output, clearMode) { 12385 const renderer = this.renderer; 12386 renderer.state.set(filter.state), this.bindAndClear(output, clearMode), filter.uniforms.uSampler = input, filter.uniforms.filterGlobals = this.globalUniforms, renderer.shader.bind(filter), filter.legacy = !!filter.program.attributeData.aTextureCoord, filter.legacy ? (this.quadUv.map(input._frame, input.filterFrame), renderer.geometry.bind(this.quadUv), renderer.geometry.draw(DRAW_MODES.TRIANGLES)) : (renderer.geometry.bind(this.quad), renderer.geometry.draw(DRAW_MODES.TRIANGLE_STRIP)); 12387 } 12388 /** 12389 * Multiply _input normalized coordinates_ to this matrix to get _sprite texture normalized coordinates_. 12390 * 12391 * Use `outputMatrix * vTextureCoord` in the shader. 12392 * @param outputMatrix - The matrix to output to. 12393 * @param {PIXI.Sprite} sprite - The sprite to map to. 12394 * @returns The mapped matrix. 12395 */ 12396 calculateSpriteMatrix(outputMatrix, sprite) { 12397 const { sourceFrame, destinationFrame } = this.activeState, { orig } = sprite._texture, mappedMatrix = outputMatrix.set( 12398 destinationFrame.width, 12399 0, 12400 0, 12401 destinationFrame.height, 12402 sourceFrame.x, 12403 sourceFrame.y 12404 ), worldTransform = sprite.worldTransform.copyTo(Matrix.TEMP_MATRIX); 12405 return worldTransform.invert(), mappedMatrix.prepend(worldTransform), mappedMatrix.scale(1 / orig.width, 1 / orig.height), mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y), mappedMatrix; 12406 } 12407 /** Destroys this Filter System. */ 12408 destroy() { 12409 this.renderer = null, this.texturePool.clear(!1); 12410 } 12411 /** 12412 * Gets a Power-of-Two render texture or fullScreen texture 12413 * @param minWidth - The minimum width of the render texture in real pixels. 12414 * @param minHeight - The minimum height of the render texture in real pixels. 12415 * @param resolution - The resolution of the render texture. 12416 * @param multisample - Number of samples of the render texture. 12417 * @returns - The new render texture. 12418 */ 12419 getOptimalFilterTexture(minWidth, minHeight, resolution = 1, multisample = MSAA_QUALITY.NONE) { 12420 return this.texturePool.getOptimalTexture(minWidth, minHeight, resolution, multisample); 12421 } 12422 /** 12423 * Gets extra render texture to use inside current filter 12424 * To be compliant with older filters, you can use params in any order 12425 * @param input - renderTexture from which size and resolution will be copied 12426 * @param resolution - override resolution of the renderTexture 12427 * @param multisample - number of samples of the renderTexture 12428 */ 12429 getFilterTexture(input, resolution, multisample) { 12430 if (typeof input == "number") { 12431 const swap = input; 12432 input = resolution, resolution = swap; 12433 } 12434 input = input || this.activeState.renderTexture; 12435 const filterTexture = this.texturePool.getOptimalTexture( 12436 input.width, 12437 input.height, 12438 resolution || input.resolution, 12439 multisample || MSAA_QUALITY.NONE 12440 ); 12441 return filterTexture.filterFrame = input.filterFrame, filterTexture; 12442 } 12443 /** 12444 * Frees a render texture back into the pool. 12445 * @param renderTexture - The renderTarget to free 12446 */ 12447 returnFilterTexture(renderTexture) { 12448 this.texturePool.returnTexture(renderTexture); 12449 } 12450 /** Empties the texture pool. */ 12451 emptyPool() { 12452 this.texturePool.clear(!0); 12453 } 12454 /** Calls `texturePool.resize()`, affects fullScreen renderTextures. */ 12455 resize() {
vendor: 4,929 bytes, lines 12456-12537
12456 this.texturePool.setScreenSize(this.renderer.view); 12457 } 12458 /** 12459 * @param matrix - first param 12460 * @param rect - second param 12461 */ 12462 transformAABB(matrix, rect) { 12463 const lt = tempPoints[0], lb = tempPoints[1], rt = tempPoints[2], rb = tempPoints[3]; 12464 lt.set(rect.left, rect.top), lb.set(rect.left, rect.bottom), rt.set(rect.right, rect.top), rb.set(rect.right, rect.bottom), matrix.apply(lt, lt), matrix.apply(lb, lb), matrix.apply(rt, rt), matrix.apply(rb, rb); 12465 const x0 = Math.min(lt.x, lb.x, rt.x, rb.x), y0 = Math.min(lt.y, lb.y, rt.y, rb.y), x1 = Math.max(lt.x, lb.x, rt.x, rb.x), y1 = Math.max(lt.y, lb.y, rt.y, rb.y); 12466 rect.x = x0, rect.y = y0, rect.width = x1 - x0, rect.height = y1 - y0; 12467 } 12468 roundFrame(frame, resolution, bindingSourceFrame, bindingDestinationFrame, transform) { 12469 if (!(frame.width <= 0 || frame.height <= 0 || bindingSourceFrame.width <= 0 || bindingSourceFrame.height <= 0)) { 12470 if (transform) { 12471 const { a, b, c, d } = transform; 12472 if ((Math.abs(b) > 1e-4 || Math.abs(c) > 1e-4) && (Math.abs(a) > 1e-4 || Math.abs(d) > 1e-4)) 12473 return; 12474 } 12475 transform = transform ? tempMatrix$2.copyFrom(transform) : tempMatrix$2.identity(), transform.translate(-bindingSourceFrame.x, -bindingSourceFrame.y).scale( 12476 bindingDestinationFrame.width / bindingSourceFrame.width, 12477 bindingDestinationFrame.height / bindingSourceFrame.height 12478 ).translate(bindingDestinationFrame.x, bindingDestinationFrame.y), this.transformAABB(transform, frame), frame.ceil(resolution), this.transformAABB(transform.invert(), frame); 12479 } 12480 } 12481} 12482FilterSystem.extension = { 12483 type: ExtensionType.RendererSystem, 12484 name: "filter" 12485}; 12486extensions$1.add(FilterSystem); 12487 12488class GLFramebuffer { 12489 constructor(framebuffer) { 12490 this.framebuffer = framebuffer, this.stencil = null, this.dirtyId = -1, this.dirtyFormat = -1, this.dirtySize = -1, this.multisample = MSAA_QUALITY.NONE, this.msaaBuffer = null, this.blitFramebuffer = null, this.mipLevel = 0; 12491 } 12492} 12493 12494const tempRectangle = new Rectangle(); 12495class FramebufferSystem { 12496 /** 12497 * @param renderer - The renderer this System works for. 12498 */ 12499 constructor(renderer) { 12500 this.renderer = renderer, this.managedFramebuffers = [], this.unknownFramebuffer = new Framebuffer(10, 10), this.msaaSamples = null; 12501 } 12502 /** Sets up the renderer context and necessary buffers. */ 12503 contextChange() { 12504 this.disposeAll(!0); 12505 const gl = this.gl = this.renderer.gl; 12506 if (this.CONTEXT_UID = this.renderer.CONTEXT_UID, this.current = this.unknownFramebuffer, this.viewport = new Rectangle(), this.hasMRT = !0, this.writeDepthTexture = !0, this.renderer.context.webGLVersion === 1) { 12507 let nativeDrawBuffersExtension = this.renderer.context.extensions.drawBuffers, nativeDepthTextureExtension = this.renderer.context.extensions.depthTexture; 12508 settings.PREFER_ENV === ENV.WEBGL_LEGACY && (nativeDrawBuffersExtension = null, nativeDepthTextureExtension = null), nativeDrawBuffersExtension ? gl.drawBuffers = (activeTextures) => nativeDrawBuffersExtension.drawBuffersWEBGL(activeTextures) : (this.hasMRT = !1, gl.drawBuffers = () => { 12509 }), nativeDepthTextureExtension || (this.writeDepthTexture = !1); 12510 } else 12511 this.msaaSamples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES); 12512 } 12513 /** 12514 * Bind a framebuffer. 12515 * @param framebuffer 12516 * @param frame - frame, default is framebuffer size 12517 * @param mipLevel - optional mip level to set on the framebuffer - defaults to 0 12518 */ 12519 bind(framebuffer, frame, mipLevel = 0) { 12520 const { gl } = this; 12521 if (framebuffer) { 12522 const fbo = framebuffer.glFramebuffers[this.CONTEXT_UID] || this.initFramebuffer(framebuffer); 12523 this.current !== framebuffer && (this.current = framebuffer, gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.framebuffer)), fbo.mipLevel !== mipLevel && (framebuffer.dirtyId++, framebuffer.dirtyFormat++, fbo.mipLevel = mipLevel), fbo.dirtyId !== framebuffer.dirtyId && (fbo.dirtyId = framebuffer.dirtyId, fbo.dirtyFormat !== framebuffer.dirtyFormat ? (fbo.dirtyFormat = framebuffer.dirtyFormat, fbo.dirtySize = framebuffer.dirtySize, this.updateFramebuffer(framebuffer, mipLevel)) : fbo.dirtySize !== framebuffer.dirtySize && (fbo.dirtySize = framebuffer.dirtySize, this.resizeFramebuffer(framebuffer))); 12524 for (let i = 0; i < framebuffer.colorTextures.length; i++) { 12525 const tex = framebuffer.colorTextures[i]; 12526 this.renderer.texture.unbind(tex.parentTextureArray || tex); 12527 } 12528 if (framebuffer.depthTexture && this.renderer.texture.unbind(framebuffer.depthTexture), frame) { 12529 const mipWidth = frame.width >> mipLevel, mipHeight = frame.height >> mipLevel, scale = mipWidth / frame.width; 12530 this.setViewport( 12531 frame.x * scale, 12532 frame.y * scale, 12533 mipWidth, 12534 mipHeight 12535 ); 12536 } else { 12537 const mipWidth = framebuffer.width >>
vendor: 9,108 bytes, lines 12537-12715
12537 mipLevel, mipHeight = framebuffer.height >> mipLevel; 12538 this.setViewport(0, 0, mipWidth, mipHeight); 12539 } 12540 } else 12541 this.current && (this.current = null, gl.bindFramebuffer(gl.FRAMEBUFFER, null)), frame ? this.setViewport(frame.x, frame.y, frame.width, frame.height) : this.setViewport(0, 0, this.renderer.width, this.renderer.height); 12542 } 12543 /** 12544 * Set the WebGLRenderingContext's viewport. 12545 * @param x - X position of viewport 12546 * @param y - Y position of viewport 12547 * @param width - Width of viewport 12548 * @param height - Height of viewport 12549 */ 12550 setViewport(x, y, width, height) { 12551 const v = this.viewport; 12552 x = Math.round(x), y = Math.round(y), width = Math.round(width), height = Math.round(height), (v.width !== width || v.height !== height || v.x !== x || v.y !== y) && (v.x = x, v.y = y, v.width = width, v.height = height, this.gl.viewport(x, y, width, height)); 12553 } 12554 /** 12555 * Get the size of the current width and height. Returns object with `width` and `height` values. 12556 * @readonly 12557 */ 12558 get size() { 12559 return this.current ? { x: 0, y: 0, width: this.current.width, height: this.current.height } : { x: 0, y: 0, width: this.renderer.width, height: this.renderer.height }; 12560 } 12561 /** 12562 * Clear the color of the context 12563 * @param r - Red value from 0 to 1 12564 * @param g - Green value from 0 to 1 12565 * @param b - Blue value from 0 to 1 12566 * @param a - Alpha value from 0 to 1 12567 * @param {PIXI.BUFFER_BITS} [mask=BUFFER_BITS.COLOR | BUFFER_BITS.DEPTH] - Bitwise OR of masks 12568 * that indicate the buffers to be cleared, by default COLOR and DEPTH buffers. 12569 */ 12570 clear(r, g, b, a, mask = BUFFER_BITS.COLOR | BUFFER_BITS.DEPTH) { 12571 const { gl } = this; 12572 gl.clearColor(r, g, b, a), gl.clear(mask); 12573 } 12574 /** 12575 * Initialize framebuffer for this context 12576 * @protected 12577 * @param framebuffer 12578 * @returns - created GLFramebuffer 12579 */ 12580 initFramebuffer(framebuffer) { 12581 const { gl } = this, fbo = new GLFramebuffer(gl.createFramebuffer()); 12582 return fbo.multisample = this.detectSamples(framebuffer.multisample), framebuffer.glFramebuffers[this.CONTEXT_UID] = fbo, this.managedFramebuffers.push(framebuffer), framebuffer.disposeRunner.add(this), fbo; 12583 } 12584 /** 12585 * Resize the framebuffer 12586 * @param framebuffer 12587 * @protected 12588 */ 12589 resizeFramebuffer(framebuffer) { 12590 const { gl } = this, fbo = framebuffer.glFramebuffers[this.CONTEXT_UID]; 12591 if (fbo.stencil) { 12592 gl.bindRenderbuffer(gl.RENDERBUFFER, fbo.stencil); 12593 let stencilFormat; 12594 this.renderer.context.webGLVersion === 1 ? stencilFormat = gl.DEPTH_STENCIL : framebuffer.depth && framebuffer.stencil ? stencilFormat = gl.DEPTH24_STENCIL8 : framebuffer.depth ? stencilFormat = gl.DEPTH_COMPONENT24 : stencilFormat = gl.STENCIL_INDEX8, fbo.msaaBuffer ? gl.renderbufferStorageMultisample( 12595 gl.RENDERBUFFER, 12596 fbo.multisample, 12597 stencilFormat, 12598 framebuffer.width, 12599 framebuffer.height 12600 ) : gl.renderbufferStorage(gl.RENDERBUFFER, stencilFormat, framebuffer.width, framebuffer.height); 12601 } 12602 const colorTextures = framebuffer.colorTextures; 12603 let count = colorTextures.length; 12604 gl.drawBuffers || (count = Math.min(count, 1)); 12605 for (let i = 0; i < count; i++) { 12606 const texture = colorTextures[i], parentTexture = texture.parentTextureArray || texture; 12607 this.renderer.texture.bind(parentTexture, 0), i === 0 && fbo.msaaBuffer && (gl.bindRenderbuffer(gl.RENDERBUFFER, fbo.msaaBuffer), gl.renderbufferStorageMultisample( 12608 gl.RENDERBUFFER, 12609 fbo.multisample, 12610 parentTexture._glTextures[this.CONTEXT_UID].internalFormat, 12611 framebuffer.width, 12612 framebuffer.height 12613 )); 12614 } 12615 framebuffer.depthTexture && this.writeDepthTexture && this.renderer.texture.bind(framebuffer.depthTexture, 0); 12616 } 12617 /** 12618 * Update the framebuffer 12619 * @param framebuffer 12620 * @param mipLevel 12621 * @protected 12622 */ 12623 updateFramebuffer(framebuffer, mipLevel) { 12624 const { gl } = this, fbo = framebuffer.glFramebuffers[this.CONTEXT_UID], colorTextures = framebuffer.colorTextures; 12625 let count = colorTextures.length; 12626 gl.drawBuffers || (count = Math.min(count, 1)), fbo.multisample > 1 && this.canMultisampleFramebuffer(framebuffer) ? fbo.msaaBuffer = fbo.msaaBuffer || gl.createRenderbuffer() : fbo.msaaBuffer && (gl.deleteRenderbuffer(fbo.msaaBuffer), fbo.msaaBuffer = null, fbo.blitFramebuffer && (fbo.blitFramebuffer.dispose(), fbo.blitFramebuffer = null)); 12627 const activeTextures = []; 12628 for (let i = 0; i < count; i++) { 12629 const texture = colorTextures[i], parentTexture = texture.parentTextureArray || texture; 12630 this.renderer.texture.bind(parentTexture, 0), i === 0 && fbo.msaaBuffer ? (gl.bindRenderbuffer(gl.RENDERBUFFER, fbo.msaaBuffer), gl.renderbufferStorageMultisample( 12631 gl.RENDERBUFFER, 12632 fbo.multisample, 12633 parentTexture._glTextures[this.CONTEXT_UID].internalFormat, 12634 framebuffer.width, 12635 framebuffer.height 12636 ), gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, fbo.msaaBuffer)) : (gl.framebufferTexture2D( 12637 gl.FRAMEBUFFER, 12638 gl.COLOR_ATTACHMENT0 + i, 12639 texture.target, 12640 parentTexture._glTextures[this.CONTEXT_UID].texture, 12641 mipLevel 12642 ), activeTextures.push(gl.COLOR_ATTACHMENT0 + i)); 12643 } 12644 if (activeTextures.length > 1 && gl.drawBuffers(activeTextures), framebuffer.depthTexture && this.writeDepthTexture) { 12645 const depthTexture = framebuffer.depthTexture; 12646 this.renderer.texture.bind(depthTexture, 0), gl.framebufferTexture2D( 12647 gl.FRAMEBUFFER, 12648 gl.DEPTH_ATTACHMENT, 12649 gl.TEXTURE_2D, 12650 depthTexture._glTextures[this.CONTEXT_UID].texture, 12651 mipLevel 12652 ); 12653 } 12654 if ((framebuffer.stencil || framebuffer.depth) && !(framebuffer.depthTexture && this.writeDepthTexture)) { 12655 fbo.stencil = fbo.stencil || gl.createRenderbuffer(); 12656 let stencilAttachment, stencilFormat; 12657 this.renderer.context.webGLVersion === 1 ? (stencilAttachment = gl.DEPTH_STENCIL_ATTACHMENT, stencilFormat = gl.DEPTH_STENCIL) : framebuffer.depth && framebuffer.stencil ? (stencilAttachment = gl.DEPTH_STENCIL_ATTACHMENT, stencilFormat = gl.DEPTH24_STENCIL8) : framebuffer.depth ? (stencilAttachment = gl.DEPTH_ATTACHMENT, stencilFormat = gl.DEPTH_COMPONENT24) : (stencilAttachment = gl.STENCIL_ATTACHMENT, stencilFormat = gl.STENCIL_INDEX8), gl.bindRenderbuffer(gl.RENDERBUFFER, fbo.stencil), fbo.msaaBuffer ? gl.renderbufferStorageMultisample( 12658 gl.RENDERBUFFER, 12659 fbo.multisample, 12660 stencilFormat, 12661 framebuffer.width, 12662 framebuffer.height 12663 ) : gl.renderbufferStorage(gl.RENDERBUFFER, stencilFormat, framebuffer.width, framebuffer.height), gl.framebufferRenderbuffer(gl.FRAMEBUFFER, stencilAttachment, gl.RENDERBUFFER, fbo.stencil); 12664 } else 12665 fbo.stencil && (gl.deleteRenderbuffer(fbo.stencil), fbo.stencil = null); 12666 } 12667 /** 12668 * Returns true if the frame buffer can be multisampled. 12669 * @param framebuffer 12670 */ 12671 canMultisampleFramebuffer(framebuffer) { 12672 return this.renderer.context.webGLVersion !== 1 && framebuffer.colorTextures.length <= 1 && !framebuffer.depthTexture; 12673 } 12674 /** 12675 * Detects number of samples that is not more than a param but as close to it as possible 12676 * @param samples - number of samples 12677 * @returns - recommended number of samples 12678 */ 12679 detectSamples(samples) { 12680 const { msaaSamples } = this; 12681 let res = MSAA_QUALITY.NONE; 12682 if (samples <= 1 || msaaSamples === null) 12683 return res; 12684 for (let i = 0; i < msaaSamples.length; i++) 12685 if (msaaSamples[i] <= samples) { 12686 res = msaaSamples[i]; 12687 break; 12688 } 12689 return res === 1 && (res = MSAA_QUALITY.NONE), res; 12690 } 12691 /** 12692 * Only works with WebGL2 12693 * 12694 * blits framebuffer to another of the same or bigger size 12695 * after that target framebuffer is bound 12696 * 12697 * Fails with WebGL warning if blits multisample framebuffer to different size 12698 * @param framebuffer - by default it blits "into itself", from renderBuffer to texture. 12699 * @param sourcePixels - source rectangle in pixels 12700 * @param destPixels - dest rectangle in pixels, assumed to be the same as sourcePixels 12701 */ 12702 blit(framebuffer, sourcePixels, destPixels) { 12703 const { current, renderer, gl, CONTEXT_UID } = this; 12704 if (renderer.context.webGLVersion !== 2 || !current) 12705 return; 12706 const fbo = current.glFramebuffers[CONTEXT_UID]; 12707 if (!fbo) 12708 return; 12709 if (!framebuffer) { 12710 if (!fbo.msaaBuffer) 12711 return; 12712 const colorTexture = current.colorTextures[0]; 12713 if (!colorTexture) 12714 return; 12715 fbo.blitFramebuffer || (fbo.blitFramebuffer = new Framebuffer(current.width, current.height), fbo.blitFramebuffer.addColorTexture(0, colorTexture)), framebuffer = fbo.blitFramebuffer, framebuffer.colorTextures[0] !== colorTexture && (framebuffer.colorTextures[0] = colorTexture, framebuffer.dirtyId++, framebuffer.dirtyFormat++), (framebuffer.width !== current.width || framebuffer.height !== current.height) && (framebuffer.width = current.width, framebuffer.he
vendor: 17,507 bytes, lines 12715-13059
12715ight = current.height, framebuffer.dirtyId++, framebuffer.dirtySize++); 12716 } 12717 sourcePixels || (sourcePixels = tempRectangle, sourcePixels.width = current.width, sourcePixels.height = current.height), destPixels || (destPixels = sourcePixels); 12718 const sameSize = sourcePixels.width === destPixels.width && sourcePixels.height === destPixels.height; 12719 this.bind(framebuffer), gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo.framebuffer), gl.blitFramebuffer( 12720 sourcePixels.left, 12721 sourcePixels.top, 12722 sourcePixels.right, 12723 sourcePixels.bottom, 12724 destPixels.left, 12725 destPixels.top, 12726 destPixels.right, 12727 destPixels.bottom, 12728 gl.COLOR_BUFFER_BIT, 12729 sameSize ? gl.NEAREST : gl.LINEAR 12730 ), gl.bindFramebuffer(gl.READ_FRAMEBUFFER, framebuffer.glFramebuffers[this.CONTEXT_UID].framebuffer); 12731 } 12732 /** 12733 * Disposes framebuffer. 12734 * @param framebuffer - framebuffer that has to be disposed of 12735 * @param contextLost - If context was lost, we suppress all delete function calls 12736 */ 12737 disposeFramebuffer(framebuffer, contextLost) { 12738 const fbo = framebuffer.glFramebuffers[this.CONTEXT_UID], gl = this.gl; 12739 if (!fbo) 12740 return; 12741 delete framebuffer.glFramebuffers[this.CONTEXT_UID]; 12742 const index = this.managedFramebuffers.indexOf(framebuffer); 12743 index >= 0 && this.managedFramebuffers.splice(index, 1), framebuffer.disposeRunner.remove(this), contextLost || (gl.deleteFramebuffer(fbo.framebuffer), fbo.msaaBuffer && gl.deleteRenderbuffer(fbo.msaaBuffer), fbo.stencil && gl.deleteRenderbuffer(fbo.stencil)), fbo.blitFramebuffer && this.disposeFramebuffer(fbo.blitFramebuffer, contextLost); 12744 } 12745 /** 12746 * Disposes all framebuffers, but not textures bound to them. 12747 * @param [contextLost=false] - If context was lost, we suppress all delete function calls 12748 */ 12749 disposeAll(contextLost) { 12750 const list = this.managedFramebuffers; 12751 this.managedFramebuffers = []; 12752 for (let i = 0; i < list.length; i++) 12753 this.disposeFramebuffer(list[i], contextLost); 12754 } 12755 /** 12756 * Forcing creation of stencil buffer for current framebuffer, if it wasn't done before. 12757 * Used by MaskSystem, when its time to use stencil mask for Graphics element. 12758 * 12759 * Its an alternative for public lazy `framebuffer.enableStencil`, in case we need stencil without rebind. 12760 * @private 12761 */ 12762 forceStencil() { 12763 const framebuffer = this.current; 12764 if (!framebuffer) 12765 return; 12766 const fbo = framebuffer.glFramebuffers[this.CONTEXT_UID]; 12767 if (!fbo || fbo.stencil && framebuffer.stencil) 12768 return; 12769 framebuffer.stencil = !0; 12770 const w = framebuffer.width, h = framebuffer.height, gl = this.gl, stencil = fbo.stencil = gl.createRenderbuffer(); 12771 gl.bindRenderbuffer(gl.RENDERBUFFER, stencil); 12772 let stencilAttachment, stencilFormat; 12773 this.renderer.context.webGLVersion === 1 ? (stencilAttachment = gl.DEPTH_STENCIL_ATTACHMENT, stencilFormat = gl.DEPTH_STENCIL) : framebuffer.depth ? (stencilAttachment = gl.DEPTH_STENCIL_ATTACHMENT, stencilFormat = gl.DEPTH24_STENCIL8) : (stencilAttachment = gl.STENCIL_ATTACHMENT, stencilFormat = gl.STENCIL_INDEX8), fbo.msaaBuffer ? gl.renderbufferStorageMultisample(gl.RENDERBUFFER, fbo.multisample, stencilFormat, w, h) : gl.renderbufferStorage(gl.RENDERBUFFER, stencilFormat, w, h), gl.framebufferRenderbuffer(gl.FRAMEBUFFER, stencilAttachment, gl.RENDERBUFFER, stencil); 12774 } 12775 /** Resets framebuffer stored state, binds screen framebuffer. Should be called before renderTexture reset(). */ 12776 reset() { 12777 this.current = this.unknownFramebuffer, this.viewport = new Rectangle(); 12778 } 12779 destroy() { 12780 this.renderer = null; 12781 } 12782} 12783FramebufferSystem.extension = { 12784 type: ExtensionType.RendererSystem, 12785 name: "framebuffer" 12786}; 12787extensions$1.add(FramebufferSystem); 12788 12789const byteSizeMap = { 5126: 4, 5123: 2, 5121: 1 }; 12790class GeometrySystem { 12791 /** @param renderer - The renderer this System works for. */ 12792 constructor(renderer) { 12793 this.renderer = renderer, this._activeGeometry = null, this._activeVao = null, this.hasVao = !0, this.hasInstance = !0, this.canUseUInt32ElementIndex = !1, this.managedGeometries = {}; 12794 } 12795 /** Sets up the renderer context and necessary buffers. */ 12796 contextChange() { 12797 this.disposeAll(!0); 12798 const gl = this.gl = this.renderer.gl, context = this.renderer.context; 12799 if (this.CONTEXT_UID = this.renderer.CONTEXT_UID, context.webGLVersion !== 2) { 12800 let nativeVaoExtension = this.renderer.context.extensions.vertexArrayObject; 12801 settings.PREFER_ENV === ENV.WEBGL_LEGACY && (nativeVaoExtension = null), nativeVaoExtension ? (gl.createVertexArray = () => nativeVaoExtension.createVertexArrayOES(), gl.bindVertexArray = (vao) => nativeVaoExtension.bindVertexArrayOES(vao), gl.deleteVertexArray = (vao) => nativeVaoExtension.deleteVertexArrayOES(vao)) : (this.hasVao = !1, gl.createVertexArray = () => null, gl.bindVertexArray = () => null, gl.deleteVertexArray = () => null); 12802 } 12803 if (context.webGLVersion !== 2) { 12804 const instanceExt = gl.getExtension("ANGLE_instanced_arrays"); 12805 instanceExt ? (gl.vertexAttribDivisor = (a, b) => instanceExt.vertexAttribDivisorANGLE(a, b), gl.drawElementsInstanced = (a, b, c, d, e) => instanceExt.drawElementsInstancedANGLE(a, b, c, d, e), gl.drawArraysInstanced = (a, b, c, d) => instanceExt.drawArraysInstancedANGLE(a, b, c, d)) : this.hasInstance = !1; 12806 } 12807 this.canUseUInt32ElementIndex = context.webGLVersion === 2 || !!context.extensions.uint32ElementIndex; 12808 } 12809 /** 12810 * Binds geometry so that is can be drawn. Creating a Vao if required 12811 * @param geometry - Instance of geometry to bind. 12812 * @param shader - Instance of shader to use vao for. 12813 */ 12814 bind(geometry, shader) { 12815 shader = shader || this.renderer.shader.shader; 12816 const { gl } = this; 12817 let vaos = geometry.glVertexArrayObjects[this.CONTEXT_UID], incRefCount = !1; 12818 vaos || (this.managedGeometries[geometry.id] = geometry, geometry.disposeRunner.add(this), geometry.glVertexArrayObjects[this.CONTEXT_UID] = vaos = {}, incRefCount = !0); 12819 const vao = vaos[shader.program.id] || this.initGeometryVao(geometry, shader, incRefCount); 12820 this._activeGeometry = geometry, this._activeVao !== vao && (this._activeVao = vao, this.hasVao ? gl.bindVertexArray(vao) : this.activateVao(geometry, shader.program)), this.updateBuffers(); 12821 } 12822 /** Reset and unbind any active VAO and geometry. */ 12823 reset() { 12824 this.unbind(); 12825 } 12826 /** Update buffers of the currently bound geometry. */ 12827 updateBuffers() { 12828 const geometry = this._activeGeometry, bufferSystem = this.renderer.buffer; 12829 for (let i = 0; i < geometry.buffers.length; i++) { 12830 const buffer = geometry.buffers[i]; 12831 bufferSystem.update(buffer); 12832 } 12833 } 12834 /** 12835 * Check compatibility between a geometry and a program 12836 * @param geometry - Geometry instance. 12837 * @param program - Program instance. 12838 */ 12839 checkCompatibility(geometry, program) { 12840 const geometryAttributes = geometry.attributes, shaderAttributes = program.attributeData; 12841 for (const j in shaderAttributes) 12842 if (!geometryAttributes[j]) 12843 throw new Error(`shader and geometry incompatible, geometry missing the "${j}" attribute`); 12844 } 12845 /** 12846 * Takes a geometry and program and generates a unique signature for them. 12847 * @param geometry - To get signature from. 12848 * @param program - To test geometry against. 12849 * @returns - Unique signature of the geometry and program 12850 */ 12851 getSignature(geometry, program) { 12852 const attribs = geometry.attributes, shaderAttributes = program.attributeData, strings = ["g", geometry.id]; 12853 for (const i in attribs) 12854 shaderAttributes[i] && strings.push(i, shaderAttributes[i].location); 12855 return strings.join("-"); 12856 } 12857 /** 12858 * Creates or gets Vao with the same structure as the geometry and stores it on the geometry. 12859 * If vao is created, it is bound automatically. We use a shader to infer what and how to set up the 12860 * attribute locations. 12861 * @param geometry - Instance of geometry to to generate Vao for. 12862 * @param shader - Instance of the shader. 12863 * @param incRefCount - Increment refCount of all geometry buffers. 12864 */ 12865 initGeometryVao(geometry, shader, incRefCount = !0) { 12866 const gl = this.gl, CONTEXT_UID = this.CONTEXT_UID, bufferSystem = this.renderer.buffer, program = shader.program; 12867 program.glPrograms[CONTEXT_UID] || this.renderer.shader.generateProgram(shader), this.checkCompatibility(geometry, program); 12868 const signature = this.getSignature(geometry, program), vaoObjectHash = geometry.glVertexArrayObjects[this.CONTEXT_UID]; 12869 let vao = vaoObjectHash[signature]; 12870 if (vao) 12871 return vaoObjectHash[program.id] = vao, vao; 12872 const buffers = geometry.buffers, attributes = geometry.attributes, tempStride = {}, tempStart = {}; 12873 for (const j in buffers) 12874 tempStride[j] = 0, tempStart[j] = 0; 12875 for (const j in attributes) 12876 !attributes[j].size && program.attributeData[j] ? attributes[j].size = program.attributeData[j].size : attributes[j].size || console.warn(`PIXI Geometry attribute '${j}' size cannot be determined (likely the bound shader does not have the attribute)`), tempStride[attributes[j].buffer] += attributes[j].size * byteSizeMap[attributes[j].type]; 12877 for (const j in attributes) { 12878 const attribute = attributes[j], attribSize = attribute.size; 12879 attribute.stride === void 0 && (tempStride[attribute.buffer] === attribSize * byteSizeMap[attribute.type] ? attribute.stride = 0 : attribute.stride = tempStride[attribute.buffer]), attribute.start === void 0 && (attribute.start = tempStart[attribute.buffer], tempStart[attribute.buffer] += attribSize * byteSizeMap[attribute.type]); 12880 } 12881 vao = gl.createVertexArray(), gl.bindVertexArray(vao); 12882 for (let i = 0; i < buffers.length; i++) { 12883 const buffer = buffers[i]; 12884 bufferSystem.bind(buffer), incRefCount && buffer._glBuffers[CONTEXT_UID].refCount++; 12885 } 12886 return this.activateVao(geometry, program), vaoObjectHash[program.id] = vao, vaoObjectHash[signature] = vao, gl.bindVertexArray(null), bufferSystem.unbind(BUFFER_TYPE.ARRAY_BUFFER), vao; 12887 } 12888 /** 12889 * Disposes geometry. 12890 * @param geometry - Geometry with buffers. Only VAO will be disposed 12891 * @param [contextLost=false] - If context was lost, we suppress deleteVertexArray 12892 */ 12893 disposeGeometry(geometry, contextLost) { 12894 if (!this.managedGeometries[geometry.id]) 12895 return; 12896 delete this.managedGeometries[geometry.id]; 12897 const vaos = geometry.glVertexArrayObjects[this.CONTEXT_UID], gl = this.gl, buffers = geometry.buffers, bufferSystem = this.renderer?.buffer; 12898 if (geometry.disposeRunner.remove(this), !!vaos) { 12899 if (bufferSystem) 12900 for (let i = 0; i < buffers.length; i++) { 12901 const buf = buffers[i]._glBuffers[this.CONTEXT_UID]; 12902 buf && (buf.refCount--, buf.refCount === 0 && !contextLost && bufferSystem.dispose(buffers[i], contextLost)); 12903 } 12904 if (!contextLost) { 12905 for (const vaoId in vaos) 12906 if (vaoId[0] === "g") { 12907 const vao = vaos[vaoId]; 12908 this._activeVao === vao && this.unbind(), gl.deleteVertexArray(vao); 12909 } 12910 } 12911 delete geometry.glVertexArrayObjects[this.CONTEXT_UID]; 12912 } 12913 } 12914 /** 12915 * Dispose all WebGL resources of all managed geometries. 12916 * @param [contextLost=false] - If context was lost, we suppress `gl.delete` calls 12917 */ 12918 disposeAll(contextLost) { 12919 const all = Object.keys(this.managedGeometries); 12920 for (let i = 0; i < all.length; i++) 12921 this.disposeGeometry(this.managedGeometries[all[i]], contextLost); 12922 } 12923 /** 12924 * Activate vertex array object. 12925 * @param geometry - Geometry instance. 12926 * @param program - Shader program instance. 12927 */ 12928 activateVao(geometry, program) { 12929 const gl = this.gl, CONTEXT_UID = this.CONTEXT_UID, bufferSystem = this.renderer.buffer, buffers = geometry.buffers, attributes = geometry.attributes; 12930 geometry.indexBuffer && bufferSystem.bind(geometry.indexBuffer); 12931 let lastBuffer = null; 12932 for (const j in attributes) { 12933 const attribute = attributes[j], buffer = buffers[attribute.buffer], glBuffer = buffer._glBuffers[CONTEXT_UID]; 12934 if (program.attributeData[j]) { 12935 lastBuffer !== glBuffer && (bufferSystem.bind(buffer), lastBuffer = glBuffer); 12936 const location = program.attributeData[j].location; 12937 if (gl.enableVertexAttribArray(location), gl.vertexAttribPointer( 12938 location, 12939 attribute.size, 12940 attribute.type || gl.FLOAT, 12941 attribute.normalized, 12942 attribute.stride, 12943 attribute.start 12944 ), attribute.instance) 12945 if (this.hasInstance) 12946 gl.vertexAttribDivisor(location, attribute.divisor); 12947 else 12948 throw new Error("geometry error, GPU Instancing is not supported on this device"); 12949 } 12950 } 12951 } 12952 /** 12953 * Draws the currently bound geometry. 12954 * @param type - The type primitive to render. 12955 * @param size - The number of elements to be rendered. If not specified, all vertices after the 12956 * starting vertex will be drawn. 12957 * @param start - The starting vertex in the geometry to start drawing from. If not specified, 12958 * drawing will start from the first vertex. 12959 * @param instanceCount - The number of instances of the set of elements to execute. If not specified, 12960 * all instances will be drawn. 12961 */ 12962 draw(type, size, start, instanceCount) { 12963 const { gl } = this, geometry = this._activeGeometry; 12964 if (geometry.indexBuffer) { 12965 const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT, glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; 12966 byteSize === 2 || byteSize === 4 && this.canUseUInt32ElementIndex ? geometry.instanced ? gl.drawElementsInstanced(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount || 1) : gl.drawElements(type, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize) : console.warn("unsupported index buffer type: uint32"); 12967 } else 12968 geometry.instanced ? gl.drawArraysInstanced(type, start, size || geometry.getSize(), instanceCount || 1) : gl.drawArrays(type, start, size || geometry.getSize()); 12969 return this; 12970 } 12971 /** Unbind/reset everything. */ 12972 unbind() { 12973 this.gl.bindVertexArray(null), this._activeVao = null, this._activeGeometry = null; 12974 } 12975 destroy() { 12976 this.renderer = null; 12977 } 12978} 12979GeometrySystem.extension = { 12980 type: ExtensionType.RendererSystem, 12981 name: "geometry" 12982}; 12983extensions$1.add(GeometrySystem); 12984 12985const tempMat$1 = new Matrix(); 12986class TextureMatrix { 12987 /** 12988 * @param texture - observed texture 12989 * @param clampMargin - Changes frame clamping, 0.5 by default. Use -0.5 for extra border. 12990 */ 12991 constructor(texture, clampMargin) { 12992 this._texture = texture, this.mapCoord = new Matrix(), this.uClampFrame = new Float32Array(4), this.uClampOffset = new Float32Array(2), this._textureID = -1, this._updateID = 0, this.clampOffset = 0, this.clampMargin = typeof clampMargin > "u" ? 0.5 : clampMargin, this.isSimple = !1; 12993 } 12994 /** Texture property. */ 12995 get texture() { 12996 return this._texture; 12997 } 12998 set texture(value) { 12999 this._texture = value, this._textureID = -1; 13000 } 13001 /** 13002 * Multiplies uvs array to transform 13003 * @param uvs - mesh uvs 13004 * @param [out=uvs] - output 13005 * @returns - output 13006 */ 13007 multiplyUvs(uvs, out) { 13008 out === void 0 && (out = uvs); 13009 const mat = this.mapCoord; 13010 for (let i = 0; i < uvs.length; i += 2) { 13011 const x = uvs[i], y = uvs[i + 1]; 13012 out[i] = x * mat.a + y * mat.c + mat.tx, out[i + 1] = x * mat.b + y * mat.d + mat.ty; 13013 } 13014 return out; 13015 } 13016 /** 13017 * Updates matrices if texture was changed. 13018 * @param [forceUpdate=false] - if true, matrices will be updated any case 13019 * @returns - Whether or not it was updated 13020 */ 13021 update(forceUpdate) { 13022 const tex = this._texture; 13023 if (!tex || !tex.valid || !forceUpdate && this._textureID === tex._updateID) 13024 return !1; 13025 this._textureID = tex._updateID, this._updateID++; 13026 const uvs = tex._uvs; 13027 this.mapCoord.set(uvs.x1 - uvs.x0, uvs.y1 - uvs.y0, uvs.x3 - uvs.x0, uvs.y3 - uvs.y0, uvs.x0, uvs.y0); 13028 const orig = tex.orig, trim = tex.trim; 13029 trim && (tempMat$1.set( 13030 orig.width / trim.width, 13031 0, 13032 0, 13033 orig.height / trim.height, 13034 -trim.x / trim.width, 13035 -trim.y / trim.height 13036 ), this.mapCoord.append(tempMat$1)); 13037 const texBase = tex.baseTexture, frame = this.uClampFrame, margin = this.clampMargin / texBase.resolution, offset = this.clampOffset; 13038 return frame[0] = (tex._frame.x + margin + offset) / texBase.width, frame[1] = (tex._frame.y + margin + offset) / texBase.height, frame[2] = (tex._frame.x + tex._frame.width - margin + offset) / texBase.width, frame[3] = (tex._frame.y + tex._frame.height - margin + offset) / texBase.height, this.uClampOffset[0] = offset / texBase.realWidth, this.uClampOffset[1] = offset / texBase.realHeight, this.isSimple = tex._frame.width === texBase.width && tex._frame.height === texBase.height && tex.rotate === 0, !0; 13039 } 13040} 13041 13042var fragment$7 = `varying vec2 vMaskCoord; 13043varying vec2 vTextureCoord; 13044 13045uniform sampler2D uSampler; 13046uniform sampler2D mask; 13047uniform float alpha; 13048uniform float npmAlpha; 13049uniform vec4 maskClamp; 13050 13051void main(void) 13052{ 13053 float clip = step(3.5, 13054 step(maskClamp.x, vMaskCoord.x) + 13055 step(maskClamp.y, vMaskCoord.y) + 13056 step(vMaskCoord.x, maskClamp.z) + 13057 step(vMaskCoord.y, maskClamp.w)); 13058 13059 vec4 original = texture2D(uSampler, vTextureCoord);
13060 vec4 masky = texture2D(mask, vMaskCoord); 13061 float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a); 13062 13063 original *= (alphaMul * masky.r * alpha * clip); 13064 13065 gl_FragColor = original; 13066} 13067`; 13068 13069var vertex$4 = `attribute vec2 aVertexPosition; 13070attribute vec2 aTextureCoord; 13071 13072uniform mat3 projectionMatrix; 13073uniform mat3 otherMatrix; 13074 13075varying vec2 vMaskCoord; 13076varying vec2 vTextureCoord; 13077 13078void main(void) 13079{ 13080 gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); 13081 13082 vTextureCoord = aTextureCoord; 13083 vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; 13084} 13085`; 13086 13087class SpriteMaskFilter extends Filter { 13088 /** @ignore */ 13089 constructor(vertexSrc, fragmentSrc, uniforms) { 13090 let sprite = null; 13091 typeof vertexSrc != "string" && fragmentSrc === void 0 && uniforms === void 0 && (sprite = vertexSrc, vertexSrc = void 0, fragmentSrc = void 0, uniforms = void 0), super(vertexSrc || vertex$4, fragmentSrc || fragment$7, uniforms), this.maskSprite = sprite, this.maskMatrix = new Matrix(); 13092 } 13093 /** 13094 * Sprite mask 13095 * @type {PIXI.DisplayObject} 13096 */ 13097 get maskSprite() { 13098 return this._maskSprite; 13099 } 13100 set maskSprite(value) { 13101 this._maskSprite = value, this._maskSprite && (this._maskSprite.renderable = !1); 13102 } 13103 /** 13104 * Applies the filter 13105 * @param filterManager - The renderer to retrieve the filter from 13106 * @param input - The input render target. 13107 * @param output - The target to output to. 13108 * @param clearMode - Should the output be cleared before rendering to it. 13109 */ 13110 apply(filterManager, input, output, clearMode) { 13111 const maskSprite = this._maskSprite, tex = maskSprite._texture; 13112 tex.valid && (tex.uvMatrix || (tex.uvMatrix = new TextureMatrix(tex, 0)), tex.uvMatrix.update(), this.uniforms.npmAlpha = tex.baseTexture.alphaMode ? 0 : 1, this.uniforms.mask = tex, this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite).prepend(tex.uvMatrix.mapCoord), this.uniforms.alpha = maskSprite.worldAlpha, this.uniforms.maskClamp = tex.uvMatrix.uClampFrame, filterManager.applyFilter(this, input, output, clearMode)); 13113 } 13114} 13115 13116class MaskData { 13117 /** 13118 * Create MaskData 13119 * @param {PIXI.DisplayObject} [maskObject=null] - object that describes the mask 13120 */ 13121 constructor(maskObject = null) { 13122 this.type = MASK_TYPES.NONE, this.autoDetect = !0, this.maskObject = maskObject || null, this.pooled = !1, this.isMaskData = !0, this.resolution = null, this.multisample = Filter.defaultMultisample, this.enabled = !0, this.colorMask = 15, this._filters = null, this._stencilCounter = 0, this._scissorCounter = 0, this._scissorRect = null, this._scissorRectLocal = null, this._colorMask = 15, this._target = null; 13123 } 13124 /** 13125 * The sprite mask filter. 13126 * If set to `null`, the default sprite mask filter is used. 13127 * @default null 13128 */ 13129 get filter() { 13130 return this._filters ? this._filters[0] : null; 13131 } 13132 set filter(value) { 13133 value ? this._filters ? this._filters[0] = value : this._filters = [value] : this._filters = null; 13134 } 13135 /** Resets the mask data after popMask(). */ 13136 reset() { 13137 this.pooled && (this.maskObject = null, this.type = MASK_TYPES.NONE, this.autoDetect = !0), this._target = null, this._scissorRectLocal = null; 13138 } 13139 /** 13140 * Copies counters from maskData above, called from pushMask(). 13141 * @param maskAbove 13142 */ 13143 copyCountersOrReset(maskAbove) { 13144 maskAbove ? (this._stencilCounter = maskAbove._stencilCounter, this._scissorCounter = maskAbove._scissorCounter, this._scissorRect = maskAbove._scissorRect) : (this._stencilCounter = 0, this._scissorCounter = 0, this._scissorRect = null); 13145 } 13146} 13147 13148class MaskSystem { 13149 /** 13150 * @param renderer - The renderer this System works for. 13151 */ 13152 constructor(renderer) { 13153 this.renderer = renderer, this.enableScissor = !0, this.alphaMaskPool = [], this.maskDataPool = [], this.maskStack = [], this.alphaMaskIndex = 0; 13154 } 13155 /** 13156 * Changes the mask stack that is used by this System. 13157 * @param maskStack - The mask stack 13158 */ 13159 setMaskStack(maskStack) { 13160 this.maskStack = maskStack, this.renderer.scissor.setMaskStack(maskStack), this.renderer.stencil.setMaskStack(maskStack); 13161 } 13162 /** 13163 * Enables the mask and appends it to the current mask stack. 13164 * 13165 * NOTE: The batch renderer should be flushed beforehand to prevent pending renders from being masked. 13166 * @param {PIXI.DisplayObject} target - Display Object to push the mask to 13167 * @param {PIXI.MaskData|PIXI.Sprite|PIXI.Graphics|PIXI.DisplayObject} maskDataOrTarget - The masking data. 13168 */ 13169 push(target, maskDataOrTarget) { 13170 let maskData = maskDataOrTarget; 13171 if (!maskData.isMaskData) { 13172 const d = this.maskDataPool.pop() || new MaskData(); 13173 d.pooled = !0, d.maskObject = maskDataOrTarget, maskData = d; 13174 } 13175 const maskAbove = this.maskStack.length !== 0 ? this.maskStack[this.maskStack.length - 1] : null; 13176 if (maskData.copyCountersOrReset(maskAbove), maskData._colorMask = maskAbove ? maskAbove._colorMask : 15, maskData.autoDetect && this.detect(maskData), maskData._target = target, maskData.type !== MASK_TYPES.SPRITE && this.maskStack.push(maskData), maskData.enabled) 13177 switch (maskData.type) { 13178 case MASK_TYPES.SCISSOR: 13179 this.renderer.scissor.push(maskData); 13180 break; 13181 case MASK_TYPES.STENCIL: 13182 this.renderer.stencil.push(maskData); 13183 break; 13184 case MASK_TYPES.SPRITE: 13185 maskData.copyCountersOrReset(null), this.pushSpriteMask(maskData); 13186 break; 13187 case MASK_TYPES.COLOR: 13188 this.pushColorMask(maskData); 13189 break; 13190 } 13191 maskData.type === MASK_TYPES.SPRITE && this.maskStack.push(maskData); 13192 } 13193 /** 13194 * Removes the last mask from the mask stack and doesn't return it. 13195 * 13196 * NOTE: The batch renderer should be flushed beforehand to render the masked contents before the mask is removed. 13197 * @param {PIXI.IMaskTarget} target - Display Object to pop the mask from 13198 */ 13199 pop(target) { 13200 const maskData = this.maskStack.pop(); 13201 if (!(!maskData || maskData._target !== target)) { 13202 if (maskData.enabled) 13203 switch (maskData.type) { 13204 case MASK_TYPES.SCISSOR: 13205 this.renderer.scissor.pop(maskData); 13206 break; 13207 case MASK_TYPES.STENCIL: 13208 this.renderer.stencil.pop(maskData.maskObject); 13209 break; 13210 case MASK_TYPES.SPRITE: 13211 this.popSpriteMask(maskData); 13212 break; 13213 case MASK_TYPES.COLOR: 13214 this.popColorMask(maskData); 13215 break; 13216 } 13217 if (maskData.reset(), maskData.pooled && this.maskDataPool.push(maskData), this.maskStack.length !== 0) { 13218 const maskCurrent = this.maskStack[this.maskStack.length - 1]; 13219 maskCurrent.type === MASK_TYPES.SPRITE && maskCurrent._filters && (maskCurrent._filters[0].maskSprite = maskCurrent.maskObject); 13220 } 13221 } 13222 } 13223 /** 13224 * Sets type of MaskData based on its maskObject. 13225 * @param maskData 13226 */ 13227 detect(maskData) { 13228 const maskObject = maskData.maskObject; 13229 maskObject ? maskObject.isSprite ? maskData.type = MASK_TYPES.SPRITE : this.enableScissor && this.renderer.scissor.testScissor(maskData) ? maskData.type = MASK_TYPES.SCISSOR : maskData.type = MASK_TYPES.STENCIL : maskData.type = MASK_TYPES.COLOR; 13230 } 13231 /** 13232 * Applies the Mask and adds it to the current filter stack. 13233 * @param maskData - Sprite to be used as the mask. 13234 */ 13235 pushSpriteMask(maskData) { 13236 const { maskObject } = maskData, target = maskData._target; 13237 let alphaMaskFilter = maskData._filters;
vendor: 4,411 bytes, lines 13238-13352
13238 alphaMaskFilter || (alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex], alphaMaskFilter || (alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new SpriteMaskFilter()])), alphaMaskFilter[0].resolution = maskData.resolution, alphaMaskFilter[0].multisample = maskData.multisample, alphaMaskFilter[0].maskSprite = maskObject; 13239 const stashFilterArea = target.filterArea; 13240 target.filterArea = maskObject.getBounds(!0), this.renderer.filter.push(target, alphaMaskFilter), target.filterArea = stashFilterArea, maskData._filters || this.alphaMaskIndex++; 13241 } 13242 /** 13243 * Removes the last filter from the filter stack and doesn't return it. 13244 * @param maskData - Sprite to be used as the mask. 13245 */ 13246 popSpriteMask(maskData) { 13247 this.renderer.filter.pop(), maskData._filters ? maskData._filters[0].maskSprite = null : (this.alphaMaskIndex--, this.alphaMaskPool[this.alphaMaskIndex][0].maskSprite = null); 13248 } 13249 /** 13250 * Pushes the color mask. 13251 * @param maskData - The mask data 13252 */ 13253 pushColorMask(maskData) { 13254 const currColorMask = maskData._colorMask, nextColorMask = maskData._colorMask = currColorMask & maskData.colorMask; 13255 nextColorMask !== currColorMask && this.renderer.gl.colorMask( 13256 (nextColorMask & 1) !== 0, 13257 (nextColorMask & 2) !== 0, 13258 (nextColorMask & 4) !== 0, 13259 (nextColorMask & 8) !== 0 13260 ); 13261 } 13262 /** 13263 * Pops the color mask. 13264 * @param maskData - The mask data 13265 */ 13266 popColorMask(maskData) { 13267 const currColorMask = maskData._colorMask, nextColorMask = this.maskStack.length > 0 ? this.maskStack[this.maskStack.length - 1]._colorMask : 15; 13268 nextColorMask !== currColorMask && this.renderer.gl.colorMask( 13269 (nextColorMask & 1) !== 0, 13270 (nextColorMask & 2) !== 0, 13271 (nextColorMask & 4) !== 0, 13272 (nextColorMask & 8) !== 0 13273 ); 13274 } 13275 destroy() { 13276 this.renderer = null; 13277 } 13278} 13279MaskSystem.extension = { 13280 type: ExtensionType.RendererSystem, 13281 name: "mask" 13282}; 13283extensions$1.add(MaskSystem); 13284 13285class AbstractMaskSystem { 13286 /** 13287 * @param renderer - The renderer this System works for. 13288 */ 13289 constructor(renderer) { 13290 this.renderer = renderer, this.maskStack = [], this.glConst = 0; 13291 } 13292 /** Gets count of masks of certain type. */ 13293 getStackLength() { 13294 return this.maskStack.length; 13295 } 13296 /** 13297 * Changes the mask stack that is used by this System. 13298 * @param {PIXI.MaskData[]} maskStack - The mask stack 13299 */ 13300 setMaskStack(maskStack) { 13301 const { gl } = this.renderer, curStackLen = this.getStackLength(); 13302 this.maskStack = maskStack; 13303 const newStackLen = this.getStackLength(); 13304 newStackLen !== curStackLen && (newStackLen === 0 ? gl.disable(this.glConst) : (gl.enable(this.glConst), this._useCurrent())); 13305 } 13306 /** 13307 * Setup renderer to use the current mask data. 13308 * @private 13309 */ 13310 _useCurrent() { 13311 } 13312 /** Destroys the mask stack. */ 13313 destroy() { 13314 this.renderer = null, this.maskStack = null; 13315 } 13316} 13317 13318const tempMatrix$1 = new Matrix(), rectPool = [], _ScissorSystem = class _ScissorSystem2 extends AbstractMaskSystem { 13319 /** 13320 * @param {PIXI.Renderer} renderer - The renderer this System works for. 13321 */ 13322 constructor(renderer) { 13323 super(renderer), this.glConst = settings.ADAPTER.getWebGLRenderingContext().SCISSOR_TEST; 13324 } 13325 getStackLength() { 13326 const maskData = this.maskStack[this.maskStack.length - 1]; 13327 return maskData ? maskData._scissorCounter : 0; 13328 } 13329 /** 13330 * evaluates _boundsTransformed, _scissorRect for MaskData 13331 * @param maskData 13332 */ 13333 calcScissorRect(maskData) { 13334 if (maskData._scissorRectLocal) 13335 return; 13336 const prevData = maskData._scissorRect, { maskObject } = maskData, { renderer } = this, renderTextureSystem = renderer.renderTexture, rect = maskObject.getBounds(!0, rectPool.pop() ?? new Rectangle()); 13337 this.roundFrameToPixels( 13338 rect, 13339 renderTextureSystem.current ? renderTextureSystem.current.resolution : renderer.resolution, 13340 renderTextureSystem.sourceFrame, 13341 renderTextureSystem.destinationFrame, 13342 renderer.projection.transform 13343 ), prevData && rect.fit(prevData), maskData._scissorRectLocal = rect; 13344 } 13345 static isMatrixRotated(matrix) { 13346 if (!matrix) 13347 return !1; 13348 const { a, b, c, d } = matrix; 13349 return (Math.abs(b) > 1e-4 || Math.abs(c) > 1e-4) && (Math.abs(a) > 1e-4 || Math.abs(d) > 1e-4); 13350 } 13351 /** 13352 * Test, whether the object can be scissor mask with current renderer projection.
vendor: 5,167 bytes, lines 13353-13458
13353 * Calls "calcScissorRect()" if its true. 13354 * @param maskData - mask data 13355 * @returns whether Whether the object can be scissor mask 13356 */ 13357 testScissor(maskData) { 13358 const { maskObject } = maskData; 13359 if (!maskObject.isFastRect || !maskObject.isFastRect() || _ScissorSystem2.isMatrixRotated(maskObject.worldTransform) || _ScissorSystem2.isMatrixRotated(this.renderer.projection.transform)) 13360 return !1; 13361 this.calcScissorRect(maskData); 13362 const rect = maskData._scissorRectLocal; 13363 return rect.width > 0 && rect.height > 0; 13364 } 13365 roundFrameToPixels(frame, resolution, bindingSourceFrame, bindingDestinationFrame, transform) { 13366 _ScissorSystem2.isMatrixRotated(transform) || (transform = transform ? tempMatrix$1.copyFrom(transform) : tempMatrix$1.identity(), transform.translate(-bindingSourceFrame.x, -bindingSourceFrame.y).scale( 13367 bindingDestinationFrame.width / bindingSourceFrame.width, 13368 bindingDestinationFrame.height / bindingSourceFrame.height 13369 ).translate(bindingDestinationFrame.x, bindingDestinationFrame.y), this.renderer.filter.transformAABB(transform, frame), frame.fit(bindingDestinationFrame), frame.x = Math.round(frame.x * resolution), frame.y = Math.round(frame.y * resolution), frame.width = Math.round(frame.width * resolution), frame.height = Math.round(frame.height * resolution)); 13370 } 13371 /** 13372 * Applies the Mask and adds it to the current stencil stack. 13373 * @author alvin 13374 * @param maskData - The mask data. 13375 */ 13376 push(maskData) { 13377 maskData._scissorRectLocal || this.calcScissorRect(maskData); 13378 const { gl } = this.renderer; 13379 maskData._scissorRect || gl.enable(gl.SCISSOR_TEST), maskData._scissorCounter++, maskData._scissorRect = maskData._scissorRectLocal, this._useCurrent(); 13380 } 13381 /** 13382 * This should be called after a mask is popped off the mask stack. It will rebind the scissor box to be latest with the 13383 * last mask in the stack. 13384 * 13385 * This can also be called when you directly modify the scissor box and want to restore PixiJS state. 13386 * @param maskData - The mask data. 13387 */ 13388 pop(maskData) { 13389 const { gl } = this.renderer; 13390 maskData && rectPool.push(maskData._scissorRectLocal), this.getStackLength() > 0 ? this._useCurrent() : gl.disable(gl.SCISSOR_TEST); 13391 } 13392 /** 13393 * Setup renderer to use the current scissor data. 13394 * @private 13395 */ 13396 _useCurrent() { 13397 const rect = this.maskStack[this.maskStack.length - 1]._scissorRect; 13398 let y; 13399 this.renderer.renderTexture.current ? y = rect.y : y = this.renderer.height - rect.height - rect.y, this.renderer.gl.scissor(rect.x, y, rect.width, rect.height); 13400 } 13401}; 13402_ScissorSystem.extension = { 13403 type: ExtensionType.RendererSystem, 13404 name: "scissor" 13405}; 13406let ScissorSystem = _ScissorSystem; 13407extensions$1.add(ScissorSystem); 13408 13409class StencilSystem extends AbstractMaskSystem { 13410 /** 13411 * @param renderer - The renderer this System works for. 13412 */ 13413 constructor(renderer) { 13414 super(renderer), this.glConst = settings.ADAPTER.getWebGLRenderingContext().STENCIL_TEST; 13415 } 13416 getStackLength() { 13417 const maskData = this.maskStack[this.maskStack.length - 1]; 13418 return maskData ? maskData._stencilCounter : 0; 13419 } 13420 /** 13421 * Applies the Mask and adds it to the current stencil stack. 13422 * @param maskData - The mask data 13423 */ 13424 push(maskData) { 13425 const maskObject = maskData.maskObject, { gl } = this.renderer, prevMaskCount = maskData._stencilCounter; 13426 prevMaskCount === 0 && (this.renderer.framebuffer.forceStencil(), gl.clearStencil(0), gl.clear(gl.STENCIL_BUFFER_BIT), gl.enable(gl.STENCIL_TEST)), maskData._stencilCounter++; 13427 const colorMask = maskData._colorMask; 13428 colorMask !== 0 && (maskData._colorMask = 0, gl.colorMask(!1, !1, !1, !1)), gl.stencilFunc(gl.EQUAL, prevMaskCount, 4294967295), gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR), maskObject.renderable = !0, maskObject.render(this.renderer), this.renderer.batch.flush(), maskObject.renderable = !1, colorMask !== 0 && (maskData._colorMask = colorMask, gl.colorMask( 13429 (colorMask & 1) !== 0, 13430 (colorMask & 2) !== 0, 13431 (colorMask & 4) !== 0, 13432 (colorMask & 8) !== 0 13433 )), this._useCurrent(); 13434 } 13435 /** 13436 * Pops stencil mask. MaskData is already removed from stack 13437 * @param {PIXI.DisplayObject} maskObject - object of popped mask data 13438 */ 13439 pop(maskObject) { 13440 const gl = this.renderer.gl; 13441 if (this.getStackLength() === 0) 13442 gl.disable(gl.STENCIL_TEST); 13443 else { 13444 const maskData = this.maskStack.length !== 0 ? this.maskStack[this.maskStack.length - 1] : null, colorMask = maskData ? maskData._colorMask : 15; 13445 colorMask !== 0 && (maskData._colorMask = 0, gl.colorMask(!1, !1, !1, !1)), gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR), maskObject.renderable = !0, maskObject.render(this.renderer), this.renderer.batch.flush(), maskObject.renderable = !1, colorMask !== 0 && (maskData._colorMask = colorMask, gl.colorMask( 13446 (colorMask & 1) !== 0, 13447 (colorMask & 2) !== 0, 13448 (colorMask & 4) !== 0, 13449 (colorMask & 8) !== 0 13450 )), this._useCurrent(); 13451 } 13452 } 13453 /** 13454 * Setup renderer to use the current stencil data. 13455 * @private 13456 */ 13457 _useCurrent() { 13458 const gl = this.renderer.gl;
vendor: 1,817 bytes, lines 13459-13520
13459 gl.stencilFunc(gl.EQUAL, this.getStackLength(), 4294967295), gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); 13460 } 13461} 13462StencilSystem.extension = { 13463 type: ExtensionType.RendererSystem, 13464 name: "stencil" 13465}; 13466extensions$1.add(StencilSystem); 13467 13468class PluginSystem { 13469 constructor(renderer) { 13470 this.renderer = renderer, this.plugins = {}, Object.defineProperties(this.plugins, { 13471 extract: { 13472 enumerable: !1, 13473 get() { 13474 return deprecation("7.0.0", "renderer.plugins.extract has moved to renderer.extract"), renderer.extract; 13475 } 13476 }, 13477 prepare: { 13478 enumerable: !1, 13479 get() { 13480 return deprecation("7.0.0", "renderer.plugins.prepare has moved to renderer.prepare"), renderer.prepare; 13481 } 13482 }, 13483 interaction: { 13484 enumerable: !1, 13485 get() { 13486 return deprecation("7.0.0", "renderer.plugins.interaction has been deprecated, use renderer.events"), renderer.events; 13487 } 13488 } 13489 }); 13490 } 13491 /** 13492 * Initialize the plugins. 13493 * @protected 13494 */ 13495 init() { 13496 const staticMap = this.rendererPlugins; 13497 for (const o in staticMap) 13498 this.plugins[o] = new staticMap[o](this.renderer); 13499 } 13500 destroy() { 13501 for (const o in this.plugins) 13502 this.plugins[o].destroy(), this.plugins[o] = null; 13503 } 13504} 13505PluginSystem.extension = { 13506 type: [ 13507 ExtensionType.RendererSystem, 13508 ExtensionType.CanvasRendererSystem 13509 ], 13510 name: "_plugin" 13511}; 13512extensions$1.add(PluginSystem); 13513 13514class ProjectionSystem { 13515 /** @param renderer - The renderer this System works for. */ 13516 constructor(renderer) { 13517 this.renderer = renderer, this.destinationFrame = null, this.sourceFrame = null, this.defaultFrame = null, this.projectionMatrix = new Matrix(), this.transform = null; 13518 } 13519 /** 13520 * Updates the projection-matrix based on the sourceFrame → de
13520stinationFrame mapping provided. 13521 * 13522 * NOTE: It is expected you call `renderer.framebuffer.setViewport(destinationFrame)` after this. This is because 13523 * the framebuffer viewport converts shader vertex output in normalized device coordinates to window coordinates. 13524 * 13525 * NOTE-2: {@link PIXI.RenderTextureSystem#bind} updates the projection-matrix when you bind a render-texture. 13526 * It is expected 13527 * that you dirty the current bindings when calling this manually. 13528 * @param destinationFrame - The rectangle in the render-target to render the contents into. If rendering to the canvas, 13529 * the origin is on the top-left; if rendering to a render-texture, the origin is on the bottom-left. 13530 * @param sourceFrame - The rectangle in world space that contains the contents being rendered. 13531 * @param resolution - The resolution of the render-target, which is the ratio of 13532 * world-space (or CSS) pixels to physical pixels. 13533 * @param root - Whether the render-target is the screen. This is required because rendering to textures 13534 * is y-flipped (i.e. upside down relative to the screen). 13535 */ 13536 update(destinationFrame, sourceFrame, resolution, root) { 13537 this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame, this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame, this.calculateProjection(this.destinationFrame, this.sourceFrame, resolution, root), this.transform && this.projectionMatrix.append(this.transform); 13538 const renderer = this.renderer; 13539 renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix, renderer.globalUniforms.update(), renderer.shader.shader && renderer.shader.syncUniformGroup(renderer.shader.shader.uniforms.globals); 13540 } 13541 /** 13542 * Calculates the `projectionMatrix` to map points inside `sourceFrame` to inside `destinationFrame`. 13543 * @param _destinationFrame - The destination frame in the render-target. 13544 * @param sourceFrame - The source frame in world space. 13545 * @param _resolution - The render-target's resolution, i.e. ratio of CSS to physical pixels. 13546 * @param root - Whether rendering into the screen. Otherwise, if rendering to a framebuffer, the projection 13547 * is y-flipped. 13548 */ 13549 calculateProjection(_destinationFrame, sourceFrame, _resolution, root) { 13550 const pm = this.projectionMatrix, sign = root ? -1 : 1; 13551 pm.identity(), pm.a = 1 / sourceFrame.width * 2, pm.d = sign * (1 / sourceFrame.height * 2), pm.tx = -1 - sourceFrame.x * pm.a, pm.ty = -sign - sourceFrame.y * pm.d; 13552 } 13553 /** 13554 * Sets the transform of the active render target to the given matrix. 13555 * @param _matrix - The transformation matrix 13556 */ 13557 setTransform(_matrix) { 13558 } 13559 destroy() { 13560 this.renderer = null; 13561 } 13562} 13563ProjectionSystem.extension = { 13564 type: ExtensionType.RendererSystem, 13565 name: "projection" 13566}; 13567extensions$1.add(ProjectionSystem); 13568 13569const tempTransform = new Transform(), tempRect$1 = new Rectangle(); 13570class GenerateTextureSystem { 13571 constructor(renderer) { 13572 this.renderer = renderer, this._tempMatrix = new Matrix(); 13573 } 13574 /** 13575 * A Useful function that returns a texture of the display object that can then be used to create sprites 13576 * This can be quite useful if your displayObject is complicated and needs to be reused multiple times. 13577 * @param displayObject - The displayObject the object will be generated from. 13578 * @param {IGenerateTextureOptions} options - Generate texture options. 13579 * @param {PIXI.Rectangle} options.region - The region of the displayObject, that shall be rendered, 13580 * if no region is specified, defaults to the local bounds of the displayObject. 13581 * @param {number} [options.resolution] - If not given, the renderer's resolution is used. 13582 * @param {PIXI.MSAA_QUALITY} [options.multisample] - If not given, the renderer's multisample is used. 13583 * @returns a shiny new texture of the display object passed in 13584 */ 13585 generateTexture(displayObject, options) { 13586 const { region: manualRegion, ...textureOptions } = options || {}, region = manualRegion?.copyTo(tempRect$1) || displayObject.getLocalBounds(tempRect$1, !0), resolution = textureOptions.resolution || this.renderer.resolution; 13587 region.width = Math.max(region.width, 1 / resolution), region.height = Math.max(region.height, 1 / resolution), textureOptions.width = region.width, textureOptions.height = region.height, textureOptions.resolution = resolution, textureOptions.multisample ?? (textureOptions.multisample = this.renderer.multisample); 13588 const renderTexture = RenderTexture.create(textureOptions); 13589 this._tempMatrix.tx = -region.x, this._tempMatrix.ty = -region.y; 13590 const transform = displayObject.transform;
vendor: 7,526 bytes, lines 13591-13725
13591 return displayObject.transform = tempTransform, this.renderer.render(displayObject, { 13592 renderTexture, 13593 transform: this._tempMatrix, 13594 skipUpdateTransform: !!displayObject.parent, 13595 blit: !0 13596 }), displayObject.transform = transform, renderTexture; 13597 } 13598 destroy() { 13599 } 13600} 13601GenerateTextureSystem.extension = { 13602 type: [ 13603 ExtensionType.RendererSystem, 13604 ExtensionType.CanvasRendererSystem 13605 ], 13606 name: "textureGenerator" 13607}; 13608extensions$1.add(GenerateTextureSystem); 13609 13610const tempRect = new Rectangle(), tempRect2 = new Rectangle(); 13611class RenderTextureSystem { 13612 /** 13613 * @param renderer - The renderer this System works for. 13614 */ 13615 constructor(renderer) { 13616 this.renderer = renderer, this.defaultMaskStack = [], this.current = null, this.sourceFrame = new Rectangle(), this.destinationFrame = new Rectangle(), this.viewportFrame = new Rectangle(); 13617 } 13618 contextChange() { 13619 const attributes = this.renderer?.gl.getContextAttributes(); 13620 this._rendererPremultipliedAlpha = !!(attributes && attributes.alpha && attributes.premultipliedAlpha); 13621 } 13622 /** 13623 * Bind the current render texture. 13624 * @param renderTexture - RenderTexture to bind, by default its `null` - the screen. 13625 * @param sourceFrame - Part of world that is mapped to the renderTexture. 13626 * @param destinationFrame - Part of renderTexture, by default it has the same size as sourceFrame. 13627 */ 13628 bind(renderTexture = null, sourceFrame, destinationFrame) { 13629 const renderer = this.renderer; 13630 this.current = renderTexture; 13631 let baseTexture, framebuffer, resolution; 13632 renderTexture ? (baseTexture = renderTexture.baseTexture, resolution = baseTexture.resolution, sourceFrame || (tempRect.width = renderTexture.frame.width, tempRect.height = renderTexture.frame.height, sourceFrame = tempRect), destinationFrame || (tempRect2.x = renderTexture.frame.x, tempRect2.y = renderTexture.frame.y, tempRect2.width = sourceFrame.width, tempRect2.height = sourceFrame.height, destinationFrame = tempRect2), framebuffer = baseTexture.framebuffer) : (resolution = renderer.resolution, sourceFrame || (tempRect.width = renderer._view.screen.width, tempRect.height = renderer._view.screen.height, sourceFrame = tempRect), destinationFrame || (destinationFrame = tempRect, destinationFrame.width = sourceFrame.width, destinationFrame.height = sourceFrame.height)); 13633 const viewportFrame = this.viewportFrame; 13634 viewportFrame.x = destinationFrame.x * resolution, viewportFrame.y = destinationFrame.y * resolution, viewportFrame.width = destinationFrame.width * resolution, viewportFrame.height = destinationFrame.height * resolution, renderTexture || (viewportFrame.y = renderer.view.height - (viewportFrame.y + viewportFrame.height)), viewportFrame.ceil(), this.renderer.framebuffer.bind(framebuffer, viewportFrame), this.renderer.projection.update(destinationFrame, sourceFrame, resolution, !framebuffer), renderTexture ? this.renderer.mask.setMaskStack(baseTexture.maskStack) : this.renderer.mask.setMaskStack(this.defaultMaskStack), this.sourceFrame.copyFrom(sourceFrame), this.destinationFrame.copyFrom(destinationFrame); 13635 } 13636 /** 13637 * Erases the render texture and fills the drawing area with a colour. 13638 * @param clearColor - The color as rgba, default to use the renderer backgroundColor 13639 * @param [mask=BUFFER_BITS.COLOR | BUFFER_BITS.DEPTH] - Bitwise OR of masks 13640 * that indicate the buffers to be cleared, by default COLOR and DEPTH buffers. 13641 */ 13642 clear(clearColor, mask) { 13643 const fallbackColor = this.current ? this.current.baseTexture.clear : this.renderer.background.backgroundColor, color = Color.shared.setValue(clearColor || fallbackColor); 13644 (this.current && this.current.baseTexture.alphaMode > 0 || !this.current && this._rendererPremultipliedAlpha) && color.premultiply(color.alpha); 13645 const destinationFrame = this.destinationFrame, baseFrame = this.current ? this.current.baseTexture : this.renderer._view.screen, clearMask = destinationFrame.width !== baseFrame.width || destinationFrame.height !== baseFrame.height; 13646 if (clearMask) { 13647 let { x, y, width, height } = this.viewportFrame; 13648 x = Math.round(x), y = Math.round(y), width = Math.round(width), height = Math.round(height), this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST), this.renderer.gl.scissor(x, y, width, height); 13649 } 13650 this.renderer.framebuffer.clear(color.red, color.green, color.blue, color.alpha, mask), clearMask && this.renderer.scissor.pop(); 13651 } 13652 resize() { 13653 this.bind(null); 13654 } 13655 /** Resets render-texture state. */ 13656 reset() { 13657 this.bind(null); 13658 } 13659 destroy() { 13660 this.renderer = null; 13661 } 13662} 13663RenderTextureSystem.extension = { 13664 type: ExtensionType.RendererSystem, 13665 name: "renderTexture" 13666}; 13667extensions$1.add(RenderTextureSystem); 13668 13669class GLProgram { 13670 /** 13671 * Makes a new Pixi program. 13672 * @param program - webgl program 13673 * @param uniformData - uniforms 13674 */ 13675 constructor(program, uniformData) { 13676 this.program = program, this.uniformData = uniformData, this.uniformGroups = {}, this.uniformDirtyGroups = {}, this.uniformBufferBindings = {}; 13677 } 13678 /** Destroys this program. */ 13679 destroy() { 13680 this.uniformData = null, this.uniformGroups = null, this.uniformDirtyGroups = null, this.uniformBufferBindings = null, this.program = null; 13681 } 13682} 13683 13684function getAttributeData(program, gl) { 13685 const attributes = {}, totalAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); 13686 for (let i = 0; i < totalAttributes; i++) { 13687 const attribData = gl.getActiveAttrib(program, i); 13688 if (attribData.name.startsWith("gl_")) 13689 continue; 13690 const type = mapType(gl, attribData.type), data = { 13691 type, 13692 name: attribData.name, 13693 size: mapSize(type), 13694 location: gl.getAttribLocation(program, attribData.name) 13695 }; 13696 attributes[attribData.name] = data; 13697 } 13698 return attributes; 13699} 13700 13701function getUniformData(program, gl) { 13702 const uniforms = {}, totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); 13703 for (let i = 0; i < totalUniforms; i++) { 13704 const uniformData = gl.getActiveUniform(program, i), name = uniformData.name.replace(/\[.*?\]$/, ""), isArray = !!uniformData.name.match(/\[.*?\]$/), type = mapType(gl, uniformData.type); 13705 uniforms[name] = { 13706 name, 13707 index: i, 13708 type, 13709 size: uniformData.size, 13710 isArray, 13711 value: defaultValue(type, uniformData.size) 13712 }; 13713 } 13714 return uniforms; 13715} 13716 13717function generateProgram(gl, program) { 13718 const glVertShader = compileShader(gl, gl.VERTEX_SHADER, program.vertexSrc), glFragShader = compileShader(gl, gl.FRAGMENT_SHADER, program.fragmentSrc), webGLProgram = gl.createProgram(); 13719 gl.attachShader(webGLProgram, glVertShader), gl.attachShader(webGLProgram, glFragShader); 13720 const transformFeedbackVaryings = program.extra?.transformFeedbackVaryings; 13721 if (transformFeedbackVaryings && (typeof gl.transformFeedbackVaryings != "function" ? console.warn("TransformFeedback is not supported but TransformFeedbackVaryings are given.") : gl.transformFeedbackVaryings( 13722 webGLProgram, 13723 transformFeedbackVaryings.names, 13724 transformFeedbackVaryings.bufferMode === "separate" ? gl.SEPARATE_ATTRIBS : gl.INTERLEAVED_ATTRIBS 13725 )), gl.linkProgram(webGLProgram), gl.getProgramParameter(webGLProgram, gl.LINK_STATUS) || logProgramError(gl, webGLProgram, glVertShader, glFragShader), program.attributeData = getAttributeData(webGLProgram, gl), program.uniformData = getUniformData(webGLProgram, gl), !/^[ \t]*#[ \t]*version[ \t]+300[ \t]+es[ \t]*$/m.test(program.vertexSrc)) {
vendor: 8,977 bytes, lines 13726-13980
13726 const keys = Object.keys(program.attributeData); 13727 keys.sort((a, b) => a > b ? 1 : -1); 13728 for (let i = 0; i < keys.length; i++) 13729 program.attributeData[keys[i]].location = i, gl.bindAttribLocation(webGLProgram, i, keys[i]); 13730 gl.linkProgram(webGLProgram); 13731 } 13732 gl.deleteShader(glVertShader), gl.deleteShader(glFragShader); 13733 const uniformData = {}; 13734 for (const i in program.uniformData) { 13735 const data = program.uniformData[i]; 13736 uniformData[i] = { 13737 location: gl.getUniformLocation(webGLProgram, i), 13738 value: defaultValue(data.type, data.size) 13739 }; 13740 } 13741 return new GLProgram(webGLProgram, uniformData); 13742} 13743 13744function uboUpdate(_ud, _uv, _renderer, _syncData, buffer) { 13745 _renderer.buffer.update(buffer); 13746} 13747const UBO_TO_SINGLE_SETTERS = { 13748 float: ` 13749 data[offset] = v; 13750 `, 13751 vec2: ` 13752 data[offset] = v[0]; 13753 data[offset+1] = v[1]; 13754 `, 13755 vec3: ` 13756 data[offset] = v[0]; 13757 data[offset+1] = v[1]; 13758 data[offset+2] = v[2]; 13759 13760 `, 13761 vec4: ` 13762 data[offset] = v[0]; 13763 data[offset+1] = v[1]; 13764 data[offset+2] = v[2]; 13765 data[offset+3] = v[3]; 13766 `, 13767 mat2: ` 13768 data[offset] = v[0]; 13769 data[offset+1] = v[1]; 13770 13771 data[offset+4] = v[2]; 13772 data[offset+5] = v[3]; 13773 `, 13774 mat3: ` 13775 data[offset] = v[0]; 13776 data[offset+1] = v[1]; 13777 data[offset+2] = v[2]; 13778 13779 data[offset + 4] = v[3]; 13780 data[offset + 5] = v[4]; 13781 data[offset + 6] = v[5]; 13782 13783 data[offset + 8] = v[6]; 13784 data[offset + 9] = v[7]; 13785 data[offset + 10] = v[8]; 13786 `, 13787 mat4: ` 13788 for(var i = 0; i < 16; i++) 13789 { 13790 data[offset + i] = v[i]; 13791 } 13792 ` 13793}, GLSL_TO_STD40_SIZE = { 13794 float: 4, 13795 vec2: 8, 13796 vec3: 12, 13797 vec4: 16, 13798 int: 4, 13799 ivec2: 8, 13800 ivec3: 12, 13801 ivec4: 16, 13802 uint: 4, 13803 uvec2: 8, 13804 uvec3: 12, 13805 uvec4: 16, 13806 bool: 4, 13807 bvec2: 8, 13808 bvec3: 12, 13809 bvec4: 16, 13810 mat2: 16 * 2, 13811 mat3: 16 * 3, 13812 mat4: 16 * 4 13813}; 13814function createUBOElements(uniformData) { 13815 const uboElements = uniformData.map((data) => ({ 13816 data, 13817 offset: 0, 13818 dataLen: 0, 13819 dirty: 0 13820 })); 13821 let size = 0, chunkSize = 0, offset = 0; 13822 for (let i = 0; i < uboElements.length; i++) { 13823 const uboElement = uboElements[i]; 13824 if (size = GLSL_TO_STD40_SIZE[uboElement.data.type], uboElement.data.size > 1 && (size = Math.max(size, 16) * uboElement.data.size), uboElement.dataLen = size, chunkSize % size !== 0 && chunkSize < 16) { 13825 const lineUpValue = chunkSize % size % 16; 13826 chunkSize += lineUpValue, offset += lineUpValue; 13827 } 13828 chunkSize + size > 16 ? (offset = Math.ceil(offset / 16) * 16, uboElement.offset = offset, offset += size, chunkSize = size) : (uboElement.offset = offset, chunkSize += size, offset += size); 13829 } 13830 return offset = Math.ceil(offset / 16) * 16, { uboElements, size: offset }; 13831} 13832function getUBOData(uniforms, uniformData) { 13833 const usedUniformDatas = []; 13834 for (const i in uniforms) 13835 uniformData[i] && usedUniformDatas.push(uniformData[i]); 13836 return usedUniformDatas.sort((a, b) => a.index - b.index), usedUniformDatas; 13837} 13838function generateUniformBufferSync(group, uniformData) { 13839 if (!group.autoManage) 13840 return { size: 0, syncFunc: uboUpdate }; 13841 const usedUniformDatas = getUBOData(group.uniforms, uniformData), { uboElements, size } = createUBOElements(usedUniformDatas), funcFragments = [` 13842 var v = null; 13843 var v2 = null; 13844 var cv = null; 13845 var t = 0; 13846 var gl = renderer.gl 13847 var index = 0; 13848 var data = buffer.data; 13849 `]; 13850 for (let i = 0; i < uboElements.length; i++) { 13851 const uboElement = uboElements[i], uniform = group.uniforms[uboElement.data.name], name = uboElement.data.name; 13852 let parsed = !1; 13853 for (let j = 0; j < uniformParsers.length; j++) { 13854 const uniformParser = uniformParsers[j]; 13855 if (uniformParser.codeUbo && uniformParser.test(uboElement.data, uniform)) { 13856 funcFragments.push( 13857 `offset = ${uboElement.offset / 4};`, 13858 uniformParsers[j].codeUbo(uboElement.data.name, uniform) 13859 ), parsed = !0; 13860 break; 13861 } 13862 } 13863 if (!parsed) 13864 if (uboElement.data.size > 1) { 13865 const size2 = mapSize(uboElement.data.type), rowSize = Math.max(GLSL_TO_STD40_SIZE[uboElement.data.type] / 16, 1), elementSize = size2 / rowSize, remainder = (4 - elementSize % 4) % 4; 13866 funcFragments.push(` 13867 cv = ud.${name}.value; 13868 v = uv.${name}; 13869 offset = ${uboElement.offset / 4}; 13870 13871 t = 0; 13872 13873 for(var i=0; i < ${uboElement.data.size * rowSize}; i++) 13874 { 13875 for(var j = 0; j < ${elementSize}; j++) 13876 { 13877 data[offset++] = v[t++]; 13878 } 13879 offset += ${remainder}; 13880 } 13881 13882 `); 13883 } else { 13884 const template = UBO_TO_SINGLE_SETTERS[uboElement.data.type]; 13885 funcFragments.push(` 13886 cv = ud.${name}.value; 13887 v = uv.${name}; 13888 offset = ${uboElement.offset / 4}; 13889 ${template}; 13890 `); 13891 } 13892 } 13893 return funcFragments.push(` 13894 renderer.buffer.update(buffer); 13895 `), { 13896 size, 13897 // eslint-disable-next-line no-new-func 13898 syncFunc: new Function( 13899 "ud", 13900 "uv", 13901 "renderer", 13902 "syncData", 13903 "buffer", 13904 funcFragments.join(` 13905`) 13906 ) 13907 }; 13908} 13909 13910let UID = 0; 13911const defaultSyncData = { textureCount: 0, uboCount: 0 }; 13912class ShaderSystem { 13913 /** @param renderer - The renderer this System works for. */ 13914 constructor(renderer) { 13915 this.destroyed = !1, this.renderer = renderer, this.systemCheck(), this.gl = null, this.shader = null, this.program = null, this.cache = {}, this._uboCache = {}, this.id = UID++; 13916 } 13917 /** 13918 * Overrideable function by `@pixi/unsafe-eval` to silence 13919 * throwing an error if platform doesn't support unsafe-evals. 13920 * @private 13921 */ 13922 systemCheck() { 13923 if (!unsafeEvalSupported()) 13924 throw new Error("Current environment does not allow unsafe-eval, please use @pixi/unsafe-eval module to enable support."); 13925 } 13926 contextChange(gl) { 13927 this.gl = gl, this.reset(); 13928 } 13929 /** 13930 * Changes the current shader to the one given in parameter. 13931 * @param shader - the new shader 13932 * @param dontSync - false if the shader should automatically sync its uniforms. 13933 * @returns the glProgram that belongs to the shader. 13934 */ 13935 bind(shader, dontSync) { 13936 shader.disposeRunner.add(this), shader.uniforms.globals = this.renderer.globalUniforms; 13937 const program = shader.program, glProgram = program.glPrograms[this.renderer.CONTEXT_UID] || this.generateProgram(shader); 13938 return this.shader = shader, this.program !== program && (this.program = program, this.gl.useProgram(glProgram.program)), dontSync || (defaultSyncData.textureCount = 0, defaultSyncData.uboCount = 0, this.syncUniformGroup(shader.uniformGroup, defaultSyncData)), glProgram; 13939 } 13940 /** 13941 * Uploads the uniforms values to the currently bound shader. 13942 * @param uniforms - the uniforms values that be applied to the current shader 13943 */ 13944 setUniforms(uniforms) { 13945 const shader = this.shader.program, glProgram = shader.glPrograms[this.renderer.CONTEXT_UID]; 13946 shader.syncUniforms(glProgram.uniformData, uniforms, this.renderer); 13947 } 13948 /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ 13949 /** 13950 * Syncs uniforms on the group 13951 * @param group - the uniform group to sync 13952 * @param syncData - this is data that is passed to the sync function and any nested sync functions 13953 */ 13954 syncUniformGroup(group, syncData) { 13955 const glProgram = this.getGlProgram(); 13956 (!group.static || group.dirtyId !== glProgram.uniformDirtyGroups[group.id]) && (glProgram.uniformDirtyGroups[group.id] = group.dirtyId, this.syncUniforms(group, glProgram, syncData)); 13957 } 13958 /** 13959 * Overrideable by the @pixi/unsafe-eval package to use static syncUniforms instead. 13960 * @param group 13961 * @param glProgram 13962 * @param syncData 13963 */ 13964 syncUniforms(group, glProgram, syncData) { 13965 (group.syncUniforms[this.shader.program.id] || this.createSyncGroups(group))(glProgram.uniformData, group.uniforms, this.renderer, syncData); 13966 } 13967 createSyncGroups(group) { 13968 const id = this.getSignature(group, this.shader.program.uniformData, "u"); 13969 return this.cache[id] || (this.cache[id] = generateUniformsSync(group, this.shader.program.uniformData)), group.syncUniforms[this.shader.program.id] = this.cache[id], group.syncUniforms[this.shader.program.id]; 13970 } 13971 /** 13972 * Syncs uniform buffers 13973 * @param group - the uniform buffer group to sync 13974 * @param name - the name of the uniform buffer 13975 */ 13976 syncUniformBufferGroup(group, name) { 13977 const glProgram = this.getGlProgram(); 13978 if (!group.static || group.dirtyId !== 0 || !glProgram.uniformGroups[group.id]) { 13979 group.dirtyId = 0; 13980 const syncFunc = glProgram.uniformGroups[group.id] || this.createSyncBufferGroup(group, glProgram, name);
vendor: 6,894 bytes, lines 13981-14105
13981 group.buffer.update(), syncFunc( 13982 glProgram.uniformData, 13983 group.uniforms, 13984 this.renderer, 13985 defaultSyncData, 13986 group.buffer 13987 ); 13988 } 13989 this.renderer.buffer.bindBufferBase(group.buffer, glProgram.uniformBufferBindings[name]); 13990 } 13991 /** 13992 * Will create a function that uploads a uniform buffer using the STD140 standard. 13993 * The upload function will then be cached for future calls 13994 * If a group is manually managed, then a simple upload function is generated 13995 * @param group - the uniform buffer group to sync 13996 * @param glProgram - the gl program to attach the uniform bindings to 13997 * @param name - the name of the uniform buffer (must exist on the shader) 13998 */ 13999 createSyncBufferGroup(group, glProgram, name) { 14000 const { gl } = this.renderer; 14001 this.renderer.buffer.bind(group.buffer); 14002 const uniformBlockIndex = this.gl.getUniformBlockIndex(glProgram.program, name); 14003 glProgram.uniformBufferBindings[name] = this.shader.uniformBindCount, gl.uniformBlockBinding(glProgram.program, uniformBlockIndex, this.shader.uniformBindCount), this.shader.uniformBindCount++; 14004 const id = this.getSignature(group, this.shader.program.uniformData, "ubo"); 14005 let uboData = this._uboCache[id]; 14006 if (uboData || (uboData = this._uboCache[id] = generateUniformBufferSync(group, this.shader.program.uniformData)), group.autoManage) { 14007 const data = new Float32Array(uboData.size / 4); 14008 group.buffer.update(data); 14009 } 14010 return glProgram.uniformGroups[group.id] = uboData.syncFunc, glProgram.uniformGroups[group.id]; 14011 } 14012 /** 14013 * Takes a uniform group and data and generates a unique signature for them. 14014 * @param group - The uniform group to get signature of 14015 * @param group.uniforms 14016 * @param uniformData - Uniform information generated by the shader 14017 * @param preFix 14018 * @returns Unique signature of the uniform group 14019 */ 14020 getSignature(group, uniformData, preFix) { 14021 const uniforms = group.uniforms, strings = [`${preFix}-`]; 14022 for (const i in uniforms) 14023 strings.push(i), uniformData[i] && strings.push(uniformData[i].type); 14024 return strings.join("-"); 14025 } 14026 /** 14027 * Returns the underlying GLShade rof the currently bound shader. 14028 * 14029 * This can be handy for when you to have a little more control over the setting of your uniforms. 14030 * @returns The glProgram for the currently bound Shader for this context 14031 */ 14032 getGlProgram() { 14033 return this.shader ? this.shader.program.glPrograms[this.renderer.CONTEXT_UID] : null; 14034 } 14035 /** 14036 * Generates a glProgram version of the Shader provided. 14037 * @param shader - The shader that the glProgram will be based on. 14038 * @returns A shiny new glProgram! 14039 */ 14040 generateProgram(shader) { 14041 const gl = this.gl, program = shader.program, glProgram = generateProgram(gl, program); 14042 return program.glPrograms[this.renderer.CONTEXT_UID] = glProgram, glProgram; 14043 } 14044 /** Resets ShaderSystem state, does not affect WebGL state. */ 14045 reset() { 14046 this.program = null, this.shader = null; 14047 } 14048 /** 14049 * Disposes shader. 14050 * If disposing one equals with current shader, set current as null. 14051 * @param shader - Shader object 14052 */ 14053 disposeShader(shader) { 14054 this.shader === shader && (this.shader = null); 14055 } 14056 /** Destroys this System and removes all its textures. */ 14057 destroy() { 14058 this.renderer = null, this.destroyed = !0; 14059 } 14060} 14061ShaderSystem.extension = { 14062 type: ExtensionType.RendererSystem, 14063 name: "shader" 14064}; 14065extensions$1.add(ShaderSystem); 14066 14067class StartupSystem { 14068 constructor(renderer) { 14069 this.renderer = renderer; 14070 } 14071 /** 14072 * It all starts here! This initiates every system, passing in the options for any system by name. 14073 * @param options - the config for the renderer and all its systems 14074 */ 14075 run(options) { 14076 const { renderer } = this; 14077 renderer.runners.init.emit(renderer.options), options.hello && console.log(`PixiJS 7.3.2 - ${renderer.rendererLogId} - https://pixijs.com`), renderer.resize(renderer.screen.width, renderer.screen.height); 14078 } 14079 destroy() { 14080 } 14081} 14082StartupSystem.defaultOptions = { 14083 /** 14084 * {@link PIXI.IRendererOptions.hello} 14085 * @default false 14086 * @memberof PIXI.settings.RENDER_OPTIONS 14087 */ 14088 hello: !1 14089}, /** @ignore */ 14090StartupSystem.extension = { 14091 type: [ 14092 ExtensionType.RendererSystem, 14093 ExtensionType.CanvasRendererSystem 14094 ], 14095 name: "startup" 14096}; 14097extensions$1.add(StartupSystem); 14098 14099function mapWebGLBlendModesToPixi(gl, array = []) { 14100 return array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.ADD] = [gl.ONE, gl.ONE], array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.NONE] = [0, 0], array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE], array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.SRC_IN] = [gl.DST_ALPHA, gl.ZERO], array[BLEND_MODES.SRC_OUT] = [gl.ONE_MINUS_DST_ALPHA, gl.ZERO], array[BLEND_MODES.SRC_ATOP] = [gl.DST_ALPHA, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.DST_OVER] = [gl.ONE_MINUS_DST_ALPHA, gl.ONE], array[BLEND_MODES.DST_IN] = [gl.ZERO, gl.SRC_ALPHA], array[BLEND_MODES.DST_OUT] = [gl.ZERO, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.DST_ATOP] = [gl.ONE_MINUS_DST_ALPHA, gl.SRC_ALPHA], array[BLEND_MODES.XOR] = [gl.ONE_MINUS_DST_ALPHA, gl.ONE_MINUS_SRC_ALPHA], array[BLEND_MODES.SUBTRACT] = [gl.ONE, gl.ONE, gl.ONE, gl.ONE, gl.FUNC_REVERSE_SUBTRACT, gl.FUNC_ADD], array; 14101} 14102 14103const BLEND = 0, OFFSET = 1, CULLING = 2, DEPTH_TEST = 3, WINDING = 4, DEPTH_MASK = 5, _StateSystem = class _StateSystem2 { 14104 constructor() { 14105 this.gl = null, this.stateId = 0, this.polygonOffset = 0, this.blendMode = BLEND_MODES.NONE, this._blendEq = !1, this.map = [], this.map[BLEND] = this.setBlend, this.map[OFFSET] = this.setOffset, this.map[CULLING]
vendor: 5,076 bytes, lines 14105-14244
14105= this.setCullFace, this.map[DEPTH_TEST] = this.setDepthTest, this.map[WINDING] = this.setFrontFace, this.map[DEPTH_MASK] = this.setDepthMask, this.checks = [], this.defaultState = new State(), this.defaultState.blend = !0; 14106 } 14107 contextChange(gl) { 14108 this.gl = gl, this.blendModes = mapWebGLBlendModesToPixi(gl), this.set(this.defaultState), this.reset(); 14109 } 14110 /** 14111 * Sets the current state 14112 * @param {*} state - The state to set. 14113 */ 14114 set(state) { 14115 if (state = state || this.defaultState, this.stateId !== state.data) { 14116 let diff = this.stateId ^ state.data, i = 0; 14117 for (; diff; ) 14118 diff & 1 && this.map[i].call(this, !!(state.data & 1 << i)), diff = diff >> 1, i++; 14119 this.stateId = state.data; 14120 } 14121 for (let i = 0; i < this.checks.length; i++) 14122 this.checks[i](this, state); 14123 } 14124 /** 14125 * Sets the state, when previous state is unknown. 14126 * @param {*} state - The state to set 14127 */ 14128 forceState(state) { 14129 state = state || this.defaultState; 14130 for (let i = 0; i < this.map.length; i++) 14131 this.map[i].call(this, !!(state.data & 1 << i)); 14132 for (let i = 0; i < this.checks.length; i++) 14133 this.checks[i](this, state); 14134 this.stateId = state.data; 14135 } 14136 /** 14137 * Sets whether to enable or disable blending. 14138 * @param value - Turn on or off WebGl blending. 14139 */ 14140 setBlend(value) { 14141 this.updateCheck(_StateSystem2.checkBlendMode, value), this.gl[value ? "enable" : "disable"](this.gl.BLEND); 14142 } 14143 /** 14144 * Sets whether to enable or disable polygon offset fill. 14145 * @param value - Turn on or off webgl polygon offset testing. 14146 */ 14147 setOffset(value) { 14148 this.updateCheck(_StateSystem2.checkPolygonOffset, value), this.gl[value ? "enable" : "disable"](this.gl.POLYGON_OFFSET_FILL); 14149 } 14150 /** 14151 * Sets whether to enable or disable depth test. 14152 * @param value - Turn on or off webgl depth testing. 14153 */ 14154 setDepthTest(value) { 14155 this.gl[value ? "enable" : "disable"](this.gl.DEPTH_TEST); 14156 } 14157 /** 14158 * Sets whether to enable or disable depth mask. 14159 * @param value - Turn on or off webgl depth mask. 14160 */ 14161 setDepthMask(value) { 14162 this.gl.depthMask(value); 14163 } 14164 /** 14165 * Sets whether to enable or disable cull face. 14166 * @param {boolean} value - Turn on or off webgl cull face. 14167 */ 14168 setCullFace(value) { 14169 this.gl[value ? "enable" : "disable"](this.gl.CULL_FACE); 14170 } 14171 /** 14172 * Sets the gl front face. 14173 * @param {boolean} value - true is clockwise and false is counter-clockwise 14174 */ 14175 setFrontFace(value) { 14176 this.gl.frontFace(this.gl[value ? "CW" : "CCW"]); 14177 } 14178 /** 14179 * Sets the blend mode. 14180 * @param {number} value - The blend mode to set to. 14181 */ 14182 setBlendMode(value) { 14183 if (value === this.blendMode) 14184 return; 14185 this.blendMode = value; 14186 const mode = this.blendModes[value], gl = this.gl; 14187 mode.length === 2 ? gl.blendFunc(mode[0], mode[1]) : gl.blendFuncSeparate(mode[0], mode[1], mode[2], mode[3]), mode.length === 6 ? (this._blendEq = !0, gl.blendEquationSeparate(mode[4], mode[5])) : this._blendEq && (this._blendEq = !1, gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD)); 14188 } 14189 /** 14190 * Sets the polygon offset. 14191 * @param {number} value - the polygon offset 14192 * @param {number} scale - the polygon offset scale 14193 */ 14194 setPolygonOffset(value, scale) { 14195 this.gl.polygonOffset(value, scale); 14196 } 14197 // used 14198 /** Resets all the logic and disables the VAOs. */ 14199 reset() { 14200 this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, !1), this.forceState(this.defaultState), this._blendEq = !0, this.blendMode = -1, this.setBlendMode(0); 14201 } 14202 /** 14203 * Checks to see which updates should be checked based on which settings have been activated. 14204 * 14205 * For example, if blend is enabled then we should check the blend modes each time the state is changed 14206 * or if polygon fill is activated then we need to check if the polygon offset changes. 14207 * The idea is that we only check what we have too. 14208 * @param func - the checking function to add or remove 14209 * @param value - should the check function be added or removed. 14210 */ 14211 updateCheck(func, value) { 14212 const index = this.checks.indexOf(func); 14213 value && index === -1 ? this.checks.push(func) : !value && index !== -1 && this.checks.splice(index, 1); 14214 } 14215 /** 14216 * A private little wrapper function that we call to check the blend mode. 14217 * @param system - the System to perform the state check on 14218 * @param state - the state that the blendMode will pulled from 14219 */ 14220 static checkBlendMode(system, state) { 14221 system.setBlendMode(state.blendMode); 14222 } 14223 /** 14224 * A private little wrapper function that we call to check the polygon offset. 14225 * @param system - the System to perform the state check on 14226 * @param state - the state that the blendMode will pulled from 14227 */ 14228 static checkPolygonOffset(system, state) { 14229 system.setPolygonOffset(1, state.polygonOffset); 14230 } 14231 /** 14232 * @ignore 14233 */ 14234 destroy() { 14235 this.gl = null; 14236 } 14237}; 14238_StateSystem.extension = { 14239 type: ExtensionType.RendererSystem, 14240 name: "state" 14241}; 14242let StateSystem = _StateSystem; 14243extensions$1.add(StateSystem); 14244
vendor: 6,066 bytes, lines 14245-14401
14245class SystemManager extends EventEmitter { 14246 constructor() { 14247 super(...arguments), this.runners = {}, this._systemsHash = {}; 14248 } 14249 /** 14250 * Set up a system with a collection of SystemClasses and runners. 14251 * Systems are attached dynamically to this class when added. 14252 * @param config - the config for the system manager 14253 */ 14254 setup(config) { 14255 this.addRunners(...config.runners); 14256 const priority = (config.priority ?? []).filter((key) => config.systems[key]), orderByPriority = [ 14257 ...priority, 14258 ...Object.keys(config.systems).filter((key) => !priority.includes(key)) 14259 ]; 14260 for (const i of orderByPriority) 14261 this.addSystem(config.systems[i], i); 14262 } 14263 /** 14264 * Create a bunch of runners based of a collection of ids 14265 * @param runnerIds - the runner ids to add 14266 */ 14267 addRunners(...runnerIds) { 14268 runnerIds.forEach((runnerId) => { 14269 this.runners[runnerId] = new Runner(runnerId); 14270 }); 14271 } 14272 /** 14273 * Add a new system to the renderer. 14274 * @param ClassRef - Class reference 14275 * @param name - Property name for system, if not specified 14276 * will use a static `name` property on the class itself. This 14277 * name will be assigned as s property on the Renderer so make 14278 * sure it doesn't collide with properties on Renderer. 14279 * @returns Return instance of renderer 14280 */ 14281 addSystem(ClassRef, name) { 14282 const system = new ClassRef(this); 14283 if (this[name]) 14284 throw new Error(`Whoops! The name "${name}" is already in use`); 14285 this[name] = system, this._systemsHash[name] = system; 14286 for (const i in this.runners) 14287 this.runners[i].add(system); 14288 return this; 14289 } 14290 /** 14291 * A function that will run a runner and call the runners function but pass in different options 14292 * to each system based on there name. 14293 * 14294 * E.g. If you have two systems added called `systemA` and `systemB` you could call do the following: 14295 * 14296 * ```js 14297 * system.emitWithCustomOptions(init, { 14298 * systemA: {...optionsForA}, 14299 * systemB: {...optionsForB}, 14300 * }); 14301 * ``` 14302 * 14303 * `init` would be called on system A passing `optionsForA` and on system B passing `optionsForB`. 14304 * @param runner - the runner to target 14305 * @param options - key value options for each system 14306 */ 14307 emitWithCustomOptions(runner, options) { 14308 const systemHashKeys = Object.keys(this._systemsHash); 14309 runner.items.forEach((system) => { 14310 const systemName = systemHashKeys.find((systemId) => this._systemsHash[systemId] === system); 14311 system[runner.name](options[systemName]); 14312 }); 14313 } 14314 /** destroy the all runners and systems. Its apps job to */ 14315 destroy() { 14316 Object.values(this.runners).forEach((runner) => { 14317 runner.destroy(); 14318 }), this._systemsHash = {}; 14319 } 14320 // TODO implement! 14321 // removeSystem(ClassRef: ISystemConstructor, name: string): void 14322 // { 14323 // } 14324} 14325 14326const _TextureGCSystem = class _TextureGCSystem2 { 14327 /** @param renderer - The renderer this System works for. */ 14328 constructor(renderer) { 14329 this.renderer = renderer, this.count = 0, this.checkCount = 0, this.maxIdle = _TextureGCSystem2.defaultMaxIdle, this.checkCountMax = _TextureGCSystem2.defaultCheckCountMax, this.mode = _TextureGCSystem2.defaultMode; 14330 } 14331 /** 14332 * Checks to see when the last time a texture was used. 14333 * If the texture has not been used for a specified amount of time, it will be removed from the GPU. 14334 */ 14335 postrender() { 14336 this.renderer.objectRenderer.renderingToScreen && (this.count++, this.mode !== GC_MODES.MANUAL && (this.checkCount++, this.checkCount > this.checkCountMax && (this.checkCount = 0, this.run()))); 14337 } 14338 /** 14339 * Checks to see when the last time a texture was used. 14340 * If the texture has not been used for a specified amount of time, it will be removed from the GPU. 14341 */ 14342 run() { 14343 const tm = this.renderer.texture, managedTextures = tm.managedTextures; 14344 let wasRemoved = !1; 14345 for (let i = 0; i < managedTextures.length; i++) { 14346 const texture = managedTextures[i]; 14347 texture.resource && this.count - texture.touched > this.maxIdle && (tm.destroyTexture(texture, !0), managedTextures[i] = null, wasRemoved = !0); 14348 } 14349 if (wasRemoved) { 14350 let j = 0; 14351 for (let i = 0; i < managedTextures.length; i++) 14352 managedTextures[i] !== null && (managedTextures[j++] = managedTextures[i]); 14353 managedTextures.length = j; 14354 } 14355 } 14356 /** 14357 * Removes all the textures within the specified displayObject and its children from the GPU. 14358 * @param {PIXI.DisplayObject} displayObject - the displayObject to remove the textures from. 14359 */ 14360 unload(displayObject) { 14361 const tm = this.renderer.texture, texture = displayObject._texture; 14362 texture && !texture.framebuffer && tm.destroyTexture(texture); 14363 for (let i = displayObject.children.length - 1; i >= 0; i--) 14364 this.unload(displayObject.children[i]); 14365 } 14366 destroy() { 14367 this.renderer = null; 14368 } 14369}; 14370_TextureGCSystem.defaultMode = GC_MODES.AUTO, /** 14371* Default maximum idle frames before a texture is destroyed by garbage collection. 14372* @static 14373* @default 3600 14374* @see PIXI.TextureGCSystem#maxIdle 14375*/ 14376_TextureGCSystem.defaultMaxIdle = 60 * 60, /** 14377* Default frames between two garbage collections. 14378* @static 14379* @default 600 14380* @see PIXI.TextureGCSystem#checkCountMax 14381*/ 14382_TextureGCSystem.defaultCheckCountMax = 60 * 10, /** @ignore */ 14383_TextureGCSystem.extension = { 14384 type: ExtensionType.RendererSystem, 14385 name: "textureGC" 14386}; 14387let TextureGCSystem = _TextureGCSystem; 14388extensions$1.add(TextureGCSystem); 14389 14390class GLTexture { 14391 constructor(texture) { 14392 this.texture = texture, this.width = -1, this.height = -1, this.dirtyId = -1, this.dirtyStyleId = -1, this.mipmap = !1, this.wrapMode = 33071, this.type = TYPES.UNSIGNED_BYTE, this.internalFormat = FORMATS.RGBA, this.samplerType = 0; 14393 } 14394} 14395 14396function mapInternalFormatToSamplerType(gl) { 14397 let table; 14398 return "WebGL2RenderingContext" in globalThis && gl instanceof globalThis.WebGL2RenderingContext ? table = { 14399 [gl.RGB]: SAMPLER_TYPES.FLOAT, 14400 [gl.RGBA]: SAMPLER_TYPES.FLOAT, 14401 [gl.ALPHA]: SAMPLER_TYPES.FLOAT,
vendor: 14,117 bytes, lines 14402-14723
14402 [gl.LUMINANCE]: SAMPLER_TYPES.FLOAT, 14403 [gl.LUMINANCE_ALPHA]: SAMPLER_TYPES.FLOAT, 14404 [gl.R8]: SAMPLER_TYPES.FLOAT, 14405 [gl.R8_SNORM]: SAMPLER_TYPES.FLOAT, 14406 [gl.RG8]: SAMPLER_TYPES.FLOAT, 14407 [gl.RG8_SNORM]: SAMPLER_TYPES.FLOAT, 14408 [gl.RGB8]: SAMPLER_TYPES.FLOAT, 14409 [gl.RGB8_SNORM]: SAMPLER_TYPES.FLOAT, 14410 [gl.RGB565]: SAMPLER_TYPES.FLOAT, 14411 [gl.RGBA4]: SAMPLER_TYPES.FLOAT, 14412 [gl.RGB5_A1]: SAMPLER_TYPES.FLOAT, 14413 [gl.RGBA8]: SAMPLER_TYPES.FLOAT, 14414 [gl.RGBA8_SNORM]: SAMPLER_TYPES.FLOAT, 14415 [gl.RGB10_A2]: SAMPLER_TYPES.FLOAT, 14416 [gl.RGB10_A2UI]: SAMPLER_TYPES.FLOAT, 14417 [gl.SRGB8]: SAMPLER_TYPES.FLOAT, 14418 [gl.SRGB8_ALPHA8]: SAMPLER_TYPES.FLOAT, 14419 [gl.R16F]: SAMPLER_TYPES.FLOAT, 14420 [gl.RG16F]: SAMPLER_TYPES.FLOAT, 14421 [gl.RGB16F]: SAMPLER_TYPES.FLOAT, 14422 [gl.RGBA16F]: SAMPLER_TYPES.FLOAT, 14423 [gl.R32F]: SAMPLER_TYPES.FLOAT, 14424 [gl.RG32F]: SAMPLER_TYPES.FLOAT, 14425 [gl.RGB32F]: SAMPLER_TYPES.FLOAT, 14426 [gl.RGBA32F]: SAMPLER_TYPES.FLOAT, 14427 [gl.R11F_G11F_B10F]: SAMPLER_TYPES.FLOAT, 14428 [gl.RGB9_E5]: SAMPLER_TYPES.FLOAT, 14429 [gl.R8I]: SAMPLER_TYPES.INT, 14430 [gl.R8UI]: SAMPLER_TYPES.UINT, 14431 [gl.R16I]: SAMPLER_TYPES.INT, 14432 [gl.R16UI]: SAMPLER_TYPES.UINT, 14433 [gl.R32I]: SAMPLER_TYPES.INT, 14434 [gl.R32UI]: SAMPLER_TYPES.UINT, 14435 [gl.RG8I]: SAMPLER_TYPES.INT, 14436 [gl.RG8UI]: SAMPLER_TYPES.UINT, 14437 [gl.RG16I]: SAMPLER_TYPES.INT, 14438 [gl.RG16UI]: SAMPLER_TYPES.UINT, 14439 [gl.RG32I]: SAMPLER_TYPES.INT, 14440 [gl.RG32UI]: SAMPLER_TYPES.UINT, 14441 [gl.RGB8I]: SAMPLER_TYPES.INT, 14442 [gl.RGB8UI]: SAMPLER_TYPES.UINT, 14443 [gl.RGB16I]: SAMPLER_TYPES.INT, 14444 [gl.RGB16UI]: SAMPLER_TYPES.UINT, 14445 [gl.RGB32I]: SAMPLER_TYPES.INT, 14446 [gl.RGB32UI]: SAMPLER_TYPES.UINT, 14447 [gl.RGBA8I]: SAMPLER_TYPES.INT, 14448 [gl.RGBA8UI]: SAMPLER_TYPES.UINT, 14449 [gl.RGBA16I]: SAMPLER_TYPES.INT, 14450 [gl.RGBA16UI]: SAMPLER_TYPES.UINT, 14451 [gl.RGBA32I]: SAMPLER_TYPES.INT, 14452 [gl.RGBA32UI]: SAMPLER_TYPES.UINT, 14453 [gl.DEPTH_COMPONENT16]: SAMPLER_TYPES.FLOAT, 14454 [gl.DEPTH_COMPONENT24]: SAMPLER_TYPES.FLOAT, 14455 [gl.DEPTH_COMPONENT32F]: SAMPLER_TYPES.FLOAT, 14456 [gl.DEPTH_STENCIL]: SAMPLER_TYPES.FLOAT, 14457 [gl.DEPTH24_STENCIL8]: SAMPLER_TYPES.FLOAT, 14458 [gl.DEPTH32F_STENCIL8]: SAMPLER_TYPES.FLOAT 14459 } : table = { 14460 [gl.RGB]: SAMPLER_TYPES.FLOAT, 14461 [gl.RGBA]: SAMPLER_TYPES.FLOAT, 14462 [gl.ALPHA]: SAMPLER_TYPES.FLOAT, 14463 [gl.LUMINANCE]: SAMPLER_TYPES.FLOAT, 14464 [gl.LUMINANCE_ALPHA]: SAMPLER_TYPES.FLOAT, 14465 [gl.DEPTH_STENCIL]: SAMPLER_TYPES.FLOAT 14466 }, table; 14467} 14468 14469function mapTypeAndFormatToInternalFormat(gl) { 14470 let table; 14471 return "WebGL2RenderingContext" in globalThis && gl instanceof globalThis.WebGL2RenderingContext ? table = { 14472 [TYPES.UNSIGNED_BYTE]: { 14473 [FORMATS.RGBA]: gl.RGBA8, 14474 [FORMATS.RGB]: gl.RGB8, 14475 [FORMATS.RG]: gl.RG8, 14476 [FORMATS.RED]: gl.R8, 14477 [FORMATS.RGBA_INTEGER]: gl.RGBA8UI, 14478 [FORMATS.RGB_INTEGER]: gl.RGB8UI, 14479 [FORMATS.RG_INTEGER]: gl.RG8UI, 14480 [FORMATS.RED_INTEGER]: gl.R8UI, 14481 [FORMATS.ALPHA]: gl.ALPHA, 14482 [FORMATS.LUMINANCE]: gl.LUMINANCE, 14483 [FORMATS.LUMINANCE_ALPHA]: gl.LUMINANCE_ALPHA 14484 }, 14485 [TYPES.BYTE]: { 14486 [FORMATS.RGBA]: gl.RGBA8_SNORM, 14487 [FORMATS.RGB]: gl.RGB8_SNORM, 14488 [FORMATS.RG]: gl.RG8_SNORM, 14489 [FORMATS.RED]: gl.R8_SNORM, 14490 [FORMATS.RGBA_INTEGER]: gl.RGBA8I, 14491 [FORMATS.RGB_INTEGER]: gl.RGB8I, 14492 [FORMATS.RG_INTEGER]: gl.RG8I, 14493 [FORMATS.RED_INTEGER]: gl.R8I 14494 }, 14495 [TYPES.UNSIGNED_SHORT]: { 14496 [FORMATS.RGBA_INTEGER]: gl.RGBA16UI, 14497 [FORMATS.RGB_INTEGER]: gl.RGB16UI, 14498 [FORMATS.RG_INTEGER]: gl.RG16UI, 14499 [FORMATS.RED_INTEGER]: gl.R16UI, 14500 [FORMATS.DEPTH_COMPONENT]: gl.DEPTH_COMPONENT16 14501 }, 14502 [TYPES.SHORT]: { 14503 [FORMATS.RGBA_INTEGER]: gl.RGBA16I, 14504 [FORMATS.RGB_INTEGER]: gl.RGB16I, 14505 [FORMATS.RG_INTEGER]: gl.RG16I, 14506 [FORMATS.RED_INTEGER]: gl.R16I 14507 }, 14508 [TYPES.UNSIGNED_INT]: { 14509 [FORMATS.RGBA_INTEGER]: gl.RGBA32UI, 14510 [FORMATS.RGB_INTEGER]: gl.RGB32UI, 14511 [FORMATS.RG_INTEGER]: gl.RG32UI, 14512 [FORMATS.RED_INTEGER]: gl.R32UI, 14513 [FORMATS.DEPTH_COMPONENT]: gl.DEPTH_COMPONENT24 14514 }, 14515 [TYPES.INT]: { 14516 [FORMATS.RGBA_INTEGER]: gl.RGBA32I, 14517 [FORMATS.RGB_INTEGER]: gl.RGB32I, 14518 [FORMATS.RG_INTEGER]: gl.RG32I, 14519 [FORMATS.RED_INTEGER]: gl.R32I 14520 }, 14521 [TYPES.FLOAT]: { 14522 [FORMATS.RGBA]: gl.RGBA32F, 14523 [FORMATS.RGB]: gl.RGB32F, 14524 [FORMATS.RG]: gl.RG32F, 14525 [FORMATS.RED]: gl.R32F, 14526 [FORMATS.DEPTH_COMPONENT]: gl.DEPTH_COMPONENT32F 14527 }, 14528 [TYPES.HALF_FLOAT]: { 14529 [FORMATS.RGBA]: gl.RGBA16F, 14530 [FORMATS.RGB]: gl.RGB16F, 14531 [FORMATS.RG]: gl.RG16F, 14532 [FORMATS.RED]: gl.R16F 14533 }, 14534 [TYPES.UNSIGNED_SHORT_5_6_5]: { 14535 [FORMATS.RGB]: gl.RGB565 14536 }, 14537 [TYPES.UNSIGNED_SHORT_4_4_4_4]: { 14538 [FORMATS.RGBA]: gl.RGBA4 14539 }, 14540 [TYPES.UNSIGNED_SHORT_5_5_5_1]: { 14541 [FORMATS.RGBA]: gl.RGB5_A1 14542 }, 14543 [TYPES.UNSIGNED_INT_2_10_10_10_REV]: { 14544 [FORMATS.RGBA]: gl.RGB10_A2, 14545 [FORMATS.RGBA_INTEGER]: gl.RGB10_A2UI 14546 }, 14547 [TYPES.UNSIGNED_INT_10F_11F_11F_REV]: { 14548 [FORMATS.RGB]: gl.R11F_G11F_B10F 14549 }, 14550 [TYPES.UNSIGNED_INT_5_9_9_9_REV]: { 14551 [FORMATS.RGB]: gl.RGB9_E5 14552 }, 14553 [TYPES.UNSIGNED_INT_24_8]: { 14554 [FORMATS.DEPTH_STENCIL]: gl.DEPTH24_STENCIL8 14555 }, 14556 [TYPES.FLOAT_32_UNSIGNED_INT_24_8_REV]: { 14557 [FORMATS.DEPTH_STENCIL]: gl.DEPTH32F_STENCIL8 14558 } 14559 } : table = { 14560 [TYPES.UNSIGNED_BYTE]: { 14561 [FORMATS.RGBA]: gl.RGBA, 14562 [FORMATS.RGB]: gl.RGB, 14563 [FORMATS.ALPHA]: gl.ALPHA, 14564 [FORMATS.LUMINANCE]: gl.LUMINANCE, 14565 [FORMATS.LUMINANCE_ALPHA]: gl.LUMINANCE_ALPHA 14566 }, 14567 [TYPES.UNSIGNED_SHORT_5_6_5]: { 14568 [FORMATS.RGB]: gl.RGB 14569 }, 14570 [TYPES.UNSIGNED_SHORT_4_4_4_4]: { 14571 [FORMATS.RGBA]: gl.RGBA 14572 }, 14573 [TYPES.UNSIGNED_SHORT_5_5_5_1]: { 14574 [FORMATS.RGBA]: gl.RGBA 14575 } 14576 }, table; 14577} 14578 14579class TextureSystem { 14580 /** 14581 * @param renderer - The renderer this system works for. 14582 */ 14583 constructor(renderer) { 14584 this.renderer = renderer, this.boundTextures = [], this.currentLocation = -1, this.managedTextures = [], this._unknownBoundTextures = !1, this.unknownTexture = new BaseTexture(), this.hasIntegerTextures = !1; 14585 } 14586 /** Sets up the renderer context and necessary buffers. */ 14587 contextChange() { 14588 const gl = this.gl = this.renderer.gl; 14589 this.CONTEXT_UID = this.renderer.CONTEXT_UID, this.webGLVersion = this.renderer.context.webGLVersion, this.internalFormats = mapTypeAndFormatToInternalFormat(gl), this.samplerTypes = mapInternalFormatToSamplerType(gl); 14590 const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); 14591 this.boundTextures.length = maxTextures; 14592 for (let i = 0; i < maxTextures; i++) 14593 this.boundTextures[i] = null; 14594 this.emptyTextures = {}; 14595 const emptyTexture2D = new GLTexture(gl.createTexture()); 14596 gl.bindTexture(gl.TEXTURE_2D, emptyTexture2D.texture), gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4)), this.emptyTextures[gl.TEXTURE_2D] = emptyTexture2D, this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(gl.createTexture()), gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); 14597 for (let i = 0; i < 6; i++) 14598 gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 14599 gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR), gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 14600 for (let i = 0; i < this.boundTextures.length; i++) 14601 this.bind(null, i); 14602 } 14603 /** 14604 * Bind a texture to a specific location 14605 * 14606 * If you want to unbind something, please use `unbind(texture)` instead of `bind(null, textureLocation)` 14607 * @param texture - Texture to bind 14608 * @param [location=0] - Location to bind at 14609 */ 14610 bind(texture, location = 0) { 14611 const { gl } = this; 14612 if (texture = texture?.castToBaseTexture(), texture?.valid && !texture.parentTextureArray) { 14613 texture.touched = this.renderer.textureGC.count; 14614 const glTexture = texture._glTextures[this.CONTEXT_UID] || this.initTexture(texture); 14615 this.boundTextures[location] !== texture && (this.currentLocation !== location && (this.currentLocation = location, gl.activeTexture(gl.TEXTURE0 + location)), gl.bindTexture(texture.target, glTexture.texture)), glTexture.dirtyId !== texture.dirtyId ? (this.currentLocation !== location && (this.currentLocation = location, gl.activeTexture(gl.TEXTURE0 + location)), this.updateTexture(texture)) : glTexture.dirtyStyleId !== texture.dirtyStyleId && this.updateTextureStyle(texture), this.boundTextures[location] = texture; 14616 } else 14617 this.currentLocation !== location && (this.currentLocation = location, gl.activeTexture(gl.TEXTURE0 + location)), gl.bindTexture(gl.TEXTURE_2D, this.emptyTextures[gl.TEXTURE_2D].texture), this.boundTextures[location] = null; 14618 } 14619 /** Resets texture location and bound textures Actual `bind(null, i)` calls will be performed at next `unbind()` call */ 14620 reset() { 14621 this._unknownBoundTextures = !0, this.hasIntegerTextures = !1, this.currentLocation = -1; 14622 for (let i = 0; i < this.boundTextures.length; i++) 14623 this.boundTextures[i] = this.unknownTexture; 14624 } 14625 /** 14626 * Unbind a texture. 14627 * @param texture - Texture to bind 14628 */ 14629 unbind(texture) { 14630 const { gl, boundTextures } = this; 14631 if (this._unknownBoundTextures) { 14632 this._unknownBoundTextures = !1; 14633 for (let i = 0; i < boundTextures.length; i++) 14634 boundTextures[i] === this.unknownTexture && this.bind(null, i); 14635 } 14636 for (let i = 0; i < boundTextures.length; i++) 14637 boundTextures[i] === texture && (this.currentLocation !== i && (gl.activeTexture(gl.TEXTURE0 + i), this.currentLocation = i), gl.bindTexture(texture.target, this.emptyTextures[texture.target].texture), boundTextures[i] = null); 14638 } 14639 /** 14640 * Ensures that current boundTextures all have FLOAT sampler type, 14641 * see {@link PIXI.SAMPLER_TYPES} for explanation. 14642 * @param maxTextures - number of locations to check 14643 */ 14644 ensureSamplerType(maxTextures) { 14645 const { boundTextures, hasIntegerTextures, CONTEXT_UID } = this; 14646 if (hasIntegerTextures) 14647 for (let i = maxTextures - 1; i >= 0; --i) { 14648 const tex = boundTextures[i]; 14649 tex && tex._glTextures[CONTEXT_UID].samplerType !== SAMPLER_TYPES.FLOAT && this.renderer.texture.unbind(tex); 14650 } 14651 } 14652 /** 14653 * Initialize a texture 14654 * @private 14655 * @param texture - Texture to initialize 14656 */ 14657 initTexture(texture) { 14658 const glTexture = new GLTexture(this.gl.createTexture()); 14659 return glTexture.dirtyId = -1, texture._glTextures[this.CONTEXT_UID] = glTexture, this.managedTextures.push(texture), texture.on("dispose", this.destroyTexture, this), glTexture; 14660 } 14661 initTextureType(texture, glTexture) { 14662 glTexture.internalFormat = this.internalFormats[texture.type]?.[texture.format] ?? texture.format, glTexture.samplerType = this.samplerTypes[glTexture.internalFormat] ?? SAMPLER_TYPES.FLOAT, this.webGLVersion === 2 && texture.type === TYPES.HALF_FLOAT ? glTexture.type = this.gl.HALF_FLOAT : glTexture.type = texture.type; 14663 } 14664 /** 14665 * Update a texture 14666 * @private 14667 * @param {PIXI.BaseTexture} texture - Texture to initialize 14668 */ 14669 updateTexture(texture) { 14670 const glTexture = texture._glTextures[this.CONTEXT_UID]; 14671 if (!glTexture) 14672 return; 14673 const renderer = this.renderer; 14674 if (this.initTextureType(texture, glTexture), texture.resource?.upload(renderer, texture, glTexture)) 14675 glTexture.samplerType !== SAMPLER_TYPES.FLOAT && (this.hasIntegerTextures = !0); 14676 else { 14677 const width = texture.realWidth, height = texture.realHeight, gl = renderer.gl; 14678 (glTexture.width !== width || glTexture.height !== height || glTexture.dirtyId < 0) && (glTexture.width = width, glTexture.height = height, gl.texImage2D( 14679 texture.target, 14680 0, 14681 glTexture.internalFormat, 14682 width, 14683 height, 14684 0, 14685 texture.format, 14686 glTexture.type, 14687 null 14688 )); 14689 } 14690 texture.dirtyStyleId !== glTexture.dirtyStyleId && this.updateTextureStyle(texture), glTexture.dirtyId = texture.dirtyId; 14691 } 14692 /** 14693 * Deletes the texture from WebGL 14694 * @private 14695 * @param texture - the texture to destroy 14696 * @param [skipRemove=false] - Whether to skip removing the texture from the TextureManager. 14697 */ 14698 destroyTexture(texture, skipRemove) { 14699 const { gl } = this; 14700 if (texture = texture.castToBaseTexture(), texture._glTextures[this.CONTEXT_UID] && (this.unbind(texture), gl.deleteTexture(texture._glTextures[this.CONTEXT_UID].texture), texture.off("dispose", this.destroyTexture, this), delete texture._glTextures[this.CONTEXT_UID], !skipRemove)) { 14701 const i = this.managedTextures.indexOf(texture); 14702 i !== -1 && removeItems(this.managedTextures, i, 1); 14703 } 14704 } 14705 /** 14706 * Update texture style such as mipmap flag 14707 * @private 14708 * @param {PIXI.BaseTexture} texture - Texture to update 14709 */ 14710 updateTextureStyle(texture) { 14711 const glTexture = texture._glTextures[this.CONTEXT_UID]; 14712 glTexture && ((texture.mipmap === MIPMAP_MODES.POW2 || this.webGLVersion !== 2) && !texture.isPowerOfTwo ? glTexture.mipmap = !1 : glTexture.mipmap = texture.mipmap >= 1, this.webGLVersion !== 2 && !texture.isPowerOfTwo ? glTexture.wrapMode = WRAP_MODES.CLAMP : glTexture.wrapMode = texture.wrapMode, texture.resource?.style(this.renderer, texture, glTexture) || this.setStyle(texture, glTexture), glTexture.dirtyStyleId = texture.dirtyStyleId); 14713 } 14714 /** 14715 * Set style for texture 14716 * @private 14717 * @param texture - Texture to update 14718 * @param glTexture 14719 */ 14720 setStyle(texture, glTexture) { 14721 const gl = this.gl; 14722 if (glTexture.mipmap && texture.mipmap !== MIPMAP_MODES.ON_MANUAL && gl.generateMipmap(texture.target), gl.texParameteri(texture.target, gl.TEXTURE_WRAP_S, glTexture.wrapMode), gl.texParameteri(texture.target, gl.TEXTURE_WRAP_T, glTexture.wrapMode), glTexture.mipmap) { 14723 gl.texParameteri(texture.target, gl.TEXTURE_MIN_FILTER, texture.scaleMode === SCALE_MODES.LINEAR ? gl.LINEAR_MIPMAP_LINEAR
vendor: 6,527 bytes, lines 14723-14889
14723: gl.NEAREST_MIPMAP_NEAREST); 14724 const anisotropicExt = this.renderer.context.extensions.anisotropicFiltering; 14725 if (anisotropicExt && texture.anisotropicLevel > 0 && texture.scaleMode === SCALE_MODES.LINEAR) { 14726 const level = Math.min(texture.anisotropicLevel, gl.getParameter(anisotropicExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT)); 14727 gl.texParameterf(texture.target, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, level); 14728 } 14729 } else 14730 gl.texParameteri(texture.target, gl.TEXTURE_MIN_FILTER, texture.scaleMode === SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST); 14731 gl.texParameteri(texture.target, gl.TEXTURE_MAG_FILTER, texture.scaleMode === SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST); 14732 } 14733 destroy() { 14734 this.renderer = null; 14735 } 14736} 14737TextureSystem.extension = { 14738 type: ExtensionType.RendererSystem, 14739 name: "texture" 14740}; 14741extensions$1.add(TextureSystem); 14742 14743class TransformFeedbackSystem { 14744 /** 14745 * @param renderer - The renderer this System works for. 14746 */ 14747 constructor(renderer) { 14748 this.renderer = renderer; 14749 } 14750 /** Sets up the renderer context and necessary buffers. */ 14751 contextChange() { 14752 this.gl = this.renderer.gl, this.CONTEXT_UID = this.renderer.CONTEXT_UID; 14753 } 14754 /** 14755 * Bind TransformFeedback and buffers 14756 * @param transformFeedback - TransformFeedback to bind 14757 */ 14758 bind(transformFeedback) { 14759 const { gl, CONTEXT_UID } = this, glTransformFeedback = transformFeedback._glTransformFeedbacks[CONTEXT_UID] || this.createGLTransformFeedback(transformFeedback); 14760 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, glTransformFeedback); 14761 } 14762 /** Unbind TransformFeedback */ 14763 unbind() { 14764 const { gl } = this; 14765 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); 14766 } 14767 /** 14768 * Begin TransformFeedback 14769 * @param drawMode - DrawMode for TransformFeedback 14770 * @param shader - A Shader used by TransformFeedback. Current bound shader will be used if not provided. 14771 */ 14772 beginTransformFeedback(drawMode, shader) { 14773 const { gl, renderer } = this; 14774 shader && renderer.shader.bind(shader), gl.beginTransformFeedback(drawMode); 14775 } 14776 /** End TransformFeedback */ 14777 endTransformFeedback() { 14778 const { gl } = this; 14779 gl.endTransformFeedback(); 14780 } 14781 /** 14782 * Create TransformFeedback and bind buffers 14783 * @param tf - TransformFeedback 14784 * @returns WebGLTransformFeedback 14785 */ 14786 createGLTransformFeedback(tf) { 14787 const { gl, renderer, CONTEXT_UID } = this, glTransformFeedback = gl.createTransformFeedback(); 14788 tf._glTransformFeedbacks[CONTEXT_UID] = glTransformFeedback, gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, glTransformFeedback); 14789 for (let i = 0; i < tf.buffers.length; i++) { 14790 const buffer = tf.buffers[i]; 14791 buffer && (renderer.buffer.update(buffer), buffer._glBuffers[CONTEXT_UID].refCount++, gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, buffer._glBuffers[CONTEXT_UID].buffer || null)); 14792 } 14793 return gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null), tf.disposeRunner.add(this), glTransformFeedback; 14794 } 14795 /** 14796 * Disposes TransfromFeedback 14797 * @param {PIXI.TransformFeedback} tf - TransformFeedback 14798 * @param {boolean} [contextLost=false] - If context was lost, we suppress delete TransformFeedback 14799 */ 14800 disposeTransformFeedback(tf, contextLost) { 14801 const glTF = tf._glTransformFeedbacks[this.CONTEXT_UID], gl = this.gl; 14802 tf.disposeRunner.remove(this); 14803 const bufferSystem = this.renderer.buffer; 14804 if (bufferSystem) 14805 for (let i = 0; i < tf.buffers.length; i++) { 14806 const buffer = tf.buffers[i]; 14807 if (!buffer) 14808 continue; 14809 const buf = buffer._glBuffers[this.CONTEXT_UID]; 14810 buf && (buf.refCount--, buf.refCount === 0 && !contextLost && bufferSystem.dispose(buffer, contextLost)); 14811 } 14812 glTF && (contextLost || gl.deleteTransformFeedback(glTF), delete tf._glTransformFeedbacks[this.CONTEXT_UID]); 14813 } 14814 destroy() { 14815 this.renderer = null; 14816 } 14817} 14818TransformFeedbackSystem.extension = { 14819 type: ExtensionType.RendererSystem, 14820 name: "transformFeedback" 14821}; 14822extensions$1.add(TransformFeedbackSystem); 14823 14824class ViewSystem { 14825 constructor(renderer) { 14826 this.renderer = renderer; 14827 } 14828 /** 14829 * initiates the view system 14830 * @param {PIXI.ViewOptions} options - the options for the view 14831 */ 14832 init(options) { 14833 this.screen = new Rectangle(0, 0, options.width, options.height), this.element = options.view || settings.ADAPTER.createCanvas(), this.resolution = options.resolution || settings.RESOLUTION, this.autoDensity = !!options.autoDensity; 14834 } 14835 /** 14836 * Resizes the screen and canvas to the specified dimensions. 14837 * @param desiredScreenWidth - The new width of the screen. 14838 * @param desiredScreenHeight - The new height of the screen. 14839 */ 14840 resizeView(desiredScreenWidth, desiredScreenHeight) { 14841 this.element.width = Math.round(desiredScreenWidth * this.resolution), this.element.height = Math.round(desiredScreenHeight * this.resolution); 14842 const screenWidth = this.element.width / this.resolution, screenHeight = this.element.height / this.resolution; 14843 this.screen.width = screenWidth, this.screen.height = screenHeight, this.autoDensity && (this.element.style.width = `${screenWidth}px`, this.element.style.height = `${screenHeight}px`), this.renderer.emit("resize", screenWidth, screenHeight), this.renderer.runners.resize.emit(this.screen.width, this.screen.height); 14844 } 14845 /** 14846 * Destroys this System and optionally removes the canvas from the dom. 14847 * @param {boolean} [removeView=false] - Whether to remove the canvas from the DOM. 14848 */ 14849 destroy(removeView) { 14850 removeView && this.element.parentNode?.removeChild(this.element), this.renderer = null, this.element = null, this.screen = null; 14851 } 14852} 14853ViewSystem.defaultOptions = { 14854 /** 14855 * {@link PIXI.IRendererOptions.width} 14856 * @default 800 14857 * @memberof PIXI.settings.RENDER_OPTIONS 14858 */ 14859 width: 800, 14860 /** 14861 * {@link PIXI.IRendererOptions.height} 14862 * @default 600 14863 * @memberof PIXI.settings.RENDER_OPTIONS 14864 */ 14865 height: 600, 14866 /** 14867 * {@link PIXI.IRendererOptions.resolution} 14868 * @type {number} 14869 * @default PIXI.settings.RESOLUTION 14870 * @memberof PIXI.settings.RENDER_OPTIONS 14871 */ 14872 resolution: void 0, 14873 /** 14874 * {@link PIXI.IRendererOptions.autoDensity} 14875 * @default false 14876 * @memberof PIXI.settings.RENDER_OPTIONS 14877 */ 14878 autoDensity: !1 14879}, /** @ignore */ 14880ViewSystem.extension = { 14881 type: [ 14882 ExtensionType.RendererSystem, 14883 ExtensionType.CanvasRendererSystem 14884 ], 14885 name: "_view" 14886}; 14887extensions$1.add(ViewSystem); 14888 14889settings.PREFER_ENV = ENV.WEBGL2;
14890settings.STRICT_TEXTURE_CACHE = !1; 14891settings.RENDER_OPTIONS = { 14892 ...ContextSystem.defaultOptions, 14893 ...BackgroundSystem.defaultOptions, 14894 ...ViewSystem.defaultOptions, 14895 ...StartupSystem.defaultOptions 14896}; 14897Object.defineProperties(settings, { 14898 /** 14899 * @static 14900 * @name WRAP_MODE 14901 * @memberof PIXI.settings 14902 * @type {PIXI.WRAP_MODES} 14903 * @deprecated since 7.1.0 14904 * @see PIXI.BaseTexture.defaultOptions.wrapMode 14905 */ 14906 WRAP_MODE: { 14907 get() { 14908 return BaseTexture.defaultOptions.wrapMode; 14909 }, 14910 set(value) { 14911 deprecation("7.1.0", "settings.WRAP_MODE is deprecated, use BaseTexture.defaultOptions.wrapMode"), BaseTexture.defaultOptions.wrapMode = value; 14912 } 14913 }, 14914 /** 14915 * @static 14916 * @name SCALE_MODE 14917 * @memberof PIXI.settings 14918 * @type {PIXI.SCALE_MODES} 14919 * @deprecated since 7.1.0 14920 * @see PIXI.BaseTexture.defaultOptions.scaleMode 14921 */ 14922 SCALE_MODE: { 14923 get() { 14924 return BaseTexture.defaultOptions.scaleMode; 14925 }, 14926 set(value) { 14927 deprecation("7.1.0", "settings.SCALE_MODE is deprecated, use BaseTexture.defaultOptions.scaleMode"), BaseTexture.defaultOptions.scaleMode = value; 14928 } 14929 }, 14930 /** 14931 * @static 14932 * @name MIPMAP_TEXTURES 14933 * @memberof PIXI.settings 14934 * @type {PIXI.MIPMAP_MODES} 14935 * @deprecated since 7.1.0 14936 * @see PIXI.BaseTexture.defaultOptions.mipmap 14937 */ 14938 MIPMAP_TEXTURES: { 14939 get() { 14940 return BaseTexture.defaultOptions.mipmap; 14941 }, 14942 set(value) { 14943 deprecation("7.1.0", "settings.MIPMAP_TEXTURES is deprecated, use BaseTexture.defaultOptions.mipmap"), BaseTexture.defaultOptions.mipmap = value; 14944 } 14945 // MIPMAP_MODES.POW2, 14946 }, 14947 /** 14948 * @static 14949 * @name ANISOTROPIC_LEVEL 14950 * @memberof PIXI.settings 14951 * @type {number} 14952 * @deprecated since 7.1.0 14953 * @see PIXI.BaseTexture.defaultOptions.anisotropicLevel 14954 */ 14955 ANISOTROPIC_LEVEL: { 14956 get() { 14957 return BaseTexture.defaultOptions.anisotropicLevel; 14958 }, 14959 set(value) { 14960 deprecation( 14961 "7.1.0", 14962 "settings.ANISOTROPIC_LEVEL is deprecated, use BaseTexture.defaultOptions.anisotropicLevel" 14963 ), BaseTexture.defaultOptions.anisotropicLevel = value; 14964 } 14965 }, 14966 /** 14967 * Default filter resolution. 14968 * @static 14969 * @name FILTER_RESOLUTION 14970 * @memberof PIXI.settings 14971 * @deprecated since 7.1.0 14972 * @type {number|null} 14973 * @see PIXI.Filter.defaultResolution 14974 */ 14975 FILTER_RESOLUTION: { 14976 get() { 14977 return deprecation("7.1.0", "settings.FILTER_RESOLUTION is deprecated, use Filter.defaultResolution"), Filter.defaultResolution; 14978 }, 14979 set(value) { 14980 Filter.defaultResolution = value; 14981 } 14982 }, 14983 /** 14984 * Default filter samples. 14985 * @static 14986 * @name FILTER_MULTISAMPLE 14987 * @memberof PIXI.settings 14988 * @deprecated since 7.1.0 14989 * @type {PIXI.MSAA_QUALITY} 14990 * @see PIXI.Filter.defaultMultisample 14991 */ 14992 FILTER_MULTISAMPLE: { 14993 get() { 14994 return deprecation("7.1.0", "settings.FILTER_MULTISAMPLE is deprecated, use Filter.defaultMultisample"), Filter.defaultMultisample; 14995 }, 14996 set(value) { 14997 Filter.defaultMultisample = value; 14998 } 14999 }, 15000 /** 15001 * The maximum textures that this device supports. 15002 * @static 15003 * @name SPRITE_MAX_TEXTURES 15004 * @memberof PIXI.settings 15005 * @deprecated since 7.1.0 15006 * @see PIXI.BatchRenderer.defaultMaxTextures 15007 * @type {number} 15008 */ 15009 SPRITE_MAX_TEXTURES: { 15010 get() { 15011 return BatchRenderer.defaultMaxTextures; 15012 }, 15013 set(value) { 15014 deprecation("7.1.0", "settings.SPRITE_MAX_TEXTURES is deprecated, use BatchRenderer.defaultMaxTextures"), BatchRenderer.defaultMaxTextures = value; 15015 } 15016 }, 15017 /** 15018 * The default sprite batch size. 15019 * 15020 * The default aims to balance desktop and mobile devices. 15021 * @static 15022 * @name SPRITE_BATCH_SIZE 15023 * @memberof PIXI.settings 15024 * @see PIXI.BatchRenderer.defaultBatchSize 15025 * @deprecated since 7.1.0 15026 * @type {number} 15027 */ 15028 SPRITE_BATCH_SIZE: { 15029 get() { 15030 return BatchRenderer.defaultBatchSize; 15031 }, 15032 set(value) { 15033 deprecation("7.1.0", "settings.SPRITE_BATCH_SIZE is deprecated, use BatchRenderer.defaultBatchSize"), BatchRenderer.defaultBatchSize = value; 15034 } 15035 }, 15036 /** 15037 * Can we upload the same buffer in a single frame? 15038 * @static 15039 * @name CAN_UPLOAD_SAME_BUFFER 15040 * @memberof PIXI.settings 15041 * @see PIXI.BatchRenderer.canUploadSameBuffer 15042 * @deprecated since 7.1.0 15043 * @type {boolean} 15044 */ 15045 CAN_UPLOAD_SAME_BUFFER: { 15046 get() { 15047 return BatchRenderer.canUploadSameBuffer; 15048 }, 15049 set(value) { 15050 deprecation("7.1.0", "settings.CAN_UPLOAD_SAME_BUFFER is deprecated, use BatchRenderer.canUploadSameBuffer"), BatchRenderer.canUploadSameBuffer = value; 15051 } 15052 }, 15053 /** 15054 * Default Garbage Collection mode. 15055 * @static 15056 * @name GC_MODE 15057 * @memberof PIXI.settings 15058 * @type {PIXI.GC_MODES} 15059 * @deprecated since 7.1.0 15060 * @see PIXI.TextureGCSystem.defaultMode 15061 */ 15062 GC_MODE: { 15063 get() { 15064 return TextureGCSystem.defaultMode; 15065 }, 15066 set(value) { 15067 deprecation("7.1.0", "settings.GC_MODE is deprecated, use TextureGCSystem.defaultMode"), TextureGCSystem.defaultMode = value; 15068 } 15069 }, 15070 /** 15071 * Default Garbage Collection max idle. 15072 * @static 15073 * @name GC_MAX_IDLE 15074 * @memberof PIXI.settings 15075 * @type {number} 15076 * @deprecated since 7.1.0 15077 * @see PIXI.TextureGCSystem.defaultMaxIdle 15078 */ 15079 GC_MAX_IDLE: { 15080 get() { 15081 return TextureGCSystem.defaultMaxIdle; 15082 }, 15083 set(value) { 15084 deprecation("7.1.0", "settings.GC_MAX_IDLE is deprecated, use TextureGCSystem.defaultMaxIdle"), TextureGCSystem.defaultMaxIdle = value; 15085 } 15086 }, 15087 /** 15088 * Default Garbage Collection maximum check count. 15089 * @static 15090 * @name GC_MAX_CHECK_COUNT 15091 * @memberof PIXI.settings 15092 * @type {number} 15093 * @deprecated since 7.1.0 15094 * @see PIXI.TextureGCSystem.defaultCheckCountMax 15095 */ 15096 GC_MAX_CHECK_COUNT: { 15097 get() { 15098 return TextureGCSystem.defaultCheckCountMax; 15099 }, 15100 set(value) { 15101 deprecation("7.1.0", "settings.GC_MAX_CHECK_COUNT is deprecated, use TextureGCSystem.defaultCheckCountMax"), TextureGCSystem.defaultCheckCountMax = value; 15102 } 15103 }, 15104 /** 15105 * Default specify float precision in vertex shader. 15106 * @static 15107 * @name PRECISION_VERTEX 15108 * @memberof PIXI.settings 15109 * @type {PIXI.PRECISION} 15110 * @deprecated since 7.1.0 15111 * @see PIXI.Program.defaultVertexPrecision 15112 */ 15113 PRECISION_VERTEX: { 15114 get() { 15115 return Program.defaultVertexPrecision; 15116 }, 15117 set(value) { 15118 deprecation("7.1.0", "settings.PRECISION_VERTEX is deprecated, use Program.defaultVertexPrecision"), Program.defaultVertexPrecision = value; 15119 } 15120 }, 15121 /** 15122 * Default specify float precision in fragment shader. 15123 * @static 15124 * @name PRECISION_FRAGMENT 15125 * @memberof PIXI.settings 15126 * @type {PIXI.PRECISION} 15127 * @deprecated since 7.1.0 15128 * @see PIXI.Program.defaultFragmentPrecision 15129 */ 15130 PRECISION_FRAGMENT: { 15131 get() { 15132 return Program.defaultFragmentPrecision; 15133 }, 15134 set(value) { 15135 deprecation("7.1.0", "settings.PRECISION_FRAGMENT is deprecated, use Program.defaultFragmentPrecision"), Program.defaultFragmentPrecision = value; 15136 } 15137 } 15138}); 15139 15140var UPDATE_PRIORITY = /* @__PURE__ */ ((UPDATE_PRIORITY2) => (UPDATE_PRIORITY2[UPDATE_PRIORITY2.INTERACTION = 50] = "INTERACTION", UPDATE_PRIORITY2[UPDATE_PRIORITY2.HIGH = 25] = "HIGH", UPDATE_PRIORITY2[UPDATE_PRIORITY2.NORMAL = 0] = "NORMAL", UPDATE_PRIORITY2[UPDATE_PRIORITY2.LOW = -25] = "LOW", UPDATE_PRIORITY2[UPDATE_PRIORITY2.UTILITY = -50] = "UTILITY", UPDATE_PRIORITY2))(UPDATE_PRIORITY || {}); 15141 15142class TickerListener { 15143 /** 15144 * Constructor 15145 * @private 15146 * @param fn - The listener function to be added for one update 15147 * @param context - The listener context 15148 * @param priority - The priority for emitting 15149 * @param once - If the handler should fire once 15150 */ 15151 constructor(fn, context = null, priority = 0, once = !1) { 15152 this.next = null, this.previous = null, this._destroyed = !1, this.fn = fn, this.context = context, this.priority = priority, this.once = once; 15153 } 15154 /**
15155 * Simple compare function to figure out if a function and context match. 15156 * @private 15157 * @param fn - The listener function to be added for one update 15158 * @param context - The listener context 15159 * @returns `true` if the listener match the arguments 15160 */ 15161 match(fn, context = null) { 15162 return this.fn === fn && this.context === context; 15163 } 15164 /** 15165 * Emit by calling the current function. 15166 * @private 15167 * @param deltaTime - time since the last emit. 15168 * @returns Next ticker 15169 */ 15170 emit(deltaTime) { 15171 this.fn && (this.context ? this.fn.call(this.context, deltaTime) : this.fn(deltaTime)); 15172 const redirect = this.next; 15173 return this.once && this.destroy(!0), this._destroyed && (this.next = null), redirect; 15174 } 15175 /** 15176 * Connect to the list. 15177 * @private 15178 * @param previous - Input node, previous listener 15179 */ 15180 connect(previous) { 15181 this.previous = previous, previous.next && (previous.next.previous = this), this.next = previous.next, previous.next = this; 15182 } 15183 /** 15184 * Destroy and don't use after this. 15185 * @private 15186 * @param hard - `true` to remove the `next` reference, this 15187 * is considered a hard destroy. Soft destroy maintains the next reference. 15188 * @returns The listener to redirect while emitting or removing. 15189 */ 15190 destroy(hard = !1) { 15191 this._destroyed = !0, this.fn = null, this.context = null, this.previous && (this.previous.next = this.next), this.next && (this.next.previous = this.previous); 15192 const redirect = this.next; 15193 return this.next = hard ? null : redirect, this.previous = null, redirect; 15194 } 15195} 15196 15197const _Ticker = class _Ticker2 { 15198 constructor() { 15199 this.autoStart = !1, this.deltaTime = 1, this.lastTime = -1, this.speed = 1, this.started = !1, this._requestId = null, this._maxElapsedMS = 100, this._minElapsedMS = 0, this._protected = !1, this._lastFrame = -1, this._head = new TickerListener(null, null, 1 / 0), this.deltaMS = 1 / _Ticker2.targetFPMS, this.elapsedMS = 1 / _Ticker2.targetFPMS, this._tick = (time) => { 15200 this._requestId = null, this.started && (this.update(time), this.started && this._requestId === null && this._head.next && (this._requestId = requestAnimationFrame(this._tick))); 15201 }; 15202 } 15203 /** 15204 * Conditionally requests a new animation frame. 15205 * If a frame has not already been requested, and if the internal 15206 * emitter has listeners, a new frame is requested. 15207 * @private 15208 */ 15209 _requestIfNeeded() { 15210 this._requestId === null && this._head.next && (this.lastTime = performance.now(), this._lastFrame = this.lastTime, this._requestId = requestAnimationFrame(this._tick)); 15211 } 15212 /** 15213 * Conditionally cancels a pending animation frame. 15214 * @private 15215 */ 15216 _cancelIfNeeded() { 15217 this._requestId !== null && (cancelAnimationFrame(this._requestId), this._requestId = null); 15218 } 15219 /** 15220 * Conditionally requests a new animation frame. 15221 * If the ticker has been started it checks if a frame has not already 15222 * been requested, and if the internal emitter has listeners. If these 15223 * conditions are met, a new frame is requested. If the ticker has not 15224 * been started, but autoStart is `true`, then the ticker starts now, 15225 * and continues with the previous conditions to request a new frame. 15226 * @private 15227 */ 15228 _startIfPossible() { 15229 this.started ? this._requestIfNeeded() : this.autoStart && this.start(); 15230 } 15231 /** 15232 * Register a handler for tick events. Calls continuously unless 15233 * it is removed or the ticker is stopped. 15234 * @param fn - The listener function to be added for updates 15235 * @param context - The listener context 15236 * @param {number} [priority=PIXI.UPDATE_PRIORITY.NORMAL] - The priority for emitting 15237 * @returns This instance of a ticker 15238 */ 15239 add(fn, context, priority = UPDATE_PRIORITY.NORMAL) { 15240 return this._addListener(new TickerListener(fn, context, priority)); 15241 } 15242 /** 15243 * Add a handler for the tick event which is only execute once. 15244 * @param fn - The listener function to be added for one update 15245 * @param context - The listener context 15246 * @param {number} [priority=PIXI.UPDATE_PRIORITY.NORMAL] - The priority for emitting 15247 * @returns This instance of a ticker 15248 */ 15249 addOnce(fn, context, priority = UPDATE_PRIORITY.NORMAL) { 15250 return this._addListener(new TickerListener(fn, context, priority, !0)); 15251 } 15252 /** 15253 * Internally adds the event handler so that it can be sorted by priority. 15254 * Priority allows certain handler (user, AnimatedSprite, Interaction) to be run 15255 * before the rendering. 15256 * @private 15257 * @param listener - Current listener being added. 15258 * @returns This instance of a ticker 15259 */ 15260 _addListener(listener) {
15261 let current = this._head.next, previous = this._head; 15262 if (!current) 15263 listener.connect(previous); 15264 else { 15265 for (; current; ) { 15266 if (listener.priority > current.priority) { 15267 listener.connect(previous); 15268 break; 15269 } 15270 previous = current, current = current.next; 15271 } 15272 listener.previous || listener.connect(previous); 15273 } 15274 return this._startIfPossible(), this; 15275 } 15276 /** 15277 * Removes any handlers matching the function and context parameters. 15278 * If no handlers are left after removing, then it cancels the animation frame. 15279 * @param fn - The listener function to be removed 15280 * @param context - The listener context to be removed 15281 * @returns This instance of a ticker 15282 */ 15283 remove(fn, context) { 15284 let listener = this._head.next; 15285 for (; listener; ) 15286 listener.match(fn, context
vendor: 6,692 bytes, lines 15286-15468
15286) ? listener = listener.destroy() : listener = listener.next; 15287 return this._head.next || this._cancelIfNeeded(), this; 15288 } 15289 /** 15290 * The number of listeners on this ticker, calculated by walking through linked list 15291 * @readonly 15292 * @member {number} 15293 */ 15294 get count() { 15295 if (!this._head) 15296 return 0; 15297 let count = 0, current = this._head; 15298 for (; current = current.next; ) 15299 count++; 15300 return count; 15301 } 15302 /** Starts the ticker. If the ticker has listeners a new animation frame is requested at this point. */ 15303 start() { 15304 this.started || (this.started = !0, this._requestIfNeeded()); 15305 } 15306 /** Stops the ticker. If the ticker has requested an animation frame it is canceled at this point. */ 15307 stop() { 15308 this.started && (this.started = !1, this._cancelIfNeeded()); 15309 } 15310 /** Destroy the ticker and don't use after this. Calling this method removes all references to internal events. */ 15311 destroy() { 15312 if (!this._protected) { 15313 this.stop(); 15314 let listener = this._head.next; 15315 for (; listener; ) 15316 listener = listener.destroy(!0); 15317 this._head.destroy(), this._head = null; 15318 } 15319 } 15320 /** 15321 * Triggers an update. An update entails setting the 15322 * current {@link PIXI.Ticker#elapsedMS}, 15323 * the current {@link PIXI.Ticker#deltaTime}, 15324 * invoking all listeners with current deltaTime, 15325 * and then finally setting {@link PIXI.Ticker#lastTime} 15326 * with the value of currentTime that was provided. 15327 * This method will be called automatically by animation 15328 * frame callbacks if the ticker instance has been started 15329 * and listeners are added. 15330 * @param {number} [currentTime=performance.now()] - the current time of execution 15331 */ 15332 update(currentTime = performance.now()) { 15333 let elapsedMS; 15334 if (currentTime > this.lastTime) { 15335 if (elapsedMS = this.elapsedMS = currentTime - this.lastTime, elapsedMS > this._maxElapsedMS && (elapsedMS = this._maxElapsedMS), elapsedMS *= this.speed, this._minElapsedMS) { 15336 const delta = currentTime - this._lastFrame | 0; 15337 if (delta < this._minElapsedMS) 15338 return; 15339 this._lastFrame = currentTime - delta % this._minElapsedMS; 15340 } 15341 this.deltaMS = elapsedMS, this.deltaTime = this.deltaMS * _Ticker2.targetFPMS; 15342 const head = this._head; 15343 let listener = head.next; 15344 for (; listener; ) 15345 listener = listener.emit(this.deltaTime); 15346 head.next || this._cancelIfNeeded(); 15347 } else 15348 this.deltaTime = this.deltaMS = this.elapsedMS = 0; 15349 this.lastTime = currentTime; 15350 } 15351 /** 15352 * The frames per second at which this ticker is running. 15353 * The default is approximately 60 in most modern browsers. 15354 * **Note:** This does not factor in the value of 15355 * {@link PIXI.Ticker#speed}, which is specific 15356 * to scaling {@link PIXI.Ticker#deltaTime}. 15357 * @member {number} 15358 * @readonly 15359 */ 15360 get FPS() { 15361 return 1e3 / this.elapsedMS; 15362 } 15363 /** 15364 * Manages the maximum amount of milliseconds allowed to 15365 * elapse between invoking {@link PIXI.Ticker#update}. 15366 * This value is used to cap {@link PIXI.Ticker#deltaTime}, 15367 * but does not effect the measured value of {@link PIXI.Ticker#FPS}. 15368 * When setting this property it is clamped to a value between 15369 * `0` and `Ticker.targetFPMS * 1000`. 15370 * @member {number} 15371 * @default 10 15372 */ 15373 get minFPS() { 15374 return 1e3 / this._maxElapsedMS; 15375 } 15376 set minFPS(fps) { 15377 const minFPS = Math.min(this.maxFPS, fps), minFPMS = Math.min(Math.max(0, minFPS) / 1e3, _Ticker2.targetFPMS); 15378 this._maxElapsedMS = 1 / minFPMS; 15379 } 15380 /** 15381 * Manages the minimum amount of milliseconds required to 15382 * elapse between invoking {@link PIXI.Ticker#update}. 15383 * This will effect the measured value of {@link PIXI.Ticker#FPS}. 15384 * If it is set to `0`, then there is no limit; PixiJS will render as many frames as it can. 15385 * Otherwise it will be at least `minFPS` 15386 * @member {number} 15387 * @default 0 15388 */ 15389 get maxFPS() { 15390 return this._minElapsedMS ? Math.round(1e3 / this._minElapsedMS) : 0; 15391 } 15392 set maxFPS(fps) { 15393 if (fps === 0) 15394 this._minElapsedMS = 0; 15395 else { 15396 const maxFPS = Math.max(this.minFPS, fps); 15397 this._minElapsedMS = 1 / (maxFPS / 1e3); 15398 } 15399 } 15400 /** 15401 * The shared ticker instance used by {@link PIXI.AnimatedSprite} and by 15402 * {@link PIXI.VideoResource} to update animation frames / video textures. 15403 * 15404 * It may also be used by {@link PIXI.Application} if created with the `sharedTicker` option property set to true. 15405 * 15406 * The property {@link PIXI.Ticker#autoStart} is set to `true` for this instance. 15407 * Please follow the examples for usage, including how to opt-out of auto-starting the shared ticker. 15408 * @example 15409 * import { Ticker } from 'pixi.js'; 15410 * 15411 * const ticker = Ticker.shared; 15412 * // Set this to prevent starting this ticker when listeners are added. 15413 * // By default this is true only for the PIXI.Ticker.shared instance. 15414 * ticker.autoStart = false; 15415 * 15416 * // FYI, call this to ensure the ticker is stopped. It should be stopped 15417 * // if you have not attempted to render anything yet. 15418 * ticker.stop(); 15419 * 15420 * // Call this when you are ready for a running shared ticker. 15421 * ticker.start(); 15422 * @example 15423 * import { autoDetectRenderer, Container } from 'pixi.js'; 15424 * 15425 * // You may use the shared ticker to render... 15426 * const renderer = autoDetectRenderer(); 15427 * const stage = new Container(); 15428 * document.body.appendChild(renderer.view); 15429 * ticker.add((time) => renderer.render(stage)); 15430 * 15431 * // Or you can just update it manually. 15432 * ticker.autoStart = false; 15433 * ticker.stop(); 15434 * const animate = (time) => { 15435 * ticker.update(time); 15436 * renderer.render(stage); 15437 * requestAnimationFrame(animate); 15438 * }; 15439 * animate(performance.now()); 15440 * @member {PIXI.Ticker} 15441 * @static 15442 */ 15443 static get shared() { 15444 if (!_Ticker2._shared) { 15445 const shared = _Ticker2._shared = new _Ticker2(); 15446 shared.autoStart = !0, shared._protected = !0; 15447 } 15448 return _Ticker2._shared; 15449 } 15450 /** 15451 * The system ticker instance used by {@link PIXI.BasePrepare} for core timing 15452 * functionality that shouldn't usually need to be paused, unlike the `shared` 15453 * ticker which drives visual animations and rendering which may want to be paused. 15454 * 15455 * The property {@link PIXI.Ticker#autoStart} is set to `true` for this instance. 15456 * @member {PIXI.Ticker} 15457 * @static 15458 */ 15459 static get system() { 15460 if (!_Ticker2._system) { 15461 const system = _Ticker2._system = new _Ticker2(); 15462 system.autoStart = !0, system._protected = !0; 15463 } 15464 return _Ticker2._system; 15465 } 15466}; 15467_Ticker.targetFPMS = 0.06; 15468let Ticker = _Ticker;
vendor: 2,149 bytes, lines 15469-15551
15469 15470Object.defineProperties(settings, { 15471 /** 15472 * Target frames per millisecond. 15473 * @static 15474 * @name TARGET_FPMS 15475 * @memberof PIXI.settings 15476 * @type {number} 15477 * @deprecated since 7.1.0 15478 * @see PIXI.Ticker.targetFPMS 15479 */ 15480 TARGET_FPMS: { 15481 get() { 15482 return Ticker.targetFPMS; 15483 }, 15484 set(value) { 15485 deprecation("7.1.0", "settings.TARGET_FPMS is deprecated, use Ticker.targetFPMS"), Ticker.targetFPMS = value; 15486 } 15487 } 15488}); 15489 15490class TickerPlugin { 15491 /** 15492 * Initialize the plugin with scope of application instance 15493 * @static 15494 * @private 15495 * @param {object} [options] - See application options 15496 */ 15497 static init(options) { 15498 options = Object.assign({ 15499 autoStart: !0, 15500 sharedTicker: !1 15501 }, options), Object.defineProperty( 15502 this, 15503 "ticker", 15504 { 15505 set(ticker) { 15506 this._ticker && this._ticker.remove(this.render, this), this._ticker = ticker, ticker && ticker.add(this.render, this, UPDATE_PRIORITY.LOW); 15507 }, 15508 get() { 15509 return this._ticker; 15510 } 15511 } 15512 ), this.stop = () => { 15513 this._ticker.stop(); 15514 }, this.start = () => { 15515 this._ticker.start(); 15516 }, this._ticker = null, this.ticker = options.sharedTicker ? Ticker.shared : new Ticker(), options.autoStart && this.start(); 15517 } 15518 /** 15519 * Clean up the ticker, scoped to application. 15520 * @static 15521 * @private 15522 */ 15523 static destroy() { 15524 if (this._ticker) { 15525 const oldTicker = this._ticker; 15526 this.ticker = null, oldTicker.destroy(); 15527 } 15528 } 15529} 15530TickerPlugin.extension = ExtensionType.Application; 15531extensions$1.add(TickerPlugin); 15532 15533const renderers = []; 15534extensions$1.handleByList(ExtensionType.Renderer, renderers); 15535function autoDetectRenderer(options) { 15536 for (const RendererType of renderers) 15537 if (RendererType.test(options)) 15538 return new RendererType(options); 15539 throw new Error("Unable to auto-detect a suitable renderer."); 15540} 15541 15542var $defaultVertex = `attribute vec2 aVertexPosition; 15543attribute vec2 aTextureCoord; 15544 15545uniform mat3 projectionMatrix; 15546 15547varying vec2 vTextureCoord; 15548 15549void main(void) 15550{ 15551 gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0
15551)).xy, 0.0, 1.0); 15552 vTextureCoord = aTextureCoord; 15553}`; 15554 15555var $defaultFilterVertex = `attribute vec2 aVertexPosition; 15556 15557uniform mat3 projectionMatrix; 15558 15559varying vec2 vTextureCoord; 15560 15561uniform vec4 inputSize; 15562uniform vec4 outputFrame; 15563 15564vec4 filterVertexPosition( void ) 15565{ 15566 vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy; 15567 15568 return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0); 15569} 15570 15571vec2 filterTextureCoord( void ) 15572{ 15573 return aVertexPosition * (outputFrame.zw * inputSize.zw); 15574} 15575 15576void main(void) 15577{ 15578 gl_Position = filterVertexPosition(); 15579 vTextureCoord = filterTextureCoord(); 15580} 15581`; 15582 15583const defaultVertex = $defaultVertex, defaultFilterVertex = $defaultFilterVertex; 15584 15585class MultisampleSystem { 15586 constructor(renderer) { 15587 this.renderer = renderer; 15588 } 15589 contextChange(gl) { 15590 let samples; 15591 if (this.renderer.context.webGLVersion === 1) { 15592 const framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING); 15593 gl.bindFramebuffer(gl.FRAMEBUFFER, null), samples = gl.getParameter(gl.SAMPLES), gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 15594 } else { 15595 const framebuffer = gl.getParameter(gl.DRAW_FRAMEBUFFER_BINDING); 15596 gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null), samples = gl.getParameter(gl.SAMPLES), gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, framebuffer); 15597 } 15598 samples >= MSAA_QUALITY.HIGH ? this.multisample = MSAA_QUALITY.HIGH : samples >= MSAA_QUALITY.MEDIUM ? this.multisample = MSAA_QUALITY.MEDIUM : samples >= MSAA_QUALITY.LOW ? this.multisample = MSAA_QUALITY.LOW : this.multisample = MSAA_QUALITY.NONE; 15599 } 15600 destroy() { 15601 } 15602} 15603MultisampleSystem.extension = { 15604 type: ExtensionType.RendererSystem, 15605 name: "_multisample" 15606}; 15607extensions$1.add(MultisampleSystem); 15608 15609class GLBuffer { 15610 constructor(buffer) { 15611 this.buffer = buffer || null, this.updateID = -1, this.byteLength = -1, this.refCount = 0; 15612 } 15613} 15614 15615class BufferSystem { 15616 /** 15617 * @param {PIXI.Renderer} renderer - The renderer this System works for. 15618 */ 15619 constructor(renderer) { 15620 this.renderer = renderer, this.managedBuffers = {}, this.boundBufferBases = {}; 15621 } 15622 /** 15623 * @ignore 15624 */ 15625 destroy() { 15626 this.renderer = null; 15627 } 15628 /** Sets up the renderer context and necessary buffers. */ 15629 contextChange() { 15630 this.disposeAll(!0), this.gl = this.renderer.gl, this.CONTEXT_UID = this.renderer.CONTEXT_UID; 15631 } 15632 /** 15633 * This binds specified buffer. On first run, it will create the webGL buffers for the context too 15634 * @param buffer - the buffer to bind to the renderer 15635 */ 15636 bind(buffer) { 15637 const { gl, CONTEXT_UID } = this, glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer); 15638 gl.bindBuffer(buffer.type, glBuffer.buffer); 15639 } 15640 unbind(type) { 15641 const { gl } = this; 15642 gl.bindBuffer(type, null); 15643 } 15644 /** 15645 * Binds an uniform buffer to at the given index. 15646 * 15647 * A cache is used so a buffer will not be bound again if already bound. 15648 * @param buffer - the buffer to bind 15649 * @param index - the base index to bind it to. 15650 */ 15651 bindBufferBase(buffer, index) { 15652 const { gl, CONTEXT_UID } = this; 15653 if (this.boundBufferBases[index] !== buffer) { 15654 const glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer); 15655 this.boundBufferBases[index] = buffer, gl.bindBufferBase(gl.UNIFORM_BUFFER, index, glBuffer.buffer); 15656 } 15657 } 15658 /** 15659 * Binds a buffer whilst also binding its range. 15660 * This will make the buffer start from the offset supplied rather than 0 when it is read. 15661 * @param buffer - the buffer to bind 15662 * @param index - the base index to bind at, defaults to 0 15663 * @param offset - the offset to bind at (this is blocks of 256). 0 = 0, 1 = 256, 2 = 512 etc 15664 */ 15665 bindBufferRange(buffer, index, offset) { 15666 const { gl, CONTEXT_UID } = this; 15667 offset = offset || 0; 15668 const glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer); 15669 gl.bindBufferRange(gl.UNIFORM_BUFFER, index || 0, glBuffer.buffer, offset * 256, 256); 15670 } 15671 /** 15672 * Will ensure the data in the buffer is uploaded to the GPU. 15673 * @param {PIXI.Buffer} buffer - the buffer to update 15674 */ 15675 update(buffer) { 15676 const { gl, CONTEXT_UID } = this, glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer); 15677 if (buffer._updateID !== glBuffer.updateID) 15678 if (glBuffer.updateID = buffer._updateID, gl.bindBuffer(buffer.type, glBuffer.buffer), glBuffer.byteLength >= buffer.data.byteLength) 15679 gl.bufferSubData(buffer.type, 0, buffer.data); 15680 else { 15681 const drawType = buffer.static ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW; 15682 glBuffer.byteLength = buffer.data.byteLength, gl.bufferData(buffer.type, buffer.data, drawType); 15683 } 15684 } 15685 /** 15686 * Disposes buffer 15687 * @param {PIXI.Buffer} buffer - buffer with data 15688 * @param {boolean} [contextLost=false] - If context was lost, we suppress deleteVertexArray 15689 */ 15690 dispose(buffer, contextLost) { 15691 if (!this.managedBuffers[buffer.id]) 15692 return; 15693 delete this.managedBuffers[buffer.id]; 15694 const glBuffer = buffer._glBuffers[this.CONTEXT_UID], gl = this.gl; 15695 buffer.disposeRunner.remove(this), glBuffer && (contextLost || gl.deleteBuffer(glBuffer.buffer), delete buffer._glBuffers[this.CONTEXT_UID]); 15696 } 15697 /** 15698 * dispose all WebGL resources of all managed buffers 15699 * @param {boolean} [contextLost=false] - If context was lost, we suppress `gl.delete` calls 15700 */ 15701 disposeAll(contextLost) { 15702 const all = Object.keys(this.managedBuffers); 15703 for (let i = 0; i < all.length; i++) 15704 this.dispose(this.managedBuffers[all[i]], contextLost); 15705 } 15706 /** 15707 * creates and attaches a GLBuffer object tied to the current context. 15708 * @param buffer 15709 * @protected 15710 */ 15711 createGLBuffer(buffer) { 15712 const { CONTEXT_UID, gl } = this; 15713 return buffer._glBuffers[CONTEXT_UID] = new GLBuffer(gl.createBuffer()), this.managedBuffers[buffer.id] = buffer, buffer.disposeRunner.add(this), buffer._glBuffers[CONTEXT_UID]; 15714 } 15715} 15716BufferSystem.extension = { 15717 type: ExtensionType.RendererSystem, 15718 name: "buffer" 15719}; 15720extensions$1.add(BufferSystem); 15721 15722class ObjectRendererSystem { 15723 // renderers scene graph! 15724 constructor(renderer) { 15725 this.renderer = renderer; 15726 } 15727 /** 15728 * Renders the object to its WebGL view. 15729 * @param displayObject - The object to be rendered. 15730 * @param options - the options to be passed to the renderer 15731 */ 15732 render(displayObject, options) { 15733 const renderer = this.renderer; 15734 let renderTexture, clear, transform, skipUpdateTransform; 15735 if (options && (renderTexture = options.renderTexture, clear = options.clear, transform = options.transform, skipUpdateTransform = options.skipUpdateTransform), this.renderingToScreen = !renderTexture, renderer.runners.prerender.emit(), renderer.emit("prerender"), renderer.projection.transform = transform, !renderer.context.
vendor: 6,851 bytes, lines 15735-15921
15735isLost) { 15736 if (renderTexture || (this.lastObjectRendered = displayObject), !skipUpdateTransform) { 15737 const cacheParent = displayObject.enableTempParent(); 15738 displayObject.updateTransform(), displayObject.disableTempParent(cacheParent); 15739 } 15740 renderer.renderTexture.bind(renderTexture), renderer.batch.currentRenderer.start(), (clear ?? renderer.background.clearBeforeRender) && renderer.renderTexture.clear(), displayObject.render(renderer), renderer.batch.currentRenderer.flush(), renderTexture && (options.blit && renderer.framebuffer.blit(), renderTexture.baseTexture.update()), renderer.runners.postrender.emit(), renderer.projection.transform = null, renderer.emit("postrender"); 15741 } 15742 } 15743 destroy() { 15744 this.renderer = null, this.lastObjectRendered = null; 15745 } 15746} 15747ObjectRendererSystem.extension = { 15748 type: ExtensionType.RendererSystem, 15749 name: "objectRenderer" 15750}; 15751extensions$1.add(ObjectRendererSystem); 15752 15753const _Renderer = class _Renderer2 extends SystemManager { 15754 /** 15755 * @param {PIXI.IRendererOptions} [options] - See {@link PIXI.settings.RENDER_OPTIONS} for defaults. 15756 */ 15757 constructor(options) { 15758 super(), this.type = RENDERER_TYPE.WEBGL, options = Object.assign({}, settings.RENDER_OPTIONS, options), this.gl = null, this.CONTEXT_UID = 0, this.globalUniforms = new UniformGroup({ 15759 projectionMatrix: new Matrix() 15760 }, !0); 15761 const systemConfig = { 15762 runners: [ 15763 "init", 15764 "destroy", 15765 "contextChange", 15766 "resolutionChange", 15767 "reset", 15768 "update", 15769 "postrender", 15770 "prerender", 15771 "resize" 15772 ], 15773 systems: _Renderer2.__systems, 15774 priority: [ 15775 "_view", 15776 "textureGenerator", 15777 "background", 15778 "_plugin", 15779 "startup", 15780 // low level WebGL systems 15781 "context", 15782 "state", 15783 "texture", 15784 "buffer", 15785 "geometry", 15786 "framebuffer", 15787 "transformFeedback", 15788 // high level pixi specific rendering 15789 "mask", 15790 "scissor", 15791 "stencil", 15792 "projection", 15793 "textureGC", 15794 "filter", 15795 "renderTexture", 15796 "batch", 15797 "objectRenderer", 15798 "_multisample" 15799 ] 15800 }; 15801 this.setup(systemConfig), "useContextAlpha" in options && (deprecation("7.0.0", "options.useContextAlpha is deprecated, use options.premultipliedAlpha and options.backgroundAlpha instead"), options.premultipliedAlpha = options.useContextAlpha && options.useContextAlpha !== "notMultiplied", options.backgroundAlpha = options.useContextAlpha === !1 ? 1 : options.backgroundAlpha), this._plugin.rendererPlugins = _Renderer2.__plugins, this.options = options, this.startup.run(this.options); 15802 } 15803 /** 15804 * Create renderer if WebGL is available. Overrideable 15805 * by the **@pixi/canvas-renderer** package to allow fallback. 15806 * throws error if WebGL is not available. 15807 * @param options 15808 * @private 15809 */ 15810 static test(options) { 15811 return options?.forceCanvas ? !1 : isWebGLSupported(); 15812 } 15813 /** 15814 * Renders the object to its WebGL view. 15815 * @param displayObject - The object to be rendered. 15816 * @param {object} [options] - Object to use for render options. 15817 * @param {PIXI.RenderTexture} [options.renderTexture] - The render texture to render to. 15818 * @param {boolean} [options.clear=true] - Should the canvas be cleared before the new render. 15819 * @param {PIXI.Matrix} [options.transform] - A transform to apply to the render texture before rendering. 15820 * @param {boolean} [options.skipUpdateTransform=false] - Should we skip the update transform pass? 15821 */ 15822 render(displayObject, options) { 15823 this.objectRenderer.render(displayObject, options); 15824 } 15825 /** 15826 * Resizes the WebGL view to the specified width and height. 15827 * @param desiredScreenWidth - The desired width of the screen. 15828 * @param desiredScreenHeight - The desired height of the screen. 15829 */ 15830 resize(desiredScreenWidth, desiredScreenHeight) { 15831 this._view.resizeView(desiredScreenWidth, desiredScreenHeight); 15832 } 15833 /** 15834 * Resets the WebGL state so you can render things however you fancy! 15835 * @returns Returns itself. 15836 */ 15837 reset() { 15838 return this.runners.reset.emit(), this; 15839 } 15840 /** Clear the frame buffer. */ 15841 clear() { 15842 this.renderTexture.bind(), this.renderTexture.clear(); 15843 } 15844 /** 15845 * Removes everything from the renderer (event listeners, spritebatch, etc...) 15846 * @param [removeView=false] - Removes the Canvas element from the DOM. 15847 * See: https://github.com/pixijs/pixijs/issues/2233 15848 */ 15849 destroy(removeView = !1) { 15850 this.runners.destroy.items.reverse(), this.emitWithCustomOptions(this.runners.destroy, { 15851 _view: removeView 15852 }), super.destroy(); 15853 } 15854 /** Collection of plugins */ 15855 get plugins() { 15856 return this._plugin.plugins; 15857 } 15858 /** The number of msaa samples of the canvas. */ 15859 get multisample() { 15860 return this._multisample.multisample; 15861 } 15862 /** 15863 * Same as view.width, actual number of pixels in the canvas by horizontal. 15864 * @member {number} 15865 * @readonly 15866 * @default 800 15867 */ 15868 get width() { 15869 return this._view.element.width; 15870 } 15871 /** 15872 * Same as view.height, actual number of pixels in the canvas by vertical. 15873 * @default 600 15874 */ 15875 get height() { 15876 return this._view.element.height; 15877 } 15878 /** The resolution / device pixel ratio of the renderer. */ 15879 get resolution() { 15880 return this._view.resolution; 15881 } 15882 set resolution(value) { 15883 this._view.resolution = value, this.runners.resolutionChange.emit(value); 15884 } 15885 /** Whether CSS dimensions of canvas view should be resized to screen dimensions automatically. */ 15886 get autoDensity() { 15887 return this._view.autoDensity; 15888 } 15889 /** The canvas element that everything is drawn to.*/ 15890 get view() { 15891 return this._view.element; 15892 } 15893 /** 15894 * Measurements of the screen. (0, 0, screenWidth, screenHeight). 15895 * 15896 * Its safe to use as filterArea or hitArea for the whole stage. 15897 * @member {PIXI.Rectangle} 15898 */ 15899 get screen() { 15900 return this._view.screen; 15901 } 15902 /** the last object rendered by the renderer. Useful for other plugins like interaction managers */ 15903 get lastObjectRendered() { 15904 return this.objectRenderer.lastObjectRendered; 15905 } 15906 /** Flag if we are rendering to the screen vs renderTexture */ 15907 get renderingToScreen() { 15908 return this.objectRenderer.renderingToScreen; 15909 } 15910 /** When logging Pixi to the console, this is the name we will show */ 15911 get rendererLogId() { 15912 return `WebGL ${this.context.webGLVersion}`; 15913 } 15914 /** 15915 * This sets weather the screen is totally cleared between each frame withthe background color and alpha 15916 * @deprecated since 7.0.0 15917 */ 15918 get clearBeforeRender() { 15919 return deprecation("7.0.0", "renderer.clearBeforeRender has been deprecated, please use renderer.background.clearBeforeRender instead."), this.background.clearBeforeRender; 15920 } 15921 /**
15922 * Pass-thru setting for the canvas' context `alpha` property. This is typically 15923 * not something you need to fiddle with. If you want transparency, use `backgroundAlpha`. 15924 * @deprecated since 7.0.0 15925 * @member {boolean} 15926 */ 15927 get useContextAlpha() { 15928 return deprecation("7.0.0", "renderer.useContextAlpha has been deprecated, please use renderer.context.premultipliedAlpha instead."), this.context.useContextAlpha; 15929 } 15930 /** 15931 * readonly drawing buffer preservation 15932 * we can only know this if Pixi created the context 15933 * @deprecated since 7.0.0 15934 */ 15935 get preserveDrawingBuffer() { 15936 return deprecation("7.0.0", "renderer.preserveDrawingBuffer has been deprecated, we cannot truly know this unless pixi created the context"), this.context.preserveDrawingBuffer; 15937 } 15938 /** 15939 * The background color to fill if not transparent 15940 * @member {number} 15941 * @deprecated since 7.0.0 15942 */ 15943 get backgroundColor() { 15944 return deprecation("7.0.0", "renderer.backgroundColor has been deprecated, use renderer.background.color instead."), this.background.color; 15945 } 15946 set backgroundColor(value) { 15947 deprecation("7.0.0", "renderer.backgroundColor has been deprecated, use renderer.background.color instead."), this.background.color = value; 15948 } 15949 /** 15950 * The background color alpha. Setting this to 0 will make the canvas transparent. 15951 * @member {number} 15952 * @deprecated since 7.0.0 15953 */ 15954 get backgroundAlpha() { 15955 return deprecation("7.0.0", "renderer.backgroundAlpha has been deprecated, use renderer.background.alpha instead."), this.background.alpha; 15956 } 15957 /** 15958 * @deprecated since 7.0.0 15959 */ 15960 set backgroundAlpha(value) { 15961 deprecation("7.0.0", "renderer.backgroundAlpha has been deprecated, use renderer.background.alpha instead."), this.background.alpha = value; 15962 } 15963 /** 15964 * @deprecated since 7.0.0 15965 */ 15966 get powerPreference() { 15967 return deprecation("7.0.0", "renderer.powerPreference has been deprecated, we can only know this if pixi creates the context"), this.context.powerPreference; 15968 } 15969 /** 15970 * Useful function that returns a texture of the display object that can then be used to create sprites 15971 * This can be quite useful if your displayObject is complicated and needs to be reused multiple times. 15972 * @param displayObject - The displayObject the object will be generated from. 15973 * @param {IGenerateTextureOptions} options - Generate texture options. 15974 * @param {PIXI.Rectangle} options.region - The region of the displayObject, that shall be rendered, 15975 * if no region is specified, defaults to the local bounds of the displayObject. 15976 * @param {number} [options.resolution] - If not given, the renderer's resolution is used. 15977 * @param {PIXI.MSAA_QUALITY} [options.multisample] - If not given, the renderer's multisample is used. 15978 * @returns A texture of the graphics object. 15979 */ 15980 generateTexture(displayObject, options) { 15981 return this.textureGenerator.generateTexture(displayObject, options); 15982 } 15983}; 15984_Renderer.extension = { 15985 type: ExtensionType.Renderer, 15986 priority: 1 15987}, /** 15988* Collection of installed plugins. These are included by default in PIXI, but can be excluded 15989* by creating a custom build. Consult the README for more information about creating custom 15990* builds and excluding plugins. 15991* @private 15992*/ 15993_Renderer.__plugins = {}, /** 15994* The collection of installed systems. 15995* @private 15996*/ 15997_Renderer.__systems = {}; 15998let Renderer = _Renderer; 15999extensions$1.handleByMap(ExtensionType.RendererPlugin, Renderer.__plugins); 16000extensions$1.handleByMap(ExtensionType.RendererSystem, Renderer.__systems); 16001extensions$1.add(Renderer); 16002 16003class AbstractMultiResource extends Resource { 16004 /** 16005 * @param length 16006 * @param options - Options to for Resource constructor 16007 * @param {number} [options.width] - Width of the resource 16008 * @param {number} [options.height] - Height of the resource 16009 */ 16010 constructor(length, options) { 16011 const { width, height } = options || {}; 16012 super(width, height), this.items = [], this.itemDirtyIds = []; 16013 for (let i = 0; i < length; i++) { 16014 const partTexture = new BaseTexture(); 16015 this.items.push(partTexture), this.itemDirtyIds.push(-2); 16016 } 16017 this.length = length, this._load = null, this.baseTexture = null; 16018 } 16019 /**
vendor: 37,664 bytes, lines 16020-16808
16020 * Used from ArrayResource and CubeResource constructors. 16021 * @param resources - Can be resources, image elements, canvas, etc. , 16022 * length should be same as constructor length 16023 * @param options - Detect options for resources 16024 */ 16025 initFromArray(resources, options) { 16026 for (let i = 0; i < this.length; i++) 16027 resources[i] && (resources[i].castToBaseTexture ? this.addBaseTextureAt(resources[i].castToBaseTexture(), i) : resources[i] instanceof Resource ? this.addResourceAt(resources[i], i) : this.addResourceAt(autoDetectResource(resources[i], options), i)); 16028 } 16029 /** Destroy this BaseImageResource. */ 16030 dispose() { 16031 for (let i = 0, len = this.length; i < len; i++) 16032 this.items[i].destroy(); 16033 this.items = null, this.itemDirtyIds = null, this._load = null; 16034 } 16035 /** 16036 * Set a resource by ID 16037 * @param resource 16038 * @param index - Zero-based index of resource to set 16039 * @returns - Instance for chaining 16040 */ 16041 addResourceAt(resource, index) { 16042 if (!this.items[index]) 16043 throw new Error(`Index ${index} is out of bounds`); 16044 return resource.valid && !this.valid && this.resize(resource.width, resource.height), this.items[index].setResource(resource), this; 16045 } 16046 /** 16047 * Set the parent base texture. 16048 * @param baseTexture 16049 */ 16050 bind(baseTexture) { 16051 if (this.baseTexture !== null) 16052 throw new Error("Only one base texture per TextureArray is allowed"); 16053 super.bind(baseTexture); 16054 for (let i = 0; i < this.length; i++) 16055 this.items[i].parentTextureArray = baseTexture, this.items[i].on("update", baseTexture.update, baseTexture); 16056 } 16057 /** 16058 * Unset the parent base texture. 16059 * @param baseTexture 16060 */ 16061 unbind(baseTexture) { 16062 super.unbind(baseTexture); 16063 for (let i = 0; i < this.length; i++) 16064 this.items[i].parentTextureArray = null, this.items[i].off("update", baseTexture.update, baseTexture); 16065 } 16066 /** 16067 * Load all the resources simultaneously 16068 * @returns - When load is resolved 16069 */ 16070 load() { 16071 if (this._load) 16072 return this._load; 16073 const promises = this.items.map((item) => item.resource).filter((item) => item).map((item) => item.load()); 16074 return this._load = Promise.all(promises).then( 16075 () => { 16076 const { realWidth, realHeight } = this.items[0]; 16077 return this.resize(realWidth, realHeight), this.update(), Promise.resolve(this); 16078 } 16079 ), this._load; 16080 } 16081} 16082 16083class ArrayResource extends AbstractMultiResource { 16084 /** 16085 * @param source - Number of items in array or the collection 16086 * of image URLs to use. Can also be resources, image elements, canvas, etc. 16087 * @param options - Options to apply to {@link PIXI.autoDetectResource} 16088 * @param {number} [options.width] - Width of the resource 16089 * @param {number} [options.height] - Height of the resource 16090 */ 16091 constructor(source, options) { 16092 const { width, height } = options || {}; 16093 let urls, length; 16094 Array.isArray(source) ? (urls = source, length = source.length) : length = source, super(length, { width, height }), urls && this.initFromArray(urls, options); 16095 } 16096 /** 16097 * Set a baseTexture by ID, 16098 * ArrayResource just takes resource from it, nothing more 16099 * @param baseTexture 16100 * @param index - Zero-based index of resource to set 16101 * @returns - Instance for chaining 16102 */ 16103 addBaseTextureAt(baseTexture, index) { 16104 if (baseTexture.resource) 16105 this.addResourceAt(baseTexture.resource, index); 16106 else 16107 throw new Error("ArrayResource does not support RenderTexture"); 16108 return this; 16109 } 16110 /** 16111 * Add binding 16112 * @param baseTexture 16113 */ 16114 bind(baseTexture) { 16115 super.bind(baseTexture), baseTexture.target = TARGETS.TEXTURE_2D_ARRAY; 16116 } 16117 /** 16118 * Upload the resources to the GPU. 16119 * @param renderer 16120 * @param texture 16121 * @param glTexture 16122 * @returns - whether texture was uploaded 16123 */ 16124 upload(renderer, texture, glTexture) { 16125 const { length, itemDirtyIds, items } = this, { gl } = renderer; 16126 glTexture.dirtyId < 0 && gl.texImage3D( 16127 gl.TEXTURE_2D_ARRAY, 16128 0, 16129 glTexture.internalFormat, 16130 this._width, 16131 this._height, 16132 length, 16133 0, 16134 texture.format, 16135 glTexture.type, 16136 null 16137 ); 16138 for (let i = 0; i < length; i++) { 16139 const item = items[i]; 16140 itemDirtyIds[i] < item.dirtyId && (itemDirtyIds[i] = item.dirtyId, item.valid && gl.texSubImage3D( 16141 gl.TEXTURE_2D_ARRAY, 16142 0, 16143 0, 16144 // xoffset 16145 0, 16146 // yoffset 16147 i, 16148 // zoffset 16149 item.resource.width, 16150 item.resource.height, 16151 1, 16152 texture.format, 16153 glTexture.type, 16154 item.resource.source 16155 )); 16156 } 16157 return !0; 16158 } 16159} 16160 16161class CanvasResource extends BaseImageResource { 16162 /** 16163 * @param source - Canvas element to use 16164 */ 16165 // eslint-disable-next-line @typescript-eslint/no-useless-constructor 16166 constructor(source) { 16167 super(source); 16168 } 16169 /** 16170 * Used to auto-detect the type of resource. 16171 * @param {*} source - The source object 16172 * @returns {boolean} `true` if source is HTMLCanvasElement or OffscreenCanvas 16173 */ 16174 static test(source) { 16175 const { OffscreenCanvas } = globalThis; 16176 return OffscreenCanvas && source instanceof OffscreenCanvas ? !0 : globalThis.HTMLCanvasElement && source instanceof HTMLCanvasElement; 16177 } 16178} 16179 16180const _CubeResource = class _CubeResource2 extends AbstractMultiResource { 16181 /** 16182 * @param {Array<string|PIXI.Resource>} [source] - Collection of URLs or resources 16183 * to use as the sides of the cube. 16184 * @param options - ImageResource options 16185 * @param {number} [options.width] - Width of resource 16186 * @param {number} [options.height] - Height of resource 16187 * @param {number} [options.autoLoad=true] - Whether to auto-load resources 16188 * @param {number} [options.linkBaseTexture=true] - In case BaseTextures are supplied, 16189 * whether to copy them or use 16190 */ 16191 constructor(source, options) { 16192 const { width, height, autoLoad, linkBaseTexture } = options || {}; 16193 if (source && source.length !== _CubeResource2.SIDES) 16194 throw new Error(`Invalid length. Got ${source.length}, expected 6`); 16195 super(6, { width, height }); 16196 for (let i = 0; i < _CubeResource2.SIDES; i++) 16197 this.items[i].target = TARGETS.TEXTURE_CUBE_MAP_POSITIVE_X + i; 16198 this.linkBaseTexture = linkBaseTexture !== !1, source && this.initFromArray(source, options), autoLoad !== !1 && this.load(); 16199 } 16200 /** 16201 * Add binding. 16202 * @param baseTexture - parent base texture 16203 */ 16204 bind(baseTexture) { 16205 super.bind(baseTexture), baseTexture.target = TARGETS.TEXTURE_CUBE_MAP; 16206 } 16207 addBaseTextureAt(baseTexture, index, linkBaseTexture) { 16208 if (linkBaseTexture === void 0 && (linkBaseTexture = this.linkBaseTexture), !this.items[index]) 16209 throw new Error(`Index ${index} is out of bounds`); 16210 if (!this.linkBaseTexture || baseTexture.parentTextureArray || Object.keys(baseTexture._glTextures).length > 0) 16211 if (baseTexture.resource) 16212 this.addResourceAt(baseTexture.resource, index); 16213 else 16214 throw new Error("CubeResource does not support copying of renderTexture."); 16215 else 16216 baseTexture.target = TARGETS.TEXTURE_CUBE_MAP_POSITIVE_X + index, baseTexture.parentTextureArray = this.baseTexture, this.items[index] = baseTexture; 16217 return baseTexture.valid && !this.valid && this.resize(baseTexture.realWidth, baseTexture.realHeight), this.items[index] = baseTexture, this; 16218 } 16219 /** 16220 * Upload the resource 16221 * @param renderer 16222 * @param _baseTexture 16223 * @param glTexture 16224 * @returns {boolean} true is success 16225 */ 16226 upload(renderer, _baseTexture, glTexture) { 16227 const dirty = this.itemDirtyIds; 16228 for (let i = 0; i < _CubeResource2.SIDES; i++) { 16229 const side = this.items[i]; 16230 (dirty[i] < side.dirtyId || glTexture.dirtyId < _baseTexture.dirtyId) && (side.valid && side.resource ? (side.resource.upload(renderer, side, glTexture), dirty[i] = side.dirtyId) : dirty[i] < -1 && (renderer.gl.texImage2D( 16231 side.target, 16232 0, 16233 glTexture.internalFormat, 16234 _baseTexture.realWidth, 16235 _baseTexture.realHeight, 16236 0, 16237 _baseTexture.format, 16238 glTexture.type, 16239 null 16240 ), dirty[i] = -1)); 16241 } 16242 return !0; 16243 } 16244 /** 16245 * Used to auto-detect the type of resource. 16246 * @param {*} source - The source object 16247 * @returns {boolean} `true` if source is an array of 6 elements 16248 */ 16249 static test(source) { 16250 return Array.isArray(source) && source.length === _CubeResource2.SIDES; 16251 } 16252}; 16253_CubeResource.SIDES = 6; 16254let CubeResource = _CubeResource; 16255 16256class ImageBitmapResource extends BaseImageResource { 16257 /** 16258 * @param source - ImageBitmap or URL to use. 16259 * @param options - Options to use. 16260 */ 16261 constructor(source, options) { 16262 options = options || {}; 16263 let baseSource, url, ownsImageBitmap; 16264 typeof source == "string" ? (baseSource = ImageBitmapResource.EMPTY, url = source, ownsImageBitmap = !0) : (baseSource = source, url = null, ownsImageBitmap = !1), super(baseSource), this.url = url, this.crossOrigin = options.crossOrigin ?? !0, this.alphaMode = typeof options.alphaMode == "number" ? options.alphaMode : null, this.ownsImageBitmap = options.ownsImageBitmap ?? ownsImageBitmap, this._load = null, options.autoLoad !== !1 && this.load(); 16265 } 16266 load() { 16267 return this._load ? this._load : (this._load = new Promise(async (resolve, reject) => { 16268 if (this.url === null) { 16269 resolve(this); 16270 return; 16271 } 16272 try { 16273 const response = await settings.ADAPTER.fetch(this.url, { 16274 mode: this.crossOrigin ? "cors" : "no-cors" 16275 }); 16276 if (this.destroyed) 16277 return; 16278 const imageBlob = await response.blob(); 16279 if (this.destroyed) 16280 return; 16281 const imageBitmap = await createImageBitmap(imageBlob, { 16282 premultiplyAlpha: this.alphaMode === null || this.alphaMode === ALPHA_MODES.UNPACK ? "premultiply" : "none" 16283 }); 16284 if (this.destroyed) { 16285 imageBitmap.close(); 16286 return; 16287 } 16288 this.source = imageBitmap, this.update(), resolve(this); 16289 } catch (e) { 16290 if (this.destroyed) 16291 return; 16292 reject(e), this.onError.emit(e); 16293 } 16294 }), this._load); 16295 } 16296 /** 16297 * Upload the image bitmap resource to GPU. 16298 * @param renderer - Renderer to upload to 16299 * @param baseTexture - BaseTexture for this resource 16300 * @param glTexture - GLTexture to use 16301 * @returns {boolean} true is success 16302 */ 16303 upload(renderer, baseTexture, glTexture) { 16304 return this.source instanceof ImageBitmap ? (typeof this.alphaMode == "number" && (baseTexture.alphaMode = this.alphaMode), super.upload(renderer, baseTexture, glTexture)) : (this.load(), !1); 16305 } 16306 /** Destroys this resource. */ 16307 dispose() { 16308 this.ownsImageBitmap && this.source instanceof ImageBitmap && this.source.close(), super.dispose(), this._load = null; 16309 } 16310 /** 16311 * Used to auto-detect the type of resource. 16312 * @param {*} source - The source object 16313 * @returns {boolean} `true` if current environment support ImageBitmap, and source is string or ImageBitmap 16314 */ 16315 static test(source) { 16316 return !!globalThis.createImageBitmap && typeof ImageBitmap < "u" && (typeof source == "string" || source instanceof ImageBitmap); 16317 } 16318 /** 16319 * ImageBitmap cannot be created synchronously, so a empty placeholder canvas is needed when loading from URLs. 16320 * Only for internal usage. 16321 * @returns The cached placeholder canvas. 16322 */ 16323 static get EMPTY() { 16324 return ImageBitmapResource._EMPTY = ImageBitmapResource._EMPTY ?? settings.ADAPTER.createCanvas(0, 0), ImageBitmapResource._EMPTY; 16325 } 16326} 16327 16328const _SVGResource = class _SVGResource2 extends BaseImageResource { 16329 /** 16330 * @param sourceBase64 - Base64 encoded SVG element or URL for SVG file. 16331 * @param {object} [options] - Options to use 16332 * @param {number} [options.scale=1] - Scale to apply to SVG. Overridden by... 16333 * @param {number} [options.width] - Rasterize SVG this wide. Aspect ratio preserved if height not specified. 16334 * @param {number} [options.height] - Rasterize SVG this high. Aspect ratio preserved if width not specified. 16335 * @param {boolean} [options.autoLoad=true] - Start loading right away. 16336 */ 16337 constructor(sourceBase64, options) { 16338 options = options || {}, super(settings.ADAPTER.createCanvas()), this._width = 0, this._height = 0, this.svg = sourceBase64, this.scale = options.scale || 1, this._overrideWidth = options.width, this._overrideHeight = options.height, this._resolve = null, this._crossorigin = options.crossorigin, this._load = null, options.autoLoad !== !1 && this.load(); 16339 } 16340 load() { 16341 return this._load ? this._load : (this._load = new Promise((resolve) => { 16342 if (this._resolve = () => { 16343 this.update(), resolve(this); 16344 }, _SVGResource2.SVG_XML.test(this.svg.trim())) { 16345 if (!btoa) 16346 throw new Error("Your browser doesn't support base64 conversions."); 16347 this.svg = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(this.svg)))}`; 16348 } 16349 this._loadSvg(); 16350 }), this._load); 16351 } 16352 /** Loads an SVG image from `imageUrl` or `data URL`. */ 16353 _loadSvg() { 16354 const tempImage = new Image(); 16355 BaseImageResource.crossOrigin(tempImage, this.svg, this._crossorigin), tempImage.src = this.svg, tempImage.onerror = (event) => { 16356 this._resolve && (tempImage.onerror = null, this.onError.emit(event)); 16357 }, tempImage.onload = () => { 16358 if (!this._resolve) 16359 return; 16360 const svgWidth = tempImage.width, svgHeight = tempImage.height; 16361 if (!svgWidth || !svgHeight) 16362 throw new Error("The SVG image must have width and height defined (in pixels), canvas API needs them."); 16363 let width = svgWidth * this.scale, height = svgHeight * this.scale; 16364 (this._overrideWidth || this._overrideHeight) && (width = this._overrideWidth || this._overrideHeight / svgHeight * svgWidth, height = this._overrideHeight || this._overrideWidth / svgWidth * svgHeight), width = Math.round(width), height = Math.round(height); 16365 const canvas = this.source; 16366 canvas.width = width, canvas.height = height, canvas._pixiId = `canvas_${uid()}`, canvas.getContext("2d").drawImage(tempImage, 0, 0, svgWidth, svgHeight, 0, 0, width, height), this._resolve(), this._resolve = null; 16367 }; 16368 } 16369 /** 16370 * Get size from an svg string using a regular expression. 16371 * @param svgString - a serialized svg element 16372 * @returns - image extension 16373 */ 16374 static getSize(svgString) { 16375 const sizeMatch = _SVGResource2.SVG_SIZE.exec(svgString), size = {}; 16376 return sizeMatch && (size[sizeMatch[1]] = Math.round(parseFloat(sizeMatch[3])), size[sizeMatch[5]] = Math.round(parseFloat(sizeMatch[7]))), size; 16377 } 16378 /** Destroys this texture. */ 16379 dispose() { 16380 super.dispose(), this._resolve = null, this._crossorigin = null; 16381 } 16382 /** 16383 * Used to auto-detect the type of resource. 16384 * @param {*} source - The source object 16385 * @param {string} extension - The extension of source, if set 16386 * @returns {boolean} - If the source is a SVG source or data file 16387 */ 16388 static test(source, extension) { 16389 return extension === "svg" || typeof source == "string" && source.startsWith("data:image/svg+xml") || typeof source == "string" && _SVGResource2.SVG_XML.test(source); 16390 } 16391 // eslint-disable-line max-len 16392}; 16393_SVGResource.SVG_XML = /^(<\?xml[^?]+\?>)?\s*(<!--[^(-->)]*-->)?\s*\<svg/m, /** 16394* Regular expression for SVG size. 16395* @example <svg width="100" height="100"></svg> 16396* @readonly 16397*/ 16398_SVGResource.SVG_SIZE = /<svg[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*>/i; 16399let SVGResource = _SVGResource; 16400 16401const _VideoResource = class _VideoResource2 extends BaseImageResource { 16402 /** 16403 * @param {HTMLVideoElement|object|string|Array<string|object>} source - Video element to use. 16404 * @param {object} [options] - Options to use 16405 * @param {boolean} [options.autoLoad=true] - Start loading the video immediately 16406 * @param {boolean} [options.autoPlay=true] - Start playing video immediately 16407 * @param {number} [options.updateFPS=0] - How many times a second to update the texture from the video. 16408 * Leave at 0 to update at every render. 16409 * @param {boolean} [options.crossorigin=true] - Load image using cross origin 16410 * @param {boolean} [options.loop=false] - Loops the video 16411 * @param {boolean} [options.muted=false] - Mutes the video audio, useful for autoplay 16412 * @param {boolean} [options.playsinline=true] - Prevents opening the video on mobile devices 16413 */ 16414 constructor(source, options) { 16415 if (options = options || {}, !(source instanceof HTMLVideoElement)) { 16416 const videoElement = document.createElement("video"); 16417 options.autoLoad !== !1 && videoElement.setAttribute("preload", "auto"), options.playsinline !== !1 && (videoElement.setAttribute("webkit-playsinline", ""), videoElement.setAttribute("playsinline", "")), options.muted === !0 && (videoElement.setAttribute("muted", ""), videoElement.muted = !0), options.loop === !0 && videoElement.setAttribute("loop", ""), options.autoPlay !== !1 && videoElement.setAttribute("autoplay", ""), typeof source == "string" && (source = [source]); 16418 const firstSrc = source[0].src || source[0]; 16419 BaseImageResource.crossOrigin(videoElement, firstSrc, options.crossorigin); 16420 for (let i = 0; i < source.length; ++i) { 16421 const sourceElement = document.createElement("source"); 16422 let { src, mime } = source[i]; 16423 if (src = src || source[i], src.startsWith("data:")) 16424 mime = src.slice(5, src.indexOf(";")); 16425 else if (!src.startsWith("blob:")) { 16426 const baseSrc = src.split("?").shift().toLowerCase(), ext = baseSrc.slice(baseSrc.lastIndexOf(".") + 1); 16427 mime = mime || _VideoResource2.MIME_TYPES[ext] || `video/${ext}`; 16428 } 16429 sourceElement.src = src, mime && (sourceElement.type = mime), videoElement.appendChild(sourceElement); 16430 } 16431 source = videoElement; 16432 } 16433 super(source), this.noSubImage = !0, this._autoUpdate = !0, this._isConnectedToTicker = !1, this._updateFPS = options.updateFPS || 0, this._msToNextUpdate = 0, this.autoPlay = options.autoPlay !== !1, this._videoFrameRequestCallback = this._videoFrameRequestCallback.bind(this), this._videoFrameRequestCallbackHandle = null, this._load = null, this._resolve = null, this._reject = null, this._onCanPlay = this._onCanPlay.bind(this), this._onError = this._onError.bind(this), this._onPlayStart = this._onPlayStart.bind(this), this._onPlayStop = this._onPlayStop.bind(this), this._onSeeked = this._onSeeked.bind(this), options.autoLoad !== !1 && this.load(); 16434 } 16435 /** 16436 * Trigger updating of the texture. 16437 * @param _deltaTime - time delta since last tick 16438 */ 16439 update(_deltaTime = 0) { 16440 if (!this.destroyed) { 16441 if (this._updateFPS) { 16442 const elapsedMS = Ticker.shared.elapsedMS * this.source.playbackRate; 16443 this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS); 16444 } 16445 (!this._updateFPS || this._msToNextUpdate <= 0) && (super.update( 16446 /* deltaTime*/ 16447 ), this._msToNextUpdate = this._updateFPS ? Math.floor(1e3 / this._updateFPS) : 0); 16448 } 16449 } 16450 _videoFrameRequestCallback() { 16451 this.update(), this.destroyed ? this._videoFrameRequestCallbackHandle = null : this._videoFrameRequestCallbackHandle = this.source.requestVideoFrameCallback( 16452 this._videoFrameRequestCallback 16453 ); 16454 } 16455 /** 16456 * Start preloading the video resource. 16457 * @returns {Promise<void>} Handle the validate event 16458 */ 16459 load() { 16460 if (this._load) 16461 return this._load; 16462 const source = this.source; 16463 return (source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA) && source.width && source.height && (source.complete = !0), source.addEventListener("play", this._onPlayStart), source.addEventListener("pause", this._onPlayStop), source.addEventListener("seeked", this._onSeeked), this._isSourceReady() ? this._onCanPlay() : (source.addEventListener("canplay", this._onCanPlay), source.addEventListener("canplaythrough", this._onCanPlay), source.addEventListener("error", this._onError, !0)), this._load = new Promise((resolve, reject) => { 16464 this.valid ? resolve(this) : (this._resolve = resolve, this._reject = reject, source.load()); 16465 }), this._load; 16466 } 16467 /** 16468 * Handle video error events. 16469 * @param event 16470 */ 16471 _onError(event) { 16472 this.source.removeEventListener("error", this._onError, !0), this.onError.emit(event), this._reject && (this._reject(event), this._reject = null, this._resolve = null); 16473 } 16474 /** 16475 * Returns true if the underlying source is playing. 16476 * @returns - True if playing. 16477 */ 16478 _isSourcePlaying() { 16479 const source = this.source; 16480 return !source.paused && !source.ended; 16481 } 16482 /** 16483 * Returns true if the underlying source is ready for playing. 16484 * @returns - True if ready. 16485 */ 16486 _isSourceReady() { 16487 return this.source.readyState > 2; 16488 } 16489 /** Runs the update loop when the video is ready to play. */ 16490 _onPlayStart() { 16491 this.valid || this._onCanPlay(), this._configureAutoUpdate(); 16492 } 16493 /** Fired when a pause event is triggered, stops the update loop. */ 16494 _onPlayStop() { 16495 this._configureAutoUpdate(); 16496 } 16497 /** Fired when the video is completed seeking to the current playback position. */ 16498 _onSeeked() { 16499 this._autoUpdate && !this._isSourcePlaying() && (this._msToNextUpdate = 0, this.update(), this._msToNextUpdate = 0); 16500 } 16501 /** Fired when the video is loaded and ready to play. */ 16502 _onCanPlay() { 16503 const source = this.source; 16504 source.removeEventListener("canplay", this._onCanPlay), source.removeEventListener("canplaythrough", this._onCanPlay); 16505 const valid = this.valid; 16506 this._msToNextUpdate = 0, this.update(), this._msToNextUpdate = 0, !valid && this._resolve && (this._resolve(this), this._resolve = null, this._reject = null), this._isSourcePlaying() ? this._onPlayStart() : this.autoPlay && source.play(); 16507 } 16508 /** Destroys this texture. */ 16509 dispose() { 16510 this._configureAutoUpdate(); 16511 const source = this.source; 16512 source && (source.removeEventListener("play", this._onPlayStart), source.removeEventListener("pause", this._onPlayStop), source.removeEventListener("seeked", this._onSeeked), source.removeEventListener("canplay", this._onCanPlay), source.removeEventListener("canplaythrough", this._onCanPlay), source.removeEventListener("error", this._onError, !0), source.pause(), source.src = "", source.load()), super.dispose(); 16513 } 16514 /** Should the base texture automatically update itself, set to true by default. */ 16515 get autoUpdate() { 16516 return this._autoUpdate; 16517 } 16518 set autoUpdate(value) { 16519 value !== this._autoUpdate && (this._autoUpdate = value, this._configureAutoUpdate()); 16520 } 16521 /** 16522 * How many times a second to update the texture from the video. Leave at 0 to update at every render. 16523 * A lower fps can help performance, as updating the texture at 60fps on a 30ps video may not be efficient. 16524 */ 16525 get updateFPS() { 16526 return this._updateFPS; 16527 } 16528 set updateFPS(value) { 16529 value !== this._updateFPS && (this._updateFPS = value, this._configureAutoUpdate()); 16530 } 16531 _configureAutoUpdate() { 16532 this._autoUpdate && this._isSourcePlaying() ? !this._updateFPS && this.source.requestVideoFrameCallback ? (this._isConnectedToTicker && (Ticker.shared.remove(this.update, this), this._isConnectedToTicker = !1, this._msToNextUpdate = 0), this._videoFrameRequestCallbackHandle === null && (this._videoFrameRequestCallbackHandle = this.source.requestVideoFrameCallback( 16533 this._videoFrameRequestCallback 16534 ))) : (this._videoFrameRequestCallbackHandle !== null && (this.source.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle), this._videoFrameRequestCallbackHandle = null), this._isConnectedToTicker || (Ticker.shared.add(this.update, this), this._isConnectedToTicker = !0, this._msToNextUpdate = 0)) : (this._videoFrameRequestCallbackHandle !== null && (this.source.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle), this._videoFrameRequestCallbackHandle = null), this._isConnectedToTicker && (Ticker.shared.remove(this.update, this), this._isConnectedToTicker = !1, this._msToNextUpdate = 0)); 16535 } 16536 /** 16537 * Used to auto-detect the type of resource. 16538 * @param {*} source - The source object 16539 * @param {string} extension - The extension of source, if set 16540 * @returns {boolean} `true` if video source 16541 */ 16542 static test(source, extension) { 16543 return globalThis.HTMLVideoElement && source instanceof HTMLVideoElement || _VideoResource2.TYPES.includes(extension); 16544 } 16545}; 16546_VideoResource.TYPES = ["mp4", "m4v", "webm", "ogg", "ogv", "h264", "avi", "mov"], /** 16547* Map of video MIME types that can't be directly derived from file extensions. 16548* @readonly 16549*/ 16550_VideoResource.MIME_TYPES = { 16551 ogv: "video/ogg", 16552 mov: "video/quicktime", 16553 m4v: "video/mp4" 16554}; 16555let VideoResource = _VideoResource; 16556 16557INSTALLED.push( 16558 ImageBitmapResource, 16559 ImageResource, 16560 CanvasResource, 16561 VideoResource, 16562 SVGResource, 16563 BufferResource, 16564 CubeResource, 16565 ArrayResource 16566); 16567 16568class Bounds { 16569 constructor() { 16570 this.minX = 1 / 0, this.minY = 1 / 0, this.maxX = -1 / 0, this.maxY = -1 / 0, this.rect = null, this.updateID = -1; 16571 } 16572 /** 16573 * Checks if bounds are empty. 16574 * @returns - True if empty. 16575 */ 16576 isEmpty() { 16577 return this.minX > this.maxX || this.minY > this.maxY; 16578 } 16579 /** Clears the bounds and resets. */ 16580 clear() { 16581 this.minX = 1 / 0, this.minY = 1 / 0, this.maxX = -1 / 0, this.maxY = -1 / 0; 16582 } 16583 /** 16584 * Can return Rectangle.EMPTY constant, either construct new rectangle, either use your rectangle 16585 * It is not guaranteed that it will return tempRect 16586 * @param rect - Temporary object will be used if AABB is not empty 16587 * @returns - A rectangle of the bounds 16588 */ 16589 getRectangle(rect) { 16590 return this.minX > this.maxX || this.minY > this.maxY ? Rectangle.EMPTY : (rect = rect || new Rectangle(0, 0, 1, 1), rect.x = this.minX, rect.y = this.minY, rect.width = this.maxX - this.minX, rect.height = this.maxY - this.minY, rect); 16591 } 16592 /** 16593 * This function should be inlined when its possible. 16594 * @param point - The point to add. 16595 */ 16596 addPoint(point) { 16597 this.minX = Math.min(this.minX, point.x), this.maxX = Math.max(this.maxX, point.x), this.minY = Math.min(this.minY, point.y), this.maxY = Math.max(this.maxY, point.y); 16598 } 16599 /** 16600 * Adds a point, after transformed. This should be inlined when its possible. 16601 * @param matrix 16602 * @param point 16603 */ 16604 addPointMatrix(matrix, point) { 16605 const { a, b, c, d, tx, ty } = matrix, x = a * point.x + c * point.y + tx, y = b * point.x + d * point.y + ty; 16606 this.minX = Math.min(this.minX, x), this.maxX = Math.max(this.maxX, x), this.minY = Math.min(this.minY, y), this.maxY = Math.max(this.maxY, y); 16607 } 16608 /** 16609 * Adds a quad, not transformed 16610 * @param vertices - The verts to add. 16611 */ 16612 addQuad(vertices) { 16613 let minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY, x = vertices[0], y = vertices[1]; 16614 minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY, x = vertices[2], y = vertices[3], minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY, x = vertices[4], y = vertices[5], minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY, x = vertices[6], y = vertices[7], minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY, this.minX = minX, this.minY = minY, this.maxX = maxX, this.maxY = maxY; 16615 } 16616 /** 16617 * Adds sprite frame, transformed. 16618 * @param transform - transform to apply 16619 * @param x0 - left X of frame 16620 * @param y0 - top Y of frame 16621 * @param x1 - right X of frame 16622 * @param y1 - bottom Y of frame 16623 */ 16624 addFrame(transform, x0, y0, x1, y1) { 16625 this.addFrameMatrix(transform.worldTransform, x0, y0, x1, y1); 16626 } 16627 /** 16628 * Adds sprite frame, multiplied by matrix 16629 * @param matrix - matrix to apply 16630 * @param x0 - left X of frame 16631 * @param y0 - top Y of frame 16632 * @param x1 - right X of frame 16633 * @param y1 - bottom Y of frame 16634 */ 16635 addFrameMatrix(matrix, x0, y0, x1, y1) { 16636 const a = matrix.a, b = matrix.b, c = matrix.c, d = matrix.d, tx = matrix.tx, ty = matrix.ty; 16637 let minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY, x = a * x0 + c * y0 + tx, y = b * x0 + d * y0 + ty; 16638 minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY, x = a * x1 + c * y0 + tx, y = b * x1 + d * y0 + ty, minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY, x = a * x0 + c * y1 + tx, y = b * x0 + d * y1 + ty, minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY, x = a * x1 + c * y1 + tx, y = b * x1 + d * y1 + ty, minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY, this.minX = minX, this.minY = minY, this.maxX = maxX, this.maxY = maxY; 16639 } 16640 /** 16641 * Adds screen vertices from array 16642 * @param vertexData - calculated vertices 16643 * @param beginOffset - begin offset 16644 * @param endOffset - end offset, excluded 16645 */ 16646 addVertexData(vertexData, beginOffset, endOffset) { 16647 let minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; 16648 for (let i = beginOffset; i < endOffset; i += 2) { 16649 const x = vertexData[i], y = vertexData[i + 1]; 16650 minX = x < minX ? x : minX, minY = y < minY ? y : minY, maxX = x > maxX ? x : maxX, maxY = y > maxY ? y : maxY; 16651 } 16652 this.minX = minX, this.minY = minY, this.maxX = maxX, this.maxY = maxY; 16653 } 16654 /** 16655 * Add an array of mesh vertices 16656 * @param transform - mesh transform 16657 * @param vertices - mesh coordinates in array 16658 * @param beginOffset - begin offset 16659 * @param endOffset - end offset, excluded 16660 */ 16661 addVertices(transform, vertices, beginOffset, endOffset) { 16662 this.addVerticesMatrix(transform.worldTransform, vertices, beginOffset, endOffset); 16663 } 16664 /** 16665 * Add an array of mesh vertices. 16666 * @param matrix - mesh matrix 16667 * @param vertices - mesh coordinates in array 16668 * @param beginOffset - begin offset 16669 * @param endOffset - end offset, excluded 16670 * @param padX - x padding 16671 * @param padY - y padding 16672 */ 16673 addVerticesMatrix(matrix, vertices, beginOffset, endOffset, padX = 0, padY = padX) { 16674 const a = matrix.a, b = matrix.b, c = matrix.c, d = matrix.d, tx = matrix.tx, ty = matrix.ty; 16675 let minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; 16676 for (let i = beginOffset; i < endOffset; i += 2) { 16677 const rawX = vertices[i], rawY = vertices[i + 1], x = a * rawX + c * rawY + tx, y = d * rawY + b * rawX + ty; 16678 minX = Math.min(minX, x - padX), maxX = Math.max(maxX, x + padX), minY = Math.min(minY, y - padY), maxY = Math.max(maxY, y + padY); 16679 } 16680 this.minX = minX, this.minY = minY, this.maxX = maxX, this.maxY = maxY; 16681 } 16682 /** 16683 * Adds other {@link PIXI.Bounds}. 16684 * @param bounds - The Bounds to be added 16685 */ 16686 addBounds(bounds) { 16687 const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; 16688 this.minX = bounds.minX < minX ? bounds.minX : minX, this.minY = bounds.minY < minY ? bounds.minY : minY, this.maxX = bounds.maxX > maxX ? bounds.maxX : maxX, this.maxY = bounds.maxY > maxY ? bounds.maxY : maxY; 16689 } 16690 /** 16691 * Adds other Bounds, masked with Bounds. 16692 * @param bounds - The Bounds to be added. 16693 * @param mask - TODO 16694 */ 16695 addBoundsMask(bounds, mask) { 16696 const _minX = bounds.minX > mask.minX ? bounds.minX : mask.minX, _minY = bounds.minY > mask.minY ? bounds.minY : mask.minY, _maxX = bounds.maxX < mask.maxX ? bounds.maxX : mask.maxX, _maxY = bounds.maxY < mask.maxY ? bounds.maxY : mask.maxY; 16697 if (_minX <= _maxX && _minY <= _maxY) { 16698 const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; 16699 this.minX = _minX < minX ? _minX : minX, this.minY = _minY < minY ? _minY : minY, this.maxX = _maxX > maxX ? _maxX : maxX, this.maxY = _maxY > maxY ? _maxY : maxY; 16700 } 16701 } 16702 /** 16703 * Adds other Bounds, multiplied by matrix. Bounds shouldn't be empty. 16704 * @param bounds - other bounds 16705 * @param matrix - multiplicator 16706 */ 16707 addBoundsMatrix(bounds, matrix) { 16708 this.addFrameMatrix(matrix, bounds.minX, bounds.minY, bounds.maxX, bounds.maxY); 16709 } 16710 /** 16711 * Adds other Bounds, masked with Rectangle. 16712 * @param bounds - TODO 16713 * @param area - TODO 16714 */ 16715 addBoundsArea(bounds, area) { 16716 const _minX = bounds.minX > area.x ? bounds.minX : area.x, _minY = bounds.minY > area.y ? bounds.minY : area.y, _maxX = bounds.maxX < area.x + area.width ? bounds.maxX : area.x + area.width, _maxY = bounds.maxY < area.y + area.height ? bounds.maxY : area.y + area.height; 16717 if (_minX <= _maxX && _minY <= _maxY) { 16718 const minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; 16719 this.minX = _minX < minX ? _minX : minX, this.minY = _minY < minY ? _minY : minY, this.maxX = _maxX > maxX ? _maxX : maxX, this.maxY = _maxY > maxY ? _maxY : maxY; 16720 } 16721 } 16722 /** 16723 * Pads bounds object, making it grow in all directions. 16724 * If paddingY is omitted, both paddingX and paddingY will be set to paddingX. 16725 * @param paddingX - The horizontal padding amount. 16726 * @param paddingY - The vertical padding amount. 16727 */ 16728 pad(paddingX = 0, paddingY = paddingX) { 16729 this.isEmpty() || (this.minX -= paddingX, this.maxX += paddingX, this.minY -= paddingY, this.maxY += paddingY); 16730 } 16731 /** 16732 * Adds padded frame. (x0, y0) should be strictly less than (x1, y1) 16733 * @param x0 - left X of frame 16734 * @param y0 - top Y of frame 16735 * @param x1 - right X of frame 16736 * @param y1 - bottom Y of frame 16737 * @param padX - padding X 16738 * @param padY - padding Y 16739 */ 16740 addFramePad(x0, y0, x1, y1, padX, padY) { 16741 x0 -= padX, y0 -= padY, x1 += padX, y1 += padY, this.minX = this.minX < x0 ? this.minX : x0, this.maxX = this.maxX > x1 ? this.maxX : x1, this.minY = this.minY < y0 ? this.minY : y0, this.maxY = this.maxY > y1 ? this.maxY : y1; 16742 } 16743} 16744 16745class DisplayObject extends EventEmitter { 16746 constructor() { 16747 super(), this.tempDisplayObjectParent = null, this.transform = new Transform(), this.alpha = 1, this.visible = !0, this.renderable = !0, this.cullable = !1, this.cullArea = null, this.parent = null, this.worldAlpha = 1, this._lastSortedIndex = 0, this._zIndex = 0, this.filterArea = null, this.filters = null, this._enabledFilters = null, this._bounds = new Bounds(), this._localBounds = null, this._boundsID = 0, this._boundsRect = null, this._localBoundsRect = null, this._mask = null, this._maskRefCount = 0, this._destroyed = !1, this.isSprite = !1, this.isMask = !1; 16748 } 16749 /** 16750 * Mixes all enumerable properties and methods from a source object to DisplayObject. 16751 * @param source - The source of properties and methods to mix in. 16752 */ 16753 static mixin(source) { 16754 const keys = Object.keys(source); 16755 for (let i = 0; i < keys.length; ++i) { 16756 const propertyName = keys[i]; 16757 Object.defineProperty( 16758 DisplayObject.prototype, 16759 propertyName, 16760 Object.getOwnPropertyDescriptor(source, propertyName) 16761 ); 16762 } 16763 } 16764 /** 16765 * Fired when this DisplayObject is added to a Container. 16766 * @instance 16767 * @event added 16768 * @param {PIXI.Container} container - The container added to. 16769 */ 16770 /** 16771 * Fired when this DisplayObject is removed from a Container. 16772 * @instance 16773 * @event removed 16774 * @param {PIXI.Container} container - The container removed from. 16775 */ 16776 /** 16777 * Fired when this DisplayObject is destroyed. This event is emitted once 16778 * destroy is finished. 16779 * @instance 16780 * @event destroyed 16781 */ 16782 /** Readonly flag for destroyed display objects. */ 16783 get destroyed() { 16784 return this._destroyed; 16785 } 16786 /** Recursively updates transform of all objects from the root to this one internal function for toLocal() */ 16787 _recursivePostUpdateTransform() { 16788 this.parent ? (this.parent._recursivePostUpdateTransform(), this.transform.updateTransform(this.parent.transform)) : this.transform.updateTransform(this._tempDisplayObjectParent.transform); 16789 } 16790 /** Updates the object transform for rendering. TODO - Optimization pass! */ 16791 updateTransform() { 16792 this._boundsID++, this.transform.updateTransform(this.parent.transform), this.worldAlpha = this.alpha * this.parent.worldAlpha; 16793 } 16794 /** 16795 * Calculates and returns the (world) bounds of the display object as a [Rectangle]{@link PIXI.Rectangle}. 16796 * 16797 * This method is expensive on containers with a large subtree (like the stage). This is because the bounds 16798 * of a container depend on its children's bounds, which recursively causes all bounds in the subtree to 16799 * be recalculated. The upside, however, is that calling `getBounds` once on a container will indeed update 16800 * the bounds of all children (the whole subtree, in fact). This side effect should be exploited by using 16801 * `displayObject._bounds.getRectangle()` when traversing through all the bounds in a scene graph. Otherwise, 16802 * calling `getBounds` on each object in a subtree will cause the total cost to increase quadratically as 16803 * its height increases. 16804 * 16805 * The transforms of all objects in a container's **subtree** and of all **ancestors** are updated. 16806 * The world bounds of all display objects in a container's **subtree** will also be recalculated. 16807 * 16808 * The `_bounds` object stores the last calculation of the bounds. You can use to entirely ski
16808p bounds 16809 * calculation if needed. 16810 * 16811 * ```js 16812 * const lastCalculatedBounds = displayObject._bounds.getRectangle(optionalRect); 16813 * ``` 16814 * 16815 * Do know that usage of `getLocalBounds` can corrupt the `_bounds` of children (the whole subtree, actually). This 16816 * is a known issue that has not been solved. See [getLocalBounds]{@link PIXI.DisplayObject#getLocalBounds} for more 16817 * details. 16818 * 16819 * `getBounds` should be called with `skipUpdate` equal to `true` in a render() call. This is because the transforms 16820 * are guaranteed to be update-to-date. In fact, recalculating inside a render() call may cause corruption in certain 16821 * cases. 16822 * @param skipUpdate - Setting to `true` will stop the transforms of the scene graph from 16823 * being updated. This means the calculation returned MAY be out of date BUT will give you a 16824 * nice performance boost. 16825 * @param rect - Optional rectangle to store the result of the bounds calculation. 16826 * @returns - The minimum axis-aligned rectangle in world space that fits around this object. 16827 */ 16828 getBounds(skipUpdate, rect) { 16829 return skipUpdate || (this.parent ? (this._recursivePostUpdateTransform(), this.updateTransform()) : (this.parent = this._tempDisplayObjectParent, this.updateTransform(), this.parent = null)), this._bounds.updateID !== this._boundsID && (this.calculateBounds(), this._bounds.updateID = this._boundsID), rect || (this._boundsRect || (this._boundsRect = new Rectangle()), rect = this._boundsRect), this._bounds.getRectangle(rect); 16830 } 16831 /** 16832 * Retrieves the local bounds of the displayObject as a rectangle object. 16833 * @param rect - Optional rectangle to store the result of the bounds calculation. 16834 * @returns - The rectangular bounding area. 16835 */ 16836 getLocalBounds(rect) { 16837 rect || (this._localBoundsRect || (this._localBoundsRect = new Rectangle()), rect = this._localBoundsRect), this._localBounds || (this._localBounds = new Bounds()); 16838 const transformRef = this.transform, parentRef = this.parent; 16839 this.parent = null, this._tempDisplayObjectParent.worldAlpha = parentRef?.worldAlpha ?? 1, this.transform = this._tempDisplayObjectParent.transform; 16840 const worldBounds = this._bounds, worldBoundsID = this._boundsID; 16841 this._bounds = this._localBounds; 16842 const bounds = this.getBounds(!1, rect); 16843 return this.parent = parentRef, this.transform = transformRef, this._bounds = worldBounds, this._bounds.updateID += this._boundsID - worldBoundsID, bounds; 16844 } 16845 /** 16846 * Calculates the global position of the display object. 16847 * @param position - The world origin to calculate from. 16848 * @param point - A Point object in which to store the value, optional 16849 * (otherwise will create a new Point). 16850 * @param skipUpdate - Should we skip the update transform. 16851 * @returns - A point object representing the position of this object. 16852 */ 16853 toGlobal(position, point, skipUpdate = !1) { 16854 return skipUpdate || (this._recursivePostUpdateTransform(), this.parent ? this.displayObjectUpdateTransform() : (this.parent = this._tempDisplayObjectParent, this.displayObjectUpdateTransform(), this.parent = null)), this.worldTransform.apply(position, point); 16855 } 16856 /** 16857 * Calculates the local position of the display object relative to another point. 16858 * @param position - The world origin to calculate from. 16859 * @param from - The DisplayObject to calculate the global position from. 16860 * @param point - A Point object in which to store the value, optional 16861 * (otherwise will create a new Point). 16862 * @param skipUpdate - Should we skip the update transform 16863 * @returns - A point object representing the position of this object 16864 */ 16865 toLocal(position, from, point, skipUpdate) { 16866 return from && (position = from.toGlobal(position, point, skipUpdate)), skipUpdate || (this._recursivePostUpdateTransform(), this.parent ? this.displayObjectUpdateTransform() : (this.parent = this._tempDisplayObjectParent, this.displayObjectUpdateTransform(), this.parent = null)), this.worldTransform.applyInverse(position, point); 16867 } 16868 /** 16869 * Set the parent Container of this DisplayObject. 16870 * @param container - The Container to add this DisplayObject to. 16871 * @returns - The Container that this DisplayObject was added to. 16872 */ 16873 setParent(container) { 16874 if (!container || !container.addChild) 16875 throw new Error("setParent: Argument must be a Container"); 16876 return container.addChild(this), container; 16877 } 16878 /** Remove the DisplayObject from its parent Container. If the DisplayObject has no parent, do nothing. */ 16879 removeFromParent() { 16880 this.parent?.removeChild(this); 16881 } 16882 /** 16883 * Convenience function to set the position, scale, skew and pivot at once. 16884 * @param x - The X position 16885 * @param y - The Y position 16886 * @param scaleX - The X scale value 16887 * @param scaleY - The Y scale value 16888 * @param rotation - The rotation 16889 * @param skewX - The X skew value 16890 * @param skewY - The Y skew value 16891 * @param pivotX - The X pivot value 16892 * @param pivotY - The Y pivot value 16893 * @returns - The DisplayObject instance 16894 */ 16895 setTransform(x = 0, y = 0, scaleX = 1, scaleY = 1, rotation = 0, skewX = 0, skewY = 0, pivotX = 0, pivotY = 0) { 16896 return this.position.x = x, this.position.y = y
vendor: 4,663 bytes, lines 16896-17047
16896, this.scale.x = scaleX || 1, this.scale.y = scaleY || 1, this.rotation = rotation, this.skew.x = skewX, this.skew.y = skewY, this.pivot.x = pivotX, this.pivot.y = pivotY, this; 16897 } 16898 /** 16899 * Base destroy method for generic display objects. This will automatically 16900 * remove the display object from its parent Container as well as remove 16901 * all current event listeners and internal references. Do not use a DisplayObject 16902 * after calling `destroy()`. 16903 * @param _options 16904 */ 16905 destroy(_options) { 16906 this.removeFromParent(), this._destroyed = !0, this.transform = null, this.parent = null, this._bounds = null, this.mask = null, this.cullArea = null, this.filters = null, this.filterArea = null, this.hitArea = null, this.eventMode = "auto", this.interactiveChildren = !1, this.emit("destroyed"), this.removeAllListeners(); 16907 } 16908 /** 16909 * @protected 16910 * @member {PIXI.Container} 16911 */ 16912 get _tempDisplayObjectParent() { 16913 return this.tempDisplayObjectParent === null && (this.tempDisplayObjectParent = new TemporaryDisplayObject()), this.tempDisplayObjectParent; 16914 } 16915 /** 16916 * Used in Renderer, cacheAsBitmap and other places where you call an `updateTransform` on root. 16917 * 16918 * ```js 16919 * const cacheParent = elem.enableTempParent(); 16920 * elem.updateTransform(); 16921 * elem.disableTempParent(cacheParent); 16922 * ``` 16923 * @returns - Current parent 16924 */ 16925 enableTempParent() { 16926 const myParent = this.parent; 16927 return this.parent = this._tempDisplayObjectParent, myParent; 16928 } 16929 /** 16930 * Pair method for `enableTempParent` 16931 * @param cacheParent - Actual parent of element 16932 */ 16933 disableTempParent(cacheParent) { 16934 this.parent = cacheParent; 16935 } 16936 /** 16937 * The position of the displayObject on the x axis relative to the local coordinates of the parent. 16938 * An alias to position.x 16939 */ 16940 get x() { 16941 return this.position.x; 16942 } 16943 set x(value) { 16944 this.transform.position.x = value; 16945 } 16946 /** 16947 * The position of the displayObject on the y axis relative to the local coordinates of the parent. 16948 * An alias to position.y 16949 */ 16950 get y() { 16951 return this.position.y; 16952 } 16953 set y(value) { 16954 this.transform.position.y = value; 16955 } 16956 /** 16957 * Current transform of the object based on world (parent) factors. 16958 * @readonly 16959 */ 16960 get worldTransform() { 16961 return this.transform.worldTransform; 16962 } 16963 /** 16964 * Current transform of the object based on local factors: position, scale, other stuff. 16965 * @readonly 16966 */ 16967 get localTransform() { 16968 return this.transform.localTransform; 16969 } 16970 /** 16971 * The coordinate of the object relative to the local coordinates of the parent. 16972 * @since 4.0.0 16973 */ 16974 get position() { 16975 return this.transform.position; 16976 } 16977 set position(value) { 16978 this.transform.position.copyFrom(value); 16979 } 16980 /** 16981 * The scale factors of this object along the local coordinate axes. 16982 * 16983 * The default scale is (1, 1). 16984 * @since 4.0.0 16985 */ 16986 get scale() { 16987 return this.transform.scale; 16988 } 16989 set scale(value) { 16990 this.transform.scale.copyFrom(value); 16991 } 16992 /** 16993 * The center of rotation, scaling, and skewing for this display object in its local space. The `position` 16994 * is the projection of `pivot` in the parent's local space. 16995 * 16996 * By default, the pivot is the origin (0, 0). 16997 * @since 4.0.0 16998 */ 16999 get pivot() { 17000 return this.transform.pivot; 17001 } 17002 set pivot(value) { 17003 this.transform.pivot.copyFrom(value); 17004 } 17005 /** 17006 * The skew factor for the object in radians. 17007 * @since 4.0.0 17008 */ 17009 get skew() { 17010 return this.transform.skew; 17011 } 17012 set skew(value) { 17013 this.transform.skew.copyFrom(value); 17014 } 17015 /** 17016 * The rotation of the object in radians. 17017 * 'rotation' and 'angle' have the same effect on a display object; rotation is in radians, angle is in degrees. 17018 */ 17019 get rotation() { 17020 return this.transform.rotation; 17021 } 17022 set rotation(value) { 17023 this.transform.rotation = value; 17024 } 17025 /** 17026 * The angle of the object in degrees. 17027 * 'rotation' and 'angle' have the same effect on a display object; rotation is in radians, angle is in degrees. 17028 */ 17029 get angle() { 17030 return this.transform.rotation * RAD_TO_DEG; 17031 } 17032 set angle(value) { 17033 this.transform.rotation = value * DEG_TO_RAD; 17034 } 17035 /** 17036 * The zIndex of the displayObject. 17037 * 17038 * If a container has the sortableChildren property set to true, children will be automatically 17039 * sorted by zIndex value; a higher value will mean it will be moved towards the end of the array, 17040 * and thus rendered on top of other display objects within the same container. 17041 * @see PIXI.Container#sortableChildren 17042 */ 17043 get zIndex() { 17044 return this._zIndex; 17045 } 17046 set zIndex(value) { 17047 this._zIndex
vendor: 10,583 bytes, lines 17047-17277
17047= value, this.parent && (this.parent.sortDirty = !0); 17048 } 17049 /** 17050 * Indicates if the object is globally visible. 17051 * @readonly 17052 */ 17053 get worldVisible() { 17054 let item = this; 17055 do { 17056 if (!item.visible) 17057 return !1; 17058 item = item.parent; 17059 } while (item); 17060 return !0; 17061 } 17062 /** 17063 * Sets a mask for the displayObject. A mask is an object that limits the visibility of an 17064 * object to the shape of the mask applied to it. In PixiJS a regular mask must be a 17065 * {@link PIXI.Graphics} or a {@link PIXI.Sprite} object. This allows for much faster masking in canvas as it 17066 * utilities shape clipping. Furthermore, a mask of an object must be in the subtree of its parent. 17067 * Otherwise, `getLocalBounds` may calculate incorrect bounds, which makes the container's width and height wrong. 17068 * To remove a mask, set this property to `null`. 17069 * 17070 * For sprite mask both alpha and red channel are used. Black mask is the same as transparent mask. 17071 * @example 17072 * import { Graphics, Sprite } from 'pixi.js'; 17073 * 17074 * const graphics = new Graphics(); 17075 * graphics.beginFill(0xFF3300); 17076 * graphics.drawRect(50, 250, 100, 100); 17077 * graphics.endFill(); 17078 * 17079 * const sprite = new Sprite(texture); 17080 * sprite.mask = graphics; 17081 * @todo At the moment, CanvasRenderer doesn't support Sprite as mask. 17082 */ 17083 get mask() { 17084 return this._mask; 17085 } 17086 set mask(value) { 17087 if (this._mask !== value) { 17088 if (this._mask) { 17089 const maskObject = this._mask.isMaskData ? this._mask.maskObject : this._mask; 17090 maskObject && (maskObject._maskRefCount--, maskObject._maskRefCount === 0 && (maskObject.renderable = !0, maskObject.isMask = !1)); 17091 } 17092 if (this._mask = value, this._mask) { 17093 const maskObject = this._mask.isMaskData ? this._mask.maskObject : this._mask; 17094 maskObject && (maskObject._maskRefCount === 0 && (maskObject.renderable = !1, maskObject.isMask = !0), maskObject._maskRefCount++); 17095 } 17096 } 17097 } 17098} 17099class TemporaryDisplayObject extends DisplayObject { 17100 constructor() { 17101 super(...arguments), this.sortDirty = null; 17102 } 17103} 17104DisplayObject.prototype.displayObjectUpdateTransform = DisplayObject.prototype.updateTransform; 17105 17106const tempMatrix = new Matrix(); 17107function sortChildren(a, b) { 17108 return a.zIndex === b.zIndex ? a._lastSortedIndex - b._lastSortedIndex : a.zIndex - b.zIndex; 17109} 17110const _Container = class _Container2 extends DisplayObject { 17111 constructor() { 17112 super(), this.children = [], this.sortableChildren = _Container2.defaultSortableChildren, this.sortDirty = !1; 17113 } 17114 /** 17115 * Overridable method that can be used by Container subclasses whenever the children array is modified. 17116 * @param _length 17117 */ 17118 onChildrenChange(_length) { 17119 } 17120 /** 17121 * Adds one or more children to the container. 17122 * 17123 * Multiple items can be added like so: `myContainer.addChild(thingOne, thingTwo, thingThree)` 17124 * @param {...PIXI.DisplayObject} children - The DisplayObject(s) to add to the container 17125 * @returns {PIXI.DisplayObject} - The first child that was added. 17126 */ 17127 addChild(...children) { 17128 if (children.length > 1) 17129 for (let i = 0; i < children.length; i++) 17130 this.addChild(children[i]); 17131 else { 17132 const child = children[0]; 17133 child.parent && child.parent.removeChild(child), child.parent = this, this.sortDirty = !0, child.transform._parentID = -1, this.children.push(child), this._boundsID++, this.onChildrenChange(this.children.length - 1), this.emit("childAdded", child, this, this.children.length - 1), child.emit("added", this); 17134 } 17135 return children[0]; 17136 } 17137 /** 17138 * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown. 17139 * If the child is already in this container, it will be moved to the specified index. 17140 * @param {PIXI.DisplayObject} child - The child to add. 17141 * @param {number} index - The absolute index where the child will be positioned at the end of the operation. 17142 * @returns {PIXI.DisplayObject} The child that was added. 17143 */ 17144 addChildAt(child, index) { 17145 if (index < 0 || index > this.children.length) 17146 throw new Error(`${child}addChildAt: The index ${index} supplied is out of bounds ${this.children.length}`); 17147 return child.parent && child.parent.removeChild(child), child.parent = this, this.sortDirty = !0, child.transform._parentID = -1, this.children.splice(index, 0, child), this._boundsID++, this.onChildrenChange(index), child.emit("added", this), this.emit("childAdded", child, this, index), child; 17148 } 17149 /** 17150 * Swaps the position of 2 Display Objects within this container. 17151 * @param child - First display object to swap 17152 * @param child2 - Second display object to swap 17153 */ 17154 swapChildren(child, child2) { 17155 if (child === child2) 17156 return; 17157 const index1 = this.getChildIndex(child), index2 = this.getChildIndex(child2); 17158 this.children[index1] = child2, this.children[index2] = child, this.onChildrenChange(index1 < index2 ? index1 : index2); 17159 } 17160 /** 17161 * Returns the index position of a child DisplayObject instance 17162 * @param child - The DisplayObject instance to identify 17163 * @returns - The index position of the child display object to identify 17164 */ 17165 getChildIndex(child) { 17166 const index = this.children.indexOf(child); 17167 if (index === -1) 17168 throw new Error("The supplied DisplayObject must be a child of the caller"); 17169 return index; 17170 } 17171 /** 17172 * Changes the position of an existing child in the display object container 17173 * @param child - The child DisplayObject instance for which you want to change the index number 17174 * @param index - The resulting index number for the child display object 17175 */ 17176 setChildIndex(child, index) { 17177 if (index < 0 || index >= this.children.length) 17178 throw new Error(`The index ${index} supplied is out of bounds ${this.children.length}`); 17179 const currentIndex = this.getChildIndex(child); 17180 removeItems(this.children, currentIndex, 1), this.children.splice(index, 0, child), this.onChildrenChange(index); 17181 } 17182 /** 17183 * Returns the child at the specified index 17184 * @param index - The index to get the child at 17185 * @returns - The child at the given index, if any. 17186 */ 17187 getChildAt(index) { 17188 if (index < 0 || index >= this.children.length) 17189 throw new Error(`getChildAt: Index (${index}) does not exist.`); 17190 return this.children[index]; 17191 } 17192 /** 17193 * Removes one or more children from the container. 17194 * @param {...PIXI.DisplayObject} children - The DisplayObject(s) to remove 17195 * @returns {PIXI.DisplayObject} The first child that was removed. 17196 */ 17197 removeChild(...children) { 17198 if (children.length > 1) 17199 for (let i = 0; i < children.length; i++) 17200 this.removeChild(children[i]); 17201 else { 17202 const child = children[0], index = this.children.indexOf(child); 17203 if (index === -1) 17204 return null; 17205 child.parent = null, child.transform._parentID = -1, removeItems(this.children, index, 1), this._boundsID++, this.onChildrenChange(index), child.emit("removed", this), this.emit("childRemoved", child, this, index); 17206 } 17207 return children[0]; 17208 } 17209 /** 17210 * Removes a child from the specified index position. 17211 * @param index - The index to get the child from 17212 * @returns The child that was removed. 17213 */ 17214 removeChildAt(index) { 17215 const child = this.getChildAt(index); 17216 return child.parent = null, child.transform._parentID = -1, removeItems(this.children, index, 1), this._boundsID++, this.onChildrenChange(index), child.emit("removed", this), this.emit("childRemoved", child, this, index), child; 17217 } 17218 /** 17219 * Removes all children from this container that are within the begin and end indexes. 17220 * @param beginIndex - The beginning position. 17221 * @param endIndex - The ending position. Default value is size of the container. 17222 * @returns - List of removed children 17223 */ 17224 removeChildren(beginIndex = 0, endIndex = this.children.length) { 17225 const begin = beginIndex, end = endIndex, range = end - begin; 17226 let removed; 17227 if (range > 0 && range <= end) { 17228 removed = this.children.splice(begin, range); 17229 for (let i = 0; i < removed.length; ++i) 17230 removed[i].parent = null, removed[i].transform && (removed[i].transform._parentID = -1); 17231 this._boundsID++, this.onChildrenChange(beginIndex); 17232 for (let i = 0; i < removed.length; ++i) 17233 removed[i].emit("removed", this), this.emit("childRemoved", removed[i], this, i); 17234 return removed; 17235 } else if (range === 0 && this.children.length === 0) 17236 return []; 17237 throw new RangeError("removeChildren: numeric values are outside the acceptable range."); 17238 } 17239 /** Sorts children by zIndex. Previous order is maintained for 2 children with the same zIndex. */ 17240 sortChildren() { 17241 let sortRequired = !1; 17242 for (let i = 0, j = this.children.length; i < j; ++i) { 17243 const child = this.children[i]; 17244 child._lastSortedIndex = i, !sortRequired && child.zIndex !== 0 && (sortRequired = !0); 17245 } 17246 sortRequired && this.children.length > 1 && this.children.sort(sortChildren), this.sortDirty = !1; 17247 } 17248 /** Updates the transform on all children of this container for rendering. */ 17249 updateTransform() { 17250 this.sortableChildren && this.sortDirty && this.sortChildren(), this._boundsID++, this.transform.updateTransform(this.parent.transform), this.worldAlpha = this.alpha * this.parent.worldAlpha; 17251 for (let i = 0, j = this.children.length; i < j; ++i) { 17252 const child = this.children[i]; 17253 child.visible && child.updateTransform(); 17254 } 17255 } 17256 /** 17257 * Recalculates the bounds of the container. 17258 * 17259 * This implementation will automatically fit the children's bounds into the calculation. Each child's bounds 17260 * is limited to its mask's bounds or filterArea, if any is applied. 17261 */ 17262 calculateBounds() { 17263 this._bounds.clear(), this._calculateBounds(); 17264 for (let i = 0; i < this.children.length; i++) { 17265 const child = this.children[i]; 17266 if (!(!child.visible || !child.renderable)) 17267 if (child.calculateBounds(), child._mask) { 17268 const maskObject = child._mask.isMaskData ? child._mask.maskObject : child._mask; 17269 maskObject ? (maskObject.calculateBounds(), this._bounds.addBoundsMask(child._bounds, maskObject._bounds)) : this._bounds.addBounds(child._bounds); 17270 } else 17271 child.filterArea ? this._bounds.addBoundsArea(child._bounds, child.filterArea) : this._bounds.addBounds(child._bounds); 17272 } 17273 this._bounds.updateID = this._boundsID; 17274 } 17275 /** 17276 * Retrieves the local bounds of the displayObject as a rectangle object. 17277 *
17278 * Calling `getLocalBounds` may invalidate the `_bounds` of the whole subtree below. If using it inside a render() 17279 * call, it is advised to call `getBounds()` immediately after to recalculate the world bounds of the subtree. 17280 * @param rect - Optional rectangle to store the result of the bounds calculation. 17281 * @param skipChildrenUpdate - Setting to `true` will stop re-calculation of children transforms, 17282 * it was default behaviour of pixi 4.0-5.2 and caused many problems to users. 17283 * @returns - The rectangular bounding area. 17284 */ 17285 getLocalBounds(rect, skipChildrenUpdate = !1) { 17286 const result = super.getLocalBounds(rect); 17287 if (!skipChildrenUpdate) 17288 for (let i = 0, j = this.children.length; i < j; ++i) { 17289 const child = this.children[i]; 17290 child.visible && child.updateTransform(); 17291 } 17292 return result; 17293 } 17294 /** 17295 * Recalculates the content bounds of this object. This should be overriden to 17296 * calculate the bounds of this specific object (not including children). 17297 * @protected 17298 */ 17299 _calculateBounds() { 17300 } 17301 /** 17302 * Renders this object and its children with culling. 17303 * @protected 17304 * @param {PIXI.Renderer} renderer - The renderer 17305 */ 17306 _renderWithCulling(renderer) { 17307 const sourceFrame = renderer.renderTexture.sourceFrame; 17308 if (!(sourceFrame.width > 0 && sourceFrame.height > 0)) 17309 return; 17310 let bounds, transform; 17311 this.cullArea ? (bounds = this.cullArea, transform = this.worldTransform) : this._render !== _Container2.prototype._render && (bounds = this.getBounds(!0)); 17312 const projectionTransform = renderer.projection.transform; 17313 if (projectionTransform && (transform ? (transform = tempMatrix.copyFrom(transform), transform.prepend(projectionTransform)) : transform = projectionTransform), bounds && sourceFrame.intersects(bounds, transform)) 17314 this._render(renderer); 17315 else if (this.cullArea) 17316 return; 17317 for (let i = 0, j = this.children.length; i < j; ++i) { 17318 const child = this.children[i], childCullable = child.cullable; 17319 child.cullable = childCullable || !this.cullArea, child.render(renderer), child.cullable = childCullable; 17320 } 17321 } 17322 /** 17323 * Renders the object using the WebGL renderer. 17324 * 17325 * The [_render]{@link PIXI.Container#_render} method is be overriden for rendering the contents of the 17326 * container itself. This `render` method will invoke it, and also invoke the `render` methods of all 17327 * children afterward. 17328 * 17329 * If `renderable` or `visible` is false or if `worldAlpha` is not positive or if `cullable` is true and 17330 * the bounds of this object are out of frame, this implementation will entirely skip rendering. 17331 * See {@link PIXI.DisplayObject} for choosing between `renderable` or `visible`. Generally, 17332 * setting alpha to zero is not recommended for purely skipping rendering. 17333 * 17334 * When your scene becomes large (especially when it is larger than can be viewed in a single screen), it is 17335 * advised to employ **culling** to automatically skip rendering objects outside of the current screen. 17336 * See [cullable]{@link PIXI.DisplayObject#cullable} and [cullArea]{@link PIXI.DisplayObject#cullArea}. 17337 * Other culling methods might be better suited for a large number static objects; see 17338 * [@pixi-essentials/cull]{@link https://www.npmjs.com/package/@pixi-essentials/cull} and 17339 * [pixi-cull]{@link https://www.npmjs.com/package/pixi-cull}. 17340 * 17341 * The [renderAdvanced]{@link PIXI.Container#renderAdvanced} method is internally used when when masking or 17342 * filtering is applied on a container. This does, however, break batching and can affect performance when 17343 * masking and filtering is applied extensively throughout the scene graph. 17344 * @param renderer - The renderer 17345 */ 17346 render(renderer) { 17347 if (!(!this.visible || this.worldAlpha <= 0 || !this.renderable)) 17348 if (this._mask || this.filters?.length) 17349 this.renderAdvanced(renderer); 17350 else if (this.cullable) 17351 this._renderWithCulling(renderer); 17352 else { 17353 this._render(renderer); 17354 for (let i = 0, j = this.children.length; i < j; ++i) 17355 this.children[i].render(renderer); 17356 } 17357 } 17358 /** 17359 * Render the object using the WebGL renderer and advanced features. 17360 * @param renderer - The renderer 17361 */ 17362 renderAdvanced(renderer) { 17363 const filters = this.filters, mask = this._mask; 17364 if (filters) { 17365 this._enabledFilters || (this._enabledFilters = []), this._enabledFilters.length = 0; 17366 for (let i = 0; i < filters.length; i++) 17367 filters[i].enabled && this._enabledFilters.push(filters[i]); 17368 } 17369 const flush = filters && this._enabledFilters?.length || mask && (!mask.isMaskData || mask.enabled && (mask.autoDetect || mask.type !== MASK_TYPES.NONE)); 17370 if (flush && renderer.batch.flush(), filters && this._enabledFilters?.length && renderer.f
17370ilter.push(this, this._enabledFilters), mask && renderer.mask.push(this, this._mask), this.cullable) 17371 this._renderWithCulling(renderer); 17372 else { 17373 this._render(renderer); 17374 for (let i = 0, j = this.children.length; i < j; ++i) 17375 this.children[i].render(renderer); 17376 } 17377 flush && renderer.batch.flush(), mask && renderer.mask.pop(this), filters && this._enabledFilters?.length && renderer.filter.pop(); 17378 } 17379 /** 17380 * To be overridden by the subclasses. 17381 * @param _renderer - The renderer 17382 */ 17383 _render(_renderer) { 17384 } 17385 /** 17386 * Removes all internal references and listeners as well as removes children from the display list. 17387 * Do not use a Container after calling `destroy`. 17388 * @param options - Options parameter. A boolean will act as if all options 17389 * have been set to that value 17390 * @param {boolean} [options.children=false] - if set to true, all the children will have their destroy 17391 * method called as well. 'options' will be passed on to those calls. 17392 * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true 17393 * Should it destroy the texture of the child sprite 17394 * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true 17395 * Should it destroy the base texture of the child sprite 17396 */ 17397 destroy(options) { 17398 super.destroy(), this.sortDirty = !1; 17399 const destroyChildren = typeof options == "boolean" ? options : options?.children, oldChildren = this.removeChildren(0, this.children.length); 17400 if (destroyChildren) 17401 for (let i = 0; i < oldChildren.length; ++i) 17402 oldChildren[i].destroy(options); 17403 } 17404 /** The width of the Container, setting this will actually modify the scale to achieve the value set. */ 17405 get width() { 17406 return this.scale.x * this.getLocalBounds().width; 17407 } 17408 set width(value) { 17409 const width = this.getLocalBounds().width; 17410 width !== 0 ? this.scale.x = value / width : this.scale.x = 1, this._width = value; 17411 } 17412 /** The height of the Container, setting this will actually modify the scale to achieve the value set. */ 17413 get height() { 17414 return this.scale.y * this.getLocalBounds().height; 17415 } 17416 set height(value) { 17417 const height = this.getLocalBounds().height; 17418 height !== 0 ? this.scale.y = value / height : this.scale.y = 1, this._height = value; 17419 } 17420}; 17421_Container.defaultSortableChildren = !1; 17422let Container = _Container; 17423Container.prototype.containerUpdateTransform = Container.prototype.updateTransform; 17424 17425Object.defineProperties(settings, { 17426 /** 17427 * Sets the default value for the container property 'sortableChildren'. 17428 * @static 17429 * @name SORTABLE_CHILDREN 17430 * @memberof PIXI.settings 17431 * @deprecated since 7.1.0 17432 * @type {boolean}
vendor: 9,566 bytes, lines 17433-17593
17433 * @see PIXI.Container.defaultSortableChildren 17434 */ 17435 SORTABLE_CHILDREN: { 17436 get() { 17437 return Container.defaultSortableChildren; 17438 }, 17439 set(value) { 17440 deprecation("7.1.0", "settings.SORTABLE_CHILDREN is deprecated, use Container.defaultSortableChildren"), Container.defaultSortableChildren = value; 17441 } 17442 } 17443}); 17444 17445const tempPoint$1 = new Point(), indices = new Uint16Array([0, 1, 2, 0, 2, 3]); 17446class Sprite extends Container { 17447 /** @param texture - The texture for this sprite. */ 17448 constructor(texture) { 17449 super(), this._anchor = new ObservablePoint( 17450 this._onAnchorUpdate, 17451 this, 17452 texture ? texture.defaultAnchor.x : 0, 17453 texture ? texture.defaultAnchor.y : 0 17454 ), this._texture = null, this._width = 0, this._height = 0, this._tintColor = new Color(16777215), this._tintRGB = null, this.tint = 16777215, this.blendMode = BLEND_MODES.NORMAL, this._cachedTint = 16777215, this.uvs = null, this.texture = texture || Texture.EMPTY, this.vertexData = new Float32Array(8), this.vertexTrimmedData = null, this._transformID = -1, this._textureID = -1, this._transformTrimmedID = -1, this._textureTrimmedID = -1, this.indices = indices, this.pluginName = "batch", this.isSprite = !0, this._roundPixels = settings.ROUND_PIXELS; 17455 } 17456 /** When the texture is updated, this event will fire to update the scale and frame. */ 17457 _onTextureUpdate() { 17458 this._textureID = -1, this._textureTrimmedID = -1, this._cachedTint = 16777215, this._width && (this.scale.x = sign(this.scale.x) * this._width / this._texture.orig.width), this._height && (this.scale.y = sign(this.scale.y) * this._height / this._texture.orig.height); 17459 } 17460 /** Called when the anchor position updates. */ 17461 _onAnchorUpdate() { 17462 this._transformID = -1, this._transformTrimmedID = -1; 17463 } 17464 /** Calculates worldTransform * vertices, store it in vertexData. */ 17465 calculateVertices() { 17466 const texture = this._texture; 17467 if (this._transformID === this.transform._worldID && this._textureID === texture._updateID) 17468 return; 17469 this._textureID !== texture._updateID && (this.uvs = this._texture._uvs.uvsFloat32), this._transformID = this.transform._worldID, this._textureID = texture._updateID; 17470 const wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty, vertexData = this.vertexData, trim = texture.trim, orig = texture.orig, anchor = this._anchor; 17471 let w0 = 0, w1 = 0, h0 = 0, h1 = 0; 17472 if (trim ? (w1 = trim.x - anchor._x * orig.width, w0 = w1 + trim.width, h1 = trim.y - anchor._y * orig.height, h0 = h1 + trim.height) : (w1 = -anchor._x * orig.width, w0 = w1 + orig.width, h1 = -anchor._y * orig.height, h0 = h1 + orig.height), vertexData[0] = a * w1 + c * h1 + tx, vertexData[1] = d * h1 + b * w1 + ty, vertexData[2] = a * w0 + c * h1 + tx, vertexData[3] = d * h1 + b * w0 + ty, vertexData[4] = a * w0 + c * h0 + tx, vertexData[5] = d * h0 + b * w0 + ty, vertexData[6] = a * w1 + c * h0 + tx, vertexData[7] = d * h0 + b * w1 + ty, this._roundPixels) { 17473 const resolution = settings.RESOLUTION; 17474 for (let i = 0; i < vertexData.length; ++i) 17475 vertexData[i] = Math.round(vertexData[i] * resolution) / resolution; 17476 } 17477 } 17478 /** 17479 * Calculates worldTransform * vertices for a non texture with a trim. store it in vertexTrimmedData. 17480 * 17481 * This is used to ensure that the true width and height of a trimmed texture is respected. 17482 */ 17483 calculateTrimmedVertices() { 17484 if (!this.vertexTrimmedData) 17485 this.vertexTrimmedData = new Float32Array(8); 17486 else if (this._transformTrimmedID === this.transform._worldID && this._textureTrimmedID === this._texture._updateID) 17487 return; 17488 this._transformTrimmedID = this.transform._worldID, this._textureTrimmedID = this._texture._updateID; 17489 const texture = this._texture, vertexData = this.vertexTrimmedData, orig = texture.orig, anchor = this._anchor, wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty, w1 = -anchor._x * orig.width, w0 = w1 + orig.width, h1 = -anchor._y * orig.height, h0 = h1 + orig.height; 17490 if (vertexData[0] = a * w1 + c * h1 + tx, vertexData[1] = d * h1 + b * w1 + ty, vertexData[2] = a * w0 + c * h1 + tx, vertexData[3] = d * h1 + b * w0 + ty, vertexData[4] = a * w0 + c * h0 + tx, vertexData[5] = d * h0 + b * w0 + ty, vertexData[6] = a * w1 + c * h0 + tx, vertexData[7] = d * h0 + b * w1 + ty, this._roundPixels) { 17491 const resolution = settings.RESOLUTION; 17492 for (let i = 0; i < vertexData.length; ++i) 17493 vertexData[i] = Math.round(vertexData[i] * resolution) / resolution; 17494 } 17495 } 17496 /** 17497 * 17498 * Renders the object using the WebGL renderer 17499 * @param renderer - The webgl renderer to use. 17500 */ 17501 _render(renderer) { 17502 this.calculateVertices(), renderer.batch.setObjectRenderer(renderer.plugins[this.pluginName]), renderer.plugins[this.pluginName].render(this); 17503 } 17504 /** Updates the bounds of the sprite. */ 17505 _calculateBounds() { 17506 const trim = this._texture.trim, orig = this._texture.orig; 17507 !trim || trim.width === orig.width && trim.height === orig.height ? (this.calculateVertices(), this._bounds.addQuad(this.vertexData)) : (this.calculateTrimmedVertices(), this._bounds.addQuad(this.vertexTrimmedData)); 17508 } 17509 /** 17510 * Gets the local bounds of the sprite object. 17511 * @param rect - Optional output rectangle. 17512 * @returns The bounds. 17513 */ 17514 getLocalBounds(rect) { 17515 return this.children.length === 0 ? (this._localBounds || (this._localBounds = new Bounds()), this._localBounds.minX = this._texture.orig.width * -this._anchor._x, this._localBounds.minY = this._texture.orig.height * -this._anchor._y, this._localBounds.maxX = this._texture.orig.width * (1 - this._anchor._x), this._localBounds.maxY = this._texture.orig.height * (1 - this._anchor._y), rect || (this._localBoundsRect || (this._localBoundsRect = new Rectangle()), rect = this._localBoundsRect), this._localBounds.getRectangle(rect)) : super.getLocalBounds.call(this, rect); 17516 } 17517 /** 17518 * Tests if a point is inside this sprite 17519 * @param point - the point to test 17520 * @returns The result of the test 17521 */ 17522 containsPoint(point) { 17523 this.worldTransform.applyInverse(point, tempPoint$1); 17524 const width = this._texture.orig.width, height = this._texture.orig.height, x1 = -width * this.anchor.x; 17525 let y1 = 0; 17526 return tempPoint$1.x >= x1 && tempPoint$1.x < x1 + width && (y1 = -height * this.anchor.y, tempPoint$1.y >= y1 && tempPoint$1.y < y1 + height); 17527 } 17528 /** 17529 * Destroys this sprite and optionally its texture and children. 17530 * @param options - Options parameter. A boolean will act as if all options 17531 * have been set to that value 17532 * @param [options.children=false] - if set to true, all the children will have their destroy 17533 * method called as well. 'options' will be passed on to those calls. 17534 * @param [options.texture=false] - Should it destroy the current texture of the sprite as well 17535 * @param [options.baseTexture=false] - Should it destroy the base texture of the sprite as well 17536 */ 17537 destroy(options) { 17538 if (super.destroy(options), this._texture.off("update", this._onTextureUpdate, this), this._anchor = null, typeof options == "boolean" ? options : options?.texture) { 17539 const destroyBaseTexture = typeof options == "boolean" ? options : options?.baseTexture; 17540 this._texture.destroy(!!destroyBaseTexture); 17541 } 17542 this._texture = null; 17543 } 17544 // some helper functions.. 17545 /** 17546 * Helper function that creates a new sprite based on the source you provide. 17547 * The source can be - frame id, image url, video url, canvas element, video element, base texture 17548 * @param {string|PIXI.Texture|HTMLImageElement|HTMLVideoElement|ImageBitmap|PIXI.ICanvas} source 17549 * - Source to create texture from 17550 * @param {object} [options] - See {@link PIXI.BaseTexture}'s constructor for options. 17551 * @returns The newly created sprite 17552 */ 17553 static from(source, options) { 17554 const texture = source instanceof Texture ? source : Texture.from(source, options); 17555 return new Sprite(texture); 17556 } 17557 /** 17558 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 17559 * 17560 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 17561 * The main disadvantage is movement of objects may appear less smooth. 17562 * 17563 * To set the global default, change {@link PIXI.settings.ROUND_PIXELS}. 17564 * @default false 17565 */ 17566 set roundPixels(value) { 17567 this._roundPixels !== value && (this._transformID = -1, this._transformTrimmedID = -1), this._roundPixels = value; 17568 } 17569 get roundPixels() { 17570 return this._roundPixels; 17571 } 17572 /** The width of the sprite, setting this will actually modify the scale to achieve the value set. */ 17573 get width() { 17574 return Math.abs(this.scale.x) * this._texture.orig.width; 17575 } 17576 set width(value) { 17577 const s = sign(this.scale.x) || 1; 17578 this.scale.x = s * value / this._texture.orig.width, this._width = value; 17579 } 17580 /** The height of the sprite, setting this will actually modify the scale to achieve the value set. */ 17581 get height() { 17582 return Math.abs(this.scale.y) * this._texture.orig.height; 17583 } 17584 set height(value) { 17585 const s = sign(this.scale.y) || 1; 17586 this.scale.y = s * value / this._texture.orig.height, this._height = value; 17587 } 17588 /** 17589 * The anchor sets the origin point of the sprite. The default value is taken from the {@link PIXI.Texture|Texture} 17590 * and passed to the constructor. 17591 * 17592 * The default is `(0,0)`, this means the sprite's origin is the top left. 17593 *
17594 * Setting the anchor to `(0.5,0.5)` means the sprite's origin is centered. 17595 * 17596 * Setting the anchor to `(1,1)` would mean the sprite's origin point will be the bottom right corner. 17597 * 17598 * If you pass only single parameter, it will set both x and y to the same value as shown in the example below. 17599 * @example 17600 * import { Sprite } from 'pixi.js'; 17601 * 17602 * const sprite = new Sprite(Texture.WHITE); 17603 * sprite.anchor.set(0.5); // This will set the origin to center. (0.5) is same as (0.5, 0.5). 17604 */ 17605 get anchor() { 17606 return this._anchor; 17607 } 17608 set anchor(value) { 17609 this._anchor.copyFrom(value); 17610 } 17611 /** 17612 * The tint applied to the sprite. This is a hex value. 17613 * 17614 * A value of 0xFFFFFF will remove any tint effect. 17615 * @default 0xFFFFFF 17616 */ 17617 get tint() { 17618 return this._tintColor.value; 17619 } 17620 set tint(value) { 17621 this._tintColor.setValue(value), this._tintRGB = this._tintColor.toLittleEndianNumber(); 17622 } 17623 /** 17624 * Get the tint as a RGB integer. 17625 * @ignore 17626 */ 17627 get tintValue() { 17628 return this._tintColor.toNumber(); 17629 } 17630 /** The texture that the sprite is using. */ 17631 get texture() { 17632 return this._texture; 17633 } 17634 set texture(value) { 17635 this._texture !== value && (this._texture && this._texture.off("update", this._onTextureUpdate, this), this._texture = value || Texture.EMPTY, this._cachedTint = 16777215, this._textureID = -1, this._textureTrimmedID = -1, value && (value.baseTexture.valid ? this._onTextureUpdate() : value.once("update", this._onTextureUpdate, this))); 17636 } 17637} 17638 17639const _tempMatrix = new Matrix(); 17640DisplayObject.prototype._cacheAsBitmap = !1; 17641DisplayObject.prototype._cacheData = null; 17642DisplayObject.prototype._cacheAsBitmapResolution = null; 17643DisplayObject.prototype._cacheAsBitmapMultisample = null; 17644class CacheData { 17645 constructor() { 17646 this.textureCacheId = null, this.originalRender = null, this.originalRenderCanvas = null, this.originalCalculateBounds = null, this.originalGetLocalBounds = null, this.originalUpdateTransform = null, this.originalDestroy = null, this.originalMask = null, this.originalFilterArea = null, this.originalContainsPoint = null, this.sprite = null; 17647 } 17648} 17649Object.defineProperties(DisplayObject.prototype, { 17650 /** 17651 * The resolution to use for cacheAsBitmap. By default this will use the renderer's resolution 17652 * but can be overriden for performance. Lower values will reduce memory usage at the expense 17653 * of render quality. A falsey value of `null` or `0` will default to the renderer's resolution. 17654 * If `cacheAsBitmap` is set to `true`, this will re-render with the new resolution. 17655 * @member {number|null} cacheAsBitmapResolution 17656 * @memberof PIXI.DisplayObject# 17657 * @default null 17658 */ 17659 cacheAsBitmapResolution: { 17660 get() { 17661 return this._cacheAsBitmapResolution; 17662 }, 17663 set(resolution) { 17664 resolution !== this._cacheAsBitmapResolution && (this._cacheAsBitmapResolution = resolution, this.cacheAsBitmap && (this.cacheAsBitmap = !1, this.cacheAsBitmap = !0)); 17665 } 17666 }, 17667 /** 17668 * The number of samples to use for cacheAsBitmap. If set to `null`, the renderer's 17669 * sample count is used. 17670 * If `cacheAsBitmap` is set to `true`, this will re-render with the new number of samples. 17671 * @member {number|null} cacheAsBitmapMultisample 17672 * @memberof PIXI.DisplayObject# 17673 * @default null 17674 */ 17675 cacheAsBitmapMultisample: { 17676 get() { 17677 return this._cacheAsBitmapMultisample; 17678 }, 17679 set(multisample) { 17680 multisample !== this._cacheAsBitmapMultisample && (this._cacheAsBitmapMultisample = multisample, this.cacheAsBitmap && (this.cacheAsBitmap = !1, this.cacheAsBitmap = !0)); 17681 } 17682 }, 17683 /** 17684 * Set this to true if you want this display object to be cached as a bitmap. 17685 * This basically takes a snapshot of the display object as it is at that moment. It can 17686 * provide a performance benefit for complex static displayObjects. 17687 * To remove simply set this property to `false` 17688 * 17689 * IMPORTANT GOTCHA - Make sure that all your textures are preloaded BEFORE setting this property to true 17690 * as it will take a snapshot of what is currently there. If the textures have not loaded then they will not appear. 17691 * @member {boolean} 17692 * @memberof PIXI.DisplayObject# 17693 */ 17694 cacheAsBitmap: { 17695 get() { 17696 return this._cacheAsBitmap; 17697 }, 17698 set(value) { 17699 if (this._cacheAsBitmap === value) 17700 return; 17701 this._cacheAsBitmap = value; 17702 let data; 17703 value ? (this._cacheData || (this._cacheData = new CacheData()), data = this._cacheData, data.originalRender = this.render, data.originalRenderCanvas = this.renderCanvas, data.originalUpdateTransform = this.updateTransform, data.originalCalculateBounds = this.calculateBounds, data.originalGetLocalBounds = this.getLocalBounds, data.originalDestroy = this.destroy, data.originalContainsPoint = this.containsPoint, data.originalMask = this._mask, data.originalFilterArea = this.filterArea, this.render = this._renderCached, this.renderCanvas = this._renderCachedCanvas, this.destroy = this._cacheAsBitmapDestroy) : (data = this._cacheData, data.sprite && this._destroyCachedDisplayObject(), this.render = data.originalRender, this.renderCanvas = data.originalRenderCanvas, this.calculateBounds = data.originalCalculateBounds, this.getLocalBounds = data.originalGetLocalBounds, this.destroy = data.originalDestroy, this.updateTransform = data.originalUpdateTransform, this.containsPoint = data.originalContainsPoint, this._mask = data.originalMask, this.filterArea = data.originalFilterArea); 17704 } 17705 } 17706}); 17707DisplayObject.prototype._renderCached = function(renderer) { 17708 !this.visible || this.worldAlpha <= 0 || !this.renderable || (this._initCachedDisplayObject(renderer), this._cacheData.sprite.transform._worldID = this.transform._worldID, this._cacheData.sprite.worldAlpha = this.worldAlpha, this._cacheData.sprite._render(renderer)); 17709}; 17710DisplayObject.prototype._initCachedDisplayObject = function(renderer) { 17711 if (this._cacheData?.sprite) 17712 return; 17713 const cacheAlpha = this.alpha; 17714 this.alpha = 1, renderer.batch.flush(); 17715 const bounds = this.getLocalBounds(new Rectangle(), !0); 17716 if (this.filters?.length) { 17717 const padding = this.filters[0].padding; 17718 bounds.pad(padding); 17719 } 17720 const resolution = this.cacheAsBitmapResolution || renderer.resolution; 17721 bounds.ceil(resolution), bounds.width = Math.max(bounds.width, 1 / resolution), bounds.height = Math.max(bounds.height, 1 / resolution); 17722 const cachedRenderTexture = renderer.renderTexture.current, cachedSourceFrame = renderer.renderTexture.sourceFrame.clone(), cachedDestinationFrame = renderer.renderTexture.destinationFrame.clone(), cachedProjectionTransform = renderer.projection.transform, renderTexture = RenderTexture.create({ 17723 width: bounds.width, 17724 height: bounds.height, 17725 resolution, 17726 multisample: this.cacheAsBitmapMultisample ?? renderer.multisample 17727 }), textureCacheId = `cacheAsBitmap_${uid()}`; 17728 this._cacheData.textureCacheId = textureCacheId, BaseTexture.addToCache(renderTexture.baseTexture, textureCacheId), Texture.addToCache(renderTexture, textureCacheId); 17729 const m = this.transform.localTransform.copyTo(_tempMatrix).invert().translate(-bounds.x, -bounds.y); 17730 this.render = this._cacheData.originalRender, renderer.render(this, { renderTexture, clear: !0, transform: m, skipUpdateTransform: !1 }), renderer.framebuffer.blit(), renderer.projection.transform = cachedProjectionTransform, renderer.renderTexture.bind(cachedRenderTexture, cachedSourceFrame, cachedDestinationFrame), this.render = this._renderCached, this.updateTransform = this.displayObjectUpdateTransform, this.calculateBounds = this._calculateCachedBounds, this.getLocalBounds = this._getCachedLocalBounds, this._mask = null, this.filterArea = null, this.alpha = cacheAlpha; 17731 const cachedSprite = new Sprite(renderTexture); 17732 cachedSprite.transform.worldTransform = this.transform.worldTransform, cachedSprite.anchor.x = -(bounds.x / bounds.width), cachedSprite.anchor.y = -(bounds.y / boun
vendor: 4,487 bytes, lines 17732-17801
17732ds.height), cachedSprite.alpha = cacheAlpha, cachedSprite._bounds = this._bounds, this._cacheData.sprite = cachedSprite, this.transform._parentID = -1, this.parent ? this.updateTransform() : (this.enableTempParent(), this.updateTransform(), this.disableTempParent(null)), this.containsPoint = cachedSprite.containsPoint.bind(cachedSprite); 17733}; 17734DisplayObject.prototype._renderCachedCanvas = function(renderer) { 17735 !this.visible || this.worldAlpha <= 0 || !this.renderable || (this._initCachedDisplayObjectCanvas(renderer), this._cacheData.sprite.worldAlpha = this.worldAlpha, this._cacheData.sprite._renderCanvas(renderer)); 17736}; 17737DisplayObject.prototype._initCachedDisplayObjectCanvas = function(renderer) { 17738 if (this._cacheData?.sprite) 17739 return; 17740 const bounds = this.getLocalBounds(new Rectangle(), !0), cacheAlpha = this.alpha; 17741 this.alpha = 1; 17742 const cachedRenderTarget = renderer.canvasContext.activeContext, cachedProjectionTransform = renderer._projTransform, resolution = this.cacheAsBitmapResolution || renderer.resolution; 17743 bounds.ceil(resolution), bounds.width = Math.max(bounds.width, 1 / resolution), bounds.height = Math.max(bounds.height, 1 / resolution); 17744 const renderTexture = RenderTexture.create({ 17745 width: bounds.width, 17746 height: bounds.height, 17747 resolution 17748 }), textureCacheId = `cacheAsBitmap_${uid()}`; 17749 this._cacheData.textureCacheId = textureCacheId, BaseTexture.addToCache(renderTexture.baseTexture, textureCacheId), Texture.addToCache(renderTexture, textureCacheId); 17750 const m = _tempMatrix; 17751 this.transform.localTransform.copyTo(m), m.invert(), m.tx -= bounds.x, m.ty -= bounds.y, this.renderCanvas = this._cacheData.originalRenderCanvas, renderer.render(this, { renderTexture, clear: !0, transform: m, skipUpdateTransform: !1 }), renderer.canvasContext.activeContext = cachedRenderTarget, renderer._projTransform = cachedProjectionTransform, this.renderCanvas = this._renderCachedCanvas, this.updateTransform = this.displayObjectUpdateTransform, this.calculateBounds = this._calculateCachedBounds, this.getLocalBounds = this._getCachedLocalBounds, this._mask = null, this.filterArea = null, this.alpha = cacheAlpha; 17752 const cachedSprite = new Sprite(renderTexture); 17753 cachedSprite.transform.worldTransform = this.transform.worldTransform, cachedSprite.anchor.x = -(bounds.x / bounds.width), cachedSprite.anchor.y = -(bounds.y / bounds.height), cachedSprite.alpha = cacheAlpha, cachedSprite._bounds = this._bounds, this._cacheData.sprite = cachedSprite, this.transform._parentID = -1, this.parent ? this.updateTransform() : (this.parent = renderer._tempDisplayObjectParent, this.updateTransform(), this.parent = null), this.containsPoint = cachedSprite.containsPoint.bind(cachedSprite); 17754}; 17755DisplayObject.prototype._calculateCachedBounds = function() { 17756 this._bounds.clear(), this._cacheData.sprite.transform._worldID = this.transform._worldID, this._cacheData.sprite._calculateBounds(), this._bounds.updateID = this._boundsID; 17757}; 17758DisplayObject.prototype._getCachedLocalBounds = function() { 17759 return this._cacheData.sprite.getLocalBounds(null); 17760}; 17761DisplayObject.prototype._destroyCachedDisplayObject = function() { 17762 this._cacheData.sprite._texture.destroy(!0), this._cacheData.sprite = null, BaseTexture.removeFromCache(this._cacheData.textureCacheId), Texture.removeFromCache(this._cacheData.textureCacheId), this._cacheData.textureCacheId = null; 17763}; 17764DisplayObject.prototype._cacheAsBitmapDestroy = function(options) { 17765 this.cacheAsBitmap = !1, this.destroy(options); 17766}; 17767 17768DisplayObject.prototype.name = null; 17769Container.prototype.getChildByName = function(name, deep) { 17770 for (let i = 0, j = this.children.length; i < j; i++) 17771 if (this.children[i].name === name) 17772 return this.children[i]; 17773 if (deep) 17774 for (let i = 0, j = this.children.length; i < j; i++) { 17775 const child = this.children[i]; 17776 if (!child.getChildByName) 17777 continue; 17778 const target = child.getChildByName(name, !0); 17779 if (target) 17780 return target; 17781 } 17782 return null; 17783}; 17784 17785DisplayObject.prototype.getGlobalPosition = function(point = new Point(), skipUpdate = !1) { 17786 return this.parent ? this.parent.toGlobal(this.position, point, skipUpdate) : (point.x = this.position.x, point.y = this.position.y), point; 17787}; 17788 17789var fragment$6 = `varying vec2 vTextureCoord; 17790 17791uniform sampler2D uSampler; 17792uniform float uAlpha; 17793 17794void main(void) 17795{ 17796 gl_FragColor = texture2D(uSampler, vTextureCoord) * uAlpha; 17797} 17798`; 17799 17800class AlphaFilter extends Filter { 17801 /**
vendor: 27,814 bytes, lines 17802-18849
17802 * @param alpha - Amount of alpha from 0 to 1, where 0 is transparent 17803 */ 17804 constructor(alpha = 1) { 17805 super(defaultVertex, fragment$6, { uAlpha: 1 }), this.alpha = alpha; 17806 } 17807 /** 17808 * Coefficient for alpha multiplication 17809 * @default 1 17810 */ 17811 get alpha() { 17812 return this.uniforms.uAlpha; 17813 } 17814 set alpha(value) { 17815 this.uniforms.uAlpha = value; 17816 } 17817} 17818 17819const GAUSSIAN_VALUES = { 17820 5: [0.153388, 0.221461, 0.250301], 17821 7: [0.071303, 0.131514, 0.189879, 0.214607], 17822 9: [0.028532, 0.067234, 0.124009, 0.179044, 0.20236], 17823 11: [93e-4, 0.028002, 0.065984, 0.121703, 0.175713, 0.198596], 17824 13: [2406e-6, 9255e-6, 0.027867, 0.065666, 0.121117, 0.174868, 0.197641], 17825 15: [489e-6, 2403e-6, 9246e-6, 0.02784, 0.065602, 0.120999, 0.174697, 0.197448] 17826}, fragTemplate = [ 17827 "varying vec2 vBlurTexCoords[%size%];", 17828 "uniform sampler2D uSampler;", 17829 "void main(void)", 17830 "{", 17831 " gl_FragColor = vec4(0.0);", 17832 " %blur%", 17833 "}" 17834].join(` 17835`); 17836function generateBlurFragSource(kernelSize) { 17837 const kernel = GAUSSIAN_VALUES[kernelSize], halfLength = kernel.length; 17838 let fragSource = fragTemplate, blurLoop = ""; 17839 const template = "gl_FragColor += texture2D(uSampler, vBlurTexCoords[%index%]) * %value%;"; 17840 let value; 17841 for (let i = 0; i < kernelSize; i++) { 17842 let blur = template.replace("%index%", i.toString()); 17843 value = i, i >= halfLength && (value = kernelSize - i - 1), blur = blur.replace("%value%", kernel[value].toString()), blurLoop += blur, blurLoop += ` 17844`; 17845 } 17846 return fragSource = fragSource.replace("%blur%", blurLoop), fragSource = fragSource.replace("%size%", kernelSize.toString()), fragSource; 17847} 17848 17849const vertTemplate = ` 17850 attribute vec2 aVertexPosition; 17851 17852 uniform mat3 projectionMatrix; 17853 17854 uniform float strength; 17855 17856 varying vec2 vBlurTexCoords[%size%]; 17857 17858 uniform vec4 inputSize; 17859 uniform vec4 outputFrame; 17860 17861 vec4 filterVertexPosition( void ) 17862 { 17863 vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy; 17864 17865 return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0); 17866 } 17867 17868 vec2 filterTextureCoord( void ) 17869 { 17870 return aVertexPosition * (outputFrame.zw * inputSize.zw); 17871 } 17872 17873 void main(void) 17874 { 17875 gl_Position = filterVertexPosition(); 17876 17877 vec2 textureCoord = filterTextureCoord(); 17878 %blur% 17879 }`; 17880function generateBlurVertSource(kernelSize, x) { 17881 const halfLength = Math.ceil(kernelSize / 2); 17882 let vertSource = vertTemplate, blurLoop = "", template; 17883 x ? template = "vBlurTexCoords[%index%] = textureCoord + vec2(%sampleIndex% * strength, 0.0);" : template = "vBlurTexCoords[%index%] = textureCoord + vec2(0.0, %sampleIndex% * strength);"; 17884 for (let i = 0; i < kernelSize; i++) { 17885 let blur = template.replace("%index%", i.toString()); 17886 blur = blur.replace("%sampleIndex%", `${i - (halfLength - 1)}.0`), blurLoop += blur, blurLoop += ` 17887`; 17888 } 17889 return vertSource = vertSource.replace("%blur%", blurLoop), vertSource = vertSource.replace("%size%", kernelSize.toString()), vertSource; 17890} 17891 17892class BlurFilterPass extends Filter { 17893 /** 17894 * @param horizontal - Do pass along the x-axis (`true`) or y-axis (`false`). 17895 * @param strength - The strength of the blur filter. 17896 * @param quality - The quality of the blur filter. 17897 * @param {number|null} [resolution=PIXI.Filter.defaultResolution] - The resolution of the blur filter. 17898 * @param kernelSize - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. 17899 */ 17900 constructor(horizontal, strength = 8, quality = 4, resolution = Filter.defaultResolution, kernelSize = 5) { 17901 const vertSrc = generateBlurVertSource(kernelSize, horizontal), fragSrc = generateBlurFragSource(kernelSize); 17902 super( 17903 // vertex shader 17904 vertSrc, 17905 // fragment shader 17906 fragSrc 17907 ), this.horizontal = horizontal, this.resolution = resolution, this._quality = 0, this.quality = quality, this.blur = strength; 17908 } 17909 /** 17910 * Applies the filter. 17911 * @param filterManager - The manager. 17912 * @param input - The input target. 17913 * @param output - The output target. 17914 * @param clearMode - How to clear 17915 */ 17916 apply(filterManager, input, output, clearMode) { 17917 if (output ? this.horizontal ? this.uniforms.strength = 1 / output.width * (output.width / input.width) : this.uniforms.strength = 1 / output.height * (output.height / input.height) : this.horizontal ? this.uniforms.strength = 1 / filterManager.renderer.width * (filterManager.renderer.width / input.width) : this.uniforms.strength = 1 / filterManager.renderer.height * (filterManager.renderer.height / input.height), this.uniforms.strength *= this.strength, this.uniforms.strength /= this.passes, this.passes === 1) 17918 filterManager.applyFilter(this, input, output, clearMode); 17919 else { 17920 const renderTarget = filterManager.getFilterTexture(), renderer = filterManager.renderer; 17921 let flip = input, flop = renderTarget; 17922 this.state.blend = !1, filterManager.applyFilter(this, flip, flop, CLEAR_MODES.CLEAR); 17923 for (let i = 1; i < this.passes - 1; i++) { 17924 filterManager.bindAndClear(flip, CLEAR_MODES.BLIT), this.uniforms.uSampler = flop; 17925 const temp = flop; 17926 flop = flip, flip = temp, renderer.shader.bind(this), renderer.geometry.draw(5); 17927 } 17928 this.state.blend = !0, filterManager.applyFilter(this, flop, output, clearMode), filterManager.returnFilterTexture(renderTarget); 17929 } 17930 } 17931 /** 17932 * Sets the strength of both the blur. 17933 * @default 16 17934 */ 17935 get blur() { 17936 return this.strength; 17937 } 17938 set blur(value) { 17939 this.padding = 1 + Math.abs(value) * 2, this.strength = value; 17940 } 17941 /** 17942 * Sets the quality of the blur by modifying the number of passes. More passes means higher 17943 * quality bluring but the lower the performance. 17944 * @default 4 17945 */ 17946 get quality() { 17947 return this._quality; 17948 } 17949 set quality(value) { 17950 this._quality = value, this.passes = value; 17951 } 17952} 17953 17954class BlurFilter extends Filter { 17955 /** 17956 * @param strength - The strength of the blur filter. 17957 * @param quality - The quality of the blur filter. 17958 * @param {number|null} [resolution=PIXI.Filter.defaultResolution] - The resolution of the blur filter. 17959 * @param kernelSize - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. 17960 */ 17961 constructor(strength = 8, quality = 4, resolution = Filter.defaultResolution, kernelSize = 5) { 17962 super(), this._repeatEdgePixels = !1, this.blurXFilter = new BlurFilterPass(!0, strength, quality, resolution, kernelSize), this.blurYFilter = new BlurFilterPass(!1, strength, quality, resolution, kernelSize), this.resolution = resolution, this.quality = quality, this.blur = strength, this.repeatEdgePixels = !1; 17963 } 17964 /** 17965 * Applies the filter. 17966 * @param filterManager - The manager. 17967 * @param input - The input target. 17968 * @param output - The output target. 17969 * @param clearMode - How to clear 17970 */ 17971 apply(filterManager, input, output, clearMode) { 17972 const xStrength = Math.abs(this.blurXFilter.strength), yStrength = Math.abs(this.blurYFilter.strength); 17973 if (xStrength && yStrength) { 17974 const renderTarget = filterManager.getFilterTexture(); 17975 this.blurXFilter.apply(filterManager, input, renderTarget, CLEAR_MODES.CLEAR), this.blurYFilter.apply(filterManager, renderTarget, output, clearMode), filterManager.returnFilterTexture(renderTarget); 17976 } else 17977 yStrength ? this.blurYFilter.apply(filterManager, input, output, clearMode) : this.blurXFilter.apply(filterManager, input, output, clearMode); 17978 } 17979 updatePadding() { 17980 this._repeatEdgePixels ? this.padding = 0 : this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2; 17981 } 17982 /** 17983 * Sets the strength of both the blurX and blurY properties simultaneously 17984 * @default 2 17985 */ 17986 get blur() { 17987 return this.blurXFilter.blur; 17988 } 17989 set blur(value) { 17990 this.blurXFilter.blur = this.blurYFilter.blur = value, this.updatePadding(); 17991 } 17992 /** 17993 * Sets the number of passes for blur. More passes means higher quality bluring. 17994 * @default 1 17995 */ 17996 get quality() { 17997 return this.blurXFilter.quality; 17998 } 17999 set quality(value) { 18000 this.blurXFilter.quality = this.blurYFilter.quality = value; 18001 } 18002 /** 18003 * Sets the strength of the blurX property 18004 * @default 2 18005 */ 18006 get blurX() { 18007 return this.blurXFilter.blur; 18008 } 18009 set blurX(value) { 18010 this.blurXFilter.blur = value, this.updatePadding(); 18011 } 18012 /** 18013 * Sets the strength of the blurY property 18014 * @default 2 18015 */ 18016 get blurY() { 18017 return this.blurYFilter.blur; 18018 } 18019 set blurY(value) { 18020 this.blurYFilter.blur = value, this.updatePadding(); 18021 } 18022 /** 18023 * Sets the blendmode of the filter 18024 * @default PIXI.BLEND_MODES.NORMAL 18025 */ 18026 get blendMode() { 18027 return this.blurYFilter.blendMode; 18028 } 18029 set blendMode(value) { 18030 this.blurYFilter.blendMode = value; 18031 } 18032 /** 18033 * If set to true the edge of the target will be clamped 18034 * @default false 18035 */ 18036 get repeatEdgePixels() { 18037 return this._repeatEdgePixels; 18038 } 18039 set repeatEdgePixels(value) { 18040 this._repeatEdgePixels = value, this.updatePadding(); 18041 } 18042} 18043 18044var fragment$5 = `varying vec2 vTextureCoord; 18045uniform sampler2D uSampler; 18046uniform float m[20]; 18047uniform float uAlpha; 18048 18049void main(void) 18050{ 18051 vec4 c = texture2D(uSampler, vTextureCoord); 18052 18053 if (uAlpha == 0.0) { 18054 gl_FragColor = c; 18055 return; 18056 } 18057 18058 // Un-premultiply alpha before applying the color matrix. See issue #3539. 18059 if (c.a > 0.0) { 18060 c.rgb /= c.a; 18061 } 18062 18063 vec4 result; 18064 18065 result.r = (m[0] * c.r); 18066 result.r += (m[1] * c.g); 18067 result.r += (m[2] * c.b); 18068 result.r += (m[3] * c.a); 18069 result.r += m[4]; 18070 18071 result.g = (m[5] * c.r); 18072 result.g += (m[6] * c.g); 18073 result.g += (m[7] * c.b); 18074 result.g += (m[8] * c.a); 18075 result.g += m[9]; 18076 18077 result.b = (m[10] * c.r); 18078 result.b += (m[11] * c.g); 18079 result.b += (m[12] * c.b); 18080 result.b += (m[13] * c.a); 18081 result.b += m[14]; 18082 18083 result.a = (m[15] * c.r); 18084 result.a += (m[16] * c.g); 18085 result.a += (m[17] * c.b); 18086 result.a += (m[18] * c.a); 18087 result.a += m[19]; 18088 18089 vec3 rgb = mix(c.rgb, result.rgb, uAlpha); 18090 18091 // Premultiply alpha again. 18092 rgb *= result.a; 18093 18094 gl_FragColor = vec4(rgb, result.a); 18095} 18096`; 18097 18098class ColorMatrixFilter extends Filter { 18099 constructor() { 18100 const uniforms = { 18101 m: new Float32Array([ 18102 1, 18103 0, 18104 0, 18105 0, 18106 0, 18107 0, 18108 1, 18109 0, 18110 0, 18111 0, 18112 0, 18113 0, 18114 1, 18115 0, 18116 0, 18117 0, 18118 0, 18119 0, 18120 1, 18121 0 18122 ]), 18123 uAlpha: 1 18124 }; 18125 super(defaultFilterVertex, fragment$5, uniforms), this.alpha = 1; 18126 } 18127 /** 18128 * Transforms current matrix and set the new one 18129 * @param {number[]} matrix - 5x4 matrix 18130 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18131 * just set the current matrix with @param matrix 18132 */ 18133 _loadMatrix(matrix, multiply = !1) { 18134 let newMatrix = matrix; 18135 multiply && (this._multiply(newMatrix, this.uniforms.m, matrix), newMatrix = this._colorMatrix(newMatrix)), this.uniforms.m = newMatrix; 18136 } 18137 /** 18138 * Multiplies two mat5's 18139 * @private 18140 * @param out - 5x4 matrix the receiving matrix 18141 * @param a - 5x4 matrix the first operand 18142 * @param b - 5x4 matrix the second operand 18143 * @returns {number[]} 5x4 matrix 18144 */ 18145 _multiply(out, a, b) { 18146 return out[0] = a[0] * b[0] + a[1] * b[5] + a[2] * b[10] + a[3] * b[15], out[1] = a[0] * b[1] + a[1] * b[6] + a[2] * b[11] + a[3] * b[16], out[2] = a[0] * b[2] + a[1] * b[7] + a[2] * b[12] + a[3] * b[17], out[3] = a[0] * b[3] + a[1] * b[8] + a[2] * b[13] + a[3] * b[18], out[4] = a[0] * b[4] + a[1] * b[9] + a[2] * b[14] + a[3] * b[19] + a[4], out[5] = a[5] * b[0] + a[6] * b[5] + a[7] * b[10] + a[8] * b[15], out[6] = a[5] * b[1] + a[6] * b[6] + a[7] * b[11] + a[8] * b[16], out[7] = a[5] * b[2] + a[6] * b[7] + a[7] * b[12] + a[8] * b[17], out[8] = a[5] * b[3] + a[6] * b[8] + a[7] * b[13] + a[8] * b[18], out[9] = a[5] * b[4] + a[6] * b[9] + a[7] * b[14] + a[8] * b[19] + a[9], out[10] = a[10] * b[0] + a[11] * b[5] + a[12] * b[10] + a[13] * b[15], out[11] = a[10] * b[1] + a[11] * b[6] + a[12] * b[11] + a[13] * b[16], out[12] = a[10] * b[2] + a[11] * b[7] + a[12] * b[12] + a[13] * b[17], out[13] = a[10] * b[3] + a[11] * b[8] + a[12] * b[13] + a[13] * b[18], out[14] = a[10] * b[4] + a[11] * b[9] + a[12] * b[14] + a[13] * b[19] + a[14], out[15] = a[15] * b[0] + a[16] * b[5] + a[17] * b[10] + a[18] * b[15], out[16] = a[15] * b[1] + a[16] * b[6] + a[17] * b[11] + a[18] * b[16], out[17] = a[15] * b[2] + a[16] * b[7] + a[17] * b[12] + a[18] * b[17], out[18] = a[15] * b[3] + a[16] * b[8] + a[17] * b[13] + a[18] * b[18], out[19] = a[15] * b[4] + a[16] * b[9] + a[17] * b[14] + a[18] * b[19] + a[19], out; 18147 } 18148 /** 18149 * Create a Float32 Array and normalize the offset component to 0-1 18150 * @param {number[]} matrix - 5x4 matrix 18151 * @returns {number[]} 5x4 matrix with all values between 0-1 18152 */ 18153 _colorMatrix(matrix) { 18154 const m = new Float32Array(matrix); 18155 return m[4] /= 255, m[9] /= 255, m[14] /= 255, m[19] /= 255, m; 18156 } 18157 /** 18158 * Adjusts brightness 18159 * @param b - value of the brigthness (0-1, where 0 is black) 18160 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18161 * just set the current matrix with @param matrix 18162 */ 18163 brightness(b, multiply) { 18164 const matrix = [ 18165 b, 18166 0, 18167 0, 18168 0, 18169 0, 18170 0, 18171 b, 18172 0, 18173 0, 18174 0, 18175 0, 18176 0, 18177 b, 18178 0, 18179 0, 18180 0, 18181 0, 18182 0, 18183 1, 18184 0 18185 ]; 18186 this._loadMatrix(matrix, multiply); 18187 } 18188 /** 18189 * Sets each channel on the diagonal of the color matrix. 18190 * This can be used to achieve a tinting effect on Containers similar to the tint field of some 18191 * display objects like Sprite, Text, Graphics, and Mesh. 18192 * @param color - Color of the tint. This is a hex value. 18193 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18194 * just set the current matrix with @param matrix 18195 */ 18196 tint(color, multiply) { 18197 const [r, g, b] = Color.shared.setValue(color).toArray(), matrix = [ 18198 r, 18199 0, 18200 0, 18201 0, 18202 0, 18203 0, 18204 g, 18205 0, 18206 0, 18207 0, 18208 0, 18209 0, 18210 b, 18211 0, 18212 0, 18213 0, 18214 0, 18215 0, 18216 1, 18217 0 18218 ]; 18219 this._loadMatrix(matrix, multiply); 18220 } 18221 /** 18222 * Set the matrices in grey scales 18223 * @param scale - value of the grey (0-1, where 0 is black) 18224 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18225 * just set the current matrix with @param matrix 18226 */ 18227 greyscale(scale, multiply) { 18228 const matrix = [ 18229 scale, 18230 scale, 18231 scale, 18232 0, 18233 0, 18234 scale, 18235 scale, 18236 scale, 18237 0, 18238 0, 18239 scale, 18240 scale, 18241 scale, 18242 0, 18243 0, 18244 0, 18245 0, 18246 0, 18247 1, 18248 0 18249 ]; 18250 this._loadMatrix(matrix, multiply); 18251 } 18252 /** 18253 * Set the black and white matrice. 18254 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18255 * just set the current matrix with @param matrix 18256 */ 18257 blackAndWhite(multiply) { 18258 const matrix = [ 18259 0.3, 18260 0.6, 18261 0.1, 18262 0, 18263 0, 18264 0.3, 18265 0.6, 18266 0.1, 18267 0, 18268 0, 18269 0.3, 18270 0.6, 18271 0.1, 18272 0, 18273 0, 18274 0, 18275 0, 18276 0, 18277 1, 18278 0 18279 ]; 18280 this._loadMatrix(matrix, multiply); 18281 } 18282 /** 18283 * Set the hue property of the color 18284 * @param rotation - in degrees 18285 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18286 * just set the current matrix with @param matrix 18287 */ 18288 hue(rotation, multiply) { 18289 rotation = (rotation || 0) / 180 * Math.PI; 18290 const cosR = Math.cos(rotation), sinR = Math.sin(rotation), sqrt = Math.sqrt, w = 1 / 3, sqrW = sqrt(w), a00 = cosR + (1 - cosR) * w, a01 = w * (1 - cosR) - sqrW * sinR, a02 = w * (1 - cosR) + sqrW * sinR, a10 = w * (1 - cosR) + sqrW * sinR, a11 = cosR + w * (1 - cosR), a12 = w * (1 - cosR) - sqrW * sinR, a20 = w * (1 - cosR) - sqrW * sinR, a21 = w * (1 - cosR) + sqrW * sinR, a22 = cosR + w * (1 - cosR), matrix = [ 18291 a00, 18292 a01, 18293 a02, 18294 0, 18295 0, 18296 a10, 18297 a11, 18298 a12, 18299 0, 18300 0, 18301 a20, 18302 a21, 18303 a22, 18304 0, 18305 0, 18306 0, 18307 0, 18308 0, 18309 1, 18310 0 18311 ]; 18312 this._loadMatrix(matrix, multiply); 18313 } 18314 /** 18315 * Set the contrast matrix, increase the separation between dark and bright 18316 * Increase contrast : shadows darker and highlights brighter 18317 * Decrease contrast : bring the shadows up and the highlights down 18318 * @param amount - value of the contrast (0-1) 18319 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18320 * just set the current matrix with @param matrix 18321 */ 18322 contrast(amount, multiply) { 18323 const v = (amount || 0) + 1, o = -0.5 * (v - 1), matrix = [ 18324 v, 18325 0, 18326 0, 18327 0, 18328 o, 18329 0, 18330 v, 18331 0, 18332 0, 18333 o, 18334 0, 18335 0, 18336 v, 18337 0, 18338 o, 18339 0, 18340 0, 18341 0, 18342 1, 18343 0 18344 ]; 18345 this._loadMatrix(matrix, multiply); 18346 } 18347 /** 18348 * Set the saturation matrix, increase the separation between colors 18349 * Increase saturation : increase contrast, brightness, and sharpness 18350 * @param amount - The saturation amount (0-1) 18351 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18352 * just set the current matrix with @param matrix 18353 */ 18354 saturate(amount = 0, multiply) { 18355 const x = amount * 2 / 3 + 1, y = (x - 1) * -0.5, matrix = [ 18356 x, 18357 y, 18358 y, 18359 0, 18360 0, 18361 y, 18362 x, 18363 y, 18364 0, 18365 0, 18366 y, 18367 y, 18368 x, 18369 0, 18370 0, 18371 0, 18372 0, 18373 0, 18374 1, 18375 0 18376 ]; 18377 this._loadMatrix(matrix, multiply); 18378 } 18379 /** Desaturate image (remove color) Call the saturate function */ 18380 desaturate() { 18381 this.saturate(-1); 18382 } 18383 /** 18384 * Negative image (inverse of classic rgb matrix) 18385 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18386 * just set the current matrix with @param matrix 18387 */ 18388 negative(multiply) { 18389 const matrix = [ 18390 -1, 18391 0, 18392 0, 18393 1, 18394 0, 18395 0, 18396 -1, 18397 0, 18398 1, 18399 0, 18400 0, 18401 0, 18402 -1, 18403 1, 18404 0, 18405 0, 18406 0, 18407 0, 18408 1, 18409 0 18410 ]; 18411 this._loadMatrix(matrix, multiply); 18412 } 18413 /** 18414 * Sepia image 18415 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18416 * just set the current matrix with @param matrix 18417 */ 18418 sepia(multiply) { 18419 const matrix = [ 18420 0.393, 18421 0.7689999, 18422 0.18899999, 18423 0, 18424 0, 18425 0.349, 18426 0.6859999, 18427 0.16799999, 18428 0, 18429 0, 18430 0.272, 18431 0.5339999, 18432 0.13099999, 18433 0, 18434 0, 18435 0, 18436 0, 18437 0, 18438 1, 18439 0 18440 ]; 18441 this._loadMatrix(matrix, multiply); 18442 } 18443 /** 18444 * Color motion picture process invented in 1916 (thanks Dominic Szablewski) 18445 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18446 * just set the current matrix with @param matrix 18447 */ 18448 technicolor(multiply) { 18449 const matrix = [ 18450 1.9125277891456083, 18451 -0.8545344976951645, 18452 -0.09155508482755585, 18453 0, 18454 11.793603434377337, 18455 -0.3087833385928097, 18456 1.7658908555458428, 18457 -0.10601743074722245, 18458 0, 18459 -70.35205161461398, 18460 -0.231103377548616, 18461 -0.7501899197440212, 18462 1.847597816108189, 18463 0, 18464 30.950940869491138, 18465 0, 18466 0, 18467 0, 18468 1, 18469 0 18470 ]; 18471 this._loadMatrix(matrix, multiply); 18472 } 18473 /** 18474 * Polaroid filter 18475 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18476 * just set the current matrix with @param matrix 18477 */ 18478 polaroid(multiply) { 18479 const matrix = [ 18480 1.438, 18481 -0.062, 18482 -0.062, 18483 0, 18484 0, 18485 -0.122, 18486 1.378, 18487 -0.122, 18488 0, 18489 0, 18490 -0.016, 18491 -0.016, 18492 1.483, 18493 0, 18494 0, 18495 0, 18496 0, 18497 0, 18498 1, 18499 0 18500 ]; 18501 this._loadMatrix(matrix, multiply); 18502 } 18503 /** 18504 * Filter who transforms : Red -> Blue and Blue -> Red 18505 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18506 * just set the current matrix with @param matrix 18507 */ 18508 toBGR(multiply) { 18509 const matrix = [ 18510 0, 18511 0, 18512 1, 18513 0, 18514 0, 18515 0, 18516 1, 18517 0, 18518 0, 18519 0, 18520 1, 18521 0, 18522 0, 18523 0, 18524 0, 18525 0, 18526 0, 18527 0, 18528 1, 18529 0 18530 ]; 18531 this._loadMatrix(matrix, multiply); 18532 } 18533 /** 18534 * Color reversal film introduced by Eastman Kodak in 1935. (thanks Dominic Szablewski) 18535 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18536 * just set the current matrix with @param matrix 18537 */ 18538 kodachrome(multiply) { 18539 const matrix = [ 18540 1.1285582396593525, 18541 -0.3967382283601348, 18542 -0.03992559172921793, 18543 0, 18544 63.72958762196502, 18545 -0.16404339962244616, 18546 1.0835251566291304, 18547 -0.05498805115633132, 18548 0, 18549 24.732407896706203, 18550 -0.16786010706155763, 18551 -0.5603416277695248, 18552 1.6014850761964943, 18553 0, 18554 35.62982807460946, 18555 0, 18556 0, 18557 0, 18558 1, 18559 0 18560 ]; 18561 this._loadMatrix(matrix, multiply); 18562 } 18563 /** 18564 * Brown delicious browni filter (thanks Dominic Szablewski) 18565 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18566 * just set the current matrix with @param matrix 18567 */ 18568 browni(multiply) { 18569 const matrix = [ 18570 0.5997023498159715, 18571 0.34553243048391263, 18572 -0.2708298674538042, 18573 0, 18574 47.43192855600873, 18575 -0.037703249837783157, 18576 0.8609577587992641, 18577 0.15059552388459913, 18578 0, 18579 -36.96841498319127, 18580 0.24113635128153335, 18581 -0.07441037908422492, 18582 0.44972182064877153, 18583 0, 18584 -7.562075277591283, 18585 0, 18586 0, 18587 0, 18588 1, 18589 0 18590 ]; 18591 this._loadMatrix(matrix, multiply); 18592 } 18593 /** 18594 * Vintage filter (thanks Dominic Szablewski) 18595 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18596 * just set the current matrix with @param matrix 18597 */ 18598 vintage(multiply) { 18599 const matrix = [ 18600 0.6279345635605994, 18601 0.3202183420819367, 18602 -0.03965408211312453, 18603 0, 18604 9.651285835294123, 18605 0.02578397704808868, 18606 0.6441188644374771, 18607 0.03259127616149294, 18608 0, 18609 7.462829176470591, 18610 0.0466055556782719, 18611 -0.0851232987247891, 18612 0.5241648018700465, 18613 0, 18614 5.159190588235296, 18615 0, 18616 0, 18617 0, 18618 1, 18619 0 18620 ]; 18621 this._loadMatrix(matrix, multiply); 18622 } 18623 /** 18624 * We don't know exactly what it does, kind of gradient map, but funny to play with! 18625 * @param desaturation - Tone values. 18626 * @param toned - Tone values. 18627 * @param lightColor - Tone values, example: `0xFFE580` 18628 * @param darkColor - Tone values, example: `0xFFE580` 18629 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18630 * just set the current matrix with @param matrix 18631 */ 18632 colorTone(desaturation, toned, lightColor, darkColor, multiply) { 18633 desaturation = desaturation || 0.2, toned = toned || 0.15, lightColor = lightColor || 16770432, darkColor = darkColor || 3375104; 18634 const temp = Color.shared, [lR, lG, lB] = temp.setValue(lightColor).toArray(), [dR, dG, dB] = temp.setValue(darkColor).toArray(), matrix = [ 18635 0.3, 18636 0.59, 18637 0.11, 18638 0, 18639 0, 18640 lR, 18641 lG, 18642 lB, 18643 desaturation, 18644 0, 18645 dR, 18646 dG, 18647 dB, 18648 toned, 18649 0, 18650 lR - dR, 18651 lG - dG, 18652 lB - dB, 18653 0, 18654 0 18655 ]; 18656 this._loadMatrix(matrix, multiply); 18657 } 18658 /** 18659 * Night effect 18660 * @param intensity - The intensity of the night effect. 18661 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18662 * just set the current matrix with @param matrix 18663 */ 18664 night(intensity, multiply) { 18665 intensity = intensity || 0.1; 18666 const matrix = [ 18667 intensity * -2, 18668 -intensity, 18669 0, 18670 0, 18671 0, 18672 -intensity, 18673 0, 18674 intensity, 18675 0, 18676 0, 18677 0, 18678 intensity, 18679 intensity * 2, 18680 0, 18681 0, 18682 0, 18683 0, 18684 0, 18685 1, 18686 0 18687 ]; 18688 this._loadMatrix(matrix, multiply); 18689 } 18690 /** 18691 * Predator effect 18692 * 18693 * Erase the current matrix by setting a new indepent one 18694 * @param amount - how much the predator feels his future victim 18695 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18696 * just set the current matrix with @param matrix 18697 */ 18698 predator(amount, multiply) { 18699 const matrix = [ 18700 // row 1 18701 11.224130630493164 * amount, 18702 -4.794486999511719 * amount, 18703 -2.8746118545532227 * amount, 18704 0 * amount, 18705 0.40342438220977783 * amount, 18706 // row 2 18707 -3.6330697536468506 * amount, 18708 9.193157196044922 * amount, 18709 -2.951810836791992 * amount, 18710 0 * amount, 18711 -1.316135048866272 * amount, 18712 // row 3 18713 -3.2184197902679443 * amount, 18714 -4.2375030517578125 * amount, 18715 7.476448059082031 * amount, 18716 0 * amount, 18717 0.8044459223747253 * amount, 18718 // row 4 18719 0, 18720 0, 18721 0, 18722 1, 18723 0 18724 ]; 18725 this._loadMatrix(matrix, multiply); 18726 } 18727 /** 18728 * LSD effect 18729 * 18730 * Multiply the current matrix 18731 * @param multiply - if true, current matrix and matrix are multiplied. If false, 18732 * just set the current matrix with @param matrix 18733 */ 18734 lsd(multiply) { 18735 const matrix = [ 18736 2, 18737 -0.4, 18738 0.5, 18739 0, 18740 0, 18741 -0.5, 18742 2, 18743 -0.4, 18744 0, 18745 0, 18746 -0.4, 18747 -0.5, 18748 3, 18749 0, 18750 0, 18751 0, 18752 0, 18753 0, 18754 1, 18755 0 18756 ]; 18757 this._loadMatrix(matrix, multiply); 18758 } 18759 /** Erase the current matrix by setting the default one. */ 18760 reset() { 18761 const matrix = [ 18762 1, 18763 0, 18764 0, 18765 0, 18766 0, 18767 0, 18768 1, 18769 0, 18770 0, 18771 0, 18772 0, 18773 0, 18774 1, 18775 0, 18776 0, 18777 0, 18778 0, 18779 0, 18780 1, 18781 0 18782 ]; 18783 this._loadMatrix(matrix, !1); 18784 } 18785 /** 18786 * The matrix of the color matrix filter 18787 * @member {number[]} 18788 * @default [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0] 18789 */ 18790 get matrix() { 18791 return this.uniforms.m; 18792 } 18793 set matrix(value) { 18794 this.uniforms.m = value; 18795 } 18796 /** 18797 * The opacity value to use when mixing the original and resultant colors. 18798 * 18799 * When the value is 0, the original color is used without modification. 18800 * When the value is 1, the result color is used. 18801 * When in the range (0, 1) the color is interpolated between the original and result by this amount. 18802 * @default 1 18803 */ 18804 get alpha() { 18805 return this.uniforms.uAlpha; 18806 } 18807 set alpha(value) { 18808 this.uniforms.uAlpha = value; 18809 } 18810} 18811ColorMatrixFilter.prototype.grayscale = ColorMatrixFilter.prototype.greyscale; 18812 18813var fragment$4 = `varying vec2 vFilterCoord; 18814varying vec2 vTextureCoord; 18815 18816uniform vec2 scale; 18817uniform mat2 rotation; 18818uniform sampler2D uSampler; 18819uniform sampler2D mapSampler; 18820 18821uniform highp vec4 inputSize; 18822uniform vec4 inputClamp; 18823 18824void main(void) 18825{ 18826 vec4 map = texture2D(mapSampler, vFilterCoord); 18827 18828 map -= 0.5; 18829 map.xy = scale * inputSize.zw * (rotation * map.xy); 18830 18831 gl_FragColor = texture2D(uSampler, clamp(vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y), inputClamp.xy, inputClamp.zw)); 18832} 18833`; 18834 18835var vertex$3 = `attribute vec2 aVertexPosition; 18836 18837uniform mat3 projectionMatrix; 18838uniform mat3 filterMatrix; 18839 18840varying vec2 vTextureCoord; 18841varying vec2 vFilterCoord; 18842 18843uniform vec4 inputSize; 18844uniform vec4 outputFrame; 18845 18846vec4 filterVertexPosition( void ) 18847{ 18848 vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy; 18849
18850 return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0); 18851} 18852 18853vec2 filterTextureCoord( void ) 18854{ 18855 return aVertexPosition * (outputFrame.zw * inputSize.zw); 18856} 18857 18858void main(void) 18859{ 18860 gl_Position = filterVertexPosition(); 18861 vTextureCoord = filterTextureCoord(); 18862 vFilterCoord = ( filterMatrix * vec3( vTextureCoord, 1.0) ).xy; 18863} 18864`; 18865 18866class DisplacementFilter extends Filter { 18867 /** 18868 * @param {PIXI.Sprite} sprite - The sprite used for the displacement map. (make sure its added to the scene!) 18869 * @param scale - The scale of the displacement 18870 */ 18871 constructor(sprite, scale) { 18872 const maskMatrix = new Matrix(); 18873 sprite.renderable = !1, super(vertex$3, fragment$4, { 18874 mapSampler: sprite._texture, 18875 filterMatrix: maskMatrix, 18876 scale: { x: 1, y: 1 }, 18877 rotation: new Float32Array([1, 0, 0, 1]) 18878 }), this.maskSprite = sprite, this.maskMatrix = maskMatrix, scale == null && (scale = 20), this.scale = new Point(scale, scale); 18879 } 18880 /** 18881 * Applies the filter. 18882 * @param filterManager - The manager. 18883 * @param input - The input target. 18884 * @param output - The output target. 18885 * @param clearMode - clearMode. 18886 */ 18887 apply(filterManager, input, output, clearMode) { 18888 this.uniforms.filterMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, this.maskSprite), this.uniforms.scale.x = this.scale.x, this.uniforms.scale.y = this.scale.y; 18889 const wt = this.maskSprite.worldTransform, lenX = Math.sqrt(wt.a * wt.a + wt.b * wt.b), lenY = Math.sqrt(wt.c * wt.c + wt.d * wt.d); 18890 lenX !== 0 && lenY !== 0 && (this.uniforms.rotation[0] = wt.a / lenX, this.uniforms.rotation[1] = wt.b / lenX, this.uniforms.rotation[2] = wt.c / lenY, this.uniforms.rotation[3] = wt.d / lenY), filterManager.applyFilter(this, input, output, clearMode); 18891 } 18892 /** The texture used for the displacement map. Must be power of 2 sized texture. */ 18893 get map() { 18894 return this.uniforms.mapSampler; 18895 } 18896 set map(value) { 18897 this.uniforms.mapSampler = value; 18898 } 18899} 18900 18901var fragment$3 = `varying vec2 v_rgbNW; 18902varying vec2 v_rgbNE; 18903varying vec2 v_rgbSW; 18904varying vec2 v_rgbSE; 18905varying vec2 v_rgbM; 18906 18907varying vec2 vFragCoord; 18908uniform sampler2D uSampler; 18909uniform highp vec4 inputSize; 18910 18911 18912/** 18913 Basic FXAA implementation based on the code on geeks3d.com with the 18914 modification that the texture2DLod stuff was removed since it's 18915 unsupported by WebGL. 18916 18917 -- 18918 18919 From: 18920 https://github.com/mitsuhiko/webgl-meincraft 18921 18922 Copyright (c) 2011 by Armin Ronacher. 18923 18924 Some rights reserved. 18925 18926 Redistribution and use in source and binary forms, with or without 18927 modification, are permitted provided that the following conditions are 18928 met: 18929 18930 * Redistributions of source code must retain the above copyright 18931 notice, this list of conditions and the following disclaimer. 18932 18933 * Redistributions in binary form must reproduce the above 18934 copyright notice, this list of conditions and the following 18935 disclaimer in the documentation and/or other materials provided 18936 with the distribution. 18937 18938 * The names of the contributors may not be used to endorse or 18939 promote products derived from this software without specific 18940 prior written permission. 18941 18942 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18943 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18944 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18945 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18946 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18947 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 18948 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 18949 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 18950 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 18951 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 18952 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18953 */ 18954 18955#ifndef FXAA_REDUCE_MIN 18956#define FXAA_REDUCE_MIN (1.0/ 128.0) 18957#endif 18958#ifndef FXAA_REDUCE_MUL 18959#define FXAA_REDUCE_MUL (1.0 / 8.0) 18960#endif 18961#ifndef FXAA_SPAN_MAX 18962#define FXAA_SPAN_MAX 8.0 18963#endif 18964 18965//optimized version for mobile, where dependent 18966//texture reads can be a bottleneck 18967vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 inverseVP, 18968 vec2 v_rgbNW, vec2 v_rgbNE, 18969 vec2 v_rgbSW, vec2 v_rgbSE, 18970 vec2 v_rgbM) { 18971 vec4 color; 18972 vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; 18973 vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; 18974 vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; 18975 vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; 18976 vec4 texColor = texture2D(tex, v_rgbM); 18977 vec3 rgbM = texColor.xyz; 18978 vec3 luma = vec3(0.299, 0.587, 0.114); 18979 float lumaNW = dot(rgbNW, luma); 18980 float lumaNE = dot(rgbNE, luma); 18981 float lumaSW = dot(rgbSW, luma); 18982 float lumaSE = dot(rgbSE, luma); 18983 float lumaM = dot(rgbM, luma); 18984 float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); 18985 float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); 18986 18987 mediump vec2 dir; 18988 dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); 18989 dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); 18990
18991 float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * 18992 (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); 18993 18994 float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); 18995 dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), 18996 max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), 18997 dir * rcpDirMin)) * inverseVP; 18998 18999 vec3 rgbA = 0.5 * ( 19000 texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + 19001 texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); 19002 vec3 rgbB = rgbA * 0.5 + 0.25 * ( 19003 texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + 19004 texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); 19005 19006 float lumaB = dot(rgbB, luma); 19007 if ((lumaB < lumaMin) || (lumaB > lumaMax)) 19008 color = vec4(rgbA, texColor.a); 19009 else 19010 color = vec4(rgbB, texColor.a); 19011 return color; 19012} 19013 19014void main() { 19015 19016 vec4 color; 19017 19018 color = fxaa(uSampler, vFragCoord, inputSize.zw, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); 19019 19020 gl_FragColor = color; 19021} 19022`; 19023 19024var vertex$2 = ` 19025attribute vec2 aVertexPosition; 19026 19027uniform mat3 projectionMatrix; 19028 19029varying vec2 v_rgbNW; 19030varying vec2 v_rgbNE; 19031varying vec2 v_rgbSW; 19032varying vec2 v_rgbSE; 19033varying vec2 v_rgbM; 19034 19035varying vec2 vFragCoord; 19036 19037uniform vec4 inputSize; 19038uniform vec4 outputFrame; 19039 19040vec4 filterVertexPosition( void ) 19041{ 19042 vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy; 19043 19044 return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0); 19045} 19046 19047void texcoords(vec2 fragCoord, vec2 inverseVP, 19048 out vec2 v_rgbNW, out vec2 v_rgbNE, 19049 out vec2 v_rgbSW, out vec2 v_rgbSE, 19050 out vec2 v_rgbM) { 19051 v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; 19052 v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; 19053 v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; 19054 v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; 19055 v_rgbM = vec2(fragCoord * inverseVP); 19056} 19057 19058void main(void) { 19059 19060 gl_Position = filterVertexPosition(); 19061 19062 vFragCoord = aVertexPosition * outputFrame.zw; 19063 19064 texcoords(vFragCoord, inputSize.zw, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); 19065} 19066`; 19067 19068class FXAAFilter extends Filter { 19069 constructor() { 19070 super(vertex$2, fragment$3); 19071 } 19072} 19073 19074var fragment$2 = `precision highp float; 19075 19076varying vec2 vTextureCoord; 19077varying vec4 vColor; 19078 19079uniform float uNoise; 19080uniform float uSeed; 19081uniform sampler2D uSampler; 19082 19083float rand(vec2 co) 19084{ 19085 return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); 19086} 19087 19088void main() 19089{ 19090 vec4 color = texture2D(uSampler, vTextureCoord); 19091 float randomValue = rand(gl_FragCoord.xy * uSeed); 19092 float diff = (randomValue - 0.5) * uNoise; 19093 19094 // Un-premultiply alpha before applying the color matrix. See issue #3539. 19095 if (color.a > 0.0) { 19096 color.rgb /= color.a; 19097 } 19098 19099 color.r += diff; 19100 color.g += diff; 19101 color.b += diff; 19102 19103 // Premultiply alpha again. 19104 color.rgb *= color.a; 19105 19106 gl_FragColor = color; 19107} 19108`; 19109 19110class NoiseFilter extends Filter { 19111 /** 19112 * @param {number} [noise=0.5] - The noise intensity, should be a normalized value in the range [0, 1]. 19113 * @param {number} [seed] - A random seed for the noise generation. Default is `Math.random()`. 19114 */ 19115 constructor(noise = 0.5, seed = Math.random()) { 19116 super(defaultFilterVertex, fragment$2, { 19117 uNoise: 0, 19118 uSeed: 0 19119 }), this.noise = noise, this.seed = seed; 19120 } 19121 /** 19122 * The amount of noise to apply, this value should be in the range (0, 1]. 19123 * @default 0.5 19124 */ 19125 get noise() { 19126 return this.uniforms.uNoise; 19127 } 19128 set noise(value) { 19129 this.uniforms.uNoise = value; 19130 } 19131 /** A seed value to apply to the random noise generation. `Math.random()` is a good value to use. */ 19132 get seed() { 19133 return this.uniforms.uSeed; 19134 } 19135 set seed(value) { 19136 this.uniforms.uSeed = value; 19137 } 19138} 19139 19140const filters = { 19141 /** 19142 * @class 19143 * @memberof PIXI.filters 19144 * @deprecated since 7.1.0 19145 * @see PIXI.AlphaFilter 19146 */ 19147 AlphaFilter, 19148 /** 19149 * @class 19150 * @memberof PIXI.filters 19151 * @deprecated since 7.1.0 19152 * @see PIXI.BlurFilter 19153 */ 19154 BlurFilter, 19155 /** 19156 * @class 19157 * @memberof PIXI.filters 19158 * @deprecated since 7.1.0 19159 * @see PIXI.BlurFilterPass 19160 */ 19161 BlurFilterPass, 19162 /** 19163 * @class 19164 * @memberof PIXI.filters 19165 * @deprecated since 7.1.0
vendor: 7,473 bytes, lines 19166-19404
19166 * @see PIXI.ColorMatrixFilter 19167 */ 19168 ColorMatrixFilter, 19169 /** 19170 * @class 19171 * @memberof PIXI.filters 19172 * @deprecated since 7.1.0 19173 * @see PIXI.DisplacementFilter 19174 */ 19175 DisplacementFilter, 19176 /** 19177 * @class 19178 * @memberof PIXI.filters 19179 * @deprecated since 7.1.0 19180 * @see PIXI.FXAAFilter 19181 */ 19182 FXAAFilter, 19183 /** 19184 * @class 19185 * @memberof PIXI.filters 19186 * @deprecated since 7.1.0 19187 * @see PIXI.NoiseFilter 19188 */ 19189 NoiseFilter 19190}; 19191Object.entries(filters).forEach(([key, FilterClass]) => { 19192 Object.defineProperty(filters, key, { 19193 get() { 19194 return deprecation("7.1.0", `filters.${key} has moved to ${key}`), FilterClass; 19195 } 19196 }); 19197}); 19198 19199class EventsTickerClass { 19200 constructor() { 19201 this.interactionFrequency = 10, this._deltaTime = 0, this._didMove = !1, this.tickerAdded = !1, this._pauseUpdate = !0; 19202 } 19203 /** 19204 * Initializes the event ticker. 19205 * @param events - The event system. 19206 */ 19207 init(events) { 19208 this.removeTickerListener(), this.events = events, this.interactionFrequency = 10, this._deltaTime = 0, this._didMove = !1, this.tickerAdded = !1, this._pauseUpdate = !0; 19209 } 19210 /** Whether to pause the update checks or not. */ 19211 get pauseUpdate() { 19212 return this._pauseUpdate; 19213 } 19214 set pauseUpdate(paused) { 19215 this._pauseUpdate = paused; 19216 } 19217 /** Adds the ticker listener. */ 19218 addTickerListener() { 19219 this.tickerAdded || !this.domElement || (Ticker.system.add(this.tickerUpdate, this, UPDATE_PRIORITY.INTERACTION), this.tickerAdded = !0); 19220 } 19221 /** Removes the ticker listener. */ 19222 removeTickerListener() { 19223 this.tickerAdded && (Ticker.system.remove(this.tickerUpdate, this), this.tickerAdded = !1); 19224 } 19225 /** Sets flag to not fire extra events when the user has already moved there mouse */ 19226 pointerMoved() { 19227 this._didMove = !0; 19228 } 19229 /** Updates the state of interactive objects. */ 19230 update() { 19231 if (!this.domElement || this._pauseUpdate) 19232 return; 19233 if (this._didMove) { 19234 this._didMove = !1; 19235 return; 19236 } 19237 const rootPointerEvent = this.events.rootPointerEvent; 19238 this.events.supportsTouchEvents && rootPointerEvent.pointerType === "touch" || globalThis.document.dispatchEvent(new PointerEvent("pointermove", { 19239 clientX: rootPointerEvent.clientX, 19240 clientY: rootPointerEvent.clientY 19241 })); 19242 } 19243 /** 19244 * Updates the state of interactive objects if at least {@link interactionFrequency} 19245 * milliseconds have passed since the last invocation. 19246 * 19247 * Invoked by a throttled ticker update from {@link PIXI.Ticker.system}. 19248 * @param deltaTime - time delta since the last call 19249 */ 19250 tickerUpdate(deltaTime) { 19251 this._deltaTime += deltaTime, !(this._deltaTime < this.interactionFrequency) && (this._deltaTime = 0, this.update()); 19252 } 19253} 19254const EventsTicker = new EventsTickerClass(); 19255 19256class FederatedEvent { 19257 /** 19258 * @param manager - The event boundary which manages this event. Propagation can only occur 19259 * within the boundary's jurisdiction. 19260 */ 19261 constructor(manager) { 19262 this.bubbles = !0, this.cancelBubble = !0, this.cancelable = !1, this.composed = !1, this.defaultPrevented = !1, this.eventPhase = FederatedEvent.prototype.NONE, this.propagationStopped = !1, this.propagationImmediatelyStopped = !1, this.layer = new Point(), this.page = new Point(), this.NONE = 0, this.CAPTURING_PHASE = 1, this.AT_TARGET = 2, this.BUBBLING_PHASE = 3, this.manager = manager; 19263 } 19264 /** @readonly */ 19265 get layerX() { 19266 return this.layer.x; 19267 } 19268 /** @readonly */ 19269 get layerY() { 19270 return this.layer.y; 19271 } 19272 /** @readonly */ 19273 get pageX() { 19274 return this.page.x; 19275 } 19276 /** @readonly */ 19277 get pageY() { 19278 return this.page.y; 19279 } 19280 /** 19281 * Fallback for the deprecated @code{PIXI.InteractionEvent.data}. 19282 * @deprecated since 7.0.0 19283 */ 19284 get data() { 19285 return this; 19286 } 19287 /** The propagation path for this event. Alias for {@link PIXI.EventBoundary.propagationPath}. */ 19288 composedPath() { 19289 return this.manager && (!this.path || this.path[this.path.length - 1] !== this.target) && (this.path = this.target ? this.manager.propagationPath(this.target) : []), this.path; 19290 } 19291 /** 19292 * Unimplemented method included for implementing the DOM interface {@code Event}. It will throw an {@code Error}. 19293 * @deprecated 19294 * @param _type 19295 * @param _bubbles 19296 * @param _cancelable 19297 */ 19298 initEvent(_type, _bubbles, _cancelable) { 19299 throw new Error("initEvent() is a legacy DOM API. It is not implemented in the Federated Events API."); 19300 } 19301 /** 19302 * Unimplemented method included for implementing the DOM interface {@code UIEvent}. It will throw an {@code Error}. 19303 * @deprecated 19304 * @param _typeArg 19305 * @param _bubblesArg 19306 * @param _cancelableArg 19307 * @param _viewArg 19308 * @param _detailArg 19309 */ 19310 initUIEvent(_typeArg, _bubblesArg, _cancelableArg, _viewArg, _detailArg) { 19311 throw new Error("initUIEvent() is a legacy DOM API. It is not implemented in the Federated Events API."); 19312 } 19313 /** Prevent default behavior of PixiJS and the user agent. */ 19314 preventDefault() { 19315 this.nativeEvent instanceof Event && this.nativeEvent.cancelable && this.nativeEvent.preventDefault(), this.defaultPrevented = !0; 19316 } 19317 /** 19318 * Stop this event from propagating to any addition listeners, including on the 19319 * {@link PIXI.FederatedEventTarget.currentTarget currentTarget} and also the following 19320 * event targets on the propagation path. 19321 */ 19322 stopImmediatePropagation() { 19323 this.propagationImmediatelyStopped = !0; 19324 } 19325 /** 19326 * Stop this event from propagating to the next {@link PIXI.FederatedEventTarget}. The rest of the listeners 19327 * on the {@link PIXI.FederatedEventTarget.currentTarget currentTarget} will still be notified. 19328 */ 19329 stopPropagation() { 19330 this.propagationStopped = !0; 19331 } 19332} 19333 19334class FederatedMouseEvent extends FederatedEvent { 19335 constructor() { 19336 super(...arguments), this.client = new Point(), this.movement = new Point(), this.offset = new Point(), this.global = new Point(), this.screen = new Point(); 19337 } 19338 /** @readonly */ 19339 get clientX() { 19340 return this.client.x; 19341 } 19342 /** @readonly */ 19343 get clientY() { 19344 return this.client.y; 19345 } 19346 /** 19347 * Alias for {@link PIXI.FederatedMouseEvent.clientX this.clientX}. 19348 * @readonly 19349 */ 19350 get x() { 19351 return this.clientX; 19352 } 19353 /** 19354 * Alias for {@link PIXI.FederatedMouseEvent.clientY this.clientY}. 19355 * @readonly 19356 */ 19357 get y() { 19358 return this.clientY; 19359 } 19360 /** @readonly */ 19361 get movementX() { 19362 return this.movement.x; 19363 } 19364 /** @readonly */ 19365 get movementY() { 19366 return this.movement.y; 19367 } 19368 /** @readonly */ 19369 get offsetX() { 19370 return this.offset.x; 19371 } 19372 /** @readonly */ 19373 get offsetY() { 19374 return this.offset.y; 19375 } 19376 /** @readonly */ 19377 get globalX() { 19378 return this.global.x; 19379 } 19380 /** @readonly */ 19381 get globalY() { 19382 return this.global.y; 19383 } 19384 /** 19385 * The pointer coordinates in the renderer's screen. Alias for {@code screen.x}. 19386 * @readonly 19387 */ 19388 get screenX() { 19389 return this.screen.x; 19390 } 19391 /** 19392 * The pointer coordinates in the renderer's screen. Alias for {@code screen.y}. 19393 * @readonly 19394 */ 19395 get screenY() { 19396 return this.screen.y; 19397 } 19398 /** 19399 * This will return the local coordinates of the specified displayObject for this InteractionData 19400 * @param {PIXI.DisplayObject} displayObject - The DisplayObject that you would like the local 19401 * coords off 19402 * @param {PIXI.IPointData} point - A Point object in which to store the value, optional (otherwise 19403 * will create a new point) 19404 * @param {PIXI.IPointData}
19404 globalPos - A Point object containing your custom global coords, optional 19405 * (otherwise will use the current global coords) 19406 * @returns - A point containing the coordinates of the InteractionData position relative 19407 * to the DisplayObject 19408 */ 19409 getLocalPosition(displayObject, point, globalPos) { 19410 return displayObject.worldTransform.applyInverse(globalPos || this.global, point); 19411 } 19412 /** 19413 * Whether the modifier key was pressed when this event natively occurred. 19414 * @param key - The modifier key. 19415 */ 19416 getModifierState(key) { 19417 return "getModifierState" in this.nativeEvent && this.nativeEvent.getModifierState(key); 19418 } 19419 /** 19420 * Not supported. 19421 * @param _typeArg 19422 * @param _canBubbleArg 19423 * @param _cancelableArg 19424 * @param _viewArg 19425 * @param _detailArg 19426 * @param _screenXArg 19427 * @param _screenYArg 19428 * @param _clientXArg 19429 * @param _clientYArg 19430 * @param _ctrlKeyArg 19431 * @param _altKeyArg 19432 * @param _shiftKeyArg 19433 * @param _metaKeyArg 19434 * @param _buttonArg 19435 * @param _relatedTargetArg 19436 * @deprecated since 7.0.0 19437 */ 19438 // eslint-disable-next-line max-params 19439 initMouseEvent(_typeArg, _canBubbleArg, _cancelableArg, _viewArg, _detailArg, _screenXArg, _screenYArg, _clientXArg, _clientYArg, _ctrlKeyArg, _altKeyArg, _shiftKeyArg, _metaKeyArg, _buttonArg, _relatedTargetArg) { 19440 throw new Error("Method not implemented."); 19441 } 19442} 19443 19444class FederatedPointerEvent extends FederatedMouseEvent { 19445 constructor() { 19446 super(...arguments), this.width = 0, this.height = 0, this.isPrimary = !1; 19447 }
vendor: 25,386 bytes, lines 19448-19905
19448 // Only included for completeness for now 19449 getCoalescedEvents() { 19450 return this.type === "pointermove" || this.type === "mousemove" || this.type === "touchmove" ? [this] : []; 19451 } 19452 // Only included for completeness for now 19453 getPredictedEvents() { 19454 throw new Error("getPredictedEvents is not supported!"); 19455 } 19456} 19457 19458class FederatedWheelEvent extends FederatedMouseEvent { 19459 constructor() { 19460 super(...arguments), this.DOM_DELTA_PIXEL = 0, this.DOM_DELTA_LINE = 1, this.DOM_DELTA_PAGE = 2; 19461 } 19462} 19463FederatedWheelEvent.DOM_DELTA_PIXEL = 0, /** Units specified in lines. */ 19464FederatedWheelEvent.DOM_DELTA_LINE = 1, /** Units specified in pages. */ 19465FederatedWheelEvent.DOM_DELTA_PAGE = 2; 19466 19467const PROPAGATION_LIMIT = 2048, tempHitLocation = new Point(), tempLocalMapping = new Point(); 19468class EventBoundary { 19469 /** 19470 * @param rootTarget - The holder of the event boundary. 19471 */ 19472 constructor(rootTarget) { 19473 this.dispatch = new EventEmitter(), this.moveOnAll = !1, this.enableGlobalMoveEvents = !0, this.mappingState = { 19474 trackingData: {} 19475 }, this.eventPool = /* @__PURE__ */ new Map(), this._allInteractiveElements = [], this._hitElements = [], this._isPointerMoveEvent = !1, this.rootTarget = rootTarget, this.hitPruneFn = this.hitPruneFn.bind(this), this.hitTestFn = this.hitTestFn.bind(this), this.mapPointerDown = this.mapPointerDown.bind(this), this.mapPointerMove = this.mapPointerMove.bind(this), this.mapPointerOut = this.mapPointerOut.bind(this), this.mapPointerOver = this.mapPointerOver.bind(this), this.mapPointerUp = this.mapPointerUp.bind(this), this.mapPointerUpOutside = this.mapPointerUpOutside.bind(this), this.mapWheel = this.mapWheel.bind(this), this.mappingTable = {}, this.addEventMapping("pointerdown", this.mapPointerDown), this.addEventMapping("pointermove", this.mapPointerMove), this.addEventMapping("pointerout", this.mapPointerOut), this.addEventMapping("pointerleave", this.mapPointerOut), this.addEventMapping("pointerover", this.mapPointerOver), this.addEventMapping("pointerup", this.mapPointerUp), this.addEventMapping("pointerupoutside", this.mapPointerUpOutside), this.addEventMapping("wheel", this.mapWheel); 19476 } 19477 /** 19478 * Adds an event mapping for the event `type` handled by `fn`. 19479 * 19480 * Event mappings can be used to implement additional or custom events. They take an event 19481 * coming from the upstream scene (or directly from the {@link PIXI.EventSystem}) and dispatch new downstream events 19482 * generally trickling down and bubbling up to {@link PIXI.EventBoundary.rootTarget this.rootTarget}. 19483 * 19484 * To modify the semantics of existing events, the built-in mapping methods of EventBoundary should be overridden 19485 * instead. 19486 * @param type - The type of upstream event to map. 19487 * @param fn - The mapping method. The context of this function must be bound manually, if desired. 19488 */ 19489 addEventMapping(type, fn) { 19490 this.mappingTable[type] || (this.mappingTable[type] = []), this.mappingTable[type].push({ 19491 fn, 19492 priority: 0 19493 }), this.mappingTable[type].sort((a, b) => a.priority - b.priority); 19494 } 19495 /** 19496 * Dispatches the given event 19497 * @param e 19498 * @param type 19499 */ 19500 dispatchEvent(e, type) { 19501 e.propagationStopped = !1, e.propagationImmediatelyStopped = !1, this.propagate(e, type), this.dispatch.emit(type || e.type, e); 19502 } 19503 /** 19504 * Maps the given upstream event through the event boundary and propagates it downstream. 19505 * @param e 19506 */ 19507 mapEvent(e) { 19508 if (!this.rootTarget) 19509 return; 19510 const mappers = this.mappingTable[e.type]; 19511 if (mappers) 19512 for (let i = 0, j = mappers.length; i < j; i++) 19513 mappers[i].fn(e); 19514 else 19515 console.warn(`[EventBoundary]: Event mapping not defined for ${e.type}`); 19516 } 19517 /** 19518 * Finds the DisplayObject that is the target of a event at the given coordinates. 19519 * 19520 * The passed (x,y) coordinates are in the world space above this event boundary. 19521 * @param x 19522 * @param y 19523 */ 19524 hitTest(x, y) { 19525 EventsTicker.pauseUpdate = !0; 19526 const fn = this._isPointerMoveEvent && this.enableGlobalMoveEvents ? "hitTestMoveRecursive" : "hitTestRecursive", invertedPath = this[fn]( 19527 this.rootTarget, 19528 this.rootTarget.eventMode, 19529 tempHitLocation.set(x, y), 19530 this.hitTestFn, 19531 this.hitPruneFn 19532 ); 19533 return invertedPath && invertedPath[0]; 19534 } 19535 /** 19536 * Propagate the passed event from from {@link PIXI.EventBoundary.rootTarget this.rootTarget} to its 19537 * target {@code e.target}. 19538 * @param e - The event to propagate. 19539 * @param type 19540 */ 19541 propagate(e, type) { 19542 if (!e.target) 19543 return; 19544 const composedPath = e.composedPath(); 19545 e.eventPhase = e.CAPTURING_PHASE; 19546 for (let i = 0, j = composedPath.length - 1; i < j; i++) 19547 if (e.currentTarget = composedPath[i], this.notifyTarget(e, type), e.propagationStopped || e.propagationImmediatelyStopped) 19548 return; 19549 if (e.eventPhase = e.AT_TARGET, e.currentTarget = e.target, this.notifyTarget(e, type), !(e.propagationStopped || e.propagationImmediatelyStopped)) { 19550 e.eventPhase = e.BUBBLING_PHASE; 19551 for (let i = composedPath.length - 2; i >= 0; i--) 19552 if (e.currentTarget = composedPath[i], this.notifyTarget(e, type), e.propagationStopped || e.propagationImmediatelyStopped) 19553 return; 19554 } 19555 } 19556 /** 19557 * Emits the event {@code e} to all interactive display objects. The event is propagated in the bubbling phase always. 19558 * 19559 * This is used in the `globalpointermove` event. 19560 * @param e - The emitted event. 19561 * @param type - The listeners to notify. 19562 * @param targets - The targets to notify. 19563 */ 19564 all(e, type, targets = this._allInteractiveElements) { 19565 if (targets.length === 0) 19566 return; 19567 e.eventPhase = e.BUBBLING_PHASE; 19568 const events = Array.isArray(type) ? type : [type]; 19569 for (let i = targets.length - 1; i >= 0; i--) 19570 events.forEach((event) => { 19571 e.currentTarget = targets[i], this.notifyTarget(e, event); 19572 }); 19573 } 19574 /** 19575 * Finds the propagation path from {@link PIXI.EventBoundary.rootTarget rootTarget} to the passed 19576 * {@code target}. The last element in the path is {@code target}. 19577 * @param target 19578 */ 19579 propagationPath(target) { 19580 const propagationPath = [target]; 19581 for (let i = 0; i < PROPAGATION_LIMIT && target !== this.rootTarget; i++) { 19582 if (!target.parent) 19583 throw new Error("Cannot find propagation path to disconnected target"); 19584 propagationPath.push(target.parent), target = target.parent; 19585 } 19586 return propagationPath.reverse(), propagationPath; 19587 } 19588 hitTestMoveRecursive(currentTarget, eventMode, location, testFn, pruneFn, ignore = !1) { 19589 let shouldReturn = !1; 19590 if (this._interactivePrune(currentTarget)) 19591 return null; 19592 if ((currentTarget.eventMode === "dynamic" || eventMode === "dynamic") && (EventsTicker.pauseUpdate = !1), currentTarget.interactiveChildren && currentTarget.children) { 19593 const children = currentTarget.children; 19594 for (let i = children.length - 1; i >= 0; i--) { 19595 const child = children[i], nestedHit = this.hitTestMoveRecursive( 19596 child, 19597 this._isInteractive(eventMode) ? eventMode : child.eventMode, 19598 location, 19599 testFn, 19600 pruneFn, 19601 ignore || pruneFn(currentTarget, location) 19602 ); 19603 if (nestedHit) { 19604 if (nestedHit.length > 0 && !nestedHit[nestedHit.length - 1].parent) 19605 continue; 19606 const isInteractive = currentTarget.isInteractive(); 19607 (nestedHit.length > 0 || isInteractive) && (isInteractive && this._allInteractiveElements.push(currentTarget), nestedHit.push(currentTarget)), this._hitElements.length === 0 && (this._hitElements = nestedHit), shouldReturn = !0; 19608 } 19609 } 19610 } 19611 const isInteractiveMode = this._isInteractive(eventMode), isInteractiveTarget = currentTarget.isInteractive(); 19612 return isInteractiveMode && isInteractiveTarget && this._allInteractiveElements.push(currentTarget), ignore || this._hitElements.length > 0 ? null : shouldReturn ? this._hitElements : isInteractiveMode && !pruneFn(currentTarget, location) && testFn(currentTarget, location) ? isInteractiveTarget ? [currentTarget] : [] : null; 19613 } 19614 /** 19615 * Recursive implementation for {@link PIXI.EventBoundary.hitTest hitTest}. 19616 * @param currentTarget - The DisplayObject that is to be hit tested. 19617 * @param eventMode - The event mode for the `currentTarget` or one of its parents. 19618 * @param location - The location that is being tested for overlap. 19619 * @param testFn - Callback that determines whether the target passes hit testing. This callback 19620 * can assume that `pruneFn` failed to prune the display object. 19621 * @param pruneFn - Callback that determiness whether the target and all of its children 19622 * cannot pass the hit test. It is used as a preliminary optimization to prune entire subtrees 19623 * of the scene graph. 19624 * @returns An array holding the hit testing target and all its ancestors in order. The first element 19625 * is the target itself and the last is {@link PIXI.EventBoundary.rootTarget rootTarget}. This is the opposite 19626 * order w.r.t. the propagation path. If no hit testing target is found, null is returned. 19627 */ 19628 hitTestRecursive(currentTarget, eventMode, location, testFn, pruneFn) { 19629 if (this._interactivePrune(currentTarget) || pruneFn(currentTarget, location)) 19630 return null; 19631 if ((currentTarget.eventMode === "dynamic" || eventMode === "dynamic") && (EventsTicker.pauseUpdate = !1), currentTarget.interactiveChildren && currentTarget.children) { 19632 const children = currentTarget.children; 19633 for (let i = children.length - 1; i >= 0; i--) { 19634 const child = children[i], nestedHit = this.hitTestRecursive( 19635 child, 19636 this._isInteractive(eventMode) ? eventMode : child.eventMode, 19637 location, 19638 testFn, 19639 pruneFn 19640 ); 19641 if (nestedHit) { 19642 if (nestedHit.length > 0 && !nestedHit[nestedHit.length - 1].parent) 19643 continue; 19644 const isInteractive = currentTarget.isInteractive(); 19645 return (nestedHit.length > 0 || isInteractive) && nestedHit.push(currentTarget), nestedHit; 19646 } 19647 } 19648 } 19649 const isInteractiveMode = this._isInteractive(eventMode), isInteractiveTarget = currentTarget.isInteractive(); 19650 return isInteractiveMode && testFn(currentTarget, location) ? isInteractiveTarget ? [currentTarget] : [] : null; 19651 } 19652 _isInteractive(int) { 19653 return int === "static" || int === "dynamic"; 19654 } 19655 _interactivePrune(displayObject) { 19656 return !!(!displayObject || displayObject.isMask || !displayObject.visible || !displayObject.renderable || displayObject.eventMode === "none" || displayObject.eventMode === "passive" && !displayObject.interactiveChildren || displayObject.isMask); 19657 } 19658 /** 19659 * Checks whether the display object or any of its children cannot pass the hit test at all. 19660 * 19661 * {@link PIXI.EventBoundary}'s implementation uses the {@link PIXI.DisplayObject.hitArea hitArea} 19662 * and {@link PIXI.DisplayObject._mask} for pruning. 19663 * @param displayObject 19664 * @param location 19665 */ 19666 hitPruneFn(displayObject, location) { 19667 if (displayObject.hitArea && (displayObject.worldTransform.applyInverse(location, tempLocalMapping), !displayObject.hitArea.contains(tempLocalMapping.x, tempLocalMapping.y))) 19668 return !0; 19669 if (displayObject._mask) { 19670 const maskObject = displayObject._mask.isMaskData ? displayObject._mask.maskObject : displayObject._mask; 19671 if (maskObject && !maskObject.containsPoint?.(location)) 19672 return !0; 19673 } 19674 return !1; 19675 } 19676 /** 19677 * Checks whether the display object passes hit testing for the given location. 19678 * @param displayObject 19679 * @param location 19680 * @returns - Whether `displayObject` passes hit testing for `location`. 19681 */ 19682 hitTestFn(displayObject, location) { 19683 return displayObject.eventMode === "passive" ? !1 : displayObject.hitArea ? !0 : displayObject.containsPoint ? displayObject.containsPoint(location) : !1; 19684 } 19685 /** 19686 * Notify all the listeners to the event's `currentTarget`. 19687 * 19688 * If the `currentTarget` contains the property `on<type>`, then it is called here, 19689 * simulating the behavior from version 6.x and prior. 19690 * @param e - The event passed to the target. 19691 * @param type 19692 */ 19693 notifyTarget(e, type) { 19694 type = type ?? e.type; 19695 const handlerKey = `on${type}`; 19696 e.currentTarget[handlerKey]?.(e); 19697 const key = e.eventPhase === e.CAPTURING_PHASE || e.eventPhase === e.AT_TARGET ? `${type}capture` : type; 19698 this.notifyListeners(e, key), e.eventPhase === e.AT_TARGET && this.notifyListeners(e, type); 19699 } 19700 /** 19701 * Maps the upstream `pointerdown` events to a downstream `pointerdown` event. 19702 * 19703 * `touchstart`, `rightdown`, `mousedown` events are also dispatched for specific pointer types. 19704 * @param from 19705 */ 19706 mapPointerDown(from) { 19707 if (!(from instanceof FederatedPointerEvent)) { 19708 console.warn("EventBoundary cannot map a non-pointer event as a pointer event"); 19709 return; 19710 } 19711 const e = this.createPointerEvent(from); 19712 if (this.dispatchEvent(e, "pointerdown"), e.pointerType === "touch") 19713 this.dispatchEvent(e, "touchstart"); 19714 else if (e.pointerType === "mouse" || e.pointerType === "pen") { 19715 const isRightButton = e.button === 2; 19716 this.dispatchEvent(e, isRightButton ? "rightdown" : "mousedown"); 19717 } 19718 const trackingData = this.trackingData(from.pointerId); 19719 trackingData.pressTargetsByButton[from.button] = e.composedPath(), this.freeEvent(e); 19720 } 19721 /** 19722 * Maps the upstream `pointermove` to downstream `pointerout`, `pointerover`, and `pointermove` events, in that order. 19723 * 19724 * The tracking data for the specific pointer has an updated `overTarget`. `mouseout`, `mouseover`, 19725 * `mousemove`, and `touchmove` events are fired as well for specific pointer types. 19726 * @param from - The upstream `pointermove` event. 19727 */ 19728 mapPointerMove(from) { 19729 if (!(from instanceof FederatedPointerEvent)) { 19730 console.warn("EventBoundary cannot map a non-pointer event as a pointer event"); 19731 return; 19732 } 19733 this._allInteractiveElements.length = 0, this._hitElements.length = 0, this._isPointerMoveEvent = !0; 19734 const e = this.createPointerEvent(from); 19735 this._isPointerMoveEvent = !1; 19736 const isMouse = e.pointerType === "mouse" || e.pointerType === "pen", trackingData = this.trackingData(from.pointerId), outTarget = this.findMountedTarget(trackingData.overTargets); 19737 if (trackingData.overTargets?.length > 0 && outTarget !== e.target) { 19738 const outType = from.type === "mousemove" ? "mouseout" : "pointerout", outEvent = this.createPointerEvent(from, outType, outTarget); 19739 if (this.dispatchEvent(outEvent, "pointerout"), isMouse && this.dispatchEvent(outEvent, "mouseout"), !e.composedPath().includes(outTarget)) { 19740 const leaveEvent = this.createPointerEvent(from, "pointerleave", outTarget); 19741 for (leaveEvent.eventPhase = leaveEvent.AT_TARGET; leaveEvent.target && !e.composedPath().includes(leaveEvent.target); ) 19742 leaveEvent.currentTarget = leaveEvent.target, this.notifyTarget(leaveEvent), isMouse && this.notifyTarget(leaveEvent, "mouseleave"), leaveEvent.target = leaveEvent.target.parent; 19743 this.freeEvent(leaveEvent); 19744 } 19745 this.freeEvent(outEvent); 19746 } 19747 if (outTarget !== e.target) { 19748 const overType = from.type === "mousemove" ? "mouseover" : "pointerover", overEvent = this.clonePointerEvent(e, overType); 19749 this.dispatchEvent(overEvent, "pointerover"), isMouse && this.dispatchEvent(overEvent, "mouseover"); 19750 let overTargetAncestor = outTarget?.parent; 19751 for (; overTargetAncestor && overTargetAncestor !== this.rootTarget.parent && overTargetAncestor !== e.target; ) 19752 overTargetAncestor = overTargetAncestor.parent; 19753 if (!overTargetAncestor || overTargetAncestor === this.rootTarget.parent) { 19754 const enterEvent = this.clonePointerEvent(e, "pointerenter"); 19755 for (enterEvent.eventPhase = enterEvent.AT_TARGET; enterEvent.target && enterEvent.target !== outTarget && enterEvent.target !== this.rootTarget.parent; ) 19756 enterEvent.currentTarget = enterEvent.target, this.notifyTarget(enterEvent), isMouse && this.notifyTarget(enterEvent, "mouseenter"), enterEvent.target = enterEvent.target.parent; 19757 this.freeEvent(enterEvent); 19758 } 19759 this.freeEvent(overEvent); 19760 } 19761 const allMethods = [], allowGlobalPointerEvents = this.enableGlobalMoveEvents ?? !0; 19762 this.moveOnAll ? allMethods.push("pointermove") : this.dispatchEvent(e, "pointermove"), allowGlobalPointerEvents && allMethods.push("globalpointermove"), e.pointerType === "touch" && (this.moveOnAll ? allMethods.splice(1, 0, "touchmove") : this.dispatchEvent(e, "touchmove"), allowGlobalPointerEvents && allMethods.push("globaltouchmove")), isMouse && (this.moveOnAll ? allMethods.splice(1, 0, "mousemove") : this.dispatchEvent(e, "mousemove"), allowGlobalPointerEvents && allMethods.push("globalmousemove"), this.cursor = e.target?.cursor), allMethods.length > 0 && this.all(e, allMethods), this._allInteractiveElements.length = 0, this._hitElements.length = 0, trackingData.overTargets = e.composedPath(), this.freeEvent(e); 19763 } 19764 /** 19765 * Maps the upstream `pointerover` to downstream `pointerover` and `pointerenter` events, in that order. 19766 * 19767 * The tracking data for the specific pointer gets a new `overTarget`. 19768 * @param from - The upstream `pointerover` event. 19769 */ 19770 mapPointerOver(from) { 19771 if (!(from instanceof FederatedPointerEvent)) { 19772 console.warn("EventBoundary cannot map a non-pointer event as a pointer event"); 19773 return; 19774 } 19775 const trackingData = this.trackingData(from.pointerId), e = this.createPointerEvent(from), isMouse = e.pointerType === "mouse" || e.pointerType === "pen"; 19776 this.dispatchEvent(e, "pointerover"), isMouse && this.dispatchEvent(e, "mouseover"), e.pointerType === "mouse" && (this.cursor = e.target?.cursor); 19777 const enterEvent = this.clonePointerEvent(e, "pointerenter"); 19778 for (enterEvent.eventPhase = enterEvent.AT_TARGET; enterEvent.target && enterEvent.target !== this.rootTarget.parent; ) 19779 enterEvent.currentTarget = enterEvent.target, this.notifyTarget(enterEvent), isMouse && this.notifyTarget(enterEvent, "mouseenter"), enterEvent.target = enterEvent.target.parent; 19780 trackingData.overTargets = e.composedPath(), this.freeEvent(e), this.freeEvent(enterEvent); 19781 } 19782 /** 19783 * Maps the upstream `pointerout` to downstream `pointerout`, `pointerleave` events, in that order. 19784 * 19785 * The tracking data for the specific pointer is cleared of a `overTarget`. 19786 * @param from - The upstream `pointerout` event. 19787 */ 19788 mapPointerOut(from) { 19789 if (!(from instanceof FederatedPointerEvent)) { 19790 console.warn("EventBoundary cannot map a non-pointer event as a pointer event"); 19791 return; 19792 } 19793 const trackingData = this.trackingData(from.pointerId); 19794 if (trackingData.overTargets) { 19795 const isMouse = from.pointerType === "mouse" || from.pointerType === "pen", outTarget = this.findMountedTarget(trackingData.overTargets), outEvent = this.createPointerEvent(from, "pointerout", outTarget); 19796 this.dispatchEvent(outEvent), isMouse && this.dispatchEvent(outEvent, "mouseout"); 19797 const leaveEvent = this.createPointerEvent(from, "pointerleave", outTarget); 19798 for (leaveEvent.eventPhase = leaveEvent.AT_TARGET; leaveEvent.target && leaveEvent.target !== this.rootTarget.parent; ) 19799 leaveEvent.currentTarget = leaveEvent.target, this.notifyTarget(leaveEvent), isMouse && this.notifyTarget(leaveEvent, "mouseleave"), leaveEvent.target = leaveEvent.target.parent; 19800 trackingData.overTargets = null, this.freeEvent(outEvent), this.freeEvent(leaveEvent); 19801 } 19802 this.cursor = null; 19803 } 19804 /** 19805 * Maps the upstream `pointerup` event to downstream `pointerup`, `pointerupoutside`, 19806 * and `click`/`rightclick`/`pointertap` events, in that order. 19807 * 19808 * The `pointerupoutside` event bubbles from the original `pointerdown` target to the most specific 19809 * ancestor of the `pointerdown` and `pointerup` targets, which is also the `click` event's target. `touchend`, 19810 * `rightup`, `mouseup`, `touchendoutside`, `rightupoutside`, `mouseupoutside`, and `tap` are fired as well for 19811 * specific pointer types. 19812 * @param from - The upstream `pointerup` event. 19813 */ 19814 mapPointerUp(from) { 19815 if (!(from instanceof FederatedPointerEvent)) { 19816 console.warn("EventBoundary cannot map a non-pointer event as a pointer event"); 19817 return; 19818 } 19819 const now = performance.now(), e = this.createPointerEvent(from); 19820 if (this.dispatchEvent(e, "pointerup"), e.pointerType === "touch") 19821 this.dispatchEvent(e, "touchend"); 19822 else if (e.pointerType === "mouse" || e.pointerType === "pen") { 19823 const isRightButton = e.button === 2; 19824 this.dispatchEvent(e, isRightButton ? "rightup" : "mouseup"); 19825 } 19826 const trackingData = this.trackingData(from.pointerId), pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]); 19827 let clickTarget = pressTarget; 19828 if (pressTarget && !e.composedPath().includes(pressTarget)) { 19829 let currentTarget = pressTarget; 19830 for (; currentTarget && !e.composedPath().includes(currentTarget); ) { 19831 if (e.currentTarget = currentTarget, this.notifyTarget(e, "pointerupoutside"), e.pointerType === "touch") 19832 this.notifyTarget(e, "touchendoutside"); 19833 else if (e.pointerType === "mouse" || e.pointerType === "pen") { 19834 const isRightButton = e.button === 2; 19835 this.notifyTarget(e, isRightButton ? "rightupoutside" : "mouseupoutside"); 19836 } 19837 currentTarget = currentTarget.parent; 19838 } 19839 delete trackingData.pressTargetsByButton[from.button], clickTarget = currentTarget; 19840 } 19841 if (clickTarget) { 19842 const clickEvent = this.clonePointerEvent(e, "click"); 19843 clickEvent.target = clickTarget, clickEvent.path = null, trackingData.clicksByButton[from.button] || (trackingData.clicksByButton[from.button] = { 19844 clickCount: 0, 19845 target: clickEvent.target, 19846 timeStamp: now 19847 }); 19848 const clickHistory = trackingData.clicksByButton[from.button]; 19849 if (clickHistory.target === clickEvent.target && now - clickHistory.timeStamp < 200 ? ++clickHistory.clickCount : clickHistory.clickCount = 1, clickHistory.target = clickEvent.target, clickHistory.timeStamp = now, clickEvent.detail = clickHistory.clickCount, clickEvent.pointerType === "mouse") { 19850 const isRightButton = clickEvent.button === 2; 19851 this.dispatchEvent(clickEvent, isRightButton ? "rightclick" : "click"); 19852 } else 19853 clickEvent.pointerType === "touch" && this.dispatchEvent(clickEvent, "tap"); 19854 this.dispatchEvent(clickEvent, "pointertap"), this.freeEvent(clickEvent); 19855 } 19856 this.freeEvent(e); 19857 } 19858 /** 19859 * Maps the upstream `pointerupoutside` event to a downstream `pointerupoutside` event, bubbling from the original 19860 * `pointerdown` target to `rootTarget`. 19861 * 19862 * (The most specific ancestor of the `pointerdown` event and the `pointerup` event must the 19863 * `{@link PIXI.EventBoundary}'s root because the `pointerup` event occurred outside of the boundary.) 19864 * 19865 * `touchendoutside`, `mouseupoutside`, and `rightupoutside` events are fired as well for specific pointer 19866 * types. The tracking data for the specific pointer is cleared of a `pressTarget`. 19867 * @param from - The upstream `pointerupoutside` event. 19868 */ 19869 mapPointerUpOutside(from) { 19870 if (!(from instanceof FederatedPointerEvent)) { 19871 console.warn("EventBoundary cannot map a non-pointer event as a pointer event"); 19872 return; 19873 } 19874 const trackingData = this.trackingData(from.pointerId), pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]), e = this.createPointerEvent(from); 19875 if (pressTarget) { 19876 let currentTarget = pressTarget; 19877 for (; currentTarget; ) 19878 e.currentTarget = currentTarget, this.notifyTarget(e, "pointerupoutside"), e.pointerType === "touch" ? this.notifyTarget(e, "touchendoutside") : (e.pointerType === "mouse" || e.pointerType === "pen") && this.notifyTarget(e, e.button === 2 ? "rightupoutside" : "mouseupoutside"), currentTarget = currentTarget.parent; 19879 delete trackingData.pressTargetsByButton[from.button]; 19880 } 19881 this.freeEvent(e); 19882 } 19883 /** 19884 * Maps the upstream `wheel` event to a downstream `wheel` event. 19885 * @param from - The upstream `wheel` event. 19886 */ 19887 mapWheel(from) { 19888 if (!(from instanceof FederatedWheelEvent)) { 19889 console.warn("EventBoundary cannot map a non-wheel event as a wheel event"); 19890 return; 19891 } 19892 const wheelEvent = this.createWheelEvent(from); 19893 this.dispatchEvent(wheelEvent), this.freeEvent(wheelEvent); 19894 } 19895 /** 19896 * Finds the most specific event-target in the given propagation path that is still mounted in the scene graph. 19897 * 19898 * This is used to find the correct `pointerup` and `pointerout` target in the case that the original `pointerdown` 19899 * or `pointerover` target was unmounted from the scene graph. 19900 * @param propagationPath - The propagation path was valid in the past. 19901 * @returns - The most specific event-target still mounted at the same location in the scene graph. 19902 */ 19903 findMountedTarget(propagationPath) { 19904 if (!propagationPath) 19905 return null;
19906 let currentTarget = propagationPath[0]; 19907 for (let i = 1; i < propagationPath.length && propagationPath[i].parent === currentTarget; i++) 19908 currentTarget = propagationPath[i]; 19909 return currentTarget; 19910 } 19911 /** 19912 * Creates an event whose {@code originalEvent} is {@code from}, with an optional `type` and `target` override. 19913 * 19914 * The event is allocated using {@link PIXI.EventBoundary#allocateEvent this.allocateEvent}. 19915 * @param from - The {@code originalEvent} for the returned event. 19916 * @param [type=from.type] - The type of the returned event. 19917 * @param target - The target of the returned event. 19918 */ 19919 createPointerEvent(from, type, target) { 19920 const event = this.allocateEvent(FederatedPointerEvent); 19921 return this.copyPointerData(from, event), this.copyMouseData(from, event), this.copyData(from, event), event.nativeEvent = from.nativeEvent, event.originalEvent = from, event.target = target ?? this.hitTest(event.global.x, event.global.y) ?? this._hitElements[0], typeof type == "string" && (event.type = type), event; 19922 } 19923 /** 19924 * Creates a wheel event whose {@code originalEvent} is {@code from}. 19925 * 19926 * The event is allocated using {@link PIXI.EventBoundary#allocateEvent this.allocateEvent}. 19927 * @param from - The upstream wheel event. 19928 */ 19929 createWheelEvent(from) { 19930 const event = this.allocateEvent(FederatedWheelEvent); 19931 return this.copyWheelData(from, event), this.copyMouseData(from, event), this.copyData(from, event), event.nativeEvent = from.nativeEvent, event.originalEvent = from, event.target = this.hitTest(event.global.x, event.global.y), event; 19932 } 19933 /** 19934 * Clones the event {@code from}, with an optional {@code type} override. 19935 * 19936 * The event is allocated using {@link PIXI.EventBoundary#allocateEvent this.allocateEvent}. 19937 * @param from - The event to clone. 19938 * @param [type=from.type] - The type of the returned event. 19939 */ 19940 clonePointerEvent(from, type) { 19941 const event = this.allocateEvent(FederatedPointerEvent); 19942 return event.nativeEvent = from.nativeEvent, event.originalEvent = from.originalEvent, this.copyPointerData(from, event), this.copyMouseData(from, event), this.copyData(from, event), event.target = from.target, event.path = from.composedPath().slice(), event.type = type ?? event.type, event; 19943 } 19944 /** 19945 * Copies wheel {@link PIXI.FederatedWheelEvent} data from {@code from} into {@code to}. 19946 * 19947 * The following properties are copied: 19948 * + deltaMode 19949 * + deltaX 19950 * + deltaY 19951 * + deltaZ 19952 * @param from 19953 * @param to 19954 */ 19955 copyWheelData(from, to) { 19956 to.deltaMode = from.deltaMode, to.deltaX = from.deltaX, to.deltaY = from.deltaY, to.deltaZ = from.deltaZ; 19957 } 19958 /** 19959 * Copies pointer {@link PIXI.FederatedPointerEvent} data from {@code from} into {@code to}. 19960 * 19961 * The following properties are copied: 19962 * + pointerId 19963 * + width 19964 * + height 19965 * + isPrimary 19966 * + pointerType 19967 * + pressure 19968 * + tangentialPressure 19969 * + tiltX 19970 * + tiltY 19971 * @param from 19972 * @param to 19973 */ 19974 copyPointerData(from, to) { 19975 from instanceof FederatedPointerEvent && to instanceof FederatedPointerEvent && (to.pointerId = from.pointerId, to.width = from.width, to.height = from.height, to.isPrimary = from.isPrimary, to.pointerType = from.pointerType, to.pressure = from.pressure, to.tangentialPressure = from.tangentialPressure, to.tiltX = from.tiltX, to.tiltY = from.tiltY, to.twist = from.twist); 19976 } 19977 /** 19978 * Copies mouse {@link PIXI.FederatedMouseEvent} data from {@code from} to {@code to}. 19979 * 19980 * The following properties are copied: 19981 * + altKey 19982 * + button 19983 * + buttons 19984 * + clientX 19985 * + clientY 19986 * + metaKey 19987 * + movementX 19988 * + movementY 19989 * + pageX 19990 * + pageY 19991 * + x 19992 * + y 19993 * + screen 19994 * + shiftKey 19995 * + global 19996 * @param from 19997 * @param to 19998 */ 19999 copyMouseData(from, to) { 20000 from instanceof FederatedMouseEvent && to instanceof FederatedMouseEvent && (to.altKey = from.altKey, to.button = from.button, to.buttons = from.buttons, to.client.copyFrom(from.client), to.ctrlKey = from.ctrlKey, to.metaKey = from.metaKey, to.movement.copyFrom(from.movement), to.screen.copyFrom(from.screen), to.shiftKey = from.shiftKey, to.global.copyFrom(from.global)); 20001 } 20002 /** 20003 * Copies base {@link PIXI.FederatedEvent} data from {@code from} into {@code to}. 20004 * 20005 * The following properties are copied: 20006 * + isTrusted 20007 * + srcElement 20008 * + timeStamp 20009 * + type 20010 * @param from - The event to copy data from. 20011 * @param to - The event to copy data into. 20012 */ 20013 copyData(from, to) { 20014 to.isTrusted = from.isTrusted, to.srcElement = from.srcElement, to.timeStamp = performance.now(), to.type = from.type, to.detail = from.detail, to.view = from.view, to.which = from.which, to.layer.copyFrom(from.layer), to.page.copyFrom(from.page); 20015 } 20016 /** 20017 * @param id - The pointer ID. 20018 * @returns The tracking data stored for the given pointer. If no data exists, a blank 20019 * state will be created. 20020 */ 20021 trackingData(id) { 20022 return this.mappingState.trackingData[id] || (this.mappingState.trackingData[id] = { 20023 pressTargetsByButton: {}, 20024 clicksByButton: {}, 20025 overTarget: null 20026 }), this.mappingState.trackingData[id]; 20027 } 20028 /** 20029 * Allocate a specific type of event from {@link PIXI.EventBoundary#eventPool this.eventPool}. 20030 * 20031 * This allocation is constructor-agnostic, as long as it only takes one argument - this event 20032 * boundary. 20033 * @param constructor - The event's constructor. 20034 */ 20035 allocateEvent(constructor) { 20036 this.eventPool.has(constructor) || this.eventPool.set(constructor, []); 20037 const event = this.eventPool.get(constructor).pop() || new constructor(this); 20038 return event.eventPhase = event.NONE, event.currentTarget = null, event.path = null, event.target = null, event; 20039 } 20040 /** 20041 * Frees the event and puts it back into the event pool. 20042 * 20043 * It is illegal to reuse the event until it is allocated again, using `this.allocateEvent`. 20044 * 20045 * It is also advised that events not allocated from {@link PIXI.EventBoundary#allocateEvent this.allocateEvent} 20046 * not be freed. This is because of the possibility that the same event is freed twice, which can cause 20047 * it to be allocated twice & result in overwriting. 20048 * @param event - The event to be freed. 20049 * @throws Error if the event is managed by another event boundary. 20050 */ 20051 freeEvent(event) { 20052 if (event.manager !== this) 20053 throw new Error("It is illegal to free an event not managed by this EventBoundary!"); 20054 const constructor = event.constructor; 20055 this.eventPool.has(constructor) || this.eventPool.set(constructor, []), this.eventPool.get(constructor).push(event); 20056 } 20057 /** 20058 * Similar to {@link PIXI.EventEmitter.emit}, except it stops if the `propagationImmediatelyStopped` flag 20059 * is set on the event. 20060 * @param e - The event to call each listener with. 20061 * @param type - The event key. 20062 */ 20063 notifyListeners(e, type) { 20064 const listeners = e.currentTarget._events[type]; 20065 if (listeners && e.currentTarget.isInteractive()) 20066 if ("fn" in listeners) 20067 listeners.once && e.currentTarget.removeListener(type, listeners.fn, void 0, !0), listeners.fn.call(listeners.context, e); 20068 else 20069 for (let i = 0, j = listeners.length; i < j && !e.propagationImmediatelyStopped; i++) 20070 listeners[i].once && e.currentTarget.removeListener(type, listeners[i].fn, void 0, !0), listeners[i].fn.call(listeners[i].context, e); 20071 } 20072} 20073 20074const MOUSE_POINTER_ID = 1, TOUCH_TO_POINTER = { 20075 touchstart: "pointerdown", 20076 touchend: "pointerup", 20077 touchendoutside: "pointerupoutside", 20078 touchmove: "pointermove", 20079 touchcancel: "pointercancel" 20080}, _EventSystem = class _EventSystem2 { 20081 /** 20082 * @param {PIXI.Renderer} renderer 20083 */ 20084 constructor(renderer) { 20085 this.supportsTouchEvents = "ontouchstart" in globalThis, this.supportsPointerEvents = !!globalThis.PointerEvent, this.domElement = null, this.resolution = 1, this.renderer = renderer, this.rootBoundary = new EventBoundary(null), EventsTicker.init(this), this.autoPreventDefault = !0, this.eventsAdded = !1, this.rootPointerEvent = new FederatedPointerEvent(null), this.rootWheelEvent = new FederatedWheelEvent(null), this.cursorStyles = { 20086 default: "inherit", 20087 pointer: "pointer" 20088 }, this.features = new Proxy({ ..._EventSystem2.defaultEventFeatures }, { 20089 set: (target, key, value) => (key === "globalMove" && (this.rootBoundary.enableGlobalMoveEvents = value), target[key] = value, !0) 20090 }), this.onPointerDown = this.onPointerDown.bind(this), this.onPointerMove = this.onPointerMove.bind(this), this.onPointerUp = this.onPointerUp.bind(this), this.onPointerOverOut = this.onPointerOverOut.bind(this), this.onWheel = this.onWheel.bind(this); 20091 } 20092 /** 20093 * The default interaction mode for all display objects. 20094 * @see PIXI.DisplayObject.eventMode 20095 * @type {PIXI.EventMode} 20096 * @readonly 20097 * @since 7.2.0 20098 */ 20099 static get defaultEventMode() { 20100 return this._defaultEventMode; 20101 } 20102 /** 20103 * Runner init called, view is available at this point. 20104 * @ignore 20105 */ 20106 init(options) { 20107 const { view, resolution } = this.renderer; 20108 this.setTargetElement(view), this.resolution = resolution, _EventSystem2._defaultEventMode = options.eventMode ?? "auto", Object.assign(this.features, options.eventFeatures ?? {}), this.rootBoundary.enableGlobalMoveEvents = this.features.globalMove; 20109 } 20110 /** 20111 * Handle changing resolution. 20112 * @ignore 20113 */ 20114 resolutionChange(resolution) { 20115 this.resolution = resolution; 20116 } 20117 /** Destroys all event listeners and detaches the renderer. */ 20118 destroy() { 20119 this.setTargetElement(null), this.renderer = null; 20120 } 20121 /** 20122 * Sets the current cursor mode, handling any callbacks or CSS style changes.
vendor: 8,892 bytes, lines 20123-20275
20123 * @param mode - cursor mode, a key from the cursorStyles dictionary 20124 */ 20125 setCursor(mode) { 20126 mode = mode || "default"; 20127 let applyStyles = !0; 20128 if (globalThis.OffscreenCanvas && this.domElement instanceof OffscreenCanvas && (applyStyles = !1), this.currentCursor === mode) 20129 return; 20130 this.currentCursor = mode; 20131 const style = this.cursorStyles[mode]; 20132 if (style) 20133 switch (typeof style) { 20134 case "string": 20135 applyStyles && (this.domElement.style.cursor = style); 20136 break; 20137 case "function": 20138 style(mode); 20139 break; 20140 case "object": 20141 applyStyles && Object.assign(this.domElement.style, style); 20142 break; 20143 } 20144 else 20145 applyStyles && typeof mode == "string" && !Object.prototype.hasOwnProperty.call(this.cursorStyles, mode) && (this.domElement.style.cursor = mode); 20146 } 20147 /** 20148 * The global pointer event. 20149 * Useful for getting the pointer position without listening to events. 20150 * @since 7.2.0 20151 */ 20152 get pointer() { 20153 return this.rootPointerEvent; 20154 } 20155 /** 20156 * Event handler for pointer down events on {@link PIXI.EventSystem#domElement this.domElement}. 20157 * @param nativeEvent - The native mouse/pointer/touch event. 20158 */ 20159 onPointerDown(nativeEvent) { 20160 if (!this.features.click) 20161 return; 20162 this.rootBoundary.rootTarget = this.renderer.lastObjectRendered; 20163 const events = this.normalizeToPointerData(nativeEvent); 20164 this.autoPreventDefault && events[0].isNormalized && (nativeEvent.cancelable || !("cancelable" in nativeEvent)) && nativeEvent.preventDefault(); 20165 for (let i = 0, j = events.length; i < j; i++) { 20166 const nativeEvent2 = events[i], federatedEvent = this.bootstrapEvent(this.rootPointerEvent, nativeEvent2); 20167 this.rootBoundary.mapEvent(federatedEvent); 20168 } 20169 this.setCursor(this.rootBoundary.cursor); 20170 } 20171 /** 20172 * Event handler for pointer move events on on {@link PIXI.EventSystem#domElement this.domElement}. 20173 * @param nativeEvent - The native mouse/pointer/touch events. 20174 */ 20175 onPointerMove(nativeEvent) { 20176 if (!this.features.move) 20177 return; 20178 this.rootBoundary.rootTarget = this.renderer.lastObjectRendered, EventsTicker.pointerMoved(); 20179 const normalizedEvents = this.normalizeToPointerData(nativeEvent); 20180 for (let i = 0, j = normalizedEvents.length; i < j; i++) { 20181 const event = this.bootstrapEvent(this.rootPointerEvent, normalizedEvents[i]); 20182 this.rootBoundary.mapEvent(event); 20183 } 20184 this.setCursor(this.rootBoundary.cursor); 20185 } 20186 /** 20187 * Event handler for pointer up events on {@link PIXI.EventSystem#domElement this.domElement}. 20188 * @param nativeEvent - The native mouse/pointer/touch event. 20189 */ 20190 onPointerUp(nativeEvent) { 20191 if (!this.features.click) 20192 return; 20193 this.rootBoundary.rootTarget = this.renderer.lastObjectRendered; 20194 let target = nativeEvent.target; 20195 nativeEvent.composedPath && nativeEvent.composedPath().length > 0 && (target = nativeEvent.composedPath()[0]); 20196 const outside = target !== this.domElement ? "outside" : "", normalizedEvents = this.normalizeToPointerData(nativeEvent); 20197 for (let i = 0, j = normalizedEvents.length; i < j; i++) { 20198 const event = this.bootstrapEvent(this.rootPointerEvent, normalizedEvents[i]); 20199 event.type += outside, this.rootBoundary.mapEvent(event); 20200 } 20201 this.setCursor(this.rootBoundary.cursor); 20202 } 20203 /** 20204 * Event handler for pointer over & out events on {@link PIXI.EventSystem#domElement this.domElement}. 20205 * @param nativeEvent - The native mouse/pointer/touch event. 20206 */ 20207 onPointerOverOut(nativeEvent) { 20208 if (!this.features.click) 20209 return; 20210 this.rootBoundary.rootTarget = this.renderer.lastObjectRendered; 20211 const normalizedEvents = this.normalizeToPointerData(nativeEvent); 20212 for (let i = 0, j = normalizedEvents.length; i < j; i++) { 20213 const event = this.bootstrapEvent(this.rootPointerEvent, normalizedEvents[i]); 20214 this.rootBoundary.mapEvent(event); 20215 } 20216 this.setCursor(this.rootBoundary.cursor); 20217 } 20218 /** 20219 * Passive handler for `wheel` events on {@link PIXI.EventSystem.domElement this.domElement}. 20220 * @param nativeEvent - The native wheel event. 20221 */ 20222 onWheel(nativeEvent) { 20223 if (!this.features.wheel) 20224 return; 20225 const wheelEvent = this.normalizeWheelEvent(nativeEvent); 20226 this.rootBoundary.rootTarget = this.renderer.lastObjectRendered, this.rootBoundary.mapEvent(wheelEvent); 20227 } 20228 /** 20229 * Sets the {@link PIXI.EventSystem#domElement domElement} and binds event listeners. 20230 * 20231 * To deregister the current DOM element without setting a new one, pass {@code null}. 20232 * @param element - The new DOM element. 20233 */ 20234 setTargetElement(element) { 20235 this.removeEvents(), this.domElement = element, EventsTicker.domElement = element, this.addEvents(); 20236 } 20237 /** Register event listeners on {@link PIXI.Renderer#domElement this.domElement}. */ 20238 addEvents() { 20239 if (this.eventsAdded || !this.domElement) 20240 return; 20241 EventsTicker.addTickerListener(); 20242 const style = this.domElement.style; 20243 style && (globalThis.navigator.msPointerEnabled ? (style.msContentZooming = "none", style.msTouchAction = "none") : this.supportsPointerEvents && (style.touchAction = "none")), this.supportsPointerEvents ? (globalThis.document.addEventListener("pointermove", this.onPointerMove, !0), this.domElement.addEventListener("pointerdown", this.onPointerDown, !0), this.domElement.addEventListener("pointerleave", this.onPointerOverOut, !0), this.domElement.addEventListener("pointerover", this.onPointerOverOut, !0), globalThis.addEventListener("pointerup", this.onPointerUp, !0)) : (globalThis.document.addEventListener("mousemove", this.onPointerMove, !0), this.domElement.addEventListener("mousedown", this.onPointerDown, !0), this.domElement.addEventListener("mouseout", this.onPointerOverOut, !0), this.domElement.addEventListener("mouseover", this.onPointerOverOut, !0), globalThis.addEventListener("mouseup", this.onPointerUp, !0), this.supportsTouchEvents && (this.domElement.addEventListener("touchstart", this.onPointerDown, !0), this.domElement.addEventListener("touchend", this.onPointerUp, !0), this.domElement.addEventListener("touchmove", this.onPointerMove, !0))), this.domElement.addEventListener("wheel", this.onWheel, { 20244 passive: !0, 20245 capture: !0 20246 }), this.eventsAdded = !0; 20247 } 20248 /** Unregister event listeners on {@link PIXI.EventSystem#domElement this.domElement}. */ 20249 removeEvents() { 20250 if (!this.eventsAdded || !this.domElement) 20251 return; 20252 EventsTicker.removeTickerListener(); 20253 const style = this.domElement.style; 20254 globalThis.navigator.msPointerEnabled ? (style.msContentZooming = "", style.msTouchAction = "") : this.supportsPointerEvents && (style.touchAction = ""), this.supportsPointerEvents ? (globalThis.document.removeEventListener("pointermove", this.onPointerMove, !0), this.domElement.removeEventListener("pointerdown", this.onPointerDown, !0), this.domElement.removeEventListener("pointerleave", this.onPointerOverOut, !0), this.domElement.removeEventListener("pointerover", this.onPointerOverOut, !0), globalThis.removeEventListener("pointerup", this.onPointerUp, !0)) : (globalThis.document.removeEventListener("mousemove", this.onPointerMove, !0), this.domElement.removeEventListener("mousedown", this.onPointerDown, !0), this.domElement.removeEventListener("mouseout", this.onPointerOverOut, !0), this.domElement.removeEventListener("mouseover", this.onPointerOverOut, !0), globalThis.removeEventListener("mouseup", this.onPointerUp, !0), this.supportsTouchEvents && (this.domElement.removeEventListener("touchstart", this.onPointerDown, !0), this.domElement.removeEventListener("touchend", this.onPointerUp, !0), this.domElement.removeEventListener("touchmove", this.onPointerMove, !0))), this.domElement.removeEventListener("wheel", this.onWheel, !0), this.domElement = null, this.eventsAdded = !1; 20255 } 20256 /** 20257 * Maps x and y coords from a DOM object and maps them correctly to the PixiJS view. The 20258 * resulting value is stored in the point. This takes into account the fact that the DOM 20259 * element could be scaled and positioned anywhere on the screen. 20260 * @param {PIXI.IPointData} point - the point that the result will be stored in 20261 * @param {number} x - the x coord of the position to map 20262 * @param {number} y - the y coord of the position to map 20263 */ 20264 mapPositionToPoint(point, x, y) { 20265 const rect = this.domElement.isConnected ? this.domElement.getBoundingClientRect() : { 20266 x: 0, 20267 y: 0, 20268 width: this.domElement.width, 20269 height: this.domElement.height, 20270 left: 0, 20271 top: 0 20272 }, resolutionMultiplier = 1 / this.resolution; 20273 point.x = (x - rect.left) * (this.domElement.width / rect.width) * resolutionMultiplier, point.y = (y - rect.top) * (this.domElement.height / rect.height) * resolutionMultiplier; 20274 } 20275 /**
20276 * Ensures that the original event object contains all data that a regular pointer event would have 20277 * @param event - The original event data from a touch or mouse event 20278 * @returns An array containing a single normalized pointer event, in the case of a pointer 20279 * or mouse event, or a multiple normalized pointer events if there are multiple changed touches 20280 */ 20281 normalizeToPointerData(event) { 20282 const normalizedEvents = []; 20283 if (this.supportsTouchEvents && event instanceof TouchEvent) 20284 for (let i = 0, li = event.changedTouches.length; i < li; i++) { 20285 const touch = event.changedTouches[i]; 20286 typeof touch.button > "u" && (touch.button = 0), typeof touch.buttons > "u" && (touch.buttons = 1), typeof touch.isPrimary > "u" && (touch.isPrimary = event.touches.length === 1 && event.type === "touchstart"), typeof touch.width > "u" && (touch.width = touch.radiusX || 1), typeof touch.height > "u" && (touch.height = touch.radiusY || 1), typeof touch.tiltX > "u" && (touch.tiltX = 0), typeof touch.tiltY > "u" && (touch.tiltY = 0), typeof touch.pointerType > "u" && (touch.pointerType = "touch"), typeof touch.pointerId > "u" && (touch.pointerId = touch.identifier || 0), typeof touch.pressure > "u" && (touch.pressure = touch.force || 0.5), typeof touch.twist > "u" && (touch.twist = 0), typeof touch.tangentialPressure > "u" && (touch.tangentialPressure = 0), typeof touch.layerX > "u" && (touch.layerX = touch.offsetX = touch.clientX), typeof touch.layerY > "u" && (touch.layerY = touch.offsetY = touch.clientY), touch.isNormalized = !0, touch.type = event.type, normalizedEvents.push(touch); 20287 } 20288 else if (!globalThis.MouseEvent || event instanceof MouseEvent && (!this.supportsPointerEvents || !(event instanceof globalThis.PointerEvent))) { 20289 const tempEvent = event; 20290 typeof tempEvent.isPrimary > "u" && (tempEvent.isPrimary = !0), typeof tempEvent.width > "u" && (tempEvent.width = 1), typeof tempEvent.height > "u" && (tempEvent.height = 1), typeof tempEvent.tiltX > "u" && (tempEvent.tiltX = 0), typeof tempEvent.tiltY > "u" && (tempEvent.tiltY = 0), typeof tempEvent.pointerType > "u" && (tempEvent.pointerType = "mouse"), typeof tempEvent.pointerId > "u" && (tempEvent.pointerId = MOUSE_POINTER_ID), typeof tempEvent.pressure > "u" && (tempEvent.pressure = 0.5), typeof tempEvent.twist > "u" && (tempEvent.twist = 0), typeof tempEvent.tangentialPressure > "u" && (tempEvent.tangentialPressure = 0), tempEvent.isNormalized = !0, normalizedEvents.push(tempEvent); 20291 } else 20292 normalizedEvents.push(event); 20293 return normalizedEvents; 20294 } 20295 /** 20296 * Normalizes the native {@link https://w3c.github.io/uievents/#interface-wheelevent WheelEvent}. 20297 * 20298 * The returned {@link PIXI.FederatedWheelEvent} is a shared instance. It will not persist across 20299 * multiple native wheel events. 20300 * @param nativeEvent - The native wheel event that occurred on the canvas. 20301 * @returns A federated wheel event. 20302 */ 20303 normalizeWheelEvent(nativeEvent) { 20304 const event = this.rootWheelEvent; 20305 return this.transferMouseData(event, nativeEvent), event.deltaX = nativeEvent.deltaX, event.deltaY = nativeEvent.deltaY, event.deltaZ = nativeEvent.deltaZ, event.deltaMode = nativeEvent.deltaMode, this.mapPositionToPoint(event.screen, nativeEvent.clientX, nativeEvent.clientY), event.global.copyFrom(event.screen), event.offset.copyFrom(event.screen), event.nativeEvent = nativeEvent, event.type = nativeEvent.type, event; 20306 } 20307 /** 20308 * Normalizes the `nativeEvent` into a federateed {@link PIXI.FederatedPointerEvent}. 20309 * @param event 20310 * @param nativeEvent 20311 */ 20312 bootstrapEvent(event, nativeEvent) { 20313 return event.originalEvent = null, event.nativeEvent = nativeEvent, event.pointerId = nativeEvent.pointerId, event.width = nativeEvent.width, event.height = nativeEvent.height, event.isPrimary = nativeEvent.isPrimary, event.pointerType = nativeEvent.pointerType, event.pressure = nativeEvent.pressure, event.tangentialPressure = nativeEvent.tangentialPressure, event.tiltX = nativeEvent.tiltX, event.tiltY = nativeEvent.tiltY, event.twist = nativeEvent.twist, this.transferMouseData(event, nativeEvent), this.mapPositionToPoint(event.screen, nativeEvent.clientX, nativeEvent.clientY), event.global.copyFrom(event.screen), event.offset.copyFrom(event.screen), event.isTrusted = nativeEvent.isTrusted, event.type === "pointerleave" && (event.type = "pointerout"), event.type.startsWith("mouse") && (event.type = event.type.replace("mouse", "pointer")), event.type.startsWith("touch") && (event.type = TOUCH_TO_POINTER[event.type] || event.type), event; 20314 } 20315 /** 20316 * Transfers base & mouse event data from the {@code nativeEvent} to the federated event. 20317 * @param event 20318 * @param nativeEvent 20319 */ 20320 transferMouseData(event, nativeEvent) { 20321 event.isTrusted = nativeEvent.isTrusted, event.srcElement = nativeEvent.srcElement, event.timeStamp = performance.now(), event.type = nativeEvent.type, event.altKey = nativeEvent.altKey, event.button = nativeEvent.button, event.buttons = nativeEvent.buttons, event.client.x = nativeEvent.clientX, event.client.y = nativeEvent.clientY, event.ctrlKey = nativeEvent.ctrlKey, event.metaKey = nativeEvent.metaKey, event.movement.x = nativeEvent.movementX, event.movement.y = nativeEvent.movementY, event.page.x = nativeEvent.pageX, event.page.y = n
20321ativeEvent.pageY, event.relatedTarget = null, event.shiftKey = nativeEvent.shiftKey; 20322 } 20323}; 20324_EventSystem.extension = { 20325 name: "events", 20326 type: [ 20327 ExtensionType.RendererSystem, 20328 ExtensionType.CanvasRendererSystem 20329 ] 20330}, /** 20331* The event features that are enabled by the EventSystem 20332* This option only is available when using **@pixi/events** package 20333* (included in the **pixi.js** and **pixi.js-legacy** bundle), otherwise it will be ignored. 20334* @since 7.2.0 20335*/ 20336_EventSystem.defaultEventFeatures = { 20337 move: !0, 20338 globalMove: !0, 20339 click: !0, 20340 wheel: !0 20341}; 20342let EventSystem = _EventSystem; 20343extensions$1.add(EventSystem); 20344 20345function convertEventModeToInteractiveMode(mode) { 20346 return mode === "dynamic" || mode === "static"; 20347} 20348const FederatedDisplayObject = { 20349 /** 20350 * Property-based event handler for the `click` event. 20351 * @memberof PIXI.DisplayObject# 20352 * @default null 20353 * @example 20354 * this.onclick = (event) => { 20355 * //some function here that happens on click 20356 * } 20357 */ 20358 onclick: null, 20359 /** 20360 * Property-based event handler for the `mousedown` event. 20361 * @memberof PIXI.DisplayObject# 20362 * @default null 20363 * @example 20364 * this.onmousedown = (event) => { 20365 * //some function here that happens on mousedown 20366 * } 20367 */ 20368 onmousedown: null, 20369 /** 20370 * Property-based event handler for the `mouseenter` event. 20371 * @memberof PIXI.DisplayObject# 20372 * @default null 20373 * @example 20374 * this.onmouseenter = (event) => { 20375 * //some function here that happens on mouseenter 20376 * } 20377 */ 20378 onmouseenter: null, 20379 /** 20380 * Property-based event handler for the `mouseleave` event. 20381 * @memberof PIXI.DisplayObject# 20382 * @default null 20383 * @example 20384 * this.onmouseleave = (event) => { 20385 * //some function here that happens on mouseleave 20386 * } 20387 */ 20388 onmouseleave: null, 20389 /** 20390 * Property-based event handler for the `mousemove` event. 20391 * @memberof PIXI.DisplayObject# 20392 * @default null 20393 * @example 20394 * this.onmousemove = (event) => { 20395 * //some function here that happens on mousemove 20396 * } 20397 */ 20398 onmousemove: null, 20399 /** 20400 * Property-based event handler for the `globalmousemove` event. 20401 * @memberof PIXI.DisplayObject# 20402 * @default null 20403 * @example 20404 * this.onglobalmousemove = (event) => { 20405 * //some function here that happens on globalmousemove 20406 * } 20407 */ 20408 onglobalmousemove: null, 20409 /** 20410 * Property-based event handler for the `mouseout` event. 20411 * @memberof PIXI.DisplayObject# 20412 * @default null 20413 * @example 20414 * this.onmouseout = (event) => { 20415 * //some function here that happens on mouseout 20416 * } 20417 */ 20418 onmouseout: null, 20419 /** 20420 * Property-based event handler for the `mouseover` event. 20421 * @memberof PIXI.DisplayObject# 20422 * @default null 20423 * @example 20424 * this.onmouseover = (event) => { 20425 * //some function here that happens on mouseover 20426 * } 20427 */ 20428 onmouseover: null, 20429 /** 20430 * Property-based event handler for the `mouseup` event. 20431 * @memberof PIXI.DisplayObject# 20432 * @default null 20433 * @example 20434 * this.onmouseup = (event) => { 20435 * //some function here that happens on mouseup 20436 * } 20437 */ 20438 onmouseup: null, 20439 /** 20440 * Property-based event handler for the `mouseupoutside` event. 20441 * @memberof PIXI.DisplayObject# 20442 * @default null 20443 * @example 20444 * this.onmouseupoutside = (event) => { 20445 * //some function here that happens on mouseupoutside 20446 * } 20447 */ 20448 onmouseupoutside: null, 20449 /** 20450 * Property-based event handler for the `pointercancel` event. 20451 * @memberof PIXI.DisplayObject# 20452 * @default null 20453 * @example 20454 * this.onpointercancel = (event) => { 20455 * //some function here that happens on pointercancel 20456 * } 20457 */ 20458 onpointercancel: null, 20459 /** 20460 * Property-based event handler for the `pointerdown` event. 20461 * @memberof PIXI.DisplayObject# 20462 * @default null 20463 * @example 20464 * this.onpointerdown = (event) => { 20465 * //some function here that happens on pointerdown 20466 * } 20467 */ 20468 onpointerdown: null, 20469 /** 20470 * Property-based event handler for the `pointerenter` event. 20471 * @memberof PIXI.DisplayObject# 20472 * @default null 20473 * @example 20474 * this.onpointerenter = (event) => { 20475 * //some function here that happens on pointerenter 20476 * } 20477 */ 20478 onpointerenter: null, 20479 /** 20480 * Property-based event handler for the `pointerleave` event. 20481 * @memberof PIXI.DisplayObject# 20482 * @default null 20483 * @example 20484 * this.onpointerleave = (event) => { 20485 * //some function here that happens on pointerleave 20486 * } 20487 */ 20488 onpointerleave: null, 20489 /** 20490 * Property-based event handler for the `pointermove` event. 20491 * @memberof PIXI.DisplayObject# 20492 * @default null 20493 * @example 20494 * this.onpointermove = (event) => { 20495 * //some function here that happens on pointermove 20496 * } 20497 */ 20498 onpointermove: null, 20499 /** 20500 * Property-based event handler for the `globalpointermove` event. 20501 * @memberof PIXI.DisplayObject# 20502 * @default null 20503 * @example 20504 * this.onglobalpointermove = (event) => { 20505 * //some function here that happens on globalpointermove 20506 * } 20507 */ 20508 onglobalpointermove: null, 20509 /** 20510 * Property-based event handler for the `pointerout` event. 20511 * @memberof PIXI.DisplayObject# 20512 * @default null 20513 * @example 20514 * this.onpointerout = (event) => { 20515 * //some function here that happens on pointerout 20516 * } 20517 */ 20518 onpointerout: null, 20519 /** 20520 * Property-based event handler for the `pointerover` event. 20521 * @memberof PIXI.DisplayObject# 20522 * @default null 20523 * @example 20524 * this.onpointerover = (event) => { 20525 * //some function here that happens on pointerover 20526 * } 20527 */ 20528 onpointerover: null, 20529 /** 20530 * Property-based event handler for the `pointertap` event. 20531 * @memberof PIXI.DisplayObject# 20532 * @default null 20533 * @example 20534 * this.onpointertap = (event) => { 20535 * //some function here that happens on pointertap 20536 * } 20537 */ 20538 onpointertap: null, 20539 /** 20540 * Property-based event handler for the `pointerup` event. 20541 * @memberof PIXI.DisplayObject# 20542 * @default null 20543 * @example 20544 * this.onpointerup = (event) => { 20545 * //some function here that happens on pointerup 20546 * } 20547 */ 20548 onpointerup: null, 20549 /** 20550 * Property-based event handler for the `pointerupoutside` event. 20551 * @memberof PIXI.DisplayObject# 20552 * @default null 20553 * @example 20554 * this.onpointerupoutside = (event) => { 20555 * //some function here that happens on pointerupoutside 20556 * } 20557 */ 20558 onpointerupoutside: null, 20559 /** 20560 * Property-based event handler for the `rightclick` event. 20561 * @memberof PIXI.DisplayObject# 20562 * @default null 20563 * @example 20564 * this.onrightclick = (event) => { 20565 * //some function here that happens on rightclick 20566 * } 20567 */ 20568 onrightclick: null, 20569 /** 20570 * Property-based event handler for the `rightdown` event. 20571 * @memberof PIXI.DisplayObject# 20572 * @default null 20573 * @example 20574 * this.onrightdown = (event) => { 20575 * //some function here that happens on rightdown 20576 * } 20577 */ 20578 onrightdown: null, 20579 /** 20580 * Property-based event handler for the `rightup` event. 20581 * @memberof PIXI.DisplayObject# 20582 * @default null 20583 * @example 20584 * this.onrightup = (event) => { 20585 * //some function here that happens on rightup 20586 * } 20587 */ 20588 onrightup: null, 20589 /** 20590 * Property-based event handler for the `rightupoutside` event. 20591 * @memberof PIXI.DisplayObject# 20592 * @default null 20593 * @example 20594 * this.onrightupoutside = (event) => { 20595 * //some function here that happens on rightupoutside 20596 * } 20597 */ 20598 onrightupoutside: null, 20599 /** 20600 * Property-based event handler for the `tap` event. 20601 * @memberof PIXI.DisplayObject# 20602 * @default null 20603 * @example 20604 * this.ontap = (event) => { 20605 * //some function here that happens on tap 20606 * } 20607 */ 20608 ontap: null, 20609 /** 20610 * Property-based event handler for the `touchcancel` event. 20611 * @memberof PIXI.DisplayObject# 20612 * @default null 20613 * @example 20614 * this.ontouchcancel = (event) => { 20615 * //some function here that happens on touchcancel 20616 * } 20617 */ 20618 ontouchcancel: null, 20619 /** 20620 * Property-based event handler for the `touchend` event. 20621 * @memberof PIXI.DisplayObject# 20622 * @default null 20623 * @example 20624 * this.ontouchend = (event) => { 20625 * //some function here that happens on touchend 20626 * } 20627 */ 20628 ontouchend: null, 20629 /** 20630 * Property-based event handler for the `touchendoutside` event. 20631 * @memberof PIXI.DisplayObject# 20632 * @default null 20633 * @example 20634 * this.ontouchendoutside = (event) => { 20635 * //some function here that happens on touchendoutside 20636 * } 20637 */ 20638 ontouchendoutside: null, 20639 /** 20640 * Property-based event handler for the `touchmove` event. 20641 * @memberof PIXI.DisplayObject# 20642 * @default null 20643 * @example 20644 * this.ontouchmove = (event) => { 20645 * //some function here that happens on touchmove 20646 * } 20647 */ 20648 ontouchmove: null, 20649 /** 20650 * Property-based event handler for the `globaltouchmove` event. 20651 * @memberof PIXI.DisplayObject# 20652 * @default null 20653 * @example 20654 * this.onglobaltouchmove = (event) => { 20655 * //some function here that happens on globaltouchmove 20656 * } 20657 */ 20658 onglobaltouchmove: null, 20659 /** 20660 * Property-based event handler for the `touchstart` event. 20661 * @memberof PIXI.DisplayObject# 20662 * @default null 20663 * @example 20664 * this.ontouchstart = (event) => { 20665 * //some function here that happens on touchstart 20666 * } 20667 */ 20668 ontouchstart: null, 20669 /** 20670 * Property-based event handler for the `wheel` event. 20671 * @memberof PIXI.DisplayObject# 20672 * @default null 20673 * @example 20674 * this.onwheel = (event) => { 20675 * //some function here that happens on wheel 20676 * } 20677 */ 20678 onwheel: null, 20679 /** 20680 * @ignore 20681 */ 20682 _internalInteractive: void 0, 20683 /** 20684 * Enable interaction events for the DisplayObject. Touch, pointer and mouse 20685 * @memberof PIXI.DisplayObject# 20686 */ 20687 get interactive() { 20688 return this._internalInteractive ?? convertEventModeToInteractiveMode(EventSystem.defaultEventMode); 20689 }, 20690 set interactive(value) { 20691 deprecation( 20692 "7.2.0", 20693 // eslint-disable-next-line max-len 20694 "Setting interactive is deprecated, use eventMode = 'none'/'passive'/'auto'/'static'/'dynamic' instead." 20695 ), this._internalInteractive = value, this.eventMode = value ? "static" : "auto"; 20696 }, 20697 /** 20698 * @ignore 20699 */ 20700 _internalEventMode: void 0, 20701 /** 20702 * Enable interaction events for the DisplayObject. Touch, pointer and mouse. 20703 * This now replaces the `interactive` property. 20704 * There are 5 types of interaction settings: 20705 * - `'none'`: Ignores all interaction events, even on its children. 20706 * - `'passive'`: Does not emit events and ignores all hit testing on itself and n
vendor: 16,384 bytes, lines 20706-21036
20706on-interactive children. 20707 * Interactive children will still emit events. 20708 * - `'auto'`: Does not emit events but is hit tested if parent is interactive. Same as `interactive = false` in v7 20709 * - `'static'`: Emit events and is hit tested. Same as `interaction = true` in v7 20710 * - `'dynamic'`: Emits events and is hit tested but will also receive mock interaction events fired from a ticker to 20711 * allow for interaction when the mouse isn't moving 20712 * @example 20713 * import { Sprite } from 'pixi.js'; 20714 * 20715 * const sprite = new Sprite(texture); 20716 * sprite.eventMode = 'static'; 20717 * sprite.on('tap', (event) => { 20718 * // Handle event 20719 * }); 20720 * @memberof PIXI.DisplayObject# 20721 * @since 7.2.0 20722 */ 20723 get eventMode() { 20724 return this._internalEventMode ?? EventSystem.defaultEventMode; 20725 }, 20726 set eventMode(value) { 20727 this._internalInteractive = convertEventModeToInteractiveMode(value), this._internalEventMode = value; 20728 }, 20729 /** 20730 * Determines if the displayObject is interactive or not 20731 * @returns {boolean} Whether the displayObject is interactive or not 20732 * @memberof PIXI.DisplayObject# 20733 * @since 7.2.0 20734 * @example 20735 * import { Sprite } from 'pixi.js'; 20736 * const sprite = new Sprite(texture); 20737 * sprite.eventMode = 'static'; 20738 * sprite.isInteractive(); // true 20739 * 20740 * sprite.eventMode = 'dynamic'; 20741 * sprite.isInteractive(); // true 20742 * 20743 * sprite.eventMode = 'none'; 20744 * sprite.isInteractive(); // false 20745 * 20746 * sprite.eventMode = 'passive'; 20747 * sprite.isInteractive(); // false 20748 * 20749 * sprite.eventMode = 'auto'; 20750 * sprite.isInteractive(); // false 20751 */ 20752 isInteractive() { 20753 return this.eventMode === "static" || this.eventMode === "dynamic"; 20754 }, 20755 /** 20756 * Determines if the children to the displayObject can be clicked/touched 20757 * Setting this to false allows PixiJS to bypass a recursive `hitTest` function 20758 * @memberof PIXI.Container# 20759 */ 20760 interactiveChildren: !0, 20761 /** 20762 * Interaction shape. Children will be hit first, then this shape will be checked. 20763 * Setting this will cause this shape to be checked in hit tests rather than the displayObject's bounds. 20764 * @example 20765 * import { Rectangle, Sprite } from 'pixi.js'; 20766 * 20767 * const sprite = new Sprite(texture); 20768 * sprite.interactive = true; 20769 * sprite.hitArea = new Rectangle(0, 0, 100, 100); 20770 * @member {PIXI.IHitArea} 20771 * @memberof PIXI.DisplayObject# 20772 */ 20773 hitArea: null, 20774 /** 20775 * Unlike `on` or `addListener` which are methods from EventEmitter, `addEventListener` 20776 * seeks to be compatible with the DOM's `addEventListener` with support for options. 20777 * **IMPORTANT:** _Only_ available if using the `@pixi/events` package. 20778 * @memberof PIXI.DisplayObject 20779 * @param type - The type of event to listen to. 20780 * @param listener - The listener callback or object. 20781 * @param options - Listener options, used for capture phase. 20782 * @example 20783 * // Tell the user whether they did a single, double, triple, or nth click. 20784 * button.addEventListener('click', { 20785 * handleEvent(e): { 20786 * let prefix; 20787 * 20788 * switch (e.detail) { 20789 * case 1: prefix = 'single'; break; 20790 * case 2: prefix = 'double'; break; 20791 * case 3: prefix = 'triple'; break; 20792 * default: prefix = e.detail + 'th'; break; 20793 * } 20794 * 20795 * console.log('That was a ' + prefix + 'click'); 20796 * } 20797 * }); 20798 * 20799 * // But skip the first click! 20800 * button.parent.addEventListener('click', function blockClickOnce(e) { 20801 * e.stopImmediatePropagation(); 20802 * button.parent.removeEventListener('click', blockClickOnce, true); 20803 * }, { 20804 * capture: true, 20805 * }); 20806 */ 20807 addEventListener(type, listener, options) { 20808 const capture = typeof options == "boolean" && options || typeof options == "object" && options.capture, context = typeof listener == "function" ? void 0 : listener; 20809 type = capture ? `${type}capture` : type, listener = typeof listener == "function" ? listener : listener.handleEvent, this.on(type, listener, context); 20810 }, 20811 /** 20812 * Unlike `off` or `removeListener` which are methods from EventEmitter, `removeEventListener` 20813 * seeks to be compatible with the DOM's `removeEventListener` with support for options. 20814 * **IMPORTANT:** _Only_ available if using the `@pixi/events` package. 20815 * @memberof PIXI.DisplayObject 20816 * @param type - The type of event the listener is bound to. 20817 * @param listener - The listener callback or object. 20818 * @param options - The original listener options. This is required to deregister a capture phase listener. 20819 */ 20820 removeEventListener(type, listener, options) { 20821 const capture = typeof options == "boolean" && options || typeof options == "object" && options.capture, context = typeof listener == "function" ? void 0 : listener; 20822 type = capture ? `${type}capture` : type, listener = typeof listener == "function" ? listener : listener.handleEvent, this.off(type, listener, context); 20823 }, 20824 /** 20825 * Dispatch the event on this {@link PIXI.DisplayObject} using the event's {@link PIXI.EventBoundary}. 20826 * 20827 * The target of the event is set to `this` and the `defaultPrevented` flag is cleared before dispatch. 20828 * 20829 * **IMPORTANT:** _Only_ available if using the `@pixi/events` package. 20830 * @memberof PIXI.DisplayObject 20831 * @param e - The event to dispatch. 20832 * @returns Whether the {@link PIXI.FederatedEvent.preventDefault preventDefault}() method was not invoked. 20833 * @example 20834 * // Reuse a click event! 20835 * button.dispatchEvent(clickEvent); 20836 */ 20837 dispatchEvent(e) { 20838 if (!(e instanceof FederatedEvent)) 20839 throw new Error("DisplayObject cannot propagate events outside of the Federated Events API"); 20840 return e.defaultPrevented = !1, e.path = null, e.target = this, e.manager.dispatchEvent(e), !e.defaultPrevented; 20841 } 20842}; 20843DisplayObject.mixin(FederatedDisplayObject); 20844 20845const accessibleTarget = { 20846 /** 20847 * Flag for if the object is accessible. If true AccessibilityManager will overlay a 20848 * shadow div with attributes set 20849 * @member {boolean} 20850 * @memberof PIXI.DisplayObject# 20851 */ 20852 accessible: !1, 20853 /** 20854 * Sets the title attribute of the shadow div 20855 * If accessibleTitle AND accessibleHint has not been this will default to 'displayObject [tabIndex]' 20856 * @member {?string} 20857 * @memberof PIXI.DisplayObject# 20858 */ 20859 accessibleTitle: null, 20860 /** 20861 * Sets the aria-label attribute of the shadow div 20862 * @member {string} 20863 * @memberof PIXI.DisplayObject# 20864 */ 20865 accessibleHint: null, 20866 /** 20867 * @member {number} 20868 * @memberof PIXI.DisplayObject# 20869 * @private 20870 * @todo Needs docs. 20871 */ 20872 tabIndex: 0, 20873 /** 20874 * @member {boolean} 20875 * @memberof PIXI.DisplayObject# 20876 * @todo Needs docs. 20877 */ 20878 _accessibleActive: !1, 20879 /** 20880 * @member {boolean} 20881 * @memberof PIXI.DisplayObject# 20882 * @todo Needs docs. 20883 */ 20884 _accessibleDiv: null, 20885 /** 20886 * Specify the type of div the accessible layer is. Screen readers treat the element differently 20887 * depending on this type. Defaults to button. 20888 * @member {string} 20889 * @memberof PIXI.DisplayObject# 20890 * @default 'button' 20891 */ 20892 accessibleType: "button", 20893 /** 20894 * Specify the pointer-events the accessible div will use 20895 * Defaults to auto. 20896 * @member {string} 20897 * @memberof PIXI.DisplayObject# 20898 * @default 'auto' 20899 */ 20900 accessiblePointerEvents: "auto", 20901 /** 20902 * Setting to false will prevent any children inside this container to 20903 * be accessible. Defaults to true. 20904 * @member {boolean} 20905 * @memberof PIXI.DisplayObject# 20906 * @default true 20907 */ 20908 accessibleChildren: !0, 20909 renderId: -1 20910}; 20911 20912DisplayObject.mixin(accessibleTarget); 20913const KEY_CODE_TAB = 9, DIV_TOUCH_SIZE = 100, DIV_TOUCH_POS_X = 0, DIV_TOUCH_POS_Y = 0, DIV_TOUCH_ZINDEX = 2, DIV_HOOK_SIZE = 1, DIV_HOOK_POS_X = -1e3, DIV_HOOK_POS_Y = -1e3, DIV_HOOK_ZINDEX = 2; 20914class AccessibilityManager { 20915 // 2fps 20916 /** 20917 * @param {PIXI.CanvasRenderer|PIXI.Renderer} renderer - A reference to the current renderer 20918 */ 20919 constructor(renderer) { 20920 this.debug = !1, this._isActive = !1, this._isMobileAccessibility = !1, this.pool = [], this.renderId = 0, this.children = [], this.androidUpdateCount = 0, this.androidUpdateFrequency = 500, this._hookDiv = null, (isMobile.tablet || isMobile.phone) && this.createTouchHook(); 20921 const div = document.createElement("div"); 20922 div.style.width = `${DIV_TOUCH_SIZE}px`, div.style.height = `${DIV_TOUCH_SIZE}px`, div.style.position = "absolute", div.style.top = `${DIV_TOUCH_POS_X}px`, div.style.left = `${DIV_TOUCH_POS_Y}px`, div.style.zIndex = DIV_TOUCH_ZINDEX.toString(), this.div = div, this.renderer = renderer, this._onKeyDown = this._onKeyDown.bind(this), this._onMouseMove = this._onMouseMove.bind(this), globalThis.addEventListener("keydown", this._onKeyDown, !1); 20923 } 20924 /** 20925 * Value of `true` if accessibility is currently active and accessibility layers are showing. 20926 * @member {boolean} 20927 * @readonly 20928 */ 20929 get isActive() { 20930 return this._isActive; 20931 } 20932 /** 20933 * Value of `true` if accessibility is enabled for touch devices. 20934 * @member {boolean} 20935 * @readonly 20936 */ 20937 get isMobileAccessibility() { 20938 return this._isMobileAccessibility; 20939 } 20940 /** 20941 * Creates the touch hooks. 20942 * @private 20943 */ 20944 createTouchHook() { 20945 const hookDiv = document.createElement("button"); 20946 hookDiv.style.width = `${DIV_HOOK_SIZE}px`, hookDiv.style.height = `${DIV_HOOK_SIZE}px`, hookDiv.style.position = "absolute", hookDiv.style.top = `${DIV_HOOK_POS_X}px`, hookDiv.style.left = `${DIV_HOOK_POS_Y}px`, hookDiv.style.zIndex = DIV_HOOK_ZINDEX.toString(), hookDiv.style.backgroundColor = "#FF0000", hookDiv.title = "select to enable accessibility for this content", hookDiv.addEventListener("focus", () => { 20947 this._isMobileAccessibility = !0, this.activate(), this.destroyTouchHook(); 20948 }), document.body.appendChild(hookDiv), this._hookDiv = hookDiv; 20949 } 20950 /** 20951 * Destroys the touch hooks. 20952 * @private 20953 */ 20954 destroyTouchHook() { 20955 this._hookDiv && (document.body.removeChild(this._hookDiv), this._hookDiv = null); 20956 } 20957 /** 20958 * Activating will cause the Accessibility layer to be shown. 20959 * This is called when a user presses the tab key. 20960 * @private 20961 */ 20962 activate() { 20963 this._isActive || (this._isActive = !0, globalThis.document.addEventListener("mousemove", this._onMouseMove, !0), globalThis.removeEventListener("keydown", this._onKeyDown, !1), this.renderer.on("postrender", this.update, this), this.renderer.view.parentNode?.appendChild(this.div)); 20964 } 20965 /** 20966 * Deactivating will cause the Accessibility layer to be hidden. 20967 * This is called when a user moves the mouse. 20968 * @private 20969 */ 20970 deactivate() { 20971 !this._isActive || this._isMobileAccessibility || (this._isActive = !1, globalThis.document.removeEventListener("mousemove", this._onMouseMove, !0), globalThis.addEventListener("keydown", this._onKeyDown, !1), this.renderer.off("postrender", this.update), this.div.parentNode?.removeChild(this.div)); 20972 } 20973 /** 20974 * This recursive function will run through the scene graph and add any new accessible objects to the DOM layer. 20975 * @private 20976 * @param {PIXI.Container} displayObject - The DisplayObject to check. 20977 */ 20978 updateAccessibleObjects(displayObject) { 20979 if (!displayObject.visible || !displayObject.accessibleChildren) 20980 return; 20981 displayObject.accessible && displayObject.isInteractive() && (displayObject._accessibleActive || this.addChild(displayObject), displayObject.renderId = this.renderId); 20982 const children = displayObject.children; 20983 if (children) 20984 for (let i = 0; i < children.length; i++) 20985 this.updateAccessibleObjects(children[i]); 20986 } 20987 /** 20988 * Before each render this function will ensure that all divs are mapped correctly to their DisplayObjects. 20989 * @private 20990 */ 20991 update() { 20992 const now = performance.now(); 20993 if (isMobile.android.device && now < this.androidUpdateCount || (this.androidUpdateCount = now + this.androidUpdateFrequency, !this.renderer.renderingToScreen)) 20994 return; 20995 this.renderer.lastObjectRendered && this.updateAccessibleObjects(this.renderer.lastObjectRendered); 20996 const { x, y, width, height } = this.renderer.view.getBoundingClientRect(), { width: viewWidth, height: viewHeight, resolution } = this.renderer, sx = width / viewWidth * resolution, sy = height / viewHeight * resolution; 20997 let div = this.div; 20998 div.style.left = `${x}px`, div.style.top = `${y}px`, div.style.width = `${viewWidth}px`, div.style.height = `${viewHeight}px`; 20999 for (let i = 0; i < this.children.length; i++) { 21000 const child = this.children[i]; 21001 if (child.renderId !== this.renderId) 21002 child._accessibleActive = !1, removeItems(this.children, i, 1), this.div.removeChild(child._accessibleDiv), this.pool.push(child._accessibleDiv), child._accessibleDiv = null, i--; 21003 else { 21004 div = child._accessibleDiv; 21005 let hitArea = child.hitArea; 21006 const wt = child.worldTransform; 21007 child.hitArea ? (div.style.left = `${(wt.tx + hitArea.x * wt.a) * sx}px`, div.style.top = `${(wt.ty + hitArea.y * wt.d) * sy}px`, div.style.width = `${hitArea.width * wt.a * sx}px`, div.style.height = `${hitArea.height * wt.d * sy}px`) : (hitArea = child.getBounds(), this.capHitArea(hitArea), div.style.left = `${hitArea.x * sx}px`, div.style.top = `${hitArea.y * sy}px`, div.style.width = `${hitArea.width * sx}px`, div.style.height = `${hitArea.height * sy}px`, div.title !== child.accessibleTitle && child.accessibleTitle !== null && (div.title = child.accessibleTitle), div.getAttribute("aria-label") !== child.accessibleHint && child.accessibleHint !== null && div.setAttribute("aria-label", child.accessibleHint)), (child.accessibleTitle !== div.title || child.tabIndex !== div.tabIndex) && (div.title = child.accessibleTitle, div.tabIndex = child.tabIndex, this.debug && this.updateDebugHTML(div)); 21008 } 21009 } 21010 this.renderId++; 21011 } 21012 /** 21013 * private function that will visually add the information to the 21014 * accessability div 21015 * @param {HTMLElement} div - 21016 */ 21017 updateDebugHTML(div) { 21018 div.innerHTML = `type: ${div.type}</br> title : ${div.title}</br> tabIndex: ${div.tabIndex}`; 21019 } 21020 /** 21021 * Adjust the hit area based on the bounds of a display object 21022 * @param {PIXI.Rectangle} hitArea - Bounds of the child 21023 */ 21024 capHitArea(hitArea) { 21025 hitArea.x < 0 && (hitArea.width += hitArea.x, hitArea.x = 0), hitArea.y < 0 && (hitArea.height += hitArea.y, hitArea.y = 0); 21026 const { width: viewWidth, height: viewHeight } = this.renderer; 21027 hitArea.x + hitArea.width > viewWidth && (hitArea.width = viewWidth - hitArea.x), hitArea.y + hitArea.height > viewHeight && (hitArea.height = viewHeight - hitArea.y); 21028 } 21029 /** 21030 * Adds a DisplayObject to the accessibility manager 21031 * @private 21032 * @param {PIXI.DisplayObject} displayObject - The child to make accessible. 21033 */ 21034 addChild(displayObject) { 21035 let div = this.pool.pop(); 21036 div || (div = document.createElement("button"), div.style.width = `${DIV_TOUCH_SIZE}px`, div.style.height = `${DIV_TOUCH_SIZE}px`, div.style.backgroundColor = this.debug ? "rgba(255,255,255,0.5)" : "transparent", div.style.position = "absolute", div.style.zIndex = DIV_TOUCH_ZINDEX.toString(), div.style.borderStyle = "none", navigator.userAgent.toLowerCase().includes("chrome") ? div.setAttribute("aria-live", "off") : div.setAttribute("aria-live", "polite"), navigator.userAgent.match(/rv:.*Gecko\//) ? div.setAttribute("aria-relevant", "additions") : div.setAttribute("aria-relevant", "text"), div.addEventListener("click", this._onClick.bind(this)), div.addEventListener("focus", this._onFocus.bind(this)), div.addEventListener("focusout", this._onFocusOut.bind(this))), div.style.pointerEvents = displayObject.accessiblePointerEvents, div.type = displayObject.accessibleType, displayObject.accessibleTitle && displayObject.accessibleTitle !== null ? div.title = displayObject.accessibleTitle : (!displayObject.accessibleHint || displayObject.accessibleHint === null) && (div.title = `displayObject ${displayObject.tabIndex}`), displayObject.accessibleHint && displayObject.accessibleHint !== null && div.setAttribute("aria-label", displayObject.accessibleHint), this.debug && this.updateDebugHTML(div), displayObject._accessibleActive = !0, displayObject._accessibleDiv = div, div.displayObject = displayObject, this.children.push(displayObject), this.div.appen
vendor: 6,618 bytes, lines 21036-21220
21036dChild(displayObject._accessibleDiv), displayObject._accessibleDiv.tabIndex = displayObject.tabIndex; 21037 } 21038 /** 21039 * Dispatch events with the EventSystem. 21040 * @param e 21041 * @param type 21042 * @private 21043 */ 21044 _dispatchEvent(e, type) { 21045 const { displayObject: target } = e.target, boundry = this.renderer.events.rootBoundary, event = Object.assign(new FederatedEvent(boundry), { target }); 21046 boundry.rootTarget = this.renderer.lastObjectRendered, type.forEach((type2) => boundry.dispatchEvent(event, type2)); 21047 } 21048 /** 21049 * Maps the div button press to pixi's EventSystem (click) 21050 * @private 21051 * @param {MouseEvent} e - The click event. 21052 */ 21053 _onClick(e) { 21054 this._dispatchEvent(e, ["click", "pointertap", "tap"]); 21055 } 21056 /** 21057 * Maps the div focus events to pixi's EventSystem (mouseover) 21058 * @private 21059 * @param {FocusEvent} e - The focus event. 21060 */ 21061 _onFocus(e) { 21062 e.target.getAttribute("aria-live") || e.target.setAttribute("aria-live", "assertive"), this._dispatchEvent(e, ["mouseover"]); 21063 } 21064 /** 21065 * Maps the div focus events to pixi's EventSystem (mouseout) 21066 * @private 21067 * @param {FocusEvent} e - The focusout event. 21068 */ 21069 _onFocusOut(e) { 21070 e.target.getAttribute("aria-live") || e.target.setAttribute("aria-live", "polite"), this._dispatchEvent(e, ["mouseout"]); 21071 } 21072 /** 21073 * Is called when a key is pressed 21074 * @private 21075 * @param {KeyboardEvent} e - The keydown event. 21076 */ 21077 _onKeyDown(e) { 21078 e.keyCode === KEY_CODE_TAB && this.activate(); 21079 } 21080 /** 21081 * Is called when the mouse moves across the renderer element 21082 * @private 21083 * @param {MouseEvent} e - The mouse event. 21084 */ 21085 _onMouseMove(e) { 21086 e.movementX === 0 && e.movementY === 0 || this.deactivate(); 21087 } 21088 /** Destroys the accessibility manager */ 21089 destroy() { 21090 this.destroyTouchHook(), this.div = null, globalThis.document.removeEventListener("mousemove", this._onMouseMove, !0), globalThis.removeEventListener("keydown", this._onKeyDown), this.pool = null, this.children = null, this.renderer = null; 21091 } 21092} 21093AccessibilityManager.extension = { 21094 name: "accessibility", 21095 type: [ 21096 ExtensionType.RendererPlugin, 21097 ExtensionType.CanvasRendererPlugin 21098 ] 21099}; 21100extensions$1.add(AccessibilityManager); 21101 21102const _Application = class _Application2 { 21103 /** 21104 * @param options - The optional application and renderer parameters. 21105 */ 21106 constructor(options) { 21107 this.stage = new Container(), options = Object.assign({ 21108 forceCanvas: !1 21109 }, options), this.renderer = autoDetectRenderer(options), _Application2._plugins.forEach((plugin) => { 21110 plugin.init.call(this, options); 21111 }); 21112 } 21113 /** Render the current stage. */ 21114 render() { 21115 this.renderer.render(this.stage); 21116 } 21117 /** 21118 * Reference to the renderer's canvas element. 21119 * @member {PIXI.ICanvas} 21120 * @readonly 21121 */ 21122 get view() { 21123 return this.renderer?.view; 21124 } 21125 /** 21126 * Reference to the renderer's screen rectangle. Its safe to use as `filterArea` or `hitArea` for the whole screen. 21127 * @member {PIXI.Rectangle} 21128 * @readonly 21129 */ 21130 get screen() { 21131 return this.renderer?.screen; 21132 } 21133 /** 21134 * Destroy and don't use after this. 21135 * @param {boolean} [removeView=false] - Automatically remove canvas from DOM. 21136 * @param {object|boolean} [stageOptions] - Options parameter. A boolean will act as if all options 21137 * have been set to that value 21138 * @param {boolean} [stageOptions.children=false] - if set to true, all the children will have their destroy 21139 * method called as well. 'stageOptions' will be passed on to those calls. 21140 * @param {boolean} [stageOptions.texture=false] - Only used for child Sprites if stageOptions.children is set 21141 * to true. Should it destroy the texture of the child sprite 21142 * @param {boolean} [stageOptions.baseTexture=false] - Only used for child Sprites if stageOptions.children is set 21143 * to true. Should it destroy the base texture of the child sprite 21144 */ 21145 destroy(removeView, stageOptions) { 21146 const plugins = _Application2._plugins.slice(0); 21147 plugins.reverse(), plugins.forEach((plugin) => { 21148 plugin.destroy.call(this); 21149 }), this.stage.destroy(stageOptions), this.stage = null, this.renderer.destroy(removeView), this.renderer = null; 21150 } 21151}; 21152_Application._plugins = []; 21153let Application = _Application; 21154extensions$1.handleByList(ExtensionType.Application, Application._plugins); 21155 21156class ResizePlugin { 21157 /** 21158 * Initialize the plugin with scope of application instance 21159 * @static 21160 * @private 21161 * @param {object} [options] - See application options 21162 */ 21163 static init(options) { 21164 Object.defineProperty( 21165 this, 21166 "resizeTo", 21167 /** 21168 * The HTML element or window to automatically resize the 21169 * renderer's view element to match width and height. 21170 * @member {Window|HTMLElement} 21171 * @name resizeTo 21172 * @memberof PIXI.Application# 21173 */ 21174 { 21175 set(dom) { 21176 globalThis.removeEventListener("resize", this.queueResize), this._resizeTo = dom, dom && (globalThis.addEventListener("resize", this.queueResize), this.resize()); 21177 }, 21178 get() { 21179 return this._resizeTo; 21180 } 21181 } 21182 ), this.queueResize = () => { 21183 this._resizeTo && (this.cancelResize(), this._resizeId = requestAnimationFrame(() => this.resize())); 21184 }, this.cancelResize = () => { 21185 this._resizeId && (cancelAnimationFrame(this._resizeId), this._resizeId = null); 21186 }, this.resize = () => { 21187 if (!this._resizeTo) 21188 return; 21189 this.cancelResize(); 21190 let width, height; 21191 if (this._resizeTo === globalThis.window) 21192 width = globalThis.innerWidth, height = globalThis.innerHeight; 21193 else { 21194 const { clientWidth, clientHeight } = this._resizeTo; 21195 width = clientWidth, height = clientHeight; 21196 } 21197 this.renderer.resize(width, height), this.render(); 21198 }, this._resizeId = null, this._resizeTo = null, this.resizeTo = options.resizeTo || null; 21199 } 21200 /** 21201 * Clean up the ticker, scoped to application 21202 * @static 21203 * @private 21204 */ 21205 static destroy() { 21206 globalThis.removeEventListener("resize", this.queueResize), this.cancelResize(), this.cancelResize = null, this.queueResize = null, this.resizeTo = null, this.resize = null; 21207 } 21208} 21209ResizePlugin.extension = ExtensionType.Application; 21210extensions$1.add(ResizePlugin); 21211 21212const assetKeyMap = { 21213 loader: ExtensionType.LoadParser, 21214 resolver: ExtensionType.ResolveParser, 21215 cache: ExtensionType.CacheParser, 21216 detection: ExtensionType.DetectionParser 21217}; 21218extensions$1.handle(ExtensionType.Asset, (extension) => { 21219 const ref = extension.ref; 21220 Object.entries(assetKeyMap).filter(([key]) =>
vendor: 8,934 bytes, lines 21220-21462
21220 !!ref[key]).forEach(([key, type]) => extensions$1.add(Object.assign( 21221 ref[key], 21222 // Allow the function to optionally define it's own 21223 // ExtensionMetadata, the use cases here is priority for LoaderParsers 21224 { extension: ref[key].extension ?? type } 21225 ))); 21226}, (extension) => { 21227 const ref = extension.ref; 21228 Object.keys(assetKeyMap).filter((key) => !!ref[key]).forEach((key) => extensions$1.remove(ref[key])); 21229}); 21230 21231class BackgroundLoader { 21232 /** 21233 * @param loader 21234 * @param verbose - should the loader log to the console 21235 */ 21236 constructor(loader, verbose = !1) { 21237 this._loader = loader, this._assetList = [], this._isLoading = !1, this._maxConcurrent = 1, this.verbose = verbose; 21238 } 21239 /** 21240 * Adds an array of assets to load. 21241 * @param assetUrls - assets to load 21242 */ 21243 add(assetUrls) { 21244 assetUrls.forEach((a) => { 21245 this._assetList.push(a); 21246 }), this.verbose && console.log("[BackgroundLoader] assets: ", this._assetList), this._isActive && !this._isLoading && this._next(); 21247 } 21248 /** 21249 * Loads the next set of assets. Will try to load as many assets as it can at the same time. 21250 * 21251 * The max assets it will try to load at one time will be 4. 21252 */ 21253 async _next() { 21254 if (this._assetList.length && this._isActive) { 21255 this._isLoading = !0; 21256 const toLoad = [], toLoadAmount = Math.min(this._assetList.length, this._maxConcurrent); 21257 for (let i = 0; i < toLoadAmount; i++) 21258 toLoad.push(this._assetList.pop()); 21259 await this._loader.load(toLoad), this._isLoading = !1, this._next(); 21260 } 21261 } 21262 /** 21263 * Activate/Deactivate the loading. If set to true then it will immediately continue to load the next asset. 21264 * @returns whether the class is active 21265 */ 21266 get active() { 21267 return this._isActive; 21268 } 21269 set active(value) { 21270 this._isActive !== value && (this._isActive = value, value && !this._isLoading && this._next()); 21271 } 21272} 21273 21274function checkDataUrl(url, mimes) { 21275 if (Array.isArray(mimes)) { 21276 for (const mime of mimes) 21277 if (url.startsWith(`data:${mime}`)) 21278 return !0; 21279 return !1; 21280 } 21281 return url.startsWith(`data:${mimes}`); 21282} 21283 21284function checkExtension(url, extension) { 21285 const tempURL = url.split("?")[0], ext = path.extname(tempURL).toLowerCase(); 21286 return Array.isArray(extension) ? extension.includes(ext) : ext === extension; 21287} 21288 21289const convertToList = (input, transform, forceTransform = !1) => (Array.isArray(input) || (input = [input]), transform ? input.map((item) => typeof item == "string" || forceTransform ? transform(item) : item) : input); 21290 21291const copySearchParams = (targetUrl, sourceUrl) => { 21292 const searchParams = sourceUrl.split("?")[1]; 21293 return searchParams && (targetUrl += `?${searchParams}`), targetUrl; 21294}; 21295 21296function processX(base, ids, depth, result, tags) { 21297 const id = ids[depth]; 21298 for (let i = 0; i < id.length; i++) { 21299 const value = id[i]; 21300 depth < ids.length - 1 ? processX(base.replace(result[depth], value), ids, depth + 1, result, tags) : tags.push(base.replace(result[depth], value)); 21301 } 21302} 21303function createStringVariations(string) { 21304 const regex = /\{(.*?)\}/g, result = string.match(regex), tags = []; 21305 if (result) { 21306 const ids = []; 21307 result.forEach((vars) => { 21308 const split = vars.substring(1, vars.length - 1).split(","); 21309 ids.push(split); 21310 }), processX(string, ids, 0, result, tags); 21311 } else 21312 tags.push(string); 21313 return tags; 21314} 21315 21316const isSingleItem = (item) => !Array.isArray(item); 21317 21318class CacheClass { 21319 constructor() { 21320 this._parsers = [], this._cache = /* @__PURE__ */ new Map(), this._cacheMap = /* @__PURE__ */ new Map(); 21321 } 21322 /** Clear all entries. */ 21323 reset() { 21324 this._cacheMap.clear(), this._cache.clear(); 21325 } 21326 /** 21327 * Check if the key exists 21328 * @param key - The key to check 21329 */ 21330 has(key) { 21331 return this._cache.has(key); 21332 } 21333 /** 21334 * Fetch entry by key 21335 * @param key - The key of the entry to get 21336 */ 21337 get(key) { 21338 const result = this._cache.get(key); 21339 return result || console.warn(`[Assets] Asset id ${key} was not found in the Cache`), result; 21340 } 21341 /** 21342 * Set a value by key or keys name 21343 * @param key - The key or keys to set 21344 * @param value - The value to store in the cache or from which cacheable assets will be derived. 21345 */ 21346 set(key, value) { 21347 const keys = convertToList(key); 21348 let cacheableAssets; 21349 for (let i = 0; i < this.parsers.length; i++) { 21350 const parser = this.parsers[i]; 21351 if (parser.test(value)) { 21352 cacheableAssets = parser.getCacheableAssets(keys, value); 21353 break; 21354 } 21355 } 21356 cacheableAssets || (cacheableAssets = {}, keys.forEach((key2) => { 21357 cacheableAssets[key2] = value; 21358 })); 21359 const cacheKeys = Object.keys(cacheableAssets), cachedAssets = { 21360 cacheKeys, 21361 keys 21362 }; 21363 if (keys.forEach((key2) => { 21364 this._cacheMap.set(key2, cachedAssets); 21365 }), cacheKeys.forEach((key2) => { 21366 this._cache.has(key2) && this._cache.get(key2) !== value && console.warn("[Cache] already has key:", key2), this._cache.set(key2, cacheableAssets[key2]); 21367 }), value instanceof Texture) { 21368 const texture = value; 21369 keys.forEach((key2) => { 21370 texture.baseTexture !== Texture.EMPTY.baseTexture && BaseTexture.addToCache(texture.baseTexture, key2), Texture.addToCache(texture, key2); 21371 }); 21372 } 21373 } 21374 /** 21375 * Remove entry by key 21376 * 21377 * This function will also remove any associated alias from the cache also. 21378 * @param key - The key of the entry to remove 21379 */ 21380 remove(key) { 21381 if (!this._cacheMap.has(key)) { 21382 console.warn(`[Assets] Asset id ${key} was not found in the Cache`); 21383 return; 21384 } 21385 const cacheMap = this._cacheMap.get(key); 21386 cacheMap.cacheKeys.forEach((key2) => { 21387 this._cache.delete(key2); 21388 }), cacheMap.keys.forEach((key2) => { 21389 this._cacheMap.delete(key2); 21390 }); 21391 } 21392 /** All loader parsers registered */ 21393 get parsers() { 21394 return this._parsers; 21395 } 21396} 21397const Cache = new CacheClass(); 21398 21399class Loader { 21400 constructor() { 21401 this._parsers = [], this._parsersValidated = !1, this.parsers = new Proxy(this._parsers, { 21402 set: (target, key, value) => (this._parsersValidated = !1, target[key] = value, !0) 21403 }), this.promiseCache = {}; 21404 } 21405 /** function used for testing */ 21406 reset() { 21407 this._parsersValidated = !1, this.promiseCache = {}; 21408 } 21409 /** 21410 * Used internally to generate a promise for the asset to be loaded. 21411 * @param url - The URL to be loaded 21412 * @param data - any custom additional information relevant to the asset being loaded 21413 * @returns - a promise that will resolve to an Asset for example a Texture of a JSON object 21414 */ 21415 _getLoadPromiseAndParser(url, data) { 21416 const result = { 21417 promise: null, 21418 parser: null 21419 }; 21420 return result.promise = (async () => { 21421 let asset = null, parser = null; 21422 if (data.loadParser && (parser = this._parserHash[data.loadParser], parser || console.warn(`[Assets] specified load parser "${data.loadParser}" not found while loading ${url}`)), !parser) { 21423 for (let i = 0; i < this.parsers.length; i++) { 21424 const parserX = this.parsers[i]; 21425 if (parserX.load && parserX.test?.(url, data, this)) { 21426 parser = parserX; 21427 break; 21428 } 21429 } 21430 if (!parser) 21431 return console.warn(`[Assets] ${url} could not be loaded as we don't know how to parse it, ensure the correct parser has been added`), null; 21432 } 21433 asset = await parser.load(url, data, this), result.parser = parser; 21434 for (let i = 0; i < this.parsers.length; i++) { 21435 const parser2 = this.parsers[i]; 21436 parser2.parse && parser2.parse && await parser2.testParse?.(asset, data, this) && (asset = await parser2.parse(asset, data, this) || asset, result.parser = parser2); 21437 } 21438 return asset; 21439 })(), result; 21440 } 21441 async load(assetsToLoadIn, onProgress) { 21442 this._parsersValidated || this._validateParsers(); 21443 let count = 0; 21444 const assets = {}, singleAsset = isSingleItem(assetsToLoadIn), assetsToLoad = convertToList(assetsToLoadIn, (item) => ({ 21445 alias: [item], 21446 src: item 21447 })), total = assetsToLoad.length, promises = assetsToLoad.map(async (asset) => { 21448 const url = path.toAbsolute(asset.src); 21449 if (!assets[asset.src]) 21450 try { 21451 this.promiseCache[url] || (this.promiseCache[url] = this._getLoadPromiseAndParser(url, asset)), assets[asset.src] = await this.promiseCache[url].promise, onProgress && onProgress(++count / total); 21452 } catch (e) { 21453 throw delete this.promiseCache[url], delete assets[asset.src], new Error(`[Loader.load] Failed to load ${url}. 21454${e}`); 21455 } 21456 }); 21457 return await Promise.all(promises), singleAsset ? assets[assetsToLoad[0].src] : assets; 21458 } 21459 /** 21460 * Unloads one or more assets. Any unloaded assets will be destroyed, freeing up memory for your app. 21461 * The parser that created the asset, will be the one that unloads it. 21462 * @example
21463 * // Single asset: 21464 * const asset = await Loader.load('cool.png'); 21465 * 21466 * await Loader.unload('cool.png'); 21467 * 21468 * console.log(asset.destroyed); // true 21469 * @param assetsToUnloadIn - urls that you want to unload, or a single one! 21470 */ 21471 async unload(assetsToUnloadIn) { 21472 const promises = convertToList(assetsToUnloadIn, (item) => ({ 21473 alias: [item], 21474 src: item 21475 })).map(async (asset) => { 21476 const url = path.toAbsolute(asset.src), loadPromise = this.promiseCache[url]; 21477 if (loadPromise) { 21478 const loadedAsset = await loadPromise.promise; 21479 delete this.promiseCache[url], loadPromise.parser?.unload?.(loadedAsset, asset, this); 21480 } 21481 }); 21482 await Promise.all(promises); 21483 } 21484 /** validates our parsers, right now it only checks for name conflicts but we can add more here as required! */ 21485 _validateParsers() { 21486 this._parsersValidated = !0, this._parserHash = this._parsers.filter((parser) => parser.name).reduce((hash, parser) => (hash[parser.name] && console.warn(`[Assets] loadParser name conflict "${parser.name}"`), { ...hash, [parser.name]: parser }), {}); 21487 } 21488} 21489 21490var LoaderParserPriority = /* @__PURE__ */ ((LoaderParserPriority2) => (LoaderParserPriority2[LoaderParserPriority2.Low = 0] = "Low", LoaderParserPriority2[LoaderParserPriority2.Normal = 1] = "Normal", LoaderParserPriority2[LoaderParserPriority2.High = 2] = "High", LoaderParserPriority2))(LoaderParserPriority || {}); 21491 21492const validJSONExtension = ".json", validJSONMIME = "application/json", loadJson = { 21493 extension: { 21494 type: ExtensionType.LoadParser, 21495 priority: LoaderParserPriority.Low 21496 }, 21497 name: "loadJson", 21498 test(url) { 21499 return checkDataUrl(url, validJSONMIME) || checkExtension(url, validJSONExtension); 21500 }, 21501 async load(url) { 21502 return await (await settings.ADAPTER.fetch(url)).json(); 21503 } 21504}; 21505extensions$1.add(loadJson); 21506 21507const validTXTExtension = ".txt", validTXTMIME = "text/plain", loadTxt = { 21508 name: "loadTxt", 21509 extension: { 21510 type: ExtensionType.LoadParser, 21511 priority: LoaderParserPriority.Low 21512 }, 21513 test(url) { 21514 return checkDataUrl(url, validTXTMIME) || checkExtension(url, validTXTExtension); 21515 }, 21516 async load(url) { 21517 return await (await settings.ADAPTER.fetch(url)).text(); 21518 } 21519}; 21520extensions$1.add(loadTxt); 21521 21522const validWeights = [ 21523 "normal", 21524 "bold", 21525 "100", 21526 "200", 21527 "300", 21528 "400", 21529 "500", 21530 "600", 21531 "700", 21532 "800", 21533 "900" 21534], validFontExtensions = [".ttf", ".otf", ".woff", ".woff2"], validFontMIMEs = [ 21535 "font/ttf", 21536 "font/otf", 21537 "font/woff", 21538 "font/woff2" 21539], CSS_IDENT_TOKEN_REGEX = /^(--|-?[A-Z_])[0-9A-Z_-]*$/i; 21540function getFontFamilyName(url) { 21541 const ext = path.extname(url), nameTokens = path.basename(url, ext).replace(/(-|_)/g, " ").toLowerCase().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)); 21542 let valid = nameTokens.length > 0; 21543 for (const token of nameTokens) 21544 if (!token.match(CSS_IDENT_TOKEN_REGEX)) { 21545 valid = !1; 21546 break; 21547 } 21548 let fontFamilyName = nameTokens.join(" "); 21549 return valid || (fontFamilyName = `"${fontFamilyName.replace(/[\\"]/g, "\\$&")}"`), fontFamilyName; 21550} 21551const validURICharactersRegex = /^[0-9A-Za-z%:/?#\[\]@!\$&'()\*\+,;=\-._~]*$/; 21552function encodeURIWhenNeeded(uri) { 21553 return validURICharactersRegex.test(uri) ? uri : encodeURI(uri); 21554} 21555const loadWebFont = { 21556 extension: { 21557 type: ExtensionType.LoadParser, 21558 priority: LoaderParserPriority.Low 21559 }, 21560 name: "loadWebFont", 21561 test(url) { 21562 return checkDataUrl(url, validFontMIMEs) || checkExtension(url, validFontExtensions); 21563 }, 21564 async load(url, options) { 21565 const fonts = settings.ADAPTER.getFontFaceSet(); 21566 if (fonts) { 21567 const fontFaces = [], name = options.data?.family ?? getFontFamilyName(url), weights = options.data?.weights?.filter((weight) => validWeights.includes(weight)) ?? ["normal"], data = options.data ?? {}; 21568 for (let i = 0; i < weights.length; i++) { 21569 const weight = weights[i], font = new FontFace(name, `url(${encodeURIWhenNeeded(url)})`, { 21570 ...data, 21571 weight 21572 }); 21573 await font.load(), fonts.add(font), fontFaces.push(font); 21574 } 21575 return fontFaces.length === 1 ? fontFaces[0] : fontFaces; 21576 } 21577 return console.warn("[loadWebFont] FontFace API is not supported. Skipping loading font"), null; 21578 }, 21579 unload(font) {
21580 (Array.isArray(font) ? font : [font]).forEach((t) => settings.ADAPTER.getFontFaceSet().delete(t)); 21581 } 21582}; 21583extensions$1.add(loadWebFont); 21584 21585let UUID = 0, MAX_WORKERS; 21586const WHITE_PNG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=", checkImageBitmapCode = { 21587 id: "checkImageBitmap", 21588 code: ` 21589 async function checkImageBitmap() 21590 { 21591 try 21592 { 21593 if (typeof createImageBitmap !== 'function') return false; 21594 21595 const response = await fetch('${WHITE_PNG}'); 21596 const imageBlob = await response.blob(); 21597 const imageBitmap = await createImageBitmap(imageBlob); 21598 21599 return imageBitmap.width === 1 && imageBitmap.height === 1; 21600 } 21601 catch (e) 21602 { 21603 return false; 21604 } 21605 } 21606 checkImageBitmap().then((result) => { self.postMessage(result); }); 21607 ` 21608}, workerCode = { 21609 id: "loadImageBitmap", 21610 code: ` 21611 async function loadImageBitmap(url) 21612 { 21613 const response = await fetch(url); 21614 21615 if (!response.ok) 21616 { 21617 throw new Error(\`[WorkerManager.loadImageBitmap] Failed to fetch \${url}: \` 21618 + \`\${response.status} \${response.statusText}\`); 21619 } 21620 21621 const imageBlob = await response.blob(); 21622 const imageBitmap = await createImageBitmap(imageBlob); 21623 21624 return imageBitmap; 21625 } 21626 self.onmessage = async (event) => 21627 { 21628 try 21629 { 21630 const imageBitmap = await loadImageBitmap(event.data.data[0]); 21631 21632 self.postMessage({ 21633 data: imageBitmap, 21634 uuid: event.data.uuid, 21635 id: event.data.id, 21636 }, [imageBitmap]); 21637 } 21638 catch(e) 21639 { 21640 self.postMessage({ 21641 error: e, 21642 uuid: event.data.uuid, 21643 id: event.data.id, 21644 }); 21645 } 21646 };` 21647}; 21648let workerURL; 21649class WorkerManagerClass { 21650 constructor() { 21651 this._initialized = !1, this._createdWorkers = 0, this.workerPool = [], this.queue = [], this.resolveHash = {}; 21652 } 21653 isImageBitmapSupported() { 21654 return this._isImageBitmapSupported !== void 0 ? this._isImageBitmapSupported : (this._isImageBitmapSupported = new Promise((resolve) => { 21655 const workerURL2 = URL.createObjectURL(new Blob( 21656 [checkImageBitmapCode.code], 21657 { type: "application/javascript" } 21658 )), worker = new Worker(workerURL2); 21659 worker.addEventListener("message", (event) => { 21660 worker.terminate(), URL.revokeObjectURL(workerURL2), resolve(event.data); 21661 }); 21662 }), this._isImageBitmapSupported); 21663 } 21664 loadImageBitmap(src) { 21665 return this._run("loadImageBitmap", [src]); 21666 } 21667 async _initWorkers() { 21668 this._initialized || (this._initialized = !0); 21669 } 21670 getWorker() { 21671 MAX_WORKERS === void 0 && (MAX_WORKERS = navigator.hardwareConcurrency || 4); 21672 let worker = this.workerPool.pop(); 21673 return !worker && this._createdWorkers < MAX_WORKERS && (workerURL || (workerURL = URL.createObjectURL(new Blob([workerCode.code], { type: "application/javascript" }))), this._createdWorkers++, worker = new Worker(workerURL), worker.addEventListener("message", (event) => { 21674 this.complete(event.data), this.returnWorker(event.target), this.next(); 21675 })), worker; 21676 } 21677 returnWorker(worker) { 21678 this.workerPool.push(worker); 21679 } 21680 complete(data) { 21681 data.error !== void 0 ? this.resolveHash[data.uuid].reject(data.error) : this.resolveHash[data.uuid].resolve(data.data), this.resolveHash[data.uuid] = null; 21682 } 21683 async _run(id, args) { 21684 await this._initWorkers(); 21685 const promise = new Promise((resolve, reject) => { 21686 this.queue.push({ id, arguments: args, resolve, reject }); 21687 }); 21688 return this.next(), promise; 21689 } 21690 next() { 21691 if (!this.queue.length) 21692 return; 21693 const worker = this.getWorker(); 21694 if (!worker) 21695 return; 21696 const toDo = this.queue.pop(), id = toDo.id; 21697 this.resolveHash[UUID] = { resolve: toDo.resolve, reject: toDo.reject }, worker.postMessage({ 21698 data: toDo.arguments, 21699 uuid: UUID++, 21700 id 21701 }); 21702 } 21703} 21704const WorkerManager = new WorkerManagerClass(); 21705 21706function createTexture(base, loader, url) { 21707 base.resource.internal = !0; 21708 const texture = new Texture(base), unload = () => { 21709 delete loader.promiseCache[url], Cache.has(url) && Cache.remove(url); 21710 }; 21711 return texture.baseTexture.once("destroyed", () => { 21712 url in loader.promiseCache && (console.warn("[Assets] A BaseTexture managed by Assets was destroyed instead of unloaded! Use Assets.unload() instead of destroying the BaseTexture."), unload()); 21713 }), texture.once("destroyed", () => { 21714 base.destroyed || (console.warn("[Assets] A Texture managed by Assets was destroyed instead of unloaded! Use Assets.unload() instead of destroying the Texture."), unload()); 21715 }), texture; 21716} 21717 21718const validImageExtensions = [".jpeg", ".jpg", ".png", ".webp", ".avif"], val
21718idImageMIMEs = [ 21719 "image/jpeg", 21720 "image/png", 21721 "image/webp", 21722 "image/avif" 21723]; 21724async function loadImageBitmap(url) { 21725 const response = await settings.ADAPTER.fetch(url); 21726 if (!response.ok) 21727 throw new Error(`[loadImageBitmap] Failed to fetch ${url}: ${response.status} ${response.statusText}`); 21728 const imageBlob = await response.blob(); 21729 return await createImageBitmap(imageBlob); 21730} 21731const loadTextures = { 21732 name: "loadTextures", 21733 extension: { 21734 type: ExtensionType.LoadParser, 21735 priority: LoaderParserPriority.High 21736 }, 21737 config: { 21738 preferWorkers: !0, 21739 preferCreateImageBitmap: !0, 21740 crossOrigin: "anonymous" 21741 }, 21742 test(url) { 21743 return checkDataUrl(url, validImageMIMEs) || checkExtension(url, validImageExtensions); 21744 }, 21745 async load(url, asset, loader) { 21746 const useImageBitmap = globalThis.createImageBitmap && this.config.preferCreateImageBitmap; 21747 let src; 21748 useImageBitmap ? this.config.preferWorkers && await WorkerManager.isImageBitmapSupported() ? src = await WorkerManager.loadImageBitmap(url) : src = await loadImageBitmap(url) : src = await new Promise((resolve, reject) => { 21749 const src2 = new Image(); 21750 src2.crossOrigin = this.config.crossOrigin, src2.src = url, src2.complete ? resolve(src2) : (src2.onload = () => resolve(src2), src2.onerror = (e) => reject(e)); 21751 }); 21752 const options = { ...asset.data }; 21753 options.resolution ?? (options.resolution = getResolutionOfUrl(url)), useImageBitmap && options.resourceOptions?.ownsImageBitmap === void 0 && (options.resourceOptions = { ...options.resourceOptions }, options.resourceOptions.ownsImageBitmap = !0); 21754 const base = new BaseTexture(src, options); 21755 return base.resource.src = url, createTexture(base, loader, url); 21756 }, 21757 unload(texture) { 21758 texture.destroy(!0); 21759 } 21760}; 21761extensions$1.add(loadTextures); 21762 21763const validSVGExtension = ".svg", validSVGMIME = "image/svg+xml", loadSVG = { 21764 extension: { 21765 type: ExtensionType.LoadParser, 21766 priority: LoaderParserPriority.High 21767 }, 21768 name: "loadSVG", 21769 test(url) { 21770 return checkDataUrl(url, validSVGMIME) || checkExtension(url, validSVGExtension); 21771 }, 21772 async testParse(data) { 21773 return SVGResource.test(data); 21774 }, 21775 async parse(asset, data, loader) { 21776 const src = new SVGResource(asset, data?.data?.resourceOptions); 21777 await src.load(); 21778 const base = new BaseTexture(src, { 21779 resolution: getResolutionOfUrl(asset), 21780 ...data?.data 21781 }); 21782 return base.resource.src = data.src, createTexture(base, loader, data.src); 21783 }, 21784 async load(url, _options) { 21785 return (await settings.ADAPTER.fetch(url)).text(); 21786 }, 21787 unload: loadTextures.unload 21788}; 21789extensions$1.add(loadSVG); 21790 21791const validVideoExtensions = [".mp4", ".m4v", ".webm", ".ogv"], validVideoMIMEs = [ 21792 "video/mp4", 21793 "video/webm", 21794 "video/ogg" 21795], loadVideo = { 21796 name: "loadVideo", 21797 extension: { 21798 type: ExtensionType.LoadParser, 21799 priority: LoaderParserPriority.High 21800 }, 21801 config: { 21802 defaultAutoPlay: !0 21803 }, 21804 test(url) { 21805 return checkDataUrl(url, validVideoMIMEs) || checkExtension(url, validVideoExtensions); 21806 }, 21807 async load(url, loadAsset, loader) { 21808 let texture; 21809 const blob = await (await settings.ADAPTER.fetch(url)).blob(), blobURL = URL.createObjectURL(blob); 21810 try { 21811 const options = { 21812 autoPlay: this.config.defaultAutoPlay, 21813 ...loadAsset?.data?.resourceOptions 21814 }, src = new VideoResource(blobURL, options); 21815 await src.load(); 21816 const base = new BaseTexture(src, { 21817 alphaMode: await detectVideoAlphaMode(), 21818 resolution: getResolutionOfUrl(url), 21819 ...loadAsset?.data 21820 }); 21821 base.resource.src = url, texture = createTexture(base, loader, url), texture.baseTexture.once("destroyed", () => { 21822 URL.revokeObjectURL(blobURL); 21823 }); 21824 } catch (e) { 21825 throw URL.revokeObjectURL(blobURL), e; 21826 } 21827 return texture; 21828 }, 21829 unload(texture) { 21830 texture.destroy(!0); 21831 } 21832}; 21833extensions$1.add(loadVideo); 21834 21835class Resolver { 21836 constructor() { 21837 this._defaultBundleIdentifierOptions = { 21838 connector: "-", 21839 createBundleAssetId: (bundleId, assetId) => `${bundleId}${this._bundleIdConnector}${assetId}`, 21840 extractAssetIdFromBundle: (bundleId, assetBundleId) => assetBundleId.replace(`${bundleId}${this._bundleIdConnector}`, "") 21841 }, this._bundleIdConnector = this._defaultBundleIdentifierOptions.connector, this._createBundleAssetId = this._defaultBundleIdentifierOptions.createBundleAssetId, this._extractAssetIdFromBundle = this._defaultBundleIdentifierOptions.extractAssetIdFromBundle, this._assetMap = {}, this._preferredOrder = [], this._parsers = [], this._resolverHash = {}, this._bundles = {}; 21842 } 21843 /** 21844 * Override how the resolver deals with generating bundle ids. 21845 * must be called before any bundles are added 21846 * @param bundleIdentifier - the bundle identifier options 21847 */ 21848 setBundleIdentifier(bundleIdentifier) { 21849 if (this._bundleIdConnector = bundleIdentifier.connector ?? this._bundleIdConnector, this._createBundleAssetId = bundleIdentifier.createBundleAssetId ?? this._createBundleAssetId, this._extractAssetIdFromBundle = bundleIdentifier.extractAssetIdFromBundle ?? this._extractAssetIdFromBundle, this._extractAssetIdFromBundle("foo", this._createBundleAssetId("foo", "bar")) !== "bar") 21850 throw new Error("[Resolver] GenerateBundleAssetId are not working correctly"); 21851 } 21852 /** 21853 * Let the resolver know which assets you prefer to use when resolving assets. 21854 * Multiple prefer user defined rules can be added. 21855 * @example 21856 * resolver.prefer({ 21857 * // first look for something with the correct format, and then then correct resolution 21858 * priority: ['format', 'resolution'], 21859 * params:{ 21860 * format:'webp', // prefer webp images 21861 * resolution: 2, // prefer a resolution of 2 21862 * } 21863 * }) 21864 * resolver.add('foo', ['[email protected]', '[email protected]', 'bar.webp', 'bar.png']); 21865 * resolver.resolveUrl('foo') // => '[email protected]' 21866 * @param preferOrders - the prefer options 21867 */ 21868 prefer(...preferOrders) {
21869 preferOrders.forEach((prefer) => { 21870 this._preferredOrder.push(prefer), prefer.priority || (prefer.priority = Object.keys(prefer.params)); 21871 }), this._resolverHash = {}; 21872 } 21873 /** 21874 * Set the base path to prepend to all urls when resolving 21875 * @example 21876 * resolver.basePath = 'https://home.com/'; 21877 * resolver.add('foo', 'bar.ong'); 21878 * resolver.resolveUrl('foo', 'bar.png'); // => 'https://home.com/bar.png' 21879 * @param basePath - the base path to use 21880 */ 21881 set basePath(basePath) { 21882 this._basePath = basePath; 21883 } 21884 get basePath() { 21885 return this._basePath; 21886 } 21887 /** 21888 * Set the root path for root-relative URLs. By default the `basePath`'s root is used. If no `basePath` is set, then the 21889 * default value for browsers is `window.location.origin` 21890 * @example 21891 * // Application hosted on https://home.com/some-path/index.html 21892 * resolver.basePath = 'https://home.com/some-path/'; 21893 * resolver.rootPath = 'https://home.com/'; 21894 * resolver.add('foo', '/bar.png'); 21895 * resolver.resolveUrl('foo', '/bar.png'); // => 'https://home.com/bar.png' 21896 * @param rootPath - the root path to use 21897 */ 21898 set rootPath(rootPath) { 21899 this._rootPath = rootPath; 21900 } 21901 get rootPath() { 21902 return this._rootPath; 21903 } 21904 /** 21905 * All the active URL parsers that help the parser to extract information and create 21906 * an asset object-based on parsing the URL itself. 21907 * 21908 * Can be added using the extensions API 21909 * @example 21910 * resolver.add('foo', [ 21911 * { 21912 * resolution: 2, 21913 * format: 'png', 21914 * src: '[email protected]', 21915 * }, 21916 * { 21917 * resolution:1, 21918 * format:'png', 21919 * src: 'image.png', 21920 * }, 21921 * ]); 21922 * 21923 * // With a url parser the information such as resolution and file format could extracted from the url itself: 21924 * extensions.add({ 21925 * extension: ExtensionType.ResolveParser, 21926 * test: loadTextures.test, // test if url ends in an image 21927 * parse: (value: string) => 21928 * ({ 21929 * resolution: parseFloat(settings.RETINA_PREFIX.exec(value)?.[1] ?? '1'), 21930 * format: value.split('.').pop(), 21931 * src: value, 21932 * }), 21933 * }); 21934 * 21935 * // Now resolution and format can be extracted from the url 21936 * resolver.add('foo', [ 21937 * '[email protected]', 21938 * 'image.png', 21939 * ]); 21940 */ 21941 get parsers() { 21942 return this._parsers; 21943 } 21944 /** Used for testing, this resets the resolver to its initial state */ 21945 reset() { 21946 this.setBundleIdentifier(this._defaultBundleIdentifierOptions), this._assetMap = {}, this._preferredOrder = [], this._resolverHash = {}, this._rootPath = null, this._basePath = null, this._manifest = null, this._bundles = {}, this._defaultSearchParams = null; 21947 } 21948 /** 21949 * Sets the default URL search parameters for the URL resolver. The urls can be specified as a string or an object. 21950 * @param searchParams - the default url parameters to append when resolving urls 21951 */ 21952 setDefaultSearchParams(searchParams) { 21953 if (typeof searchParams == "string") 21954 this._defaultSearchParams = searchParams; 21955 else { 21956 const queryValues = searchParams; 21957 this._defaultSearchParams = Object.keys(queryValues).map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryValues[key])}`).join("&"); 21958 } 21959 } 21960 /** 21961 * Returns the aliases for a given asset 21962 * @param asset - the asset to get the aliases for 21963 */ 21964 getAlias(asset) { 21965 const { alias, name, src, srcs } = asset; 21966 return convertToList( 21967 alias || name || src || srcs, 21968 (value) => typeof value == "string" ? value : Array.isArray(value) ? value.map((v) => v?.src ?? v?.srcs ?? v) : value?.src || value?.srcs ? value.src ?? value.srcs : value, 21969 !0 21970 ); 21971 } 21972 /** 21973 * Add a manifest to the asset resolver. This is a nice way to add all the asset information in one go. 21974 * generally a manifest would be built using a tool. 21975 * @param manifest - the manifest to add to the resolver 21976 */ 21977 addManifest(manifest) { 21978 this._manifest && console.warn("[Resolver] Manifest already exists, this will be overwritten"), this._manifest = manifest, manifest.bundles.forEac
21978h((bundle) => { 21979 this.addBundle(bundle.name, bundle.assets); 21980 }); 21981 } 21982 /** 21983 * This adds a bundle of assets in one go so that you can resolve them as a group. 21984 * For example you could add a bundle for each screen in you pixi app 21985 * @example 21986 * resolver.addBundle('animals', { 21987 * bunny: 'bunny.png', 21988 * chicken: 'chicken.png', 21989 * thumper: 'thumper.png', 21990 * }); 21991 * 21992 * const resolvedAssets = await resolver.resolveBundle('animals'); 21993 * @param bundleId - The id of the bundle to add 21994 * @param assets - A record of the asset or assets that will be chosen from when loading via the specified key 21995 */ 21996 addBundle(bundleId, assets) { 21997 const assetNames = []; 21998 Array.isArray(assets) ? assets.forEach((asset) => { 21999 const srcs = asset.src ?? asset.srcs, aliases = asset.alias ?? asset.name; 22000 let ids; 22001 if (typeof aliases == "string") { 22002 const bundleAssetId = this._createBundleAssetId(bundleId, aliases); 22003 assetNames.push(bundleAssetId), ids = [aliases, bundleAssetId]; 22004 } else { 22005 const bundleIds = aliases.map((name) => this._createBundleAssetId(bundleId, name)); 22006 assetNames.push(...bundleIds), ids = [...aliases, ...bundleIds]; 22007 } 22008 this.add({ 22009 ...asset, 22010 alias: ids, 22011 src: srcs 22012 }); 22013 }) : Object.keys(assets).forEach((key) => { 22014 const aliases = [key, this._createBundleAssetId(bundleId, key)]; 22015 if (typeof assets[key] == "string") 22016 this.add({ 22017 alias: aliases, 22018 src: assets[key] 22019 }); 22020 else if (Array.isArray(assets[key])) 22021 this.add({ 22022 alias: aliases, 22023 src: assets[key] 22024 }); 22025 else { 22026 const asset = assets[key], assetSrc = asset.src ?? asset.srcs; 22027 this.add({ 22028 ...asset, 22029 alias: aliases, 22030 src: Array.isArray(assetSrc) ? assetSrc : [assetSrc] 22031 }); 22032 } 22033 assetNames.push(...aliases); 22034 }), this._bundles[bundleId] = assetNames; 22035 } 22036 add(aliases, srcs, data, format, loadParser) { 22037 const assets = []; 22038 typeof aliases == "string" || Array.isArray(aliases) && typeof aliases[0] == "string" ? (deprecation("7.2.0", `Assets.add now uses an object instead of individual parameters. 22039Please use Assets.add({ alias, src, data, format, loadParser }) instead.`), assets.push({ alias: aliases, src: srcs, data, format, loadParser })) : Array.isArray(aliases) ? assets.push(...aliases) : assets.push(aliases); 22040 let keyCheck; 22041 keyCheck = (key) => { 22042 this.hasKey(key) && console.warn(`[Resolver] already has key: ${key} overwriting`); 22043 }, convertToList(assets).forEach((asset) => { 22044 const { src, srcs: srcs2 } = asset; 22045 let { data: data2, format: format2, loadParser: loadParser2 } = asset; 22046 const srcsToUse = convertToList(src || srcs2).map((src2) => typeof src2 == "string" ? createStringVariations(src2) : Array.isArray(src2) ? src2 : [src2]), aliasesToUse = this.getAlias(asset); 22047 Array.isArray(aliasesToUse) ? aliasesToUse.forEach(keyCheck) : keyCheck(aliasesToUse); 22048 const resolvedAssets = []; 22049 srcsToUse.forEach((srcs3) => { 22050 srcs3.forEach((src2) => { 22051 let formattedAsset = {}; 22052 if (typeof src2 != "object") { 22053 formattedAsset.src = src2; 22054 for (let i = 0; i < this._parsers.length; i++) { 22055 const parser = this._parsers[i]; 22056 if (parser.test(src2)) { 22057 formattedAsset = parser.parse(src2); 22058 break; 22059 } 22060 } 22061 } else 22062 data2 = src2.data ?? data2, format2 = src2.format ?? format2, loadParser2 = src2.loadParser ?? loadParser2, formattedAsset = { 22063 ...formattedAsset, 22064 ...src2 22065 }; 22066 if (!aliasesToUse) 22067 throw new Error(`[Resolver] alias is undefined for this asset: ${formattedAsset.src}`); 22068 formattedAsset = this.buildResolvedAsset(formattedAsset, { 22069 aliases: aliasesToUse, 22070 data: data2, 22071 format: format2, 22072 loadParser: loadParser2 22073 }), resolvedAssets.push(formattedAsset); 22074 }); 22075 }), aliasesToUse.forEach((alias) => { 22076 this._assetMap[alias] = resolvedAssets; 22077 }); 22078 }); 22079 } 22080 // TODO: this needs an overload like load did in Assets 22081 /** 22082 * If the resolver has had a manifest set via setManifest, this will return the assets urls for 22083 * a given bundleId or bundleIds. 22084 * @example 22085 * // Manifest Example 22086 * const manifest = { 22087 * bundles: [ 22088 * { 22089 * name: 'load-screen', 22090 * assets: [ 22091 * { 22092 * alias: 'background', 22093 * src: 'sunset.png', 22094 * }, 22095 * { 22096 * alias: 'bar', 22097 * src: 'load-bar.{png,webp}', 22098 * }, 22099 * ], 22100 * }, 22101 * { 22102 * name: 'game-screen', 22103 * assets: [ 22104 * { 22105 * alias: 'character', 22106 * src: 'robot.png', 22107 * }, 22108 * { 22109 * alias: 'enemy', 22110 * src: 'bad-guy.png', 22111 * }, 22112 * ], 22113 * }, 22114 * ] 22115 * }; 22116 * 22117 * resolver.setManifest(manifest); 22118 * const resolved = resolver.resolveBundle('load-screen'); 22119 * @param bundleIds - The bundle ids to resolve 22120 * @returns All the bundles assets or a hash of assets for each bundle specified 22121 */ 22122 resolveBundle(bundleIds) { 22123 const singleAsset = isSingleItem(bundleIds); 22124 bundleIds = convertToList(bundleIds); 22125 const out = {}; 22126 return bundleIds.forEach((bundleId) => { 22127 const assetNames = this._bundles[bundleId];
22128 if (assetNames) { 22129 const results = this.resolve(assetNames), assets = {}; 22130 for (const key in results) { 22131 const asset = results[key]; 22132 assets[this._extractAssetIdFromBundle(bundleId, key)] = asset; 22133 } 22134 out[bundleId] = assets; 22135 } 22136 }), singleAsset ? out[bundleIds[0]] : out; 22137 } 22138 /** 22139 * Does exactly what resolve does, but returns just the URL rather than the whole asset object 22140 * @param key - The key or keys to resolve 22141 * @returns - The URLs associated with the key(s) 22142 */ 22143 resolveUrl(key) { 22144 const result = this.resolve(key); 22145 if (typeof key != "string") { 22146 const out = {}; 22147 for (const i in result) 22148 out[i] = result[i].src; 22149 return out; 22150 } 22151 return result.src; 22152 } 22153 resolve(keys) { 22154 const singleAsset = isSingleItem(keys); 22155 keys = convertToList(keys); 22156 const result = {}; 22157 return keys.forEach((key) => { 22158 if (!this._resolverHash[key]) 22159 if (this._assetMap[key]) { 22160 let assets = this._assetMap[key]; 22161 const bestAsset = assets[0], preferredOrder = this._getPreferredOrder(assets); 22162 preferredOrder?.priority.forEach((priorityKey) => { 22163 preferredOrder.params[priorityKey].forEach((value) => { 22164 const filteredAssets = assets.filter((asset) => asset[priorityKey] ? asset[priorityKey] === value : !1); 22165 filteredAssets.length && (assets = filteredAssets); 22166 }); 22167 }), this._resolverHash[key] = assets[0] ?? bestAsset; 22168 } else 22169 this._resolverHash[key] = this.buildResolvedAsset({ 22170 alias: [key], 22171 src: key 22172 }, {}); 22173 result[key] = this._resolverHash[key]; 22174 }), singleAsset ? result[keys[0]] : result; 22175 } 22176 /** 22177 * Checks if an asset with a given key exists in the resolver 22178 * @param key - The key of the asset 22179 */ 22180 hasKey(key) { 22181 return !!this._assetMap[key]; 22182 } 22183 /** 22184 * Checks if a bundle with the given key exists in the resolver 22185 * @param key - The key of the bundle 22186 */ 22187 hasBundle(key) { 22188 return !!this._bundles[key]; 22189 } 22190 /** 22191 * Internal function for figuring out what prefer criteria an asset should use. 22192 * @param assets 22193 */ 22194 _getPreferredOrder(assets) { 22195 for (let i = 0; i < assets.length; i++) { 22196 const asset = assets[0], preferred = this._preferredOrder.find((preference) => preference.params.format.includes(asset.format)); 22197 if (preferred) 22198 return preferred; 22199 } 22200 return this._preferredOrder[0]; 22201 } 22202 /** 22203 * Appends the default url parameters to the url 22204 * @param url - The url to append the default parameters to 22205 * @returns - The url with the default parameters appended 22206 */ 22207 _appendDefaultSearchParams(url) { 22208 if (!this._defaultSearchParams) 22209 return url; 22210 const paramConnector = /\?/.test(url) ? "&" : "?"; 22211 return `${url}${paramConnector}${this._defaultSearchParams}`; 22212 } 22213 buildResolvedAsset(formattedAsset, data) { 22214 const { aliases, data: assetData, loadParser, format } = data; 22215 return (this._basePath || this._rootPath) && (formattedAsset.src = path.toAbsolute(formattedAsset.src, this._basePath, this._rootPath)), formattedAsset.alias = aliases ?? formattedAsset.alias ?? [formattedAsset.src], formattedAsset.src = this._appendDefaultSearchParams(formattedAsset.src), formattedAsset.data = { ...assetData || {}, ...formattedAsset.data }, formattedAsset.loadParser = loadParser ?? formattedAsset.loadParser, formattedAsset.format = format ?? path.extname(formattedAsset.src).slice(1), formattedAsset.srcs = formattedAsset.src, formattedAsset.name = formattedAsset.alias, formattedAsset; 22216 } 22217} 22218 22219class AssetsClass { 22220 constructor() { 22221 this._detections = [], this._initialized = !1, this.resolver = new Resolver(), this.loader = new Loader(), this.cache = Cache, this._backgroundLoader = new BackgroundLoader(this.loader), this._backgroundLoader.active = !0, this.reset(); 22222 } 22223 /** 22224 * Best practice is to call this function before any loading commences 22225 * Initiating is the best time to add any customization to the way things are loaded. 22226 * 22227 * you do not need to call this for the Asset class to work, only if you want to set any initial properties 22228 * @param options - options to initialize the Asset manager with 22229 */
22230 async init(options = {}) { 22231 if (this._initialized) { 22232 console.warn("[Assets]AssetManager already initialized, did you load before calling this Asset.init()?"); 22233 return; 22234 } 22235 if (this._initialized = !0, options.defaultSearchParams && this.resolver.setDefaultSearchParams(options.defaultSearchParams), options.basePath && (this.resolver.basePath = options.basePath), options.bundleIdentifier && this.resolver.setBundleIdentifier(options.bundleIdentifier), options.manifest) { 22236 let manifest = options.manifest; 22237 typeof manifest == "string" && (manifest = await this.load(manifest)), this.resolver.addManifest(manifest); 22238 } 22239 const resolutionPref = options.texturePreference?.resolution ?? 1, resolution = typeof resolutionPref == "number" ? [resolutionPref] : resolutionPref, formats = await this._detectFormats({ 22240 preferredFormats: options.texturePreference?.format, 22241 skipDetections: options.skipDetections, 22242 detections: this._detections 22243 }); 22244 this.resolver.prefer({ 22245 params: { 22246 format: formats, 22247 resolution 22248 } 22249 }), options.preferences && this.setPreferences(options.preferences); 22250 } 22251 add(aliases, srcs, data, format, loadParser) { 22252 this.resolver.add(aliases, srcs, data, format, loadParser); 22253 } 22254 async load(urls, onProgress) { 22255 this._initialized || await this.init(); 22256 const singleAsset = isSingleItem(urls), urlArray = convertToList(urls).map((url) => { 22257 if (typeof url != "string") { 22258 const aliases = this.resolver.getAlias(url); 22259 return aliases.some((alias) => !this.resolver.hasKey(alias)) && this.add(url), Array.isArray(aliases) ? aliases[0] : aliases; 22260 } 22261 return this.resolver.hasKey(url) || this.add({ alias: url, src: url }), url; 22262 }), resolveResults = this.resolver.resolve(urlArray), out = await this._mapLoadToResolve(resolveResults, onProgress); 22263 return singleAsset ? out[urlArray[0]] : out; 22264 } 22265 /** 22266 * This adds a bundle of assets in one go so that you can load them as a group. 22267 * For example you could add a bundle for each screen in you pixi app 22268 * @example 22269 * import { Assets } from 'pixi.js'; 22270 * 22271 * Assets.addBundle('animals', { 22272 * bunny: 'bunny.png', 22273 * chicken: 'chicken.png', 22274 * thumper: 'thumper.png', 22275 * }); 22276 * 22277 * const assets = await Assets.loadBundle('animals'); 22278 * @param bundleId - the id of the bundle to add 22279 * @param assets - a record of the asset or assets that will be chosen from when loading via the specified key 22280 */ 22281 addBundle(bundleId, assets) { 22282 this.resolver.addBundle(bundleId, assets); 22283 } 22284 /** 22285 * Bundles are a way to load multiple assets at once. 22286 * If a manifest has been provided to the init function then you can load a bundle, or bundles. 22287 * you can also add bundles via `addBundle` 22288 * @example 22289 * import { Assets } from 'pixi.js'; 22290 * 22291 * // Manifest Example 22292 * const manifest = { 22293 * bundles: [ 22294 * { 22295 * name: 'load-screen', 22296 * assets: [ 22297 * { 22298 * alias: 'background', 22299 * src: 'sunset.png', 22300 * }, 22301 * { 22302 * alias: 'bar', 22303 * src: 'load-bar.{png,webp}', 22304 * }, 22305 * ], 22306 * }, 22307 * { 22308 * name: 'game-screen', 22309 * assets: [ 22310 * { 22311 * alias: 'character', 22312 * src: 'robot.png', 22313 * }, 22314 * { 22315 * alias: 'enemy', 22316 * src: 'bad-guy.png', 22317 * }, 22318 * ], 22319 * }, 22320 * ] 22321 * }; 22322 * 22323 * await Asset.init({ manifest }); 22324 * 22325 * // Load a bundle... 22326 * loadScreenAssets = await Assets.loadBundle('load-screen'); 22327 * // Load another bundle... 22328 * gameScreenAssets = await Assets.loadBundle('game-screen'); 22329 * @param bundleIds - the bundle id or ids to load 22330 * @param onProgress - Optional function that is called when progress on asset loading is made. 22331 * The function is passed a single parameter, `progress`, which represents the percentage (0.0 - 1.0) 22332 * of the assets loaded. Do not use this function to detect when assets are complete and available, 22333 * instead use the Promise returned by this function. 22334 * @returns all the bundles assets or a hash of assets for each bundle specified 22335 */ 22336 async loadBundle(bundleIds, onProgress) { 22337 this._initialized || await this.init(); 22338 let singleAsset = !1; 22339 typeof bundleIds == "string" && (singleAsset = !0, bundleIds = [bundleIds]
22339); 22340 const resolveResults = this.resolver.resolveBundle(bundleIds), out = {}, keys = Object.keys(resolveResults); 22341 let count = 0, total = 0; 22342 const _onProgress = () => { 22343 onProgress?.(++count / total); 22344 }, promises = keys.map((bundleId) => { 22345 const resolveResult = resolveResults[bundleId]; 22346 return total += Object.keys(resolveResult).length, this._mapLoadToResolve(resolveResult, _onProgress).then((resolveResult2) => { 22347 out[bundleId] = resolveResult2; 22348 }); 22349 }); 22350 return await Promise.all(promises), singleAsset ? out[bundleIds[0]] : out; 22351 } 22352 /** 22353 * Initiate a background load of some assets. It will passively begin to load these assets in the background. 22354 * So when you actually come to loading them you will get a promise that resolves to the loaded assets immediately 22355 * 22356 * An example of this might be that you would background load game assets after your inital load. 22357 * then when you got to actually load your game screen assets when a player goes to the game - the loading 22358 * would already have stared or may even be complete, saving you having to show an interim load bar. 22359 * @example 22360 * import { Assets } from 'pixi.js'; 22361 * 22362 * Assets.backgroundLoad('bunny.png'); 22363 * 22364 * // later on in your app... 22365 * await Assets.loadBundle('bunny.png'); // Will resolve quicker as loading may have completed! 22366 * @param urls - the url / urls you want to background load 22367 */ 22368 async backgroundLoad(urls) { 22369 this._initialized || await this.init(), typeof urls == "string" && (urls = [urls]); 22370 const resolveResults = this.resolver.resolve(urls); 22371 this._backgroundLoader.add(Object.values(resolveResults)); 22372 } 22373 /** 22374 * Initiate a background of a bundle, works exactly like backgroundLoad but for bundles. 22375 * this can only be used if the loader has been initiated with a manifest 22376 * @example 22377 * import { Assets } from 'pixi.js'; 22378 * 22379 * await Assets.init({ 22380 * manifest: { 22381 * bundles: [ 22382 * { 22383 * name: 'load-screen', 22384 * assets: [...], 22385 * }, 22386 * ... 22387 * ], 22388 * }, 22389 * }); 22390 * 22391 * Assets.backgroundLoadBundle('load-screen'); 22392 * 22393 * // Later on in your app... 22394 * await Assets.loadBundle('load-screen'); // Will resolve quicker as loading may have completed! 22395 * @param bundleIds - the bundleId / bundleIds you want to background load 22396 */ 22397 async backgroundLoadBundle(bundleIds) { 22398 this._initialized || await this.init(), typeof bundleIds == "string" && (bundleIds = [bundleIds]); 22399 const resolveResults = this.resolver.resolveBundle(bundleIds); 22400 Object.values(resolveResults).forEach((resolveResult) => { 22401 this._backgroundLoader.add(Object.values(resolveResult)); 22402 }); 22403 } 22404 /** 22405 * Only intended for development purposes. 22406 * This will wipe the resolver and caches. 22407 * You will need to reinitialize the Asset 22408 */ 22409 reset() { 22410 this.resolver.reset(), this.loader.reset(), this.cache.reset(), this._initialized = !1; 22411 } 22412 get(keys) { 22413 if (typeof keys == "string") 22414 return Cache.get(keys); 22415 const assets = {}; 22416 for (let i = 0; i < keys.length; i++) 22417 assets[i] = Cache.get(keys[i]); 22418 return assets; 22419 } 22420 /** 22421 * helper function to map resolved assets back to loaded assets 22422 * @param resolveResults - the resolve results from the resolver 22423 * @param onProgress - the progress callback 22424 */ 22425 async _mapLoadToResolve(resolveResults, onProgress) { 22426 const resolveArray = Object.values(resolveResults), resolveKeys = Object.keys(resolveResults); 22427 this._backgroundLoader.active = !1; 22428 const loadedAssets = await this.loader.load(resolveArray, onProgress); 22429 this._backgroundLoader.active = !0; 22430 const out = {}; 22431 return resolveArray.forEach((resolveResult, i) => { 22432 const asset = loadedAssets[resolveResult.src], keys = [resolveResult.src]; 22433 resolveResult.alias && keys.push(...resolveResult.alias), out[resolveKeys[i]] = asset, C
22433ache.set(keys, asset); 22434 }), out; 22435 } 22436 /** 22437 * Unload an asset or assets. As the Assets class is responsible for creating the assets via the `load` function 22438 * this will make sure to destroy any assets and release them from memory. 22439 * Once unloaded, you will need to load the asset again. 22440 * 22441 * Use this to help manage assets if you find that you have a large app and you want to free up memory. 22442 * 22443 * - it's up to you as the developer to make sure that textures are not actively being used when you unload them, 22444 * Pixi won't break but you will end up with missing assets. Not a good look for the user! 22445 * @example 22446 * import { Assets } from 'pixi.js'; 22447 * 22448 * // Load a URL: 22449 * const myImageTexture = await Assets.load('http://some.url.com/image.png'); // => returns a texture 22450 * 22451 * await Assets.unload('http://some.url.com/image.png') 22452 * 22453 * // myImageTexture will be destroyed now. 22454 * 22455 * // Unload multiple assets: 22456 * const textures = await Assets.unload(['thumper', 'chicko']); 22457 * @param urls - the urls to unload 22458 */ 22459 async unload(urls) { 22460 this._initialized || await this.init(); 22461 const urlArray = convertToList(urls).map((url) => typeof url != "string" ? url.src : url), resolveResults = this.resolver.resolve(urlArray); 22462 await this._unloadFromResolved(resolveResults); 22463 } 22464 /** 22465 * Bundles are a way to manage multiple assets at once. 22466 * this will unload all files in a bundle. 22467 * 22468 * once a bundle has been unloaded, you need to load it again to have access to the assets. 22469 * @example 22470 * import { Assets } from 'pixi.js'; 22471 * 22472 * Assets.addBundle({ 22473 * 'thumper': 'http://some.url.com/thumper.png', 22474 * }) 22475 * 22476 * const assets = await Assets.loadBundle('thumper'); 22477 * 22478 * // Now to unload... 22479 * 22480 * await Assets.unloadBundle('thumper'); 22481 * 22482 * // All assets in the assets object will now have been destroyed and purged from the cache 22483 * @param bundleIds - the bundle id or ids to unload 22484 */ 22485 async unloadBundle(bundleIds) { 22486 this._initialized || await this.init(), bundleIds = convertToList(bundleIds); 22487 const resolveResults = this.resolver.resolveBundle(bundleIds), promises = Object.keys(resolveResults).map((bundleId) => this._unloadFromResolved(resolveResults[bundleId])); 22488 await Promise.all(promises); 22489 } 22490 async _unloadFromResolved(resolveResult) { 22491 const resolveArray = Object.values(resolveResult); 22492 resolveArray.forEach((resolveResult2) => { 22493 Cache.remove(resolveResult2.src); 22494 }), await this.loader.unload(resolveArray); 22495 } 22496 /** 22497 * Detects the supported formats for the browser, and returns an array of supported formats, respecting 22498 * the users preferred formats order. 22499 * @param options - the options to use when detecting formats 22500 * @param options.preferredFormats - the preferred formats to use 22501 * @param options.skipDetections - if we should skip the detections altogether 22502 * @param options.detections - the detections to use 22503 * @returns - the detected formats 22504 */ 22505 async _detectFormats(options) { 22506 let formats = []; 22507 options.preferredFormats && (formats = Array.isArray(options.preferredFormats) ? options.preferredFormats : [options.preferredFormats]); 22508 for (const detection of options.detections) 22509 options.skipDetections || await detection.test() ? formats = await detection.add(formats) : options.skipDetections || (formats = await detection.remove(formats)); 22510 return formats = formats.filter((format, index) => formats.indexOf(format) === index), formats; 22511 } 22512 /** All the detection parsers currently added to the Assets class. */ 22513 get detections() { 22514 return this._detections; 22515 } 22516 /** 22517 * @deprecated since 7.2.0 22518 * @see {@link Assets.setPreferences} 22519 */ 22520 get preferWorkers() { 22521 return loadTextures.config.preferWorkers; 22522 } 22523 set preferWorkers(value) { 22524 deprecation("7.2.0", "Assets.prefersWorkers is deprecated, use Assets.setPreferences({ preferWorkers: true }) instead."), this.setPreferences({ preferWorkers: value }); 22525 } 22526 /** 22527 * General setter for preferences. This is a helper function to set preferences on all parsers. 22528 * @param preferences - the preferences to set 22529 */ 22530 setPreferences(preferences) {
22531 this.loader.parsers.forEach((parser) => { 22532 parser.config && Object.keys(parser.config).filter((key) => key in preferences).forEach((key) => { 22533 parser.config[key] = preferences[key]; 22534 }); 22535 }); 22536 } 22537} 22538const Assets = new AssetsClass(); 22539extensions$1.handleByList(ExtensionType.LoadParser, Assets.loader.parsers).handleByList(ExtensionType.ResolveParser, Assets.resolver.parsers).handleByList(ExtensionType.CacheParser, Assets.cache.parsers).handleByList(ExtensionType.DetectionParser, Assets.detections); 22540 22541const cacheTextureArray = { 22542 extension: ExtensionType.CacheParser, 22543 test: (asset) => Array.isArray(asset) && asset.every((t) => t instanceof Texture), 22544 getCacheableAssets: (keys, asset) => { 22545 const out = {}; 22546 return keys.forEach((key) => { 22547 asset.forEach((item, i) => { 22548 out[key + (i === 0 ? "" : i + 1)] = item; 22549 }); 22550 }), out; 22551 } 22552}; 22553extensions$1.add(cacheTextureArray); 22554 22555async function testImageFormat(imageData) { 22556 if ("Image" in globalThis) 22557 return new Promise((resolve) => { 22558 const image = new Image(); 22559 image.onload = () => { 22560 resolve(!0); 22561 }, image.onerror = () => { 22562 resolve(!1); 22563 }, image.src = imageData; 22564 }); 22565 if ("createImageBitmap" in globalThis && "fetch" in globalThis) { 22566 try { 22567 const blob = await (await fetch(imageData)).blob(); 22568 await createImageBitmap(blob); 22569 } catch { 22570 return !1; 22571 } 22572 return !0; 22573 } 22574 return !1; 22575} 22576 22577const detectAvif = { 22578 extension: { 22579 type: ExtensionType.DetectionParser, 22580 priority: 1 22581 }, 22582 test: async () => testImageFormat( 22583 // eslint-disable-next-line max-len 22584 "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=" 22585 ), 22586 add: async (formats) => [...formats, "avif"], 22587 remove: async (formats) => formats.filter((f) => f !== "avif") 22588}; 22589extensions$1.add(detectAvif); 22590 22591const detectWebp = { 22592 extension: { 22593 type: ExtensionType.DetectionParser, 22594 priority: 0 22595 }, 22596 test: async () => testImageFormat( 22597 "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=" 22598 ), 22599 add: async (formats) => [...formats, "webp"], 22600 remove: async (formats) => formats.filter((f) => f !== "webp") 22601}; 22602extensions$1.add(detectWebp); 22603 22604const imageFormats = ["png", "jpg", "jpeg"], detectDefaults = { 22605 extension: { 22606 type: ExtensionType.DetectionParser, 22607 priority: -1 22608 }, 22609 test: () => Promise.resolve(!0), 22610 add: async (formats) => [...formats, ...imageFormats], 22611 remove: async (formats) => formats.filter((f) => !imageFormats.includes(f)) 22612}; 22613extensions$1.add(detectDefaults); 22614 22615const inWorker = "WorkerGlobalScope" in globalThis && globalThis instanceof globalThis.WorkerGlobalScope; 22616function testVideoFormat(mimeType) { 22617 return inWorker ? !1 : document.createElement("video").canPlayType(mimeType) !== ""; 22618} 22619 22620const detectWebm = { 22621 extension: { 22622 type: ExtensionType.DetectionParser, 22623 priority: 0 22624 }, 22625 test: async () => testVideoFormat("video/webm"), 22626 add: async (formats) => [...formats, "webm"], 22627 remove: async (formats) => formats.filter((f) => f !== "webm") 22628}; 22629extensions$1.add(detectWebm); 22630 22631const detectMp4 = { 22632 extension: { 22633 type: ExtensionType.DetectionParser, 22634 priority: 0 22635 }, 22636 test: async () => testVideoFormat("video/mp4"), 22637 add: async (formats) => [...formats, "mp4", "m4v"], 22638 remove: async (formats) => formats.filter((f) => f !== "mp4" && f !== "m4v") 22639}; 22640extensions$1.add(detectMp4); 22641 22642const detectOgv = { 22643 extension: { 22644 type: ExtensionType.DetectionParser, 22645 priority: 0 22646 }, 22647 test: async () => testVideoFormat("video/ogg"), 22648 add: async (formats) => [...formats, "ogv"], 22649 remove: async (formats) => formats.filter((f) => f !== "ogv") 22650}; 22651extensions$1.add(detectOgv); 22652 22653const resolveTextureUrl = { 22654 extension: ExtensionType.ResolveParser, 22655 test: loadTextures.test, 22656 parse: (value) => ({ 22657 resolution: parseFloat(settings.RETINA_PREFIX.exec(value)?.[1] ?? "1"), 22658 format: path.extname(value).slice(1), 22659 src: value 22660 }) 22661}; 22662extensions$1.add(resolveTextureUrl); 22663 22664var INTERNAL_FORMATS = /* @__PURE__ */ ((INTERNAL_FORMATS2) => (INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGB_S3TC_DXT1_EXT = 33776] = "COMPRESSED_RGB_S3TC_DXT1_EXT", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA_S3TC_DXT1_EXT = 33777] = "COMPRESSED_RGBA_S3TC_DXT1_EXT", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA_S3TC_DXT3_EXT = 33778] = "COMPRESSED_RGBA_S3TC_DXT3_EXT", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA_S3TC_DXT5_EXT = 33779] = "COMPRESSED_RGBA_S3TC_DXT5_EXT", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 35917] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 35918] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 35919] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SRGB_S3TC_DXT1_EXT = 35916] = "COMPRESSED_SRGB_S3TC_DXT1_EXT", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_R11_
22664EAC = 37488] = "COMPRESSED_R11_EAC", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SIGNED_R11_EAC = 37489] = "COMPRESSED_SIGNED_R11_EAC", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RG11_EAC = 37490] = "COMPRESSED_RG11_EAC", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SIGNED_RG11_EAC = 37491] = "COMPRESSED_SIGNED_RG11_EAC", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGB8_ETC2 = 37492] = "COMPRESSED_RGB8_ETC2", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA8_ETC2_EAC = 37496] = "COMPRESSED_RGBA8_ETC2_EAC", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SRGB8_ETC2 = 37493] = "COMPRESSED_SRGB8_ETC2", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 37497] = "COMPRESSED_SRGB8_ALPHA8_ETC2_EAC", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 37494] = "COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 37495] = "COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 35840] = "COMPRESSED_RGB_PVRTC_4BPPV1_IMG", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 35842] = "COMPRESSED_RGBA_PVRTC_4BPPV1_IMG", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 35841] = "COMPRESSED_RGB_PVRTC_2BPPV1_IMG", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 35843] = "COMPRESSED_RGBA_PVRTC_2BPPV1_IMG", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGB_ETC1_WEBGL = 36196] = "COMPRESSED_RGB_ETC1_WEBGL", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGB_ATC_WEBGL = 35986] = "COMPRESSED_RGB_ATC_WEBGL", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 35986] = "COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 34798] = "COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL", INTERNAL_FORMATS2[INTERNAL_FORMATS2.COMPRESSED_RGBA_ASTC_4x4_KHR = 37808] = "COMPRESSED_RGBA_ASTC_4x4_KHR", INTERNAL_FORMATS2))(INTERNAL_FORMATS || {}); 22665const INTERNAL_FORMAT_TO_BYTES_PER_PIXEL = { 22666 // WEBGL_compressed_texture_s3tc 22667 33776: 0.5, 22668 33777: 0.5, 22669 33778: 1, 22670 33779: 1, 22671 // WEBGL_compressed_texture_s3tc 22672 35916: 0.5, 22673 35917: 0.5, 22674 35918: 1, 22675 35919: 1, 22676 // WEBGL_compressed_texture_etc 22677 37488: 0.5, 22678 37489: 0.5, 22679 37490: 1, 22680 37491: 1, 22681 37492: 0.5, 22682 37496: 1, 22683 37493: 0.5, 22684 37497: 1, 22685 37494: 0.5, 22686 // ~~ 22687 37495: 0.5, 22688 // ~~ 22689 // WEBGL_compressed_texture_pvrtc 22690 35840: 0.5, 22691 35842: 0.5, 22692 35841: 0.25, 22693 35843: 0.25, 22694 // WEBGL_compressed_texture_etc1 22695 36196: 0.5, 22696 // @see https://www.khronos.org/registry/OpenGL/extensions/AMD/AMD_compressed_ATC_texture.txt 22697 // WEBGL_compressed_texture_atc 22698 35986: 0.5, 22699 35986: 1, 22700 34798: 1, 22701 // @see https://registry.khronos.org/OpenGL/extensions/KHR/KHR_texture_compression_astc_hdr.txt 22702 // WEBGL_compressed_texture_astc 22703 /* eslint-disable-next-line camelcase */ 22704 37808: 1 22705}; 22706 22707let storedGl, extensions; 22708function getCompressedTextureExtensions() { 22709 extensions = { 22710 s3tc: storedGl.getExtension("WEBGL_compressed_texture_s3tc"), 22711 s3tc_sRGB: storedGl.getExtension("WEBGL_compressed_texture_s3tc_srgb"), 22712 /* eslint-disable-line camelcase */ 22713 etc: storedGl.getExtension("WEBGL_compressed_texture_etc"), 22714 etc1: storedGl.getExtension("WEBGL_compressed_texture_etc1"), 22715 pvrtc: storedGl.getExtension("WEBGL_compressed_texture_pvrtc") || storedGl.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"), 22716 atc: storedGl.getExtension("WEBGL_compressed_texture_atc"), 22717 astc: storedGl.getExtension("WEBGL_compressed_texture_astc") 22718 }; 22719} 22720const detectCompressedTextures = { 22721 extension: { 22722 type: ExtensionType.DetectionParser, 22723 priority: 2 22724 }, 22725 test: async () => { 22726 const gl = settings.ADAPTER.createCanvas().getContext("webgl"); 22727 return gl ? (storedGl = gl, !0) : (console.warn("WebGL not available for compressed textures."), !1); 22728 }, 22729 add: async (formats) => { 22730 extensions || getCompressedTextureExtensions(); 22731 const textureFormats = []; 22732 for (const extensionName in extensions) 22733 extensions[extensionName] && textureFormats.push(extensionName); 22734 return [...textureFormats, ...formats]; 22735 }, 22736 remove: async (formats) => (extensions || getCompressedTextureExtensions(), formats.filter((f) => !(f in extensions))) 22737}; 22738extensions$1.add(detectCompressedTextures); 22739 22740class BlobResource extends BufferResource { 22741 /** 22742 * @param source - The buffer/URL of the texture file. 22743 * @param {PIXI.IBlobResourceOptions} [options] 22744 * @param {boolean} [options.autoLoad=false] - Whether to fetch the data immediately; 22745 * you can fetch it later via {@link PIXI.BlobResource#load}. 22746 * @param {number} [options.width=1] - The width in pixels. 22747 * @param {number} [options.height=1] - The height in pixels. 22748 * @param {1|2|4|8} [options.unpackAlignment=4] - The alignment of the pixel rows. 22749 */ 22750 constructor(source, options = { width: 1, height: 1, autoLoad: !0 }) { 22751 let origin, data; 22752 typeof source == "string" ? (origin = source, data = new Uint8Array()) : (origin = null, data = source), super(data, options), this.origin = origin, this.buffer = data ? new ViewableBuffer(data) : null, this._load = null, this.loaded = !1, this.origin !== null && options.autoLoad !== !1 && this.load(), this.origin === null && this.buffer && (this._load = Promise.resolve(this), this.loaded = !0, this.onBlobLoaded(this.buffer.rawBinaryData)); 22753 } 22754 onBlobLoaded(_data) { 22755 } 22756 /** Loads the blob */ 22757 load() { 22758 return this._load ? this._load : (this._load = fetch(this.origin).then((response) => response.blob()).then((blob) => blob.arrayBuffer()).then((arrayBuffer) => (this.data = new Uint32Array(arrayBuffer), this.buffer = new ViewableBuffer(arrayBuffer), this.loaded = !0, this.onBlobLoaded(arrayBuffer), this.update(), this)), this._load); 22759 } 22760} 22761 22762class CompressedTextureResource extends BlobResource { 22763 /** 22764 * @param source - the buffer/URL holding the compressed texture data 22765 * @param options 22766 * @param {PIXI.INTERNAL_FORMATS} options.format - the compression format 22767 * @param {number} options.width - the image width in pixels. 22768 * @param {number} options.height - the image height in pixels. 22769 * @param {number} [options.level=1] - the mipmap levels stored in the compressed texture, including level 0. 22770 * @param {number}
22770 [options.levelBuffers] - the buffers for each mipmap level. `CompressedTextureResource` can allows you 22771 * to pass `null` for `source`, for cases where each level is stored in non-contiguous memory. 22772 */ 22773 constructor(source, options) { 22774 super(source, options), this.format = options.format, this.levels = options.levels || 1, this._width = options.width, this._height = options.height, this._extension = CompressedTextureResource._formatToExtension(this.format), (options.levelBuffers || this.buffer) && (this._levelBuffers = options.levelBuffers || CompressedTextureResource._createLevelBuffers( 22775 source instanceof Uint8Array ? source : this.buffer.uint8View, 22776 this.format, 22777 this.levels, 22778 4, 22779 4, 22780 // PVRTC has 8x4 blocks in 2bpp mode 22781 this.width, 22782 this.height 22783 )); 22784 } 22785 /** 22786 * @override 22787 * @param renderer - A reference to the current renderer 22788 * @param _texture - the texture 22789 * @param _glTexture - texture instance for this webgl context 22790 */ 22791 upload(renderer, _texture, _glTexture) { 22792 const gl = renderer.gl; 22793 if (!renderer.context.extensions[this._extension]) 22794 throw new Error(`${this._extension} textures are not supported on the current machine`); 22795 if (!this._levelBuffers) 22796 return !1; 22797 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); 22798 for (let i = 0, j = this.levels; i < j; i++) { 22799 const { levelID, levelWidth, levelHeight, levelBuffer } = this._levelBuffers[i]; 22800 gl.compressedTexImage2D(gl.TEXTURE_2D, levelID, this.format, levelWidth, levelHeight, 0, levelBuffer); 22801 } 22802 return !0; 22803 } 22804 /** @protected */ 22805 onBlobLoaded() { 22806 this._levelBuffers = CompressedTextureResource._createLevelBuffers( 22807 this.buffer.uint8View, 22808 this.format, 22809 this.levels, 22810 4, 22811 4, 22812 // PVRTC has 8x4 blocks in 2bpp mode 22813 this.width, 22814 this.height 22815 ); 22816 } 22817 /** 22818 * Returns the key (to ContextSystem#extensions) for the WebGL extension supporting the compression format 22819 * @private 22820 * @param format - the compression format to get the extension for. 22821 */ 22822 static _formatToExtension(format) { 22823 if (format >= 33776 && format <= 33779) 22824 return "s3tc"; 22825 if (format >= 37488 && format <= 37497) 22826 return "etc"; 22827 if (format >= 35840 && format <= 35843) 22828 return "pvrtc"; 22829 if (format >= 36196) 22830 return "etc1"; 22831 if (format >= 35986 && format <= 34798) 22832 return "atc"; 22833 throw new Error("Invalid (compressed) texture format given!"); 22834 } 22835 /** 22836 * Pre-creates buffer views for each mipmap level 22837 * @private 22838 * @param buffer - 22839 * @param format - compression formats 22840 * @param levels - mipmap levels 22841 * @param blockWidth - 22842 * @param blockHeight - 22843 * @param imageWidth - width of the image in pixels 22844 * @param imageHeight - height of the image in pixels 22845 */ 22846 static _createLevelBuffers(buffer, format, levels, blockWidth, blockHeight, imageWidth, imageHeight) { 22847 const buffers = new Array(levels); 22848 let offset = buffer.byteOffset, levelWidth = imageWidth, levelHeight = imageHeight, alignedLevelWidth = levelWidth + blockWidth - 1 & ~(blockWidth - 1), alignedLevelHeight = levelHeight + blockHeight - 1 & ~(blockHeight - 1), levelSize = alignedLevelWidth * alignedLevelHeight * INTERNAL_FORMAT_TO_BYTES_PER_PIXEL[format]; 22849 for (let i = 0; i < levels; i++) 22850 buffers[i] = { 22851 levelID: i, 22852 levelWidth: levels > 1 ? levelWidth : alignedLevelWidth, 22853 levelHeight: levels > 1 ? levelHeight : alignedLevelHeight, 22854 levelBuffer: new Uint8Array(buffer.buffer, offset, levelSize) 22855 }, offset += levelSize, levelWidth = levelWidth >> 1 || 1, levelHeight = levelHeight >> 1 || 1, alignedLevelWidth = levelWidth + blockWidth - 1 & ~(blockWidth - 1), alignedLevelHeight = levelHeight + blockHeight - 1 & ~(blockHeight - 1), levelSize = alignedLevelWidth * alignedLevelHeight * INTERNAL_FORMAT_TO_BYTES_PER_PIXEL[format]; 22856 return buffers; 22857 } 22858} 22859 22860const DDS_MAGIC_SIZE = 4, DDS_HEADER_SIZE = 124, DDS_HEADER_PF_SIZE = 32, DDS_HEADER_DX10_SIZE = 20, DDS_MAGIC = 542327876, DDS_FIELDS = { 22861 SIZE: 1, 22862 FLAGS: 2, 22863 HEIGHT: 3, 22864 WIDTH: 4, 22865 MIPMAP_COUNT: 7, 22866 PIXEL_FORMAT: 19 22867}, DDS_PF_FIELDS = { 22868 SIZE: 0, 22869 FLAGS: 1, 22870 FOURCC: 2, 22871 RGB_BITCOUNT: 3, 22872 R_BIT_MASK: 4, 22873 G_BIT_MASK: 5, 22874 B_BIT_MASK: 6, 22875 A_BIT_MASK: 7 22876}, DDS_DX10_FIELDS = { 22877 DXGI_FORMAT: 0, 22878 RESOURCE_DIMENSION: 1, 22879 MISC_FLAG: 2, 22880 ARRAY_SIZE: 3, 22881 MISC_FLAGS2: 4 22882}, PF_FLAGS = 1, DDPF_ALPHA = 2, DDPF_FOURCC = 4, DDPF_RGB = 64, DDPF_YUV = 512, DDPF_LUMINANCE = 131072, FOURCC_DXT1 = 827611204, FOURCC_DXT3 = 861165636, FOURCC_DXT5 = 894720068, FOURCC_DX10 = 808540228, DDS_RESOURCE_MISC_TEXTURECUBE = 4, FOURCC_TO_FORMAT = { 22883 [FOURCC_DXT1]: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT1_EXT, 22884 [FOURCC_DXT3]: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT3_EXT, 22885 [FOURCC_DXT5]: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT5_EXT 22886}, DXGI_TO_FORMAT = { 22887 // WEBGL_compressed_texture_s3tc 22888 70: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT1_EXT, 22889 71: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT1_EXT, 22890 73: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT3_EXT, 22891 74: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT3_EXT, 22892 76: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT5_EXT, 22893 77: INTERNAL_FORMATS.COMPRESSED_RGBA_S3TC_DXT5_EXT, 22894 // WEBGL_compressed_texture_s3tc_srgb 22895 72: INTERNAL_FORMATS.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 22896 75: INTERNAL_FORMATS.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 22897 78: INTERNAL_FORMATS.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 22898}; 22899function parseDDS(arrayBuffer) { 22900 const data = new Uint32Array(arrayBuffer); 22901 if (data[0] !== DDS_MAGIC) 22902 throw new Error("Invalid DDS file magic word"); 22903 const header = new Uint32Array(arrayBuffer, 0, DDS_HEADER_SIZE / Uint32Array.BYTES_PER_ELEMENT), height = header[DDS_FIELDS.HEIGHT], width = header[DDS_FIELDS.WIDTH], mipmapCount = header[DDS_FIELDS.MIPMAP_COUNT], pixelFormat = new Uint32Array( 22904 arrayBuffer, 22905 DDS_FIELDS.PIXEL_FORMAT * Uint32Array.BYTES_PER_ELEMENT, 22906 DDS_HEADER_PF_SIZE / Uint32Array.BYTES_PER_ELEMENT 22907 ), formatFlags = pixelFormat[PF_FLAGS]; 22908 if (formatFlags & DDPF_FOURCC) { 22909 const fourCC = pixelFormat[DDS_PF_FIELDS.FOURCC]; 22910 if (fourCC !== FOURCC_DX10) { 22911 const internalFormat2 = FOURCC_TO_FORMAT[fourCC], dataOffset2 = DDS_MAGIC_SIZE + DDS_HEADER_SIZE, texData = new Uint8Array(arrayBuffer, dataOffset2); 22912 return [new CompressedTextureResource(texData, { 22913 format: internalFormat2, 22914 width, 22915 height, 22916 levels: mipmapCount 22917 // CompressedTextureResource will separate the levelBuffers for us! 22918 })]; 22919 } 22920 const dx10Offset = DDS_MAGIC_SIZE + DDS_HEADER_SIZE, dx10Header = new Uint32Array( 22921 data.buffer, 22922 dx10Offset, 22923 DDS_HEADER_DX10_SIZE / Uint32Array.BYTES_PER_ELEMENT 22924 ), dxgiFormat = dx10Header[DDS_DX10_FIELDS.DXGI_FORMAT], resourceDimension = dx10Header[DDS_DX10_FIELDS.RESOURCE_DIMENSION], misc
22924Flag = dx10Header[DDS_DX10_FIELDS.MISC_FLAG], arraySize = dx10Header[DDS_DX10_FIELDS.ARRAY_SIZE], internalFormat = DXGI_TO_FORMAT[dxgiFormat]; 22925 if (internalFormat === void 0) 22926 throw new Error(`DDSParser cannot parse texture data with DXGI format ${dxgiFormat}`); 22927 if (miscFlag === DDS_RESOURCE_MISC_TEXTURECUBE) 22928 throw new Error("DDSParser does not support cubemap textures"); 22929 if (resourceDimension === 6) 22930 throw new Error("DDSParser does not supported 3D texture data"); 22931 const imageBuffers = new Array(), dataOffset = DDS_MAGIC_SIZE + DDS_HEADER_SIZE + DDS_HEADER_DX10_SIZE; 22932 if (arraySize === 1) 22933 imageBuffers.push(new Uint8Array(arrayBuffer, dataOffset)); 22934 else { 22935 const pixelSize = INTERNAL_FORMAT_TO_BYTES_PER_PIXEL[internalFormat]; 22936 let imageSize = 0, levelWidth = width, levelHeight = height; 22937 for (let i = 0; i < mipmapCount; i++) { 22938 const alignedLevelWidth = Math.max(1, levelWidth + 3 & -4), alignedLevelHeight = Math.max(1, levelHeight + 3 & -4), levelSize = alignedLevelWidth * alignedLevelHeight * pixelSize; 22939 imageSize += levelSize, levelWidth = levelWidth >>> 1, levelHeight = levelHeight >>> 1; 22940 } 22941 let imageOffset = dataOffset; 22942 for (let i = 0; i < arraySize; i++) 22943 imageBuffers.push(new Uint8Array(arrayBuffer, imageOffset, imageSize)), imageOffset += imageSize; 22944 } 22945 return imageBuffers.map((buffer) => new CompressedTextureResource(buffer, { 22946 format: internalFormat, 22947 width, 22948 height, 22949 levels: mipmapCount 22950 })); 22951 } 22952 throw formatFlags & DDPF_RGB ? new Error("DDSParser does not support uncompressed texture data.") : formatFlags & DDPF_YUV ? new Error("DDSParser does not supported YUV uncompressed texture data.") : formatFlags & DDPF_LUMINANCE ? new Error("DDSParser does not support single-channel (lumninance) texture data!") : formatFlags & DDPF_ALPHA ? new Error("DDSParser does not support single-channel (alpha) texture data!") : new Error("DDSParser failed to load a texture file due to an unknown reason!"); 22953} 22954 22955const FILE_IDENTIFIER = [171, 75, 84, 88, 32, 49, 49, 187, 13, 10, 26, 10], ENDIANNESS = 67305985, KTX_FIELDS = { 22956 FILE_IDENTIFIER: 0, 22957 ENDIANNESS: 12, 22958 GL_TYPE: 16, 22959 GL_TYPE_SIZE: 20, 22960 GL_FORMAT: 24, 22961 GL_INTERNAL_FORMAT: 28, 22962 GL_BASE_INTERNAL_FORMAT: 32, 22963 PIXEL_WIDTH: 36, 22964 PIXEL_HEIGHT: 40, 22965 PIXEL_DEPTH: 44, 22966 NUMBER_OF_ARRAY_ELEMENTS: 48, 22967 NUMBER_OF_FACES: 52, 22968 NUMBER_OF_MIPMAP_LEVELS: 56, 22969 BYTES_OF_KEY_VALUE_DATA: 60 22970}, FILE_HEADER_SIZE = 64, TYPES_TO_BYTES_PER_COMPONENT = { 22971 [TYPES.UNSIGNED_BYTE]: 1, 22972 [TYPES.UNSIGNED_SHORT]: 2, 22973 [TYPES.INT]: 4, 22974 [TYPES.UNSIGNED_INT]: 4, 22975 [TYPES.FLOAT]: 4, 22976 [TYPES.HALF_FLOAT]: 8 22977}, FORMATS_TO_COMPONENTS = { 22978 [FORMATS.RGBA]: 4, 22979 [FORMATS.RGB]: 3, 22980 [FORMATS.RG]: 2, 22981 [FORMATS.RED]: 1, 22982 [FORMATS.LUMINANCE]: 1, 22983 [FORMATS.LUMINANCE_ALPHA]: 2, 22984 [FORMATS.ALPHA]: 1 22985}, TYPES_TO_BYTES_PER_PIXEL = { 22986 [TYPES.UNSIGNED_SHORT_4_4_4_4]: 2, 22987 [TYPES.UNSIGNED_SHORT_5_5_5_1]: 2, 22988 [TYPES.UNSIGNED_SHORT_5_6_5]: 2 22989}; 22990function parseKTX(url, arrayBuffer, loadKeyValueData = !1) { 22991 const dataView = new DataView(arrayBuffer); 22992 if (!validate(url, dataView)) 22993 return null; 22994 const littleEndian = dataView.getUint32(KTX_FIELDS.ENDIANNESS, !0) === ENDIANNESS, glType = dataView.getUint32(KTX_FIELDS.GL_TYPE, littleEndian), glFormat = dataView.getUint32(KTX_FIELDS.GL_FORMAT, littleEndian), glInternalFormat = dataView.getUint32(KTX_FIELDS.GL_INTERNAL_FORMAT, littleEndian), pixelWidth = dataView.getUint32(KTX_FIELDS.PIXEL_WIDTH, littleEndian), pixelHeight = dataView.getUint32(KTX_FIELDS.PIXEL_HEIGHT, littleEndian) || 1, pixelDepth = dataView.getUint32(KTX_FIELDS.PIXEL_DEPTH, littleEndian) || 1, numberOfArrayElements = dataView.getUint32(KTX_FIELDS.NUMBER_OF_ARRAY_ELEMENTS, littleEndian) || 1, numberOfFaces = dataView.getUint32(KTX_FIELDS.NUMBER_OF_FACES, littleEndian), numberOfMipmapLevels = dataView.getUint32(KTX_FIELDS.NUMBER_OF_MIPMAP_LEVELS, littleEndian), bytesOfKeyValueData = dataView.getUint32(KTX_FIELDS.BYTES_OF_KEY_VALUE_DATA, littleEndian); 22995 if (pixelHeight === 0 || pixelDepth !== 1) 22996 throw new Error("Only 2D textures are supported"); 22997 if (numberOfFaces !== 1) 22998 throw new Error("CubeTextures are not supported by KTXLoader yet!"); 22999 if (numberOfArrayElements !== 1) 23000 throw new Error("WebGL does not support array textures"); 23001 const blockWidth = 4, blockHeight = 4, alignedWidth = pixelWidth + 3 & -4, alignedHeight = pixelHeight + 3 & -4, imageBuffers = new Array(numberOfArrayElements); 23002 let imagePixels = pixelWidth * pixelHeight; 23003 glType === 0 && (imagePixels = alignedWidth * alignedHeight); 23004 let imagePixelByteSize; 23005 if (glType !== 0 ? TYPES_TO_BYTES_PER_COMPONENT[glType] ? imagePixelByteSize = TYPES_TO_BYTES_PER_COMPONENT[glType] * FORMATS_TO_COMPONENTS[glFormat] : imagePixelByteSize = TYPES_TO_BYTES_PER_PIXEL[glType] : imagePixelByteSize = INTERNAL_FORMAT_TO_BYTES_PER_PIXEL[glInternalFormat], imagePixelByteSize === void 0) 23006 throw new Error("Unable to resolve the pixel format stored in the *.ktx file!"); 23007 const kvData = loadKeyValueData ? parseKvData(dataView, bytesOfKeyValueData, littleEndian) : null; 23008 let mipByteSize = imagePixels * imagePixelByteSize, mipWidth = pixelWidth, mipHeight = pixelHeight, alignedMipWidth = alignedWidth, alignedMipHeight = alignedHeight, imageOffset = FILE_HEADER_SIZE + bytesOfKeyValueData; 23009 for (let mipmapLevel = 0; mipmapLevel < numberOfMipmapLevels; mipmapLevel++) { 23010 const imageSize = dataView.getUint32(imageOffset, littleEndian); 23011 let elementOffset = imageOffset + 4; 23012 for (let arrayElement = 0; arrayElement < numberOfArrayElements; arrayElement++) { 23013 let mips = imageBuffers[arrayElement]; 23014 mips || (mips = imageBuffers[arrayElement] = new Array(numberOfMipmapLevels)
23014), mips[mipmapLevel] = { 23015 levelID: mipmapLevel, 23016 // don't align mipWidth when texture not compressed! (glType not zero) 23017 levelWidth: numberOfMipmapLevels > 1 || glType !== 0 ? mipWidth : alignedMipWidth, 23018 levelHeight: numberOfMipmapLevels > 1 || glType !== 0 ? mipHeight : alignedMipHeight, 23019 levelBuffer: new Uint8Array(arrayBuffer, elementOffset, mipByteSize) 23020 }, elementOffset += mipByteSize; 23021 } 23022 imageOffset += imageSize + 4, imageOffset = imageOffset % 4 !== 0 ? imageOffset + 4 - imageOffset % 4 : imageOffset, mipWidth = mipWidth >> 1 || 1, mipHeight = mipHeight >> 1 || 1, alignedMipWidth = mipWidth + blockWidth - 1 & ~(blockWidth - 1), alignedMipHeight = mipHeight + blockHeight - 1 & ~(blockHeight - 1), mipByteSize = alignedMipWidth * alignedMipHeight * imagePixelByteSize; 23023 } 23024 return glType !== 0 ? { 23025 uncompressed: imageBuffers.map((levelBuffers) => { 23026 let buffer = levelBuffers[0].levelBuffer, convertToInt = !1; 23027 return glType === TYPES.FLOAT ? buffer = new Float32Array( 23028 levelBuffers[0].levelBuffer.buffer, 23029 levelBuffers[0].levelBuffer.byteOffset, 23030 levelBuffers[0].levelBuffer.byteLength / 4 23031 ) : glType === TYPES.UNSIGNED_INT ? (convertToInt = !0, buffer = new Uint32Array( 23032 levelBuffers[0].levelBuffer.buffer, 23033 levelBuffers[0].levelBuffer.byteOffset, 23034 levelBuffers[0].levelBuffer.byteLength / 4 23035 )) : glType === TYPES.INT && (convertToInt = !0, buffer = new Int32Array( 23036 levelBuffers[0].levelBuffer.buffer, 23037 levelBuffers[0].levelBuffer.byteOffset, 23038 levelBuffers[0].levelBuffer.byteLength / 4 23039 )), { 23040 resource: new BufferResource( 23041 buffer, 23042 { 23043 width: levelBuffers[0].levelWidth, 23044 height: levelBuffers[0].levelHeight 23045 } 23046 ), 23047 type: glType, 23048 format: convertToInt ? convertFormatToInteger(glFormat) : glFormat 23049 }; 23050 }), 23051 kvData 23052 } : { 23053 compressed: imageBuffers.map((levelBuffers) => new CompressedTextureResource(null, { 23054 format: glInternalFormat, 23055 width: pixelWidth, 23056 height: pixelHeight, 23057 levels: numberOfMipmapLevels, 23058 levelBuffers 23059 })), 23060 kvData 23061 }; 23062} 23063function validate(url, dataView) { 23064 for (let i = 0; i < FILE_IDENTIFIER.length; i++) 23065 if (dataView.getUint8(i) !== FILE_IDENTIFIER[i]) 23066 return console.error(`${url} is not a valid *.ktx file!`), !1; 23067 return !0; 23068} 23069function convertFormatToInteger(format) { 23070 switch (format) { 23071 case FORMATS.RGBA: 23072 return FORMATS.RGBA_INTEGER; 23073 case FORMATS.RGB: 23074 return FORMATS.RGB_INTEGER; 23075 case FORMATS.RG: 23076 return FORMATS.RG_INTEGER; 23077 case FORMATS.RED: 23078 return FORMATS.RED_INTEGER; 23079 default: 23080 return format; 23081 } 23082} 23083function parseKvData(dataView, bytesOfKeyValueData, littleEndian) { 23084 const kvData = /* @__PURE__ */ new Map(); 23085 let bytesIntoKeyValueData = 0; 23086 for (; bytesIntoKeyValueData < bytesOfKeyValueData; ) { 23087 const keyAndValueByteSize = dataView.getUint32(FILE_HEADER_SIZE + bytesIntoKeyValueData, littleEndian), keyAndValueByteOffset = FILE_HEADER_SIZE + bytesIntoKeyValueData + 4, valuePadding = 3 - (keyAndValueByteSize + 3) % 4; 23088 if (keyAndValueByteSize === 0 || keyAndValueByteSize > bytesOfKeyValueData - bytesIntoKeyValueData) { 23089 console.error("KTXLoader: keyAndValueByteSize out of bounds"); 23090 break; 23091 } 23092 let keyNulByte = 0; 23093 for (; keyNulByte < keyAndValueByteSize && dataView.getUint8(keyAndValueByteOffset + keyNulByte) !== 0; keyNulByte++) 23094 ; 23095 if (keyNulByte === -1) { 23096 console.error("KTXLoader: Failed to find null byte terminating kvData key"); 23097 break; 23098 } 23099 const key = new TextDecoder().decode( 23100 new Uint8Array(dataView.buffer, keyAndValueByteOffset, keyNulByte) 23101 ), value = new DataView( 23102 dataView.buffer, 23103 keyAndValueByteOffset + keyNulByte + 1, 23104 keyAndValueByteSize - keyNulByte - 1 23105 ); 23106 kvData.set(key, value), bytesIntoKeyValueData += 4 + keyAndValueByteSize + valuePadding; 23107 } 23108 return kvData; 23109} 23110 23111const loadDDS = { 23112 extension: { 23113 type: ExtensionType.LoadParser, 23114 priority: LoaderParserPriority.High 23115 }, 23116 name: "loadDDS", 23117 test(url) { 23118 return checkExtension(url, ".dds"); 23119 }, 23120 async load(url, asset, loader) { 23121 const arrayBuffer = await (await settings.ADAPTER.fetch(url)).arrayBuffer(), textures = parseDDS(arrayBuffer).map((resource) => { 23122 const base = new BaseTexture(resource, { 23123 mipmap: MIPMAP_MODES.OFF, 23124 alphaMode: ALPHA_MODES.NO_PREMULTIPLIED_ALPHA, 23125 resolution: getResolutionOfUrl(url), 23126 ...asset.data 23127 }); 23128 return createTexture(base, loader, url); 23129 }); 23130 return textures.length === 1 ? textures[0] : textures; 23131 }, 23132 unload(texture) { 23133 Array.isArray(texture) ? texture.forEach((t) => t.destroy(!0)) : texture.destroy(!0); 23134 } 23135}; 23136extensions$1.add(loadDDS); 23137 23138const loadKTX = { 23139 extension: { 23140 type: ExtensionType.LoadParser, 23141 priority: LoaderParserPriority.High 23142 }, 23143 name: "loadKTX", 23144 test(url) { 23145 return checkExtension(url, ".ktx"); 23146 }, 23147 async load(url, asset, loader) { 23148 const arrayBuffer = await (await settings.ADAPTER.fetch(url)).arrayBuffer(), { compressed, uncompressed, kvData } = parseKTX(url, arrayBuffer), resources = compressed ?? uncompressed, options = { 23149 mipmap: MIPMAP_MODES.OFF, 23150 alphaMode: ALPHA_MODES.NO_PREMULTIPLIED_ALPHA, 23151 resolution: getResolutionOfUrl(url), 23152 ...asset.data 23153 }, textures = resources.map((resource) => { 23154 resources === uncompressed && Object.assign(options, { 23155 type: resource.type, 23156 format: resource.format 23157 }); 23158 const res = resource.resource ?? resource, base = new BaseTexture(res, options); 23159 return base.ktxKeyValueData = kvData, createTexture(base, loader, url); 23160 }); 23161 return textures.length === 1 ? textures[0] : textures; 23162 }, 23163 unload(texture) { 23164 Array.isArray(texture) ? texture.forEach((t) => t.destroy(!0)) : texture.destroy(!0); 23165 } 23166}; 23167extensions$1.add(loadKTX); 23168 23169const resolveCompressedTextureUrl = { 23170 extension: ExtensionType.ResolveParser, 23171 test: (value) => { 23172 const extension = path.extname(value).slice(1); 23173 return ["basis", "ktx", "dds"].includes(extension); 23174 }, 23175 parse: (value) => { 23176 const extension = path.extname(value).slice(1); 23177 if (extension === "ktx") { 23178 const extensions2 = [ 23179 ".s3tc.ktx", 23180 ".s3tc_sRGB.ktx", 23181 ".etc.ktx", 23182 ".etc1.ktx", 23183 ".pvrt.ktx",
23184 ".atc.ktx", 23185 ".astc.ktx" 23186 ]; 23187 if (extensions2.some((ext) => value.endsWith(ext))) 23188 return { 23189 resolution: parseFloat(settings.RETINA_PREFIX.exec(value)?.[1] ?? "1"), 23190 format: extensions2.find((ext) => value.endsWith(ext)), 23191 src: value 23192 }; 23193 } 23194 return { 23195 resolution: parseFloat(settings.RETINA_PREFIX.exec(value)?.[1] ?? "1"), 23196 format: extension, 23197 src: value 23198 }; 23199 } 23200}; 23201extensions$1.add(resolveCompressedTextureUrl); 23202 23203const TEMP_RECT = new Rectangle(), BYTES_PER_PIXEL = 4, _Extract = class _Extract2 { 23204 /** 23205 * @param renderer - A reference to the current renderer 23206 */ 23207 constructor(renderer) { 23208 this.renderer = renderer, this._rendererPremultipliedAlpha = !1; 23209 } 23210 contextChange() { 23211 const attributes = this.renderer?.gl.getContextAttributes(); 23212 this._rendererPremultipliedAlpha = !!(attributes && attributes.alpha && attributes.premultipliedAlpha); 23213 } 23214 /** 23215 * Will return a HTML Image of the target 23216 * @param target - A displayObject or renderTexture 23217 * to convert. If left empty will use the main renderer 23218 * @param format - Image format, e.g. "image/jpeg" or "image/webp". 23219 * @param quality - JPEG or Webp compression from 0 to 1. Default is 0.92. 23220 * @param frame - The frame the extraction is restricted to. 23221 * @returns - HTML Image of the target 23222 */ 23223 async image(target, format, quality, frame) { 23224 const image = new Image(); 23225 return image.src = await this.base64(target, format, quality, frame), image; 23226 } 23227 /** 23228 * Will return a base64 encoded string of this target. It works by calling 23229 * `Extract.canvas` and then running toDataURL on that. 23230 * @param target - A displayObject or renderTexture 23231 * to convert. If left empty will use the main renderer 23232 * @param format - Image format, e.g. "image/jpeg" or "image/webp". 23233 * @param quality - JPEG or Webp compression from 0 to 1. Default is 0.92. 23234 * @param frame - The frame the extraction is restricted to. 23235 * @returns - A base64 encoded string of the texture. 23236 */ 23237 async base64(target, format, quality, frame) { 23238 const canvas = this.canvas(target, frame); 23239 if (canvas.toBlob !== void 0) 23240 return new Promise((resolve, reject) => { 23241 canvas.toBlob((blob) => { 23242 if (!blob) { 23243 reject(new Error("ICanvas.toBlob failed!")); 23244 return; 23245 } 23246 const reader = new FileReader(); 23247 reader.onload = () => resolve(reader.result), reader.onerror = reject, reader.readAsDataURL(blob); 23248 }, format, quality); 23249 }); 23250 if (canvas.toDataURL !== void 0) 23251 return canvas.toDataURL(format, quality); 23252 if (canvas.convertToBlob !== void 0) { 23253 const blob = await canvas.convertToBlob({ type: format, quality }); 23254 return new Promise((resolve, reject) => { 23255 const reader = new FileReader(); 23256 reader.onload = () => resolve(reader.result), reader.onerror = reject, reader.readAsDataURL(blob); 23257 }); 23258 } 23259 throw new Error("Extract.base64() requires ICanvas.toDataURL, ICanvas.toBlob, or ICanvas.convertToBlob to be implemented"); 23260 } 23261 /** 23262 * Creates a Canvas element, renders this target to it and then returns it. 23263 * @param target - A displayObject or renderTexture 23264 * to convert. If left empty will use the main renderer 23265 * @param frame - The frame the extraction is restricted to. 23266 * @returns - A Canvas element with the texture rendered on. 23267 */ 23268 canvas(target, frame) { 23269 const { pixels, width, height, flipY, premultipliedAlpha } = this._rawPixels(target, frame); 23270 flipY && _Extract2._flipY(pixels, width, height), premultipliedAlpha && _Extract2._unpremultiplyAlpha(pixels); 23271 const canvasBuffer = new CanvasRenderTarget(width, height, 1), imageData = new ImageData(new Uint8ClampedArray(pixels.buffer), width, height); 23272 return canvasBuffer.context.putImageData(imageData, 0, 0), canvasBuffer.canvas; 23273 } 23274 /** 23275 * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA 23276 * order, with integer values between 0 and 255 (included). 23277 * @param target - A displayObject or renderTexture 23278 * to convert. If left empty will use the main renderer 23279 * @param frame - The frame the extraction is restricted to. 23280 * @returns - One-dimensional array containing the pixel data of the entire texture 23281 */ 23282 pixels(target, frame) { 23283 const { pixels, width, height, flipY, premultipliedAlpha } = this._rawPixels(target, frame); 23284 return flipY && _Extract2._flipY(pixels, width, height), premultipliedAlpha && _Extract2._unpremultiplyAlpha(pixels), pixels; 23285 } 23286 _rawPixels(target, frame) { 23287 const renderer = this.renderer; 23288 if (!renderer) 23289 throw new Error("The Extract has already been destroyed"); 23290 let resolution, flipY = !1, premultipliedAlpha = !1, renderTexture, generated = !1; 23291 target && (target instanceof RenderTexture ? renderTexture = target : (renderTexture = renderer.generateTexture(target, { 23292 region: frame, 23293 resolution: renderer.resolution, 23294 multisample: renderer.multisample 23295 }), generated = !0, frame && (TEMP_RECT.width = frame.width, TEMP_RECT.height = frame.height, frame = TEMP_RECT))); 23296 const gl = renderer.gl; 23297 if (renderTexture) { 23298 if (resolution = renderTexture.baseTexture.resolution, frame = frame ?? renderTexture.frame, flipY = !1, premultipliedAlpha = renderTexture.baseTexture.alphaMode > 0 && renderTexture.baseTexture.format === FORMATS.RGBA, !generated) { 23299 renderer.renderTexture.bind(renderTexture); 23300 const fbo = renderTexture.framebuffer.glFramebuffers[renderer.CONTEXT_UID]; 23301 fbo.blitFramebuffer && renderer.framebuffer.bind(fbo.blitFramebuffer); 23302 } 23303 } else 23304 resolution = renderer.resolution, frame || (frame = TEMP_RECT, frame.width = renderer.width / resolution, frame.height = renderer.height / resolution), flipY = !0, premultipliedAlpha = this._rendererPremultipliedAlpha, renderer.renderTexture.bind(); 23305 const width = Math.max(Math.round(frame.width * resolution), 1), height = Math.max(Math.round(frame.height * resolution), 1), pixels = new Uint8Array(BYTES_PER_PIXEL * width * height); 23306 return gl.readPixels( 23307 Math.round(frame.x * resolution), 23308 Math.round(frame.y * resolution), 23309 width, 23310 height, 23311 gl.RGBA, 23312 gl.UNSIGNED_BYTE, 23313 pixels 23314 ), generated && renderTexture?.destroy(!0), { pixels, width, height, flipY, premultipliedAlpha }; 23315 } 23316 /** Destroys the extract. */ 23317 destroy() { 23318 this.renderer = null; 23319 } 23320 static _flipY(pixels, width, height) { 23321 const w = width << 2, h = height >> 1, temp = new Uint8Array(w); 23322 for (let y = 0; y < h; y++) { 23323 const t = y * w, b = (height - y - 1) * w; 23324 temp.set(pixels.subarray(t, t + w)), pixels.copyWithin(t, b, b + w), pixels.set(temp, b); 23325 } 23326 } 23327 static _unpremultiplyAlpha(pixels) { 23328 pixels instanceof Uint8ClampedArray && (pixels = new Uint8Array(pixels.buffer)); 23329 const n = pixels.length; 23330 for (let i = 0; i < n; i += 4) {
23331 const alpha = pixels[i + 3]; 23332 if (alpha !== 0) { 23333 const a = 255.001 / alpha; 23334 pixels[i] = pixels[i] * a + 0.5, pixels[i + 1] = pixels[i + 1] * a + 0.5, pixels[i + 2] = pixels[i + 2] * a + 0.5; 23335 } 23336 } 23337 } 23338}; 23339_Extract.extension = { 23340 name: "extract", 23341 type: ExtensionType.RendererSystem 23342}; 23343let Extract = _Extract; 23344extensions$1.add(Extract); 23345 23346const buildCircle = { 23347 build(graphicsData) { 23348 const points = graphicsData.points; 23349 let x, y, dx, dy, rx, ry; 23350 if (graphicsData.type === SHAPES.CIRC) { 23351 const circle = graphicsData.shape; 23352 x = circle.x, y = circle.y, rx = ry = circle.radius, dx = dy = 0; 23353 } else if (graphicsData.type === SHAPES.ELIP) { 23354 const ellipse = graphicsData.shape; 23355 x = ellipse.x, y = ellipse.y, rx = ellipse.width, ry = ellipse.height, dx = dy = 0; 23356 } else { 23357 const roundedRect = graphicsData.shape, halfWidth = roundedRect.width / 2, halfHeight = roundedRect.height / 2; 23358 x = roundedRect.x + halfWidth, y = roundedRect.y + halfHeight, rx = ry = Math.max(0, Math.min(roundedRect.radius, Math.min(halfWidth, halfHeight))), dx = halfWidth - rx, dy = halfHeight - ry; 23359 } 23360 if (!(rx >= 0 && ry >= 0 && dx >= 0 && dy >= 0)) { 23361 points.length = 0; 23362 return; 23363 } 23364 const n = Math.ceil(2.3 * Math.sqrt(rx + ry)), m = n * 8 + (dx ? 4 : 0) + (dy ? 4 : 0); 23365 if (points.length = m, m === 0) 23366 return; 23367 if (n === 0) { 23368 points.length = 8, points[0] = points[6] = x + dx, points[1] = points[3] = y + dy, points[2] = points[4] = x - dx, points[5] = points[7] = y - dy; 23369 return; 23370 } 23371 let j1 = 0, j2 = n * 4 + (dx ? 2 : 0) + 2, j3 = j2, j4 = m; 23372 { 23373 const x0 = dx + rx, y0 = dy, x1 = x + x0, x2 = x - x0, y1 = y + y0; 23374 if (points[j1++] = x1, points[j1++] = y1, points[--j2] = y1, points[--j2] = x2, dy) { 23375 const y2 = y - y0; 23376 points[j3++] = x2, points[j3++] = y2, points[--j4] = y2, points[--j4] = x1; 23377 } 23378 } 23379 for (let i = 1; i < n; i++) { 23380 const a = Math.PI / 2 * (i / n), x0 = dx + Math.cos(a) * rx, y0 = dy + Math.sin(a) * ry, x1 = x + x0, x2 = x - x0, y1 = y + y0, y2 = y - y0; 23381 points[j1++] = x1, points[j1++] = y1, points[--j2] = y1, points[--j2] = x2, points[j3++] = x2, points[j3++] = y2, points[--j4] = y2, points[--j4] = x1; 23382 } 23383 { 23384 const x0 = dx, y0 = dy + ry, x1 = x + x0, x2 = x - x0, y1 = y + y0, y2 = y - y0; 23385 points[j1++] = x1, points[j1++] = y1, points[--j4] = y2, points[--j4] = x1, dx && (points[j1++] = x2, points[j1++] = y1, points[--j4] = y2, points[--j4] = x2); 23386 } 23387 }, 23388 triangulate(graphicsData, graphicsGeometry) { 23389 const points = graphicsData.points, verts = graphicsGeometry.points, indices = graphicsGeometry.indices; 23390 if (points.length === 0) 23391 return; 23392 let vertPos = verts.length / 2; 23393 const center = vertPos; 23394 let x, y; 23395 if (graphicsData.type !== SHAPES.RREC) { 23396 const circle = graphicsData.shape; 23397 x = circle.x, y = circle.y; 23398 } else { 23399 const roundedRect = graphicsData.shape; 23400 x = roundedRect.x + roundedRect.width / 2, y = roundedRect.y + roundedRect.height / 2; 23401 } 23402 const matrix = graphicsData.matrix; 23403 verts.push( 23404 graphicsData.matrix ? matrix.a * x + matrix.c * y + matrix.tx : x, 23405 graphicsData.matrix ? matrix.b * x + matrix.d * y + matrix.ty : y 23406 ), vertPos++, verts.push(points[0], points[1]); 23407 for (let i = 2; i < points.length; i += 2) 23408 verts.push(points[i], points[i + 1]), indices.push(vertPos++, center, vertPos); 23409 indices.push(center + 1, center, vertPos); 23410 } 23411}; 23412 23413function fixOrientation(points, hole = !1) { 23414 const m = points.length; 23415 if (m < 6) 23416 return; 23417 let area = 0; 23418 for (let i = 0, x1 = points[m - 2], y1 = points[m - 1]; i < m; i += 2) { 23419 const x2 = points[i], y2 = points[i + 1]; 23420 area += (x2 - x1) * (y2 + y1), x1 = x2, y1 = y2; 23421 } 23422 if (!hole && area > 0 || hole && area <= 0) { 23423 const n = m / 2; 23424 for (let i = n + n % 2; i < m; i += 2) { 23425 const i1 = m - i - 2, i2 = m - i - 1, i3 = i, i4 = i + 1; 23426 [points[i1], points[i3]] = [points[i3], points[i1]], [points[i2], points[i4]] = [points[i4], points[i2]]; 23427 } 23428 } 23429} 23430const buildPoly = { 23431 build(graphicsData) { 23432 graphicsData.points = graphicsData.shape.points.slice(); 23433 }, 23434 triangulate(graphicsData, graphicsGeometry) { 23435 let points = graphicsData.points; 23436 const holes = graphicsData.holes, verts = graphicsGeometry.points, indices = graphicsGeometry.indices; 23437 if (points.length >= 6) { 23438 fixOrientation(points, !1); 23439 const holeArray = []; 23440 for (let i = 0; i < holes.length; i++) { 23441 const hole = holes[i]; 23442 fixOrientation(hole.points, !0), holeArray.push(points.length / 2), points = points.concat(hole.points); 23443 } 23444 const triangles = earcut$1(points, holeArray, 2); 23445 if (!triangles) 23446 return; 23447 const vertPos = verts.length / 2; 23448 for (let i = 0; i < triangles.length; i += 3) 23449 indices.push(triangles[i] + vertPos), indices.push(triangles[i + 1] + vertPos), indices.push(triangles[i + 2] + vertPos); 23450 for (let i = 0; i < points.length; i++) 23451 verts.push(points[i]); 23452 } 23453 } 23454}; 23455 23456const buildRectangle = { 23457 build(graphicsData) { 23458 const rectData = graphicsData.shape, x = rectData.x, y = rectData.y, width = rectData.width, height = rectData.height, points = graphicsData.points; 23459 points.length = 0, width >= 0 && height >= 0 && points.push( 23460 x, 23461 y, 23462 x + width, 23463 y, 23464 x + width, 23465 y + height, 23466 x, 23467 y + height 23468 ); 23469 }, 23470 triangulate(graphicsData, graphicsGeometry) { 23471 const points = graphicsData.points, verts = graphicsGeometry.points; 23472 if (points.length === 0) 23473 return; 23474 const vertPos = verts.length / 2; 23475 verts.push( 23476 points[0], 23477 points[1], 23478 points[2], 23479 points[3], 23480 points[6], 23481 points[7], 23482 points[4], 23483 points[5] 23484 ), graphicsGeometry.indices.push( 23485 vertPos, 23486 vertPos + 1, 23487 vertPos + 2, 23488 vertPos + 1, 23489 vertPos + 2, 23490 vertPos + 3 23491 ); 23492 } 23493}; 23494 23495const buildRoundedRectangle = { 23496 build(graphicsData) { 23497 buildCircle.build(graphicsData); 23498 }, 23499 triangulate(graphicsData, graphicsGeometry) { 23500 buildCircle.triangulate(graphicsData, graphicsGeometry); 23501 } 23502}; 23503 23504var LINE_JOIN = /* @__PURE__ */ ((LINE_JOIN2) => (LINE_JOIN2.MITER = "miter", LINE_JOIN2.BEVEL = "bevel", LINE_JOIN2.ROUND = "round", LINE_JOIN2))(LINE_JOIN || {}), LINE_CAP = /* @__PURE__ */ ((LINE_CAP2) => (LINE_CAP2.BUTT = "butt", LINE_CAP2.ROUND = "round", LINE_CAP2.SQUARE = "square", LINE_CAP2))(LINE_CAP || {}); 23505const curves = { 23506 adaptive: !0, 23507 maxLength: 10, 23508 minSegments: 8, 23509 maxSegments: 2048, 23510 epsilon: 1e-4, 23511 _segmentsCount(length, defaultSegments = 20) { 23512 if (!this.adaptive || !length || isNaN(length)) 23513 return defaultSegments;
23514 let result = Math.ceil(length / this.maxLength); 23515 return result < this.minSegments ? result = this.minSegments : result > this.maxSegments && (result = this.maxSegments), result; 23516 } 23517}; 23518 23519class ArcUtils { 23520 /** 23521 * Calculate information of the arc for {@link PIXI.Graphics.arcTo}. 23522 * @private 23523 * @param x1 - The x-coordinate of the first control point of the arc 23524 * @param y1 - The y-coordinate of the first control point of the arc 23525 * @param x2 - The x-coordinate of the second control point of the arc 23526 * @param y2 - The y-coordinate of the second control point of the arc 23527 * @param radius - The radius of the arc 23528 * @param points - Collection of points to add to 23529 * @returns - If the arc length is valid, return center of circle, radius and other info otherwise `null`. 23530 */ 23531 static curveTo(x1, y1, x2, y2, radius, points) { 23532 const fromX = points[points.length - 2], a1 = points[points.length - 1] - y1, b1 = fromX - x1, a2 = y2 - y1, b2 = x2 - x1, mm = Math.abs(a1 * b2 - b1 * a2); 23533 if (mm < 1e-8 || radius === 0) 23534 return (points[points.length - 2] !== x1 || points[points.length - 1] !== y1) && points.push(x1, y1), null; 23535 const dd = a1 * a1 + b1 * b1, cc = a2 * a2 + b2 * b2, tt = a1 * a2 + b1 * b2, k1 = radius * Math.sqrt(dd) / mm, k2 = radius * Math.sqrt(cc) / mm, j1 = k1 * tt / dd, j2 = k2 * tt / cc, cx = k1 * b2 + k2 * b1, cy = k1 * a2 + k2 * a1, px = b1 * (k2 + j1), py = a1 * (k2 + j1), qx = b2 * (k1 + j2), qy = a2 * (k1 + j2), startAngle = Math.atan2(py - cy, px - cx), endAngle = Math.atan2(qy - cy, qx - cx); 23536 return { 23537 cx: cx + x1, 23538 cy: cy + y1, 23539 radius, 23540 startAngle, 23541 endAngle, 23542 anticlockwise: b1 * a2 > b2 * a1 23543 }; 23544 } 23545 /** 23546 * The arc method creates an arc/curve (used to create circles, or parts of circles). 23547 * @private 23548 * @param _startX - Start x location of arc 23549 * @param _startY - Start y location of arc 23550 * @param cx - The x-coordinate of the center of the circle 23551 * @param cy - The y-coordinate of the center of the circle 23552 * @param radius - The radius of the circle 23553 * @param startAngle - The starting angle, in radians (0 is at the 3 o'clock position 23554 * of the arc's circle) 23555 * @param endAngle - The ending angle, in radians 23556 * @param _anticlockwise - Specifies whether the drawing should be 23557 * counter-clockwise or clockwise. False is default, and indicates clockwise, while true 23558 * indicates counter-clockwise. 23559 * @param points - Collection of points to add to 23560 */ 23561 static arc(_startX, _startY, cx, cy, radius, startAngle, endAngle, _anticlockwise, points) { 23562 const sweep = endAngle - startAngle, n = curves._segmentsCount( 23563 Math.abs(sweep) * radius, 23564 Math.ceil(Math.abs(sweep) / PI_2) * 40 23565 ), theta = sweep / (n * 2), theta2 = theta * 2, cTheta = Math.cos(theta), sTheta = Math.sin(theta), segMinus = n - 1, remainder = segMinus % 1 / segMinus; 23566 for (let i = 0; i <= segMinus; ++i) { 23567 const real = i + remainder * i, angle = theta + startAngle + theta2 * real, c = Math.cos(angle), s = -Math.sin(angle); 23568 points.push( 23569 (cTheta * c + sTheta * s) * radius + cx, 23570 (cTheta * -s + sTheta * c) * radius + cy 23571 ); 23572 } 23573 } 23574} 23575 23576class BatchPart { 23577 constructor() { 23578 this.reset(); 23579 } 23580 /** 23581 * Begin batch part. 23582 * @param style 23583 * @param startIndex 23584 * @param attribStart 23585 */ 23586 begin(style, startIndex, attribStart) { 23587 this.reset(), this.style = style, this.start = startIndex, this.attribStart = attribStart; 23588 } 23589 /** 23590 * End batch part. 23591 * @param endIndex 23592 * @param endAttrib 23593 */ 23594 end(endIndex, endAttrib) { 23595 this.attribSize = endAttrib - this.attribStart, this.size = endIndex - this.start; 23596 } 23597 reset() { 23598 this.style = null, this.size = 0, this.start = 0, this.attribStart = 0, this.attribSize = 0; 23599 } 23600} 23601 23602class BezierUtils { 23603 /** 23604 * Calculate length of bezier curve. 23605 * Analytical solution is impossible, since it involves an integral that does not integrate in general. 23606 * Therefore numerical solution is used. 23607 * @private 23608 * @param fromX - Starting point x 23609 * @param fromY - Starting point y 23610 * @param cpX - Control point x 23611 * @param cpY - Control point y 23612 * @param cpX2 - Second Control point x 23613 * @param cpY2 - Second Control point y 23614 * @param toX - Destination point x 23615 * @param toY - Destination point y 23616 * @returns - Length of bezier curve 23617 */ 23618 static curveLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY) { 23619 let result = 0, t = 0, t2 = 0, t3 = 0, nt = 0, nt2 = 0, nt3 = 0, x = 0, y = 0, dx = 0, dy = 0, prevX = fromX, prevY = fromY; 23620 for (let i = 1; i <= 10; ++i) 23621 t = i / 10, t2 = t * t, t3 = t2 * t, nt = 1 - t, nt2 = nt * nt, nt3 = nt2 * nt, x = nt3 * fromX + 3 * nt2 * t * cpX + 3 * nt * t2 * cpX2 + t3 * toX, y = nt3 * fromY + 3 * nt2 * t * cpY + 3 * nt * t2 * cpY2 + t3 * toY, dx = prevX - x, dy = prevY - y, prevX = x, prevY = y, result += Math.sqrt(dx * dx + dy * dy); 23622 return result; 23623 } 23624 /** 23625 * Calculate the points for a bezier curve and then draws it. 23626 *
23627 * Ignored from docs since it is not directly exposed. 23628 * @ignore 23629 * @param cpX - Control point x 23630 * @param cpY - Control point y 23631 * @param cpX2 - Second Control point x 23632 * @param cpY2 - Second Control point y 23633 * @param toX - Destination point x 23634 * @param toY - Destination point y 23635 * @param points - Path array to push points into 23636 */ 23637 static curveTo(cpX, cpY, cpX2, cpY2, toX, toY, points) { 23638 const fromX = points[points.length - 2], fromY = points[points.length - 1]; 23639 points.length -= 2; 23640 const n = curves._segmentsCount( 23641 BezierUtils.curveLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY) 23642 ); 23643 let dt = 0, dt2 = 0, dt3 = 0, t2 = 0, t3 = 0; 23644 points.push(fromX, fromY); 23645 for (let i = 1, j = 0; i <= n; ++i) 23646 j = i / n, dt = 1 - j, dt2 = dt * dt, dt3 = dt2 * dt, t2 = j * j, t3 = t2 * j, points.push( 23647 dt3 * fromX + 3 * dt2 * j * cpX + 3 * dt * t2 * cpX2 + t3 * toX, 23648 dt3 * fromY + 3 * dt2 * j * cpY + 3 * dt * t2 * cpY2 + t3 * toY 23649 ); 23650 } 23651} 23652 23653function square(x, y, nx, ny, innerWeight, outerWeight, clockwise, verts) { 23654 const ix = x - nx * innerWeight, iy = y - ny * innerWeight, ox = x + nx * outerWeight, oy = y + ny * outerWeight; 23655 let exx, eyy; 23656 clockwise ? (exx = ny, eyy = -nx) : (exx = -ny, eyy = nx); 23657 const eix = ix + exx, eiy = iy + eyy, eox = ox + exx, eoy = oy + eyy; 23658 return verts.push( 23659 eix, 23660 eiy, 23661 eox, 23662 eoy 23663 ), 2; 23664} 23665function round(cx, cy, sx, sy, ex, ey, verts, clockwise) { 23666 const cx2p0x = sx - cx, cy2p0y = sy - cy; 23667 let angle0 = Math.atan2(cx2p0x, cy2p0y), angle1 = Math.atan2(ex - cx, ey - cy); 23668 clockwise && angle0 < angle1 ? angle0 += Math.PI * 2 : !clockwise && angle0 > angle1 && (angle1 += Math.PI * 2); 23669 let startAngle = angle0; 23670 const angleDiff = angle1 - angle0, absAngleDiff = Math.abs(angleDiff), radius = Math.sqrt(cx2p0x * cx2p0x + cy2p0y * cy2p0y), segCount = (15 * absAngleDiff * Math.sqrt(radius) / Math.PI >> 0) + 1, angleInc = angleDiff / segCount; 23671 if (startAngle += angleInc, clockwise) { 23672 verts.push( 23673 cx, 23674 cy, 23675 sx, 23676 sy 23677 ); 23678 for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) 23679 verts.push( 23680 cx, 23681 cy, 23682 cx + Math.sin(angle) * radius, 23683 cy + Math.cos(angle) * radius 23684 ); 23685 verts.push( 23686 cx, 23687 cy, 23688 ex, 23689 ey 23690 ); 23691 } else { 23692 verts.push( 23693 sx, 23694 sy, 23695 cx, 23696 cy 23697 ); 23698 for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) 23699 verts.push( 23700 cx + Math.sin(angle) * radius, 23701 cy + Math.cos(angle) * radius, 23702 cx, 23703 cy 23704 ); 23705 verts.push( 23706 ex, 23707 ey, 23708 cx, 23709 cy 23710 ); 23711 } 23712 return segCount * 2; 23713} 23714function buildNonNativeLine(graphicsData, graphicsGeometry) { 23715 const shape = graphicsData.shape; 23716 let points = graphicsData.points || shape.points.slice(); 23717 const eps = graphicsGeometry.closePointEps; 23718 if (points.length === 0) 23719 return; 23720 const style = graphicsData.lineStyle, firstPoint = new Point(points[0], points[1]), lastPoint = new Point(points[points.length - 2], points[points.length - 1]), closedShape = shape.type !== SHAPES.POLY || shape.closeStroke, closedPath = Math.abs(firstPoint.x - lastPoint.x) < eps && Math.abs(firstPoint.y - lastPoint.y) < eps; 23721 if (closedShape) { 23722 points = points.slice(), closedPath && (points.pop(), points.pop(), lastPoint.set(points[points.length - 2], points[points.length - 1])); 23723 const midPointX = (firstPoint.x + lastPoint.x) * 0.5, midPointY = (lastPoint.y + firstPoint.y) * 0.5; 23724 points.unshift(midPointX, midPointY), points.push(midPointX, midPointY); 23725 } 23726 const verts = graphicsGeometry.points, length = points.length / 2; 23727 let indexCount = points.length; 23728 const indexStart = verts.length / 2, width = style.width / 2, widthSquared = width * width, miterLimitSquared = style.miterLimit * style.miterLimit; 23729 let x0 = points[0], y0 = points[1], x1 = points[2], y1 = points[3], x2 = 0, y2 = 0, perpx = -(y0 - y1), perpy = x0 - x1, perp1x = 0, perp1y = 0, dist = Math.sqrt(perpx * perpx + perpy * perpy); 23730 perpx /= dist, perpy /= dist, perpx *= width, perpy *= width; 23731 const ratio = style.alignment, innerWeight = (1 - ratio) * 2, outerWeight = ratio * 2; 23732 closedShape || (style.cap === LINE_CAP.ROUND ? indexCount += round( 23733 x0 - perpx * (innerWeight - outerWeight) * 0.5, 23734 y0 - perpy * (innerWeight - outerWeight) * 0.5, 23735 x0 - perpx * innerWeight, 23736 y0 - perpy * innerWeight, 23737 x0 + perpx * outerWeight, 23738 y0 + perpy * outerWeight, 23739 verts, 23740 !0 23741 ) + 2 : style.cap === LINE_CAP.SQUARE && (indexCount += square(x0, y0, perpx, perpy, innerWeight, outerWeight, !0, verts))), verts.push( 23742 x0 - perpx * innerWeight, 23743 y0 - perpy * innerWeight, 23744 x0 + perpx * outerWeight, 23745 y0 + perpy * outerWeight 23746 ); 23747 for (let i = 1; i < length - 1; ++i) { 23748 x0 = points[(i - 1) * 2], y0 = points[(i - 1) * 2 + 1], x1 = points[i * 2], y1 = points[i * 2 + 1], x2 = points[(i + 1) * 2], y2 = points[(i
vendor: 6,449 bytes, lines 23748-23928
23748 + 1) * 2 + 1], perpx = -(y0 - y1), perpy = x0 - x1, dist = Math.sqrt(perpx * perpx + perpy * perpy), perpx /= dist, perpy /= dist, perpx *= width, perpy *= width, perp1x = -(y1 - y2), perp1y = x1 - x2, dist = Math.sqrt(perp1x * perp1x + perp1y * perp1y), perp1x /= dist, perp1y /= dist, perp1x *= width, perp1y *= width; 23749 const dx0 = x1 - x0, dy0 = y0 - y1, dx1 = x1 - x2, dy1 = y2 - y1, dot = dx0 * dx1 + dy0 * dy1, cross = dy0 * dx1 - dy1 * dx0, clockwise = cross < 0; 23750 if (Math.abs(cross) < 1e-3 * Math.abs(dot)) { 23751 verts.push( 23752 x1 - perpx * innerWeight, 23753 y1 - perpy * innerWeight, 23754 x1 + perpx * outerWeight, 23755 y1 + perpy * outerWeight 23756 ), dot >= 0 && (style.join === LINE_JOIN.ROUND ? indexCount += round( 23757 x1, 23758 y1, 23759 x1 - perpx * innerWeight, 23760 y1 - perpy * innerWeight, 23761 x1 - perp1x * innerWeight, 23762 y1 - perp1y * innerWeight, 23763 verts, 23764 !1 23765 ) + 4 : indexCount += 2, verts.push( 23766 x1 - perp1x * outerWeight, 23767 y1 - perp1y * outerWeight, 23768 x1 + perp1x * innerWeight, 23769 y1 + perp1y * innerWeight 23770 )); 23771 continue; 23772 } 23773 const c1 = (-perpx + x0) * (-perpy + y1) - (-perpx + x1) * (-perpy + y0), c2 = (-perp1x + x2) * (-perp1y + y1) - (-perp1x + x1) * (-perp1y + y2), px = (dx0 * c2 - dx1 * c1) / cross, py = (dy1 * c1 - dy0 * c2) / cross, pdist = (px - x1) * (px - x1) + (py - y1) * (py - y1), imx = x1 + (px - x1) * innerWeight, imy = y1 + (py - y1) * innerWeight, omx = x1 - (px - x1) * outerWeight, omy = y1 - (py - y1) * outerWeight, smallerInsideSegmentSq = Math.min(dx0 * dx0 + dy0 * dy0, dx1 * dx1 + dy1 * dy1), insideWeight = clockwise ? innerWeight : outerWeight, smallerInsideDiagonalSq = smallerInsideSegmentSq + insideWeight * insideWeight * widthSquared, insideMiterOk = pdist <= smallerInsideDiagonalSq; 23774 let join = style.join; 23775 if (join === LINE_JOIN.MITER && pdist / widthSquared > miterLimitSquared && (join = LINE_JOIN.BEVEL), insideMiterOk) 23776 switch (join) { 23777 case LINE_JOIN.MITER: { 23778 verts.push( 23779 imx, 23780 imy, 23781 omx, 23782 omy 23783 ); 23784 break; 23785 } 23786 case LINE_JOIN.BEVEL: { 23787 clockwise ? verts.push( 23788 imx, 23789 imy, 23790 // inner miter point 23791 x1 + perpx * outerWeight, 23792 y1 + perpy * outerWeight, 23793 // first segment's outer vertex 23794 imx, 23795 imy, 23796 // inner miter point 23797 x1 + perp1x * outerWeight, 23798 y1 + perp1y * outerWeight 23799 ) : verts.push( 23800 x1 - perpx * innerWeight, 23801 y1 - perpy * innerWeight, 23802 // first segment's inner vertex 23803 omx, 23804 omy, 23805 // outer miter point 23806 x1 - perp1x * innerWeight, 23807 y1 - perp1y * innerWeight, 23808 // second segment's outer vertex 23809 omx, 23810 omy 23811 ), indexCount += 2; 23812 break; 23813 } 23814 case LINE_JOIN.ROUND: { 23815 clockwise ? (verts.push( 23816 imx, 23817 imy, 23818 x1 + perpx * outerWeight, 23819 y1 + perpy * outerWeight 23820 ), indexCount += round( 23821 x1, 23822 y1, 23823 x1 + perpx * outerWeight, 23824 y1 + perpy * outerWeight, 23825 x1 + perp1x * outerWeight, 23826 y1 + perp1y * outerWeight, 23827 verts, 23828 !0 23829 ) + 4, verts.push( 23830 imx, 23831 imy, 23832 x1 + perp1x * outerWeight, 23833 y1 + perp1y * outerWeight 23834 )) : (verts.push( 23835 x1 - perpx * innerWeight, 23836 y1 - perpy * innerWeight, 23837 omx, 23838 omy 23839 ), indexCount += round( 23840 x1, 23841 y1, 23842 x1 - perpx * innerWeight, 23843 y1 - perpy * innerWeight, 23844 x1 - perp1x * innerWeight, 23845 y1 - perp1y * innerWeight, 23846 verts, 23847 !1 23848 ) + 4, verts.push( 23849 x1 - perp1x * innerWeight, 23850 y1 - perp1y * innerWeight, 23851 omx, 23852 omy 23853 )); 23854 break; 23855 } 23856 } 23857 else { 23858 switch (verts.push( 23859 x1 - perpx * innerWeight, 23860 y1 - perpy * innerWeight, 23861 // first segment's inner vertex 23862 x1 + perpx * outerWeight, 23863 y1 + perpy * outerWeight 23864 ), join) { 23865 case LINE_JOIN.MITER: { 23866 clockwise ? verts.push( 23867 omx, 23868 omy, 23869 // inner miter point 23870 omx, 23871 omy 23872 ) : verts.push( 23873 imx, 23874 imy, 23875 // outer miter point 23876 imx, 23877 imy 23878 ), indexCount += 2; 23879 break; 23880 } 23881 case LINE_JOIN.ROUND: { 23882 clockwise ? indexCount += round( 23883 x1, 23884 y1, 23885 x1 + perpx * outerWeight, 23886 y1 + perpy * outerWeight, 23887 x1 + perp1x * outerWeight, 23888 y1 + perp1y * outerWeight, 23889 verts, 23890 !0 23891 ) + 2 : indexCount += round( 23892 x1, 23893 y1, 23894 x1 - perpx * innerWeight, 23895 y1 - perpy * innerWeight, 23896 x1 - perp1x * innerWeight, 23897 y1 - perp1y * innerWeight, 23898 verts, 23899 !1 23900 ) + 2; 23901 break; 23902 } 23903 } 23904 verts.push( 23905 x1 - perp1x * innerWeight, 23906 y1 - perp1y * innerWeight, 23907 // second segment's inner vertex 23908 x1 + perp1x * outerWeight, 23909 y1 + perp1y * outerWeight 23910 ), indexCount += 2; 23911 } 23912 } 23913 x0 = points[(length - 2) * 2], y0 = points[(length - 2) * 2 + 1], x1 = points[(length - 1) * 2], y1 = points[(length - 1) * 2 + 1], perpx = -(y0 - y1), perpy = x0 - x1, dist = Math.sqrt(perpx * perpx + perpy * perpy), perpx /= dist, perpy /= dist, perpx *= width, perpy *= width, verts.push( 23914 x1 - perpx * innerWeight, 23915 y1 - perpy * innerWeight, 23916 x1 + perpx * outerWeight, 23917 y1 + perpy * outerWeight 23918 ), closedShape || (style.cap === LINE_CAP.ROUND ? indexCount += round( 23919 x1 - perpx * (innerWeight - outerWeight) * 0.5, 23920 y1 - perpy * (innerWeight - outerWeight) * 0.5, 23921 x1 - perpx * innerWeight, 23922 y1 - perpy * innerWeight, 23923 x1 + perpx * outerWeight, 23924 y1 + perpy * outerWeight, 23925 verts, 23926 !1 23927 ) + 2 : style.cap === LINE_CAP.SQUARE && (indexCount += square(x1, y1, perpx, perpy, innerWeight, outerWeight, !1, verts))); 23928 const indices
23928 = graphicsGeometry.indices, eps2 = curves.epsilon * curves.epsilon; 23929 for (let i = indexStart; i < indexCount + indexStart - 2; ++i) 23930 x0 = verts[i * 2], y0 = verts[i * 2 + 1], x1 = verts[(i + 1) * 2], y1 = verts[(i + 1) * 2 + 1], x2 = verts[(i + 2) * 2], y2 = verts[(i + 2) * 2 + 1], !(Math.abs(x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1)) < eps2) && indices.push(i, i + 1, i + 2); 23931} 23932function buildNativeLine(graphicsData, graphicsGeometry) { 23933 let i = 0; 23934 const shape = graphicsData.shape, points = graphicsData.points || shape.points, closedShape = shape.type !== SHAPES.POLY || shape.closeStroke; 23935 if (points.length === 0) 23936 return; 23937 const verts = graphicsGeometry.points, indices = graphicsGeometry.indices, length = points.length / 2, startIndex = verts.length / 2; 23938 let currentIndex = startIndex; 23939 for (verts.push(points[0], points[1]), i = 1; i < length; i++) 23940 verts.push(points[i * 2], points[i * 2 + 1]), indices.push(currentIndex, currentIndex + 1), currentIndex++; 23941 closedShape && indices.push(currentIndex, startIndex); 23942} 23943function buildLine(graphicsData, graphicsGeometry) { 23944 graphicsData.lineStyle.native ? buildNativeLine(graphicsData, graphicsGeometry) : buildNonNativeLine(graphicsData, graphicsGeometry); 23945} 23946 23947class QuadraticUtils { 23948 /** 23949 * Calculate length of quadratic curve 23950 * @see {@link http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/} 23951 * for the detailed explanation of math behind this. 23952 * @private 23953 * @param fromX - x-coordinate of curve start point 23954 * @param fromY - y-coordinate of curve start point 23955 * @param cpX - x-coordinate of curve control point 23956 * @param cpY - y-coordinate of curve control point 23957 * @param toX - x-coordinate of curve end point 23958 * @param toY - y-coordinate of curve end point 23959 * @returns - Length of quadratic curve 23960 */ 23961 static curveLength(fromX, fromY, cpX, cpY, toX, toY) { 23962 const ax = fromX - 2 * cpX + toX, ay = fromY - 2 * cpY + toY, bx = 2 * cpX - 2 * fromX, by = 2 * cpY - 2 * fromY, a = 4 * (ax * ax + ay * ay), b = 4 * (ax * bx + ay * by), c = bx * bx + by * by, s = 2 * Math.sqrt(a + b + c), a2 = Math.sqrt(a), a32 = 2 * a * a2, c2 = 2 * Math.sqrt(c), ba = b / a2; 23963 return (a32 * s + a2 * b * (s - c2) + (4 * c * a - b * b) * Math.log((2 * a2 + ba + s) / (ba + c2))) / (4 * a32); 23964 } 23965 /** 23966 * Calculate the points for a quadratic bezier curve and then draws it. 23967 * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c 23968 * @private 23969 * @param cpX - Control point x 23970 * @param cpY - Control point y 23971 * @param toX - Destination point x 23972 * @param toY - Destination point y 23973 * @param points - Points to add segments to. 23974 */ 23975 static curveTo(cpX, cpY, toX, toY, points) { 23976 const fromX = points[points.length - 2], fromY = points[points.length - 1], n = curves._segmentsCount( 23977 QuadraticUtils.curveLength(fromX, fromY, cpX, cpY, toX, toY) 23978 ); 23979 let xa = 0, ya = 0; 23980 for (let i = 1; i <= n; ++i) { 23981 const j = i / n; 23982 xa = fromX + (cpX - fromX) * j, ya = fromY + (cpY - fromY) * j, points.push( 23983 xa + (cpX + (toX - cpX) * j - xa) * j, 23984 ya + (cpY + (toY - cpY) * j - ya) * j 23985 ); 23986 } 23987 } 23988} 23989 23990const FILL_COMMANDS = { 23991 [SHAPES.POLY]: buildPoly, 23992 [SHAPES.CIRC]: buildCircle, 23993 [SHAPES.ELIP]: buildCircle, 23994 [SHAPES.RECT]: buildRectangle, 23995 [SHAPES.RREC]: buildRoundedRectangle 23996}, BATCH_POOL = [], DRAW_CALL_POOL = []; 23997 23998class GraphicsData { 23999 /** 24000 * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw. 24001 * @param fillStyle - the width of the line to draw 24002 * @param lineStyle - the color of the line to draw 24003 * @param matrix - Transform matrix 24004 */ 24005 constructor(shape, fillStyle = null, lineStyle = null, matrix = null) { 24006 this.points = [], this.holes = [], this.shape = shape, this.lineStyle = lineStyle, this.fillStyle = fillStyle, this.matrix = matrix, this.type = shape.type; 24007 } 24008 /** 24009 * Creates a new GraphicsData object with the same values as this one. 24010 * @returns - Cloned GraphicsData object 24011 */ 24012 clone() { 24013 return new GraphicsData( 24014 this.shape, 24015 this.fillStyle, 24016 this.lineStyle, 24017 this.matrix 24018 ); 24019 } 24020 /** Destroys the Graphics data. */ 24021 destroy() { 24022 this.shape = null, this.holes.length = 0, this.holes = null, this.points.length = 0, this.points = null, this.lineStyle = null, this.fillStyle = null; 24023 } 24024} 24025 24026const tmpPoint = new Point(), _GraphicsGeometry = class _GraphicsGeometry2 extends BatchGeometry { 24027 // eslint-disable-next-line @typescript-eslint/no-useless-constructor 24028 constructor() { 24029 super(), this.closePointEps = 1e-4, this.boundsPadding = 0, this.uvsFloat32 = null, this.indicesUint16 = null, this.batchable = !1, this.points = [], this.colors = [], this.uvs = [], this.indices = [], this.textureIds = [], this.graphicsData = [], this.drawCalls = [], this.batchDirty = -1, this.batches = [], this.dirty = 0, this.cacheDirty = -1, this.clearDirty = 0, this.shapeIndex = 0, this._bounds = new Bounds(), this.boundsDirty = -1; 24030 } 24031 /** 24032 * Get the current bounds of the graphic geometry. 24033 * 24034 * Since 6.5.0, bounds of the graphics geometry are calculated based on the vertices of generated geometry. 24035 * Since shapes or strokes with full transparency (`alpha: 0`) will not generate geometry, they are not considered 24036 * when calculating bounds for the graphics geometry. See PR [#8343]{@link https://github.com/pixijs/pixijs/pull/8343} 24037 * and issue [#8623]{@link https://github.com/pixijs/pixijs/pull/8623}. 24038 * @readonly 24039 */ 24040 get bounds() { 24041 return this.updateBatches(), this.boundsDirty !== this.dirty && (this.boundsDirty = this.dirty, this.calculateBounds()), this._bounds; 24042 } 24043 /** Call if you changed graphicsData manually. Empties all batch buffers. */ 24044 invalidate() { 24045 this.boundsDirty = -1, this.dirty++, this.batchDirty++, this.shapeIndex = 0, this.points.length = 0, this.colors.length = 0, this.uvs.length = 0, this.indices.length = 0, this.textureIds.length = 0; 24046 for (let i = 0; i < this.drawCalls.length; i++) 24047 this.drawCalls[i].texArray.clear(), DRAW_CALL_POOL.push(this.drawCalls[i]); 24048 this.drawCalls.length = 0; 24049 for (let i = 0; i < this.batches.length; i++) { 24050 const batchPart = this.batches[i]; 24051 batchPart.reset(), BATCH_POOL.push(batchPart); 24052 } 24053 this.batches.length = 0; 24054 } 24055 /** 24056 * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. 24057 * @returns - This GraphicsGeometry object. Good for chaining method calls 24058 */ 24059 clear() { 24060 return this.graphicsData.length > 0 && (this.invalidate(), this.clearDirty++, this.graphicsData.length = 0), this; 24061 } 24062 /** 24063 * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon. 24064 * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw. 24065 * @param fillStyle - Defines style of the fill. 24066 * @param lineStyle - Defines style of the lines. 24067 * @param matrix - Transform applied to the points of the shape. 24068 * @returns - Returns geometry for chaining. 24069 */ 24070 drawShape(shape, fillStyle = null, lineStyle = null, matrix = null) { 24071 const data = new GraphicsData(shape, fillStyle, lineStyle, matrix
24071); 24072 return this.graphicsData.push(data), this.dirty++, this; 24073 } 24074 /** 24075 * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon. 24076 * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw. 24077 * @param matrix - Transform applied to the points of the shape. 24078 * @returns - Returns geometry for chaining. 24079 */ 24080 drawHole(shape, matrix = null) { 24081 if (!this.graphicsData.length) 24082 return null; 24083 const data = new GraphicsData(shape, null, null, matrix), lastShape = this.graphicsData[this.graphicsData.length - 1]; 24084 return data.lineStyle = lastShape.lineStyle, lastShape.holes.push(data), this.dirty++, this; 24085 } 24086 /** Destroys the GraphicsGeometry object. */ 24087 destroy() { 24088 super.destroy(); 24089 for (let i = 0; i < this.graphicsData.length; ++i) 24090 this.graphicsData[i].destroy(); 24091 this.points.length = 0, this.points = null, this.colors.length = 0, this.colors = null, this.uvs.length = 0, this.uvs = null, this.indices.length = 0, this.indices = null, this.indexBuffer.destroy(), this.indexBuffer = null, this.graphicsData.length = 0, this.graphicsData = null, this.drawCalls.length = 0, this.drawCalls = null, this.batches.length = 0, this.batches = null, this._bounds = null; 24092 } 24093 /** 24094 * Check to see if a point is contained within this geometry. 24095 * @param point - Point to check if it's contained. 24096 * @returns {boolean} `true` if the point is contained within geometry. 24097 */ 24098 containsPoint(point) { 24099 const graphicsData = this.graphicsData; 24100 for (let i = 0; i < graphicsData.length; ++i) { 24101 const data = graphicsData[i]; 24102 if (data.fillStyle.visible && data.shape && (data.matrix ? data.matrix.applyInverse(point, tmpPoint) : tmpPoint.copyFrom(point), data.shape.contains(tmpPoint.x, tmpPoint.y))) { 24103 let hitHole = !1; 24104 if (data.holes) { 24105 for (let i2 = 0; i2 < data.holes.length; i2++) 24106 if (data.holes[i2].shape.contains(tmpPoint.x, tmpPoint.y)) { 24107 hitHole = !0; 24108 break; 24109 } 24110 } 24111 if (!hitHole) 24112 return !0; 24113 } 24114 } 24115 return !1; 24116 } 24117 /** 24118 * Generates intermediate batch data. Either gets converted to drawCalls 24119 * or used to convert to batch objects directly by the Graphics object. 24120 */ 24121 updateBatches() { 24122 if (!this.graphicsData.length) { 24123 this.batchable = !0; 24124 return; 24125 } 24126 if (!this.validateBatching()) 24127 return; 24128 this.cacheDirty = this.dirty; 24129 const uvs = this.uvs, graphicsData = this.graphicsData; 24130 let batchPart = null, currentStyle = null; 24131 this.batches.length > 0 && (batchPart = this.batches[this.batches.length - 1], currentStyle = batchPart.style); 24132 for (let i = this.shapeIndex; i < graphicsData.length; i++) { 24133 this.shapeIndex++; 24134 const data = graphicsData[i], fillStyle = data.fillStyle, lineStyle = data.lineStyle; 24135 FILL_COMMANDS[data.type].build(data), data.matrix && this.transformPoints(data.points, data.matrix), (fillStyle.visible || lineStyle.visible) && this.processHoles(data.holes); 24136 for (let j = 0; j < 2; j++) { 24137 const style = j === 0 ? fillStyle : lineStyle; 24138 if (!style.visible) 24139 continue; 24140 const nextTexture = style.texture.baseTexture, index2 = this.indices.length, attribIndex = this.points.length / 2; 24141 nextTexture.wrapMode = WRAP_MODES.REPEAT, j === 0 ? this.processFill(data) : this.processLine(data); 24142 const size = this.points.length / 2 - attribIndex; 24143 size !== 0 && (batchPart && !this._compareStyles(currentStyle, style) && (batchPart.end(index2, attribIndex), batchPart = null), batchPart || (batchPart = BATCH_POOL.pop() || new BatchPart(), batchPart.begin(style, index2, attribIndex), this.batches.push(batchPart), currentStyle = style), this.addUvs(this.points, uvs, style.texture, attribIndex, size, style.matrix)); 24144 } 24145 } 24146 const index = this.indices.length, attrib = this.points.length / 2; 24147 if (batchPart && batchPart.end(index, attrib), this.batches.length === 0) { 24148 this.batchable = !0; 24149 return; 24150 } 24151 const need32 = attrib > 65535; 24152 this.indicesUint16 && this.indices.length === this.indicesUint16.length && need32 === this.indicesUint16.BYTES_PER_ELEMENT > 2 ? this.indicesUint16.set(this.indices) : this.indicesUint16 = need32 ? new Uint32Array(this.indices) : new Uint16Array(this.indices), this.batchable = this.isBatchable(), this.batchable ? this.packBatches() : this.buildDrawCalls(); 24153 } 24154 /** 24155 * Affinity check 24156 * @param styleA 24157 * @param styleB 24158 */
24159 _compareStyles(styleA, styleB) { 24160 return !(!styleA || !styleB || styleA.texture.baseTexture !== styleB.texture.baseTexture || styleA.color + styleA.alpha !== styleB.color + styleB.alpha || !!styleA.native != !!styleB.native); 24161 } 24162 /** Test geometry for batching process. */ 24163 validateBatching() { 24164 if (this.dirty === this.cacheDirty || !this.graphicsData.length) 24165 return !1; 24166 for (let i = 0, l = this.graphicsData.length; i < l; i++) { 24167 const data = this.graphicsData[i], fill = data.fillStyle, line = data.lineStyle; 24168 if (fill && !fill.texture.baseTexture.valid || line && !line.texture.baseTexture.valid) 24169 return !1; 24170 } 24171 return !0; 24172 } 24173 /** Offset the indices so that it works with the batcher. */ 24174 packBatches() { 24175 this.batchDirty++, this.uvsFloat32 = new Float32Array(this.uvs); 24176 const batches = this.batches; 24177 for (let i = 0, l = batches.length; i < l; i++) { 24178 const batch = batches[i]; 24179 for (let j = 0; j < batch.size; j++) { 24180 const index = batch.start + j; 24181 this.indicesUint16[index] = this.indicesUint16[index] - batch.attribStart; 24182 } 24183 } 24184 } 24185 /** 24186 * Checks to see if this graphics geometry can be batched. 24187 * Currently it needs to be small enough and not contain any native lines. 24188 */ 24189 isBatchable() { 24190 if (this.points.length > 65535 * 2) 24191 return !1; 24192 const batches = this.batches; 24193 for (let i = 0; i < batches.length; i++) 24194 if (batches[i].style.native) 24195 return !1; 24196 return this.points.length < _GraphicsGeometry2.BATCHABLE_SIZE * 2; 24197 } 24198 /** Converts intermediate batches data to drawCalls. */ 24199 buildDrawCalls() { 24200 let TICK = ++BaseTexture._globalBatch; 24201 for (let i = 0; i < this.drawCalls.length; i++) 24202 this.drawCalls[i].texArray.clear(), DRAW_CALL_POOL.push(this.drawCalls[i]); 24203 this.drawCalls.length = 0; 24204 const colors = this.colors, textureIds = this.textureIds; 24205 let currentGroup = DRAW_CALL_POOL.pop(); 24206 currentGroup || (currentGroup = new BatchDrawCall(), currentGroup.texArray = new BatchTextureArray()), currentGroup.texArray.count = 0, currentGroup.start = 0, currentGroup.size = 0, currentGroup.type = DRAW_MODES.TRIANGLES; 24207 let textureCount = 0, currentTexture = null, textureId = 0, native = !1, drawMode = DRAW_MODES.TRIANGLES, index = 0; 24208 this.drawCalls.push(currentGroup); 24209 for (let i = 0; i < this.batches.length; i++) { 24210 const data = this.batches[i], maxTextures = 8, style = data.style, nextTexture = style.texture.baseTexture; 24211 native !== !!style.native && (native = !!style.native, drawMode = native ? DRAW_MODES.LINES : DRAW_MODES.TRIANGLES, currentTexture = null, textureCount = maxTextures, TICK++), currentTexture !== nextTexture && (currentTexture = nextTexture, nextTexture._batchEnabled !== TICK && (textureCount === maxTextures && (TICK++, textureCount = 0, currentGroup.size > 0 && (currentGroup = DRAW_CALL_POOL.pop(), currentGroup || (currentGroup = new BatchDrawCall(), currentGroup.texArray = new BatchTextureArray()), this.drawCalls.push(currentGroup)), currentGroup.start = index, currentGroup.size = 0, currentGroup.texArray.count = 0, currentGroup.type = drawMode), nextTexture.touched = 1, nextTexture._batchEnabled = TICK, nextTexture._batchLocation = textureCount, nextTexture.wrapMode = WRAP_MODES.REPEAT, currentGroup.texArray.elements[currentGroup.texArray.count++] = nextTexture, textureCount++)), currentGroup.size += data.size, index += data.size, textureId = nextTexture._batchLocation, this.addColors(colors, style.color, style.alpha, data.attribSize, data.attribStart), this.addTextureIds(textureIds, textureId, data.attribSize, data.attribStart); 24212 } 24213 BaseTexture._globalBatch = TICK, this.packAttributes(); 24214 } 24215 /** Packs attributes to single buffer. */ 24216 packAttributes() { 24217 const verts = this.points, uvs = this.uvs, colors = this.colors, textureIds = this.textureIds, glPoints = new ArrayBuffer(verts.length * 3 * 4), f32 = new Float32Array(glPoints), u32 = new Uint32Array(glPoints); 24218 let p = 0; 24219 for (let i = 0; i < verts.length / 2; i++) 24220 f32[p++] = verts[i * 2], f32[p++] = verts[i * 2 + 1], f32[p++] = uvs[i * 2], f32[p++] = uvs[i * 2 + 1], u32[p++] = colors[i], f32[p++] = textureIds[i]; 24221 this._buffer.update(glPoints), this._indexBuffer.update(this.indicesUint16); 24222 } 24223 /** 24224 * Process fill part of Graphics. 24225 * @param data 24226 */ 24227 processFill(data) { 24228 data.holes.length ? buildPoly.triangulate(data, this) : FILL_COMMANDS[data.type].triangulate(data, this); 24229 } 24230 /** 24231 * Process line part of Graphics. 24232 * @param data 24233 */ 24234 processLine(data) { 24235 buildLine(data, this); 24236 for (let i = 0; i < data.holes.length; i++) 24237 buildLine(data.holes[i], this); 24238 } 24239 /** 24240 * Process the holes data. 24241 * @param holes 24242 */ 24243 processHoles(holes) { 24244 for (let i = 0; i < holes.length; i++) { 24245 const hole = holes[i]; 24246 FILL_COMMANDS[hole.type].build(hole), hole.matrix && this.transformPoints(hole.points, hole.matrix); 24247 } 24248 } 24249 /** Update the local bounds of the object. Expensive to use performance-wise. */ 24250 calculateBounds() { 24251 const bounds = this._bounds; 24252 bounds.clear(), bounds.addVertexData(this.points, 0, this.points.length), bounds.pad(this.boundsPadding, this.boundsPadding); 24253 } 24254 /** 24255 * Transform points using matrix. 24256 * @param points - Points to transform 24257 * @param matrix - Transform matrix 24258 */ 24259 transformPoints(points, matrix) { 24260 for (let i = 0; i < points.length / 2; i++) { 24261 const x = points[i * 2], y = points[i * 2 + 1]; 24262 points[i * 2] = matrix.a * x + matrix.c * y + matrix.tx, points[i * 2 + 1] = matrix.b * x + matrix.d * y + matrix.ty; 24263 } 24264 } 24265 /** 24266 * Add colors. 24267 * @param colors - List of colors to add to 24268 * @param color - Color to add 24269 * @param alpha - Alpha to use 24270 * @param size - Number of colors to add 24271 * @param offset 24272 */ 24273 addColors(colors, color, alpha, size, offset = 0) { 24274 const bgr = Color.shared.setValue(color).toLittleEndianNumber(), result = Color.shared.setValue(bgr).toPremultiplied(alpha); 24275 colors.length = Math.max(colors.length, offset + size); 24276 for (let i = 0; i < size; i++) 24277 colors[offset + i] = result; 24278 } 24279 /** 24280 * Add texture id that the shader/fragment wants to use. 24281 * @param textureIds 24282 * @param id 24283 * @param size 24284 * @param offset 24285 */ 24286 addTextureIds(textureIds, id, size, offset = 0) { 24287 textureIds.length = Math.max(textureIds.length, offset + size); 24288 for (let i = 0; i < size; i++) 24289 textureIds[offset + i] = id; 24290 } 24291 /** 24292 * Generates the UVs for a shape. 24293 * @param verts - Vertices 24294 * @param uvs - UVs 24295 * @param texture - Reference to Texture 24296 * @param start - Index buffer start index. 24297 * @param size - The size/length for index buffer. 24298 * @param matrix - Optional transform for all points. 24299 */ 24300 addUvs(verts, uvs, texture, start, size, matrix = null) { 24301 let index = 0; 24302 const uvsStart = uvs.length, frame = texture.frame; 24303 for (; index < size; ) { 24304 let x = verts[(start + index) * 2], y = verts[(start + index) * 2 + 1]; 24305 if (matrix) { 24306 const nx = matrix.a * x + matrix.c * y + matrix.tx; 24307 y = matrix.b * x + matrix.d * y + matrix.ty, x = nx; 24308 } 24309 index++, uvs.push(x / frame.width, y / frame.height); 24310 } 24311 const baseTexture = texture.baseTexture; 24312 (frame.width < baseTexture.width || frame.height < baseTexture.height) && this.adjustUvs(uvs, texture, uvsStart, size); 24313 } 24314 /** 24315 * Modify uvs array according to position of texture region 24316 * Does not work with rotated or trimmed textures 24317 * @param uvs - array 24318 * @param texture - region 24319 * @param start - starting index for uvs 24320 * @param size - how many points to adjust 24321 */ 24322 adjustUvs(uvs, texture, start, size) { 24323 const baseTexture = texture.baseTexture, eps = 1e-6, finish = start + size * 2, frame = texture.frame, scaleX = frame.width / baseTexture.width, scaleY = frame.height / baseTexture.height; 24324 let offsetX = frame.x / frame.width, offsetY = frame.y / frame.height, minX = Math.floor(uvs[start] + eps), minY = Math.floor(uvs[start + 1] + eps); 24325 for (let i = start + 2; i < finish; i += 2) 24326 minX = Math.min(minX, Math.floor(uvs[i] + eps)), minY = Math.min(minY, Math.floor(uvs[i + 1] + eps)); 24327 offsetX -= minX, offsetY -= minY; 24328 for (let i = start; i < finish; i += 2) 24329 uvs[i] = (uvs[i] + offsetX) * scaleX, uvs[i + 1] = (uvs[i + 1] + offsetY) * scaleY; 24330 } 24331}; 24332_GraphicsGeometry.BATCHABLE_SIZE = 100; 24333let GraphicsGeometry = _GraphicsGeometry; 24334 24335class FillStyle { 24336 constructor() { 24337 this.color = 16777215, this.alpha = 1, this.texture = Texture.WHITE, this.matrix = null, this.visible = !1, this.reset(); 24338 } 24339 /** Clones the object */ 24340 clone() { 24341 const obj = new FillStyle(); 24342 return obj.color = this.color, obj.alpha = this.alpha, obj.texture = this.texture, obj.matrix = this.matrix, obj.visible = this.visible, obj; 24343 } 24344 /** Reset */ 24345 reset() { 24346 this.color = 16777215, this.alpha = 1, this.texture = Texture.WHITE, this.matrix = null, this.visible = !1; 24347 } 24348 /** Destroy and don't use after this. */ 24349 destroy() { 24350 this.texture = null, this.matrix = null; 24351 } 24352} 24353 24354class LineStyle extends FillStyle { 24355 constructor() { 24356 super(...arguments), this.width = 0, this.alignment = 0.5, this.native = !1, this.cap = LINE_CAP.BUTT, this.join = LINE_JOIN.MITER, this.miterLimit = 10; 24357 } 24358 /** Clones the object. */ 24359 clone() { 24360 const obj = new LineStyle(); 24361 return obj.color = this.color, obj.alpha = this.alpha, obj.texture = this.texture, obj.matrix = this.matrix, obj.visible = this.visible, obj.width = this.width, obj.alignment = this.alignment, obj.native = this.native, obj.cap = this.cap, obj.join = this.join, obj.miterLimit = this.miterLimit, obj; 24362 } 24363 /** Reset the line style to default. */ 24364 reset() { 24365 super.reset(), this.color = 0, this.alignment = 0.5, this.width = 0, this.native = !1, this.cap = LINE_CAP.BUTT, this.join = LINE_JOIN.MITER, this.miterLimit = 10; 24366 } 24367} 24368 24369const DEFAULT_SHADERS = {}, _Graphics = class _Graphics2 extends Container { 24370 /** 24371 * @param geometry - Geometry to use, if omitted will create a new GraphicsGeometry instance. 24372 */ 24373 constructor(geometry = null) { 24374 super(), this.shader = null, this.pluginName = "batch", this.currentPath = null, this.batches = [], this.batchTint = -1, this.batchDirty = -1, this.vertexData = null, this._fillStyle = new FillStyle(), this._lineStyle = new LineStyle(), this._matrix = null, this._holeMode = !1, this.state = State.for2d(), this._geometry = geometry || new GraphicsGeometry(), this._geometry.refCount++, this._transformID =
24374-1, this._tintColor = new Color(16777215), this.blendMode = BLEND_MODES.NORMAL; 24375 } 24376 /** 24377 * Includes vertex positions, face indices, normals, colors, UVs, and 24378 * custom attributes within buffers, reducing the cost of passing all 24379 * this data to the GPU. Can be shared between multiple Mesh or Graphics objects. 24380 * @readonly 24381 */ 24382 get geometry() { 24383 return this._geometry; 24384 } 24385 /** 24386 * Creates a new Graphics object with the same values as this one. 24387 * Note that only the geometry of the object is cloned, not its transform (position,scale,etc) 24388 * @returns - A clone of the graphics object 24389 */ 24390 clone() { 24391 return this.finishPoly(), new _Graphics2(this._geometry); 24392 } 24393 /** 24394 * The blend mode to be applied to the graphic shape. Apply a value of 24395 * `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. Note that, since each 24396 * primitive in the GraphicsGeometry list is rendered sequentially, modes 24397 * such as `PIXI.BLEND_MODES.ADD` and `PIXI.BLEND_MODES.MULTIPLY` will 24398 * be applied per-primitive. 24399 * @default PIXI.BLEND_MODES.NORMAL 24400 */ 24401 set blendMode(value) { 24402 this.state.blendMode = value; 24403 } 24404 get blendMode() { 24405 return this.state.blendMode; 24406 } 24407 /** 24408 * The tint applied to each graphic shape. This is a hex value. A value of 24409 * 0xFFFFFF will remove any tint effect. 24410 * @default 0xFFFFFF 24411 */ 24412 get tint() { 24413 return this._tintColor.value; 24414 } 24415 set tint(value) { 24416 this._tintColor.setValue(value); 24417 } 24418 /** 24419 * The current fill style. 24420 * @readonly 24421 */ 24422 get fill() { 24423 return this._fillStyle; 24424 } 24425 /** 24426 * The current line style. 24427 * @readonly 24428 */ 24429 get line() { 24430 return this._lineStyle; 24431 } 24432 lineStyle(options = null, color = 0, alpha, alignment = 0.5, native = !1) { 24433 return typeof options == "number" && (options = { width: options, color, alpha, alignment, native }), this.lineTextureStyle(options); 24434 } 24435 /** 24436 * Like line style but support texture for line fill. 24437 * @param [options] - Collection of options for setting line style. 24438 * @param {number} [options.width=0] - width of the line to draw, will update the objects stored style 24439 * @param {PIXI.Texture} [options.texture=PIXI.Texture.WHITE] - Texture to use 24440 * @param {PIXI.ColorSource} [options.color=0x0] - color of the line to draw, will update the objects stored style. 24441 * Default 0xFFFFFF if texture present. 24442 * @param {number} [options.alpha=1] - alpha of the line to draw, will update the objects stored style 24443 * @param {PIXI.Matrix} [options.matrix=null] - Texture matrix to transform texture 24444 * @param {number} [options.alignment=0.5] - alignment of the line to draw, (0 = inner, 0.5 = middle, 1 = outer). 24445 * WebGL only. 24446 * @param {boolean} [options.native=false] - If true the lines will be draw using LINES instead of TRIANGLE_STRIP 24447 * @param {PIXI.LINE_CAP}[options.cap=PIXI.LINE_CAP.BUTT] - line cap style 24448 * @param {PIXI.LINE_JOIN}[options.join=PIXI.LINE_JOIN.MITER] - line join style 24449 * @param {number}[options.miterLimit=10] - miter limit ratio 24450 * @returns {PIXI.Graphics} This Graphics object. Good for chaining method calls 24451 */ 24452 lineTextureStyle(options) { 24453 const defaultLineStyleOptions = { 24454 width: 0, 24455 texture: Texture.WHITE, 24456 color: options?.texture ? 16777215 : 0, 24457 matrix: null, 24458 alignment: 0.5, 24459 native: !1, 24460 cap: LINE_CAP.BUTT, 24461 join: LINE_JOIN.MITER, 24462 miterLimit: 10 24463 }; 24464 options = Object.assign(defaultLineStyleOptions, options), this.normalizeColor(options), this.currentPath && this.startPoly(); 24465 const visible = options.width > 0 && options.alpha > 0; 24466 return visible ? (options.matrix && (options.matrix = options.matrix.clone(), options.matrix.invert()), Object.assign(this._lineStyle, { visible }, options)) : this._lineStyle.reset(), this; 24467 } 24468 /** 24469 * Start a polygon object internally. 24470 * @protected 24471 */ 24472 startPoly() { 24473 if (this.currentPath) { 24474 const points = this.currentPath.points, len = this.currentPath.points.length; 24475 len > 2 && (this.drawShape(this.currentPath), this.currentPath = new Polygon(), this.currentPath.closeStroke = !1, this.currentPath.points.push(points[len - 2], points[len - 1])); 24476 } else 24477 this.currentPath = new Polygon(), this.currentPath.closeStroke = !1; 24478 } 24479 /** 24480 * Finish the polygon object. 24481 * @protected 24482 */ 24483 finishPoly() { 24484 this.currentPath && (this.currentPath.points.length > 2 ? (this.drawShape(this.currentPath), this.currentPath = null) : this.currentPath.points.length = 0); 24485 } 24486 /** 24487 * Moves the current drawing position to x, y. 24488 * @param x - the X coordinate to move to 24489 * @param y - the Y coordinate to move to 24490 * @returns - This Graphics object. Good for chaining method calls 24491 */ 24492 moveTo(x, y) { 24493 return this.startPoly(), this.currentPath.points[0] = x, this.currentPath.points[1] = y, this; 24494 } 24495 /** 24496 * Draws a line using the current line style from the current drawing position to (x, y); 24497 * The current drawing position is then set to (x, y). 24498 * @param x - the X coordinate to draw to 24499 * @param y - the Y coordinate to draw to 24500 * @returns - This Graphics object. Good for chaining method calls 24501 */ 24502 lineTo(x, y) { 24503 this.currentPath || this.moveTo(0, 0); 24504 const points = this.currentPath.points, fromX = points[points.length - 2], fromY = points[points.length - 1]; 24505 return (fromX !== x || fromY !== y) && points.push(x, y), this; 24506 } 24507 /** 24508 * Initialize the curve 24509 * @param x 24510 * @param y 24511 */ 24512 _initCurve(x = 0, y = 0) { 24513 this.currentPath ? this.currentPath.points.length === 0 && (this.currentPath.points = [x, y]) : this.moveTo(x, y); 24514 } 24515 /** 24516 * Calculate the points for a quadratic bezier curve and then draws it. 24517 * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c 24518 * @param cpX - Control point x 24519 * @param cpY - Control point y 24520 * @param toX - Destination point x 24521 * @param toY - Destination point y 24522 * @returns - This Graphics object. Good for chaining method calls 24523 */ 24524 quadraticCurveTo(cpX, cpY, toX, toY) { 24525 this._initCurve(); 24526 const points = this.currentPath.points; 24527 return points.length === 0 && this.moveTo(0, 0), QuadraticUtils.curveTo(cpX, cpY, toX, toY, points), this; 24528 } 24529 /** 24530 * Calculate the points for a bezier curve and then draws it. 24531 * @param cpX - Control point x 24532 * @param cpY - Control point y 24533 * @param cpX2 - Second Control point x 24534 * @param cpY2 - Second Control point y 24535 * @param toX - Destination point x 24536 * @param toY - Destination point y 24537 * @returns This Graphics object. Good for chaining method calls 24538 */ 24539 bezierCurveTo(cpX, cpY, cpX2, cpY2, toX, toY) { 24540 return this._initCurve(), BezierUtils.curveTo(cpX, cpY, cpX2, cpY2, toX, toY, this.currentPath.points), this; 24541 } 24542 /** 24543 * The `arcTo` method creates an arc/curve between two tangents on the canvas. 24544 * The first tangent is from the start point to the first control point, 24545 * and the second tangent is from the first control point to the second control point. 24546 * Note that the second control point is not necessarily the end point of the arc. 24547 * 24548 * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google! 24549 * @param x1 - The x-coordinate of the first control point of the arc 24550 * @param y1 - The y-coordinate of the first control point of the arc 24551 * @param x2 - The x-coordinate of the second control point of the arc 24552 * @param y2 - The y-coordinate of the second control point of the arc 24553 * @param radius - The radius of the arc 24554 * @returns - This Graphics object. Good for chaining method calls 24555 */ 24556 arcTo(x1, y1, x2, y2, radius) { 24557 this._initCurve(x1, y1); 24558 const points = this.currentPath.points, result = ArcUtils.curveTo(x1, y1, x2, y2, radius, points); 24559 if (result) { 24560 const { cx, cy, radius: radius2, startAngle, endAngle, anticlockwise } = result; 24561 this.arc(cx, cy, radius2, startAngle, endAngle, anticlockwise); 24562 } 24563 return this; 24564 } 24565 /** 24566 * The arc method creates an arc/curve (used to create circles, or parts of circles). 24567 * @param cx - The x-coordinate of the center of the circle 24568 * @param cy - The y-coordinate of the center of the circle 24569 * @param radius - The radius of the circle 24570 * @param startAngle - The starting angle, in radians (0 is at the 3 o'clock position 24571 * of the arc's circle) 24572 * @param endAngle - The ending angle, in radians
24573 * @param anticlockwise - Specifies whether the drawing should be 24574 * counter-clockwise or clockwise. False is default, and indicates clockwise, while true 24575 * indicates counter-clockwise. 24576 * @returns - This Graphics object. Good for chaining method calls 24577 */ 24578 arc(cx, cy, radius, startAngle, endAngle, anticlockwise = !1) { 24579 if (startAngle === endAngle) 24580 return this; 24581 if (!anticlockwise && endAngle <= startAngle ? endAngle += PI_2 : anticlockwise && startAngle <= endAngle && (startAngle += PI_2), endAngle - startAngle === 0) 24582 return this; 24583 const startX = cx + Math.cos(startAngle) * radius, startY = cy + Math.sin(startAngle) * radius, eps = this._geometry.closePointEps; 24584 let points = this.currentPath ? this.currentPath.points : null; 24585 if (points) { 24586 const xDiff = Math.abs(points[points.length - 2] - startX), yDiff = Math.abs(points[points.length - 1] - startY); 24587 xDiff < eps && yDiff < eps || points.push(startX, startY); 24588 } else 24589 this.moveTo(startX, startY), points = this.currentPath.points; 24590 return ArcUtils.arc(startX, startY, cx, cy, radius, startAngle, endAngle, anticlockwise, points), this; 24591 } 24592 /** 24593 * Specifies a simple one-color fill that subsequent calls to other Graphics methods 24594 * (such as lineTo() or drawCircle()) use when drawing. 24595 * @param {PIXI.ColorSource} color - the color of the fill 24596 * @param alpha - the alpha of the fill, will override the color's alpha 24597 * @returns - This Graphics object. Suitable for chaining method calls 24598 */ 24599 beginFill(color = 0, alpha) { 24600 return this.beginTextureFill({ texture: Texture.WHITE, color, alpha }); 24601 } 24602 /** 24603 * Normalize the color input from options for line style or fill 24604 * @param {PIXI.IFillStyleOptions} options - Fill style object. 24605 */ 24606 normalizeColor(options) { 24607 const temp = Color.shared.setValue(options.color ?? 0); 24608 options.color = temp.toNumber(), options.alpha ?? (options.alpha = temp.alpha); 24609 } 24610 /** 24611 * Begin the texture fill. 24612 * Note: The wrap mode of the texture is forced to REPEAT on render. 24613 * @param options - Fill style object. 24614 * @param {PIXI.Texture} [options.texture=PIXI.Texture.WHITE] - Texture to fill 24615 * @param {PIXI.ColorSource} [options.color=0xffffff] - Background to fill behind texture 24616 * @param {number} [options.alpha] - Alpha of fill, overrides the color's alpha 24617 * @param {PIXI.Matrix} [options.matrix=null] - Transform matrix 24618 * @returns {PIXI.Graphics} This Graphics object. Good for chaining method calls 24619 */ 24620 beginTextureFill(options) { 24621 const defaultOptions = { 24622 texture: Texture.WHITE, 24623 color: 16777215, 24624 matrix: null 24625 }; 24626 options = Object.assign(defaultOptions, options), this.normalizeColor(options), this.currentPath && this.startPoly(); 24627 const visible = options.alpha > 0; 24628 return visible ? (options.matrix && (options.matrix = options.matrix.clone(), options.matrix.invert()), Object.assign(this._fillStyle, { visible }, options)) : this._fillStyle.reset(), this; 24629 } 24630 /** 24631 * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method. 24632 * @returns - This Graphics object. Good for chaining method calls 24633 */ 24634 endFill() { 24635 return this.finishPoly(), this._fillStyle.reset(), this; 24636 } 24637 /** 24638 * Draws a rectangle shape. 24639 * @param x - The X coord of the top-left of the rectangle 24640 * @param y - The Y coord of the top-left of the rectangle 24641 * @param width - The width of the rectangle 24642 * @param height - The height of the rectangle 24643 * @returns - This Graphics object. Good for chaining method calls 24644 */ 24645 drawRect(x, y, width, height) { 24646 return this.drawShape(new Rectangle(x, y, width, height)); 24647 } 24648 /** 24649 * Draw a rectangle shape with rounded/beveled corners. 24650 * @param x - The X coord of the top-left of the rectangle 24651 * @param y - The Y coord of the top-left of the rectangle 24652 * @param width - The width of the rectangle 24653 * @param height - The height of the rectangle 24654 * @param radius - Radius of the rectangle corners 24655 * @returns - This Graphics object. Good for chaining method calls 24656 */ 24657 drawRoundedRect(x, y, width, height, radius) { 24658 return this.drawShape(new RoundedRectangle(x, y, width, height, radius)); 24659 } 24660 /** 24661 * Draws a circle. 24662 * @param x - The X coordinate of the center of the circle 24663 * @param y - The Y coordinate of the center of the circle 24664 * @param radius - The radius of the circle 24665 * @returns - This Graphics object. Good for chaining method calls 24666 */ 24667 drawCircle(x, y, radius) { 24668 return this.drawShape(new Circle(x, y, radius)); 24669 } 24670 /** 24671 * Draws an ellipse. 24672 * @param x - The X coordinate of the center of the ellipse 24673 * @param y - The Y coordinate of the center of the ellipse 24674 * @param width - The half width of the ellipse 24675 * @param height - The half height of the ellipse 24676 * @returns - This Graphics object. Good for chaining method calls 24677 */ 24678 drawEllipse(x, y, width, height) { 24679 return this.drawShape(new Ellipse(x, y, width, height)); 24680 } 24681 /** 24682 * Draws a polygon using the given path. 24683 * @param {number[]|PIXI.IPointData[]|PIXI.Polygon} path - The path data used to construct the polygon. 24684 * @returns - This Graphics object. Good for chaining method calls 24685 */ 24686 drawPolygon(...path) { 24687 let points, closeStroke = !0; 24688 const poly = path[0]; 24689 poly.points ? (closeStroke = poly.closeStroke, points = poly.points) : Array.isArray(path[0]) ? points = path[0] : points = path; 24690 const shape = new Polygon(points); 24691 return shape.closeStroke = closeStroke, this.drawShape(shape), this; 24692 } 24693 /** 24694 * Draw any shape. 24695 * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - Shape to draw 24696 * @returns - This Graphics object. Good for chaining method calls 24697 */ 24698 drawShape(shape) { 24699 return this._holeMode ? this._geometry.drawHole(shape, this._matrix) : this._geometry.drawShape( 24700 shape, 24701 this._fillStyle.clone(), 24702 this._lineStyle.clone(), 24703 this._matrix 24704 ), this; 24705 } 24706 /** 24707 * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. 24708 * @returns - This Graphics object. Good for chaining method calls 24709 */ 24710 clear() { 24711 return this._geometry.clear(), this._lineStyle.reset(), this._fillStyle.reset(), this._boundsID++, this._matrix = null, this._holeMode = !1, this.currentPath = null, this; 24712 } 24713 /** 24714 * True if graphics consists of one rectangle, and thus, can be drawn like a Sprite and 24715 * masked with gl.scissor. 24716 * @returns - True if only 1 rect. 24717 */
24718 isFastRect() { 24719 const data = this._geometry.graphicsData; 24720 return data.length === 1 && data[0].shape.type === SHAPES.RECT && !data[0].matrix && !data[0].holes.length && !(data[0].lineStyle.visible && data[0].lineStyle.width); 24721 } 24722 /** 24723 * Renders the object using the WebGL renderer 24724 * @param renderer - The renderer 24725 */ 24726 _render(renderer) { 24727 this.finishPoly(); 24728 const geometry = this._geometry; 24729 geometry.updateBatches(), geometry.batchable ? (this.batchDirty !== geometry.batchDirty && this._populateBatches(), this._renderBatched(renderer)) : (renderer.batch.flush(), this._renderDirect(renderer)); 24730 } 24731 /** Populating batches for rendering. */ 24732 _populateBatches() { 24733 const geometry = this._geometry, blendMode = this.blendMode, len = geometry.batches.length; 24734 this.batchTint = -1, this._transformID = -1, this.batchDirty = geometry.batchDirty, this.batches.length = len, this.vertexData = new Float32Array(geometry.points); 24735 for (let i = 0; i < len; i++) { 24736 const gI = geometry.batches[i], color = gI.style.color, vertexData = new Float32Array( 24737 this.vertexData.buffer, 24738 gI.attribStart * 4 * 2, 24739 gI.attribSize * 2 24740 ), uvs = new Float32Array( 24741 geometry.uvsFloat32.buffer, 24742 gI.attribStart * 4 * 2, 24743 gI.attribSize * 2 24744 ), indices = new Uint16Array( 24745 geometry.indicesUint16.buffer, 24746 gI.start * 2, 24747 gI.size 24748 ), batch = { 24749 vertexData, 24750 blendMode, 24751 indices, 24752 uvs, 24753 _batchRGB: Color.shared.setValue(color).toRgbArray(), 24754 _tintRGB: color, 24755 _texture: gI.style.texture, 24756 alpha: gI.style.alpha, 24757 worldAlpha: 1 24758 }; 24759 this.batches[i] = batch; 24760 } 24761 } 24762 /** 24763 * Renders the batches using the BathedRenderer plugin 24764 * @param renderer - The renderer 24765 */ 24766 _renderBatched(renderer) { 24767 if (this.batches.length) { 24768 renderer.batch.setObjectRenderer(renderer.plugins[this.pluginName]), this.calculateVertices(), this.calculateTints(); 24769 for (let i = 0, l = this.batches.length; i < l; i++) { 24770 const batch = this.batches[i]; 24771 batch.worldAlpha = this.worldAlpha * batch.alpha, renderer.plugins[this.pluginName].render(batch); 24772 } 24773 } 24774 } 24775 /** 24776 * Renders the graphics direct 24777 * @param renderer - The renderer 24778 */ 24779 _renderDirect(renderer) { 24780 const shader = this._resolveDirectShader(renderer), geometry = this._geometry, worldAlpha = this.worldAlpha, uniforms = shader.uniforms, drawCalls = geometry.drawCalls; 24781 uniforms.translationMatrix = this.transform.worldTransform, Color.shared.setValue(this._tintColor).premultiply(worldAlpha).toArray(uniforms.tint), renderer.shader.bind(shader), renderer.geometry.bind(geometry, shader), renderer.state.set(this.state); 24782 for (let i = 0, l = drawCalls.length; i < l; i++) 24783 this._renderDrawCallDirect(renderer, geometry.drawCalls[i]); 24784 } 24785 /** 24786 * Renders specific DrawCall 24787 * @param renderer 24788 * @param drawCall 24789 */ 24790 _renderDrawCallDirect(renderer, drawCall) { 24791 const { texArray, type, size, start } = drawCall, groupTextureCount = texArray.count; 24792 for (let j = 0; j < groupTextureCount; j++) 24793 renderer.texture.bind(texArray.elements[j], j); 24794 renderer.geometry.draw(type, size, start); 24795 } 24796 /** 24797 * Resolves shader for direct rendering 24798 * @param renderer - The renderer 24799 */ 24800 _resolveDirectShader(renderer) { 24801 let shader = this.shader; 24802 const pluginName = this.pluginName; 24803 if (!shader) { 24804 if (!DEFAULT_SHADERS[pluginName]) { 24805 const { maxTextures } = renderer.plugins[pluginName], sampleValues = new Int32Array(maxTextures); 24806 for (let i = 0; i < maxTextures; i++) 24807 sampleValues[i] = i; 24808 const uniforms = { 24809 tint: new Float32Array([1, 1, 1, 1]), 24810 translationMatrix: new Matrix(), 24811 default: UniformGroup.from({ uSamplers: sampleValues }, !0) 24812 }, program = renderer.plugins[pluginName]._shader.program; 24813 DEFAULT_SHADERS[pluginName] = new Shader(program, uniforms); 24814 } 24815 shader = DEFAULT_SHADERS[pluginName]; 24816 } 24817 return shader; 24818 } 24819 /** 24820 * Retrieves the bounds of the graphic shape as a rectangle object. 24821 * @see PIXI.GraphicsGeometry#bounds 24822 */ 24823 _calculateBounds() { 24824 this.finishPoly(); 24825 const geometry = this._geometry; 24826 if (!geometry.graphicsData.length) 24827 return; 24828 const { minX, minY, maxX, maxY } = geometry.bounds; 24829 this._bounds.addFrame(this.transform, minX, minY, maxX, maxY); 24830 } 24831 /** 24832 * Tests if a point is inside this graphics object 24833 * @param point - the point to test 24834 * @returns - the result of the test 24835 */ 24836 containsPoint(point) { 24837 return this.worldTransform.applyInverse(point, _Graphics2._TEMP_POINT), this._geometry.containsPoint(_Graphics2._TEMP_POINT); 24838 } 24839 /** Recalculate the tint by applying tint to batches using Graphics tint. */ 24840 calculateTints() { 24841 if (this.batchTint !== this.tint) { 24842 this.batchTint = this._tintColor.toNumber(); 24843 for (let i = 0; i < this.batches.length; i++) { 24844 const batch = this.batches[i]; 24845 batch._tintRGB = Color.shared.setValue(this._tintColor).multiply(batch._batchRGB).toLittleEndianNumber(); 24846 } 24847 } 24848 } 24849 /** If there's a transform update or a change to the shape of the geometry, recalculate the vertices. */ 24850 calculateVertices() { 24851 const wtID = this.transform._worldID; 24852 if (this._transformID === wtID) 24853 return; 24854 this._transformID = wtID; 24855 const wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx
24855= wt.tx, ty = wt.ty, data = this._geometry.points, vertexData = this.vertexData; 24856 let count = 0; 24857 for (let i = 0; i < data.length; i += 2) { 24858 const x = data[i], y = data[i + 1]; 24859 vertexData[count++] = a * x + c * y + tx, vertexData[count++] = d * y + b * x + ty; 24860 } 24861 } 24862 /** 24863 * Closes the current path. 24864 * @returns - Returns itself. 24865 */ 24866 closePath() { 24867 const currentPath = this.currentPath; 24868 return currentPath && (currentPath.closeStroke = !0, this.finishPoly()), this; 24869 } 24870 /** 24871 * Apply a matrix to the positional data. 24872 * @param matrix - Matrix to use for transform current shape. 24873 * @returns - Returns itself. 24874 */ 24875 setMatrix(matrix) { 24876 return this._matrix = matrix, this; 24877 } 24878 /** 24879 * Begin adding holes to the last draw shape 24880 * IMPORTANT: holes must be fully inside a shape to work 24881 * Also weirdness ensues if holes overlap! 24882 * Ellipses, Circles, Rectangles and Rounded Rectangles cannot be holes or host for holes in CanvasRenderer, 24883 * please use `moveTo` `lineTo`, `quadraticCurveTo` if you rely on pixi-legacy bundle. 24884 * @returns - Returns itself. 24885 */ 24886 beginHole() { 24887 return this.finishPoly(), this._holeMode = !0, this; 24888 } 24889 /** 24890 * End adding holes to the last draw shape. 24891 * @returns - Returns itself. 24892 */ 24893 endHole() { 24894 return this.finishPoly(), this._holeMode = !1, this; 24895 } 24896 /** 24897 * Destroys the Graphics object. 24898 * @param options - Options parameter. A boolean will act as if all 24899 * options have been set to that value 24900 * @param {boolean} [options.children=false] - if set to true, all the children will have 24901 * their destroy method called as well. 'options' will be passed on to those calls. 24902 * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true 24903 * Should it destroy the texture of the child sprite 24904 * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true 24905 * Should it destroy the base texture of the child sprite 24906 */ 24907 destroy(options) { 24908 this._geometry.refCount--, this._geometry.refCount === 0 && this._geometry.dispose(), this._matrix = null, this.currentPath = null, this._lineStyle.destroy(), this._lineStyle = null, this._fillStyle.destroy(), this._fillStyle = null, this._geometry = null, this.shader = null, this.vertexData = null, this.batches.length = 0, this.batches = null, super.destroy(options); 24909 } 24910}; 24911_Graphics.curves = curves, /** 24912* Temporary point to use for containsPoint. 24913* @private 24914*/ 24915_Graphics._TEMP_POINT = new Point(); 24916let Graphics = _Graphics; 24917 24918class MeshBatchUvs { 24919 /** 24920 * @param uvBuffer - Buffer with normalized uv's 24921 * @param uvMatrix - Material UV matrix 24922 */ 24923 constructor(uvBuffer, uvMatrix) { 24924 this.uvBuffer = uvBuffer, this.uvMatrix = uvMatrix, this.data = null, this._bufferUpdateId = -1, this._textureUpdateId = -1, this._updateID = 0; 24925 } 24926 /** 24927 * Updates 24928 * @param forceUpdate - force the update 24929 */ 24930 update(forceUpdate) { 24931 if (!forceUpdate && this._bufferUpdateId === this.uvBuffer._updateID && this._textureUpdateId === this.uvMatrix._updateID) 24932 return; 24933 this._bufferUpdateId = this.uvBuffer._updateID, this._textureUpdateId = this.uvMatrix._updateID; 24934 const data = this.uvBuffer.data; 24935 (!this.data || this.data.length !== data.length) && (this.data = new Float32Array(data.length)), this.uvMatrix.multiplyUvs(data, this.data), this._updateID++; 24936 } 24937} 24938 24939const tempPoint = new Point(), tempPolygon = new Polygon(), _Mesh = class _Mesh2 extends Container { 24940 /** 24941 * @param geometry - The geometry the mesh will use. 24942 * @param {PIXI.MeshMaterial} shader - The shader the mesh will use. 24943 * @param state - The state that the WebGL context is required to be in to render the mesh 24944 * if no state is provided, uses {@link PIXI.State.for2d} to create a 2D state for PixiJS. 24945 * @param drawMode - The drawMode, can be any of the {@link PIXI.DRAW_MODES} constants. 24946 */ 24947 constructor(geometry, shader, state, drawMode = DRAW_MODES.TRIANGLES) { 24948 super(), this.geometry = geometry, this.shader = shader, this.state = state || State.for2d(), this.drawMode = drawMode, this.start = 0, this.size = 0, this.uvs = null, this.indices = null, this.vertexData = new Float32Array(1), this.vertexDirty = -1, this._transformID =
24948-1, this._roundPixels = settings.ROUND_PIXELS, this.batchUvs = null; 24949 } 24950 /** 24951 * Includes vertex positions, face indices, normals, colors, UVs, and 24952 * custom attributes within buffers, reducing the cost of passing all 24953 * this data to the GPU. Can be shared between multiple Mesh objects. 24954 */ 24955 get geometry() { 24956 return this._geometry; 24957 } 24958 set geometry(value) { 24959 this._geometry !== value && (this._geometry && (this._geometry.refCount--, this._geometry.refCount === 0 && this._geometry.dispose()), this._geometry = value, this._geometry && this._geometry.refCount++, this.vertexDirty = -1); 24960 } 24961 /** 24962 * To change mesh uv's, change its uvBuffer data and increment its _updateID. 24963 * @readonly 24964 */ 24965 get uvBuffer() { 24966 return this.geometry.buffers[1]; 24967 } 24968 /** 24969 * To change mesh vertices, change its uvBuffer data and increment its _updateID. 24970 * Incrementing _updateID is optional because most of Mesh objects do it anyway. 24971 * @readonly 24972 */ 24973 get verticesBuffer() { 24974 return this.geometry.buffers[0]; 24975 } 24976 /** Alias for {@link PIXI.Mesh#shader}. */ 24977 set material(value) { 24978 this.shader = value; 24979 } 24980 get material() { 24981 return this.shader; 24982 } 24983 /** 24984 * The blend mode to be applied to the Mesh. Apply a value of 24985 * `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. 24986 * @default PIXI.BLEND_MODES.NORMAL; 24987 */ 24988 set blendMode(value) { 24989 this.state.blendMode = value; 24990 } 24991 get blendMode() { 24992 return this.state.blendMode; 24993 } 24994 /** 24995 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 24996 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 24997 * The main disadvantage is movement of objects may appear less smooth. 24998 * To set the global default, change {@link PIXI.settings.ROUND_PIXELS} 24999 * @default false 25000 */ 25001 set roundPixels(value) { 25002 this._roundPixels !== value && (this._transformID = -1), this._roundPixels = value; 25003 } 25004 get roundPixels() { 25005 return this._roundPixels; 25006 } 25007 /** 25008 * The multiply tint applied to the Mesh. This is a hex value. A value of 25009 * `0xFFFFFF` will remove any tint effect. 25010 * 25011 * Null for non-MeshMaterial shaders 25012 * @default 0xFFFFFF 25013 */ 25014 get tint() { 25015 return "tint" in this.shader ? this.shader.tint : null; 25016 } 25017 set tint(value) { 25018 this.shader.tint = value; 25019 } 25020 /** 25021 * The tint color as a RGB integer 25022 * @ignore 25023 */ 25024 get tintValue() { 25025 return this.shader.tintValue; 25026 } 25027 /** The texture that the Mesh uses. Null for non-MeshMaterial shaders */ 25028 get texture() { 25029 return "texture" in this.shader ? this.shader.texture : null; 25030 } 25031 set texture(value) { 25032 this.shader.texture = value; 25033 } 25034 /** 25035 * Standard renderer draw. 25036 * @param renderer - Instance to renderer. 25037 */ 25038 _render(renderer) { 25039 const vertices = this.geometry.buffers[0].data; 25040 this.shader.batchable && this.drawMode === DRAW_MODES.TRIANGLES && vertices.length < _Mesh2.BATCHABLE_SIZE * 2 ? this._renderToBatch(renderer) : this._renderDefault(renderer); 25041 } 25042 /** 25043 * Standard non-batching way of rendering. 25044 * @param renderer - Instance to renderer. 25045 */ 25046 _renderDefault(renderer) { 25047 const shader = this.shader; 25048 shader.alpha = this.worldAlpha, shader.update && shader.update(), renderer.batch.flush(), shader.uniforms.translationMatrix = this.transform.worldTransform.toArray(!0), renderer.shader.bind(shader), renderer.state.set(this.state), renderer.geometry.bind(this.geometry, shader), renderer.geometry.draw(this.drawMode, this.size, this.start, this.geometry.instanceCount); 25049 } 25050 /** 25051 * Rendering by using the Batch system. 25052 * @param renderer - Instance to renderer. 25053 */ 25054 _renderToBatch(renderer) { 25055 const geometry = this.geometry, shader = this.shader; 25056 shader.uvMatrix && (shader.uvMatrix.update(), this.calculateUvs()), this.calculateVertices(), this.indices = geometry.indexBuffer.data, this._tintRGB = shader._tintRGB, this._texture = shader.texture; 25057 const pluginName = this.material.pluginName; 25058 renderer.batch.setObjectRenderer(renderer.plugins[pluginName]), renderer.plugins[pluginName].render(this); 25059 } 25060 /** Updates vertexData field based on transform and vertices. */ 25061 calculateVertices() { 25062 const verticesBuffer = this.geometry.buffers[0], vertices = verticesBuffer.data, vertexDirtyId = verticesBuffer._updateID; 25063 if (vertexDirtyId === this.vertexDirty && this._transformID === this.transform._worldID) 25064 return; 25065 this._transformID = this.transform._worldID, this.vertexData.length !== vertices.length && (this.vertexData = new Float32Array(vertices.length)); 25066 const wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx
25066= wt.tx, ty = wt.ty, vertexData = this.vertexData; 25067 for (let i = 0; i < vertexData.length / 2; i++) { 25068 const x = vertices[i * 2], y = vertices[i * 2 + 1]; 25069 vertexData[i * 2] = a * x + c * y + tx, vertexData[i * 2 + 1] = b * x + d * y + ty; 25070 } 25071 if (this._roundPixels) { 25072 const resolution = settings.RESOLUTION; 25073 for (let i = 0; i < vertexData.length; ++i) 25074 vertexData[i] = Math.round(vertexData[i] * resolution) / resolution; 25075 } 25076 this.vertexDirty = vertexDirtyId; 25077 } 25078 /** Updates uv field based on from geometry uv's or batchUvs. */ 25079 calculateUvs() { 25080 const geomUvs = this.geometry.buffers[1], shader = this.shader; 25081 shader.uvMatrix.isSimple ? this.uvs = geomUvs.data : (this.batchUvs || (this.batchUvs = new MeshBatchUvs(geomUvs, shader.uvMatrix)), this.batchUvs.update(), this.uvs = this.batchUvs.data); 25082 } 25083 /** 25084 * Updates the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. 25085 * there must be a aVertexPosition attribute present in the geometry for bounds to be calculated correctly. 25086 */ 25087 _calculateBounds() { 25088 this.calculateVertices(), this._bounds.addVertexData(this.vertexData, 0, this.vertexData.length); 25089 } 25090 /** 25091 * Tests if a point is inside this mesh. Works only for PIXI.DRAW_MODES.TRIANGLES. 25092 * @param point - The point to test. 25093 * @returns - The result of the test. 25094 */ 25095 containsPoint(point) { 25096 if (!this.getBounds().contains(point.x, point.y)) 25097 return !1; 25098 this.worldTransform.applyInverse(point, tempPoint); 25099 const vertices = this.geometry.getBuffer("aVertexPosition").data, points = tempPolygon.points, indices = this.geometry.getIndex().data, len = indices.length, step = this.drawMode === 4 ? 3 : 1; 25100 for (let i = 0; i + 2 < len; i += step) { 25101 const ind0 = indices[i] * 2, ind1 = indices[i + 1] * 2, ind2 = indices[i + 2] * 2; 25102 if (points[0] = vertices[ind0], points[1] = vertices[ind0 + 1], points[2] = vertices[ind1], points[3] = vertices[ind1 + 1], points[4] = vertices[ind2], points[5] = vertices[ind2 + 1], tempPolygon.contains(tempPoint.x, tempPoint.y)) 25103 return !0; 25104 } 25105 return !1; 25106 } 25107 destroy(options) { 25108 super.destroy(options), this._cachedTexture && (this._cachedTexture.destroy(), this._cachedTexture = null), this.geometry = null, this.shader = null, this.state = null, this.uvs = null, this.indices = null, this.vertexData = null; 25109 } 25110}; 25111_Mesh.BATCHABLE_SIZE = 100; 25112let Mesh = _Mesh; 25113 25114class MeshGeometry extends Geometry { 25115 /** 25116 * @param {Float32Array|number[]} [vertices] - Positional data on geometry. 25117 * @param {Float32Array|number[]} [uvs] - Texture UVs. 25118 * @param {Uint16Array|number[]} [index] - IndexBuffer 25119 */ 25120 constructor(vertices, uvs, index) { 25121 super(); 25122 const verticesBuffer = new Buffer(vertices), uvsBuffer = new Buffer(uvs, !0), indexBuffer = new Buffer(index, !0, !0); 25123 this.addAttribute("aVertexPosition", verticesBuffer, 2, !1, TYPES.FLOAT).addAttribute("aTextureCoord", uvsBuffer, 2, !1, TYPES.FLOAT).addIndex(indexBuffer), this._updateId = -1; 25124 } 25125 /** 25126 * If the vertex position is updated. 25127 * @readonly 25128 * @private 25129 */ 25130 get vertexDirtyId() { 25131 return this.buffers[0]._updateID; 25132 } 25133} 25134 25135var fragment$1 = `varying vec2 vTextureCoord; 25136uniform vec4 uColor; 25137 25138uniform sampler2D uSampler; 25139 25140void main(void) 25141{ 25142 gl_FragColor = texture2D(uSampler, vTextureCoord) * uColor; 25143} 25144`; 25145 25146var vertex$1 = `attribute vec2 aVertexPosition; 25147attribute vec2 aTextureCoord; 25148 25149uniform mat3 projectionMatrix; 25150uniform mat3 translationMatrix; 25151uniform mat3 uTextureMatrix; 25152 25153varying vec2 vTextureCoord; 25154 25155void main(void) 25156{ 25157 gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0
25157)).xy, 0.0, 1.0); 25158 25159 vTextureCoord = (uTextureMatrix * vec3(aTextureCoord, 1.0)).xy; 25160} 25161`; 25162 25163class MeshMaterial extends Shader { 25164 /** 25165 * @param uSampler - Texture that material uses to render. 25166 * @param options - Additional options 25167 * @param {number} [options.alpha=1] - Default alpha. 25168 * @param {PIXI.ColorSource} [options.tint=0xFFFFFF] - Default tint. 25169 * @param {string} [options.pluginName='batch'] - Renderer plugin for batching. 25170 * @param {PIXI.Program} [options.program=0xFFFFFF] - Custom program. 25171 * @param {object} [options.uniforms] - Custom uniforms. 25172 */ 25173 constructor(uSampler, options) { 25174 const uniforms = { 25175 uSampler, 25176 alpha: 1, 25177 uTextureMatrix: Matrix.IDENTITY, 25178 uColor: new Float32Array([1, 1, 1, 1]) 25179 }; 25180 options = Object.assign({ 25181 tint: 16777215, 25182 alpha: 1, 25183 pluginName: "batch" 25184 }, options), options.uniforms && Object.assign(uniforms, options.uniforms), super(options.program || Program.from(vertex$1, fragment$1), uniforms), this._colorDirty = !1, this.uvMatrix = new TextureMatrix(uSampler), this.batchable = options.program === void 0, this.pluginName = options.pluginName, this._tintColor = new Color(options.tint), this._tintRGB = this._tintColor.toLittleEndianNumber(), this._colorDirty = !0, this.alpha = options.alpha; 25185 } 25186 /** Reference to the texture being rendered. */ 25187 get texture() { 25188 return this.uniforms.uSampler; 25189 } 25190 set texture(value) { 25191 this.uniforms.uSampler !== value && (!this.uniforms.uSampler.baseTexture.alphaMode != !value.baseTexture.alphaMode && (this._colorDirty = !0), this.uniforms.uSampler = value, this.uvMatrix.texture = value); 25192 } 25193 /** 25194 * This gets automatically set by the object using this. 25195 * @default 1 25196 */ 25197 set alpha(value) { 25198 value !== this._alpha && (this._alpha = value, this._colorDirty = !0); 25199 } 25200 get alpha() { 25201 return this._alpha; 25202 } 25203 /** 25204 * Multiply tint for the material. 25205 * @default 0xFFFFFF 25206 */ 25207 set tint(value) { 25208 value !== this.tint && (this._tintColor.setValue(value), this._tintRGB = this._tintColor.toLittleEndianNumber(), this._colorDirty = !0); 25209 } 25210 get tint() { 25211 return this._tintColor.value; 25212 } 25213 /** 25214 * Get the internal number from tint color 25215 * @ignore 25216 */ 25217 get tintValue() { 25218 return this._tintColor.toNumber(); 25219 } 25220 /** Gets called automatically by the Mesh. Intended to be overridden for custom {@link PIXI.MeshMaterial} objects. */ 25221 update() { 25222 if (this._colorDirty) { 25223 this._colorDirty = !1; 25224 const applyToChannels = this.texture.baseTexture.alphaMode; 25225 Color.shared.setValue(this._tintColor).premultiply(this._alpha, applyToChannels).toArray(this.uniforms.uColor); 25226 } 25227 this.uvMatrix.update() && (this.uniforms.uTextureMatrix = this.uvMatrix.mapCoord); 25228 } 25229} 25230 25231class ParticleBuffer { 25232 /** 25233 * @param {object} properties - The properties to upload. 25234 * @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic. 25235 * @param {number} size - The size of the batch. 25236 */ 25237 constructor(properties, dynamicPropertyFlags, size) { 25238 this.geometry = new Geometry(), this.indexBuffer = null, this.size = size, this.dynamicProperties = [], this.staticProperties = []; 25239 for (let i = 0; i < properties.length; ++i) { 25240 let property = properties[i]; 25241 property = { 25242 attributeName: property.attributeName, 25243 size: property.size, 25244 uploadFunction: property.uploadFunction, 25245 type: property.type || TYPES.FLOAT, 25246 offset: property.offset 25247 }, dynamicPropertyFlags[i] ? this.dynamicProperties.push(property) : this.staticProperties.push(property); 25248 } 25249 this.staticStride = 0, this.staticBuffer = null, this.staticData = null, this.staticDataUint32 = null, this.dynamicStride = 0, this.dynamicBuffer = null, this.dynamicData = null, this.dynamicDataUint32 = null, this._updateID = 0, this.initBuffers(); 25250 } 25251 /** Sets up the renderer context and necessary buffers. */ 25252 initBuffers() { 25253 const geometry = this.geometry; 25254 let dynamicOffset = 0; 25255 this.indexBuffer = new Buffer(createIndicesForQuads(this.size), !0, !0), geometry.addIndex(this.indexBuffer), this.dynamicStride = 0; 25256 for (let i = 0; i < this.dynamicProperties.length; ++i) { 25257 const property = this.dynamicProperties[i]; 25258 property.offset = dynamicOffset, dynamicOffset += property.size, this.dynamicStride += property.size; 25259 } 25260 const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4); 25261 this.dynamicData = new Float32Array(dynBuffer), this.dynamicDataUint32 = new Uint32Array(dynBuffer), this.dynamicBuffer = new Buffer(this.dynamicData, !1, !1); 25262 let staticOffset = 0;
vendor: 16,384 bytes, lines 25263-25609
25263 this.staticStride = 0; 25264 for (let i = 0; i < this.staticProperties.length; ++i) { 25265 const property = this.staticProperties[i]; 25266 property.offset = staticOffset, staticOffset += property.size, this.staticStride += property.size; 25267 } 25268 const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4); 25269 this.staticData = new Float32Array(statBuffer), this.staticDataUint32 = new Uint32Array(statBuffer), this.staticBuffer = new Buffer(this.staticData, !0, !1); 25270 for (let i = 0; i < this.dynamicProperties.length; ++i) { 25271 const property = this.dynamicProperties[i]; 25272 geometry.addAttribute( 25273 property.attributeName, 25274 this.dynamicBuffer, 25275 0, 25276 property.type === TYPES.UNSIGNED_BYTE, 25277 property.type, 25278 this.dynamicStride * 4, 25279 property.offset * 4 25280 ); 25281 } 25282 for (let i = 0; i < this.staticProperties.length; ++i) { 25283 const property = this.staticProperties[i]; 25284 geometry.addAttribute( 25285 property.attributeName, 25286 this.staticBuffer, 25287 0, 25288 property.type === TYPES.UNSIGNED_BYTE, 25289 property.type, 25290 this.staticStride * 4, 25291 property.offset * 4 25292 ); 25293 } 25294 } 25295 /** 25296 * Uploads the dynamic properties. 25297 * @param children - The children to upload. 25298 * @param startIndex - The index to start at. 25299 * @param amount - The number to upload. 25300 */ 25301 uploadDynamic(children, startIndex, amount) { 25302 for (let i = 0; i < this.dynamicProperties.length; i++) { 25303 const property = this.dynamicProperties[i]; 25304 property.uploadFunction( 25305 children, 25306 startIndex, 25307 amount, 25308 property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, 25309 this.dynamicStride, 25310 property.offset 25311 ); 25312 } 25313 this.dynamicBuffer._updateID++; 25314 } 25315 /** 25316 * Uploads the static properties. 25317 * @param children - The children to upload. 25318 * @param startIndex - The index to start at. 25319 * @param amount - The number to upload. 25320 */ 25321 uploadStatic(children, startIndex, amount) { 25322 for (let i = 0; i < this.staticProperties.length; i++) { 25323 const property = this.staticProperties[i]; 25324 property.uploadFunction( 25325 children, 25326 startIndex, 25327 amount, 25328 property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData, 25329 this.staticStride, 25330 property.offset 25331 ); 25332 } 25333 this.staticBuffer._updateID++; 25334 } 25335 /** Destroys the ParticleBuffer. */ 25336 destroy() { 25337 this.indexBuffer = null, this.dynamicProperties = null, this.dynamicBuffer = null, this.dynamicData = null, this.dynamicDataUint32 = null, this.staticProperties = null, this.staticBuffer = null, this.staticData = null, this.staticDataUint32 = null, this.geometry.destroy(); 25338 } 25339} 25340 25341var fragment = `varying vec2 vTextureCoord; 25342varying vec4 vColor; 25343 25344uniform sampler2D uSampler; 25345 25346void main(void){ 25347 vec4 color = texture2D(uSampler, vTextureCoord) * vColor; 25348 gl_FragColor = color; 25349}`; 25350 25351var vertex = `attribute vec2 aVertexPosition; 25352attribute vec2 aTextureCoord; 25353attribute vec4 aColor; 25354 25355attribute vec2 aPositionCoord; 25356attribute float aRotation; 25357 25358uniform mat3 translationMatrix; 25359uniform vec4 uColor; 25360 25361varying vec2 vTextureCoord; 25362varying vec4 vColor; 25363 25364void main(void){ 25365 float x = (aVertexPosition.x) * cos(aRotation) - (aVertexPosition.y) * sin(aRotation); 25366 float y = (aVertexPosition.x) * sin(aRotation) + (aVertexPosition.y) * cos(aRotation); 25367 25368 vec2 v = vec2(x, y); 25369 v = v + aPositionCoord; 25370 25371 gl_Position = vec4((translationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0); 25372 25373 vTextureCoord = aTextureCoord; 25374 vColor = aColor * uColor; 25375} 25376`; 25377 25378class ParticleRenderer extends ObjectRenderer { 25379 /** 25380 * @param renderer - The renderer this sprite batch works for. 25381 */ 25382 constructor(renderer) { 25383 super(renderer), this.shader = null, this.properties = null, this.tempMatrix = new Matrix(), this.properties = [ 25384 // verticesData 25385 { 25386 attributeName: "aVertexPosition", 25387 size: 2, 25388 uploadFunction: this.uploadVertices, 25389 offset: 0 25390 }, 25391 // positionData 25392 { 25393 attributeName: "aPositionCoord", 25394 size: 2, 25395 uploadFunction: this.uploadPosition, 25396 offset: 0 25397 }, 25398 // rotationData 25399 { 25400 attributeName: "aRotation", 25401 size: 1, 25402 uploadFunction: this.uploadRotation, 25403 offset: 0 25404 }, 25405 // uvsData 25406 { 25407 attributeName: "aTextureCoord", 25408 size: 2, 25409 uploadFunction: this.uploadUvs, 25410 offset: 0 25411 }, 25412 // tintData 25413 { 25414 attributeName: "aColor", 25415 size: 1, 25416 type: TYPES.UNSIGNED_BYTE, 25417 uploadFunction: this.uploadTint, 25418 offset: 0 25419 } 25420 ], this.shader = Shader.from(vertex, fragment, {}), this.state = State.for2d(); 25421 } 25422 /** 25423 * Renders the particle container object. 25424 * @param container - The container to render using this ParticleRenderer. 25425 */ 25426 render(container) { 25427 const children = container.children, maxSize = container._maxSize, batchSize = container._batchSize, renderer = this.renderer; 25428 let totalChildren = children.length; 25429 if (totalChildren === 0) 25430 return; 25431 totalChildren > maxSize && !container.autoResize && (totalChildren = maxSize); 25432 let buffers = container._buffers; 25433 buffers || (buffers = container._buffers = this.generateBuffers(container)); 25434 const baseTexture = children[0]._texture.baseTexture, premultiplied = baseTexture.alphaMode > 0; 25435 this.state.blendMode = correctBlendMode(container.blendMode, premultiplied), renderer.state.set(this.state); 25436 const gl = renderer.gl, m = container.worldTransform.copyTo(this.tempMatrix); 25437 m.prepend(renderer.globalUniforms.uniforms.projectionMatrix), this.shader.uniforms.translationMatrix = m.toArray(!0), this.shader.uniforms.uColor = Color.shared.setValue(container.tintRgb).premultiply(container.worldAlpha, premultiplied).toArray(this.shader.uniforms.uColor), this.shader.uniforms.uSampler = baseTexture, this.renderer.shader.bind(this.shader); 25438 let updateStatic = !1; 25439 for (let i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) { 25440 let amount = totalChildren - i; 25441 amount > batchSize && (amount = batchSize), j >= buffers.length && buffers.push(this._generateOneMoreBuffer(container)); 25442 const buffer = buffers[j]; 25443 buffer.uploadDynamic(children, i, amount); 25444 const bid = container._bufferUpdateIDs[j] || 0; 25445 updateStatic = updateStatic || buffer._updateID < bid, updateStatic && (buffer._updateID = container._updateID, buffer.uploadStatic(children, i, amount)), renderer.geometry.bind(buffer.geometry), gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0); 25446 } 25447 } 25448 /** 25449 * Creates one particle buffer for each child in the container we want to render and updates internal properties. 25450 * @param container - The container to render using this ParticleRenderer 25451 * @returns - The buffers 25452 */ 25453 generateBuffers(container) { 25454 const buffers = [], size = container._maxSize, batchSize = container._batchSize, dynamicPropertyFlags = container._properties; 25455 for (let i = 0; i < size; i += batchSize) 25456 buffers.push(new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize)); 25457 return buffers; 25458 } 25459 /** 25460 * Creates one more particle buffer, because container has autoResize feature. 25461 * @param container - The container to render using this ParticleRenderer 25462 * @returns - The generated buffer 25463 */ 25464 _generateOneMoreBuffer(container) { 25465 const batchSize = container._batchSize, dynamicPropertyFlags = container._properties; 25466 return new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize); 25467 } 25468 /** 25469 * Uploads the vertices. 25470 * @param children - the array of sprites to render 25471 * @param startIndex - the index to start from in the children array 25472 * @param amount - the amount of children that will have their vertices uploaded 25473 * @param array - The vertices to upload. 25474 * @param stride - Stride to use for iteration. 25475 * @param offset - Offset to start at. 25476 */ 25477 uploadVertices(children, startIndex, amount, array, stride, offset) { 25478 let w0 = 0, w1 = 0, h0 = 0, h1 = 0; 25479 for (let i = 0; i < amount; ++i) { 25480 const sprite = children[startIndex + i], texture = sprite._texture, sx = sprite.scale.x, sy = sprite.scale.y, trim = texture.trim, orig = texture.orig; 25481 trim ? (w1 = trim.x - sprite.anchor.x * orig.width, w0 = w1 + trim.width, h1 = trim.y - sprite.anchor.y * orig.height, h0 = h1 + trim.height) : (w0 = orig.width * (1 - sprite.anchor.x), w1 = orig.width * -sprite.anchor.x, h0 = orig.height * (1 - sprite.anchor.y), h1 = orig.height * -sprite.anchor.y), array[offset] = w1 * sx, array[offset + 1] = h1 * sy, array[offset + stride] = w0 * sx, array[offset + stride + 1] = h1 * sy, array[offset + stride * 2] = w0 * sx, array[offset + stride * 2 + 1] = h0 * sy, array[offset + stride * 3] = w1 * sx, array[offset + stride * 3 + 1] = h0 * sy, offset += stride * 4; 25482 } 25483 } 25484 /** 25485 * Uploads the position. 25486 * @param children - the array of sprites to render 25487 * @param startIndex - the index to start from in the children array 25488 * @param amount - the amount of children that will have their positions uploaded 25489 * @param array - The vertices to upload. 25490 * @param stride - Stride to use for iteration. 25491 * @param offset - Offset to start at. 25492 */ 25493 uploadPosition(children, startIndex, amount, array, stride, offset) { 25494 for (let i = 0; i < amount; i++) { 25495 const spritePosition = children[startIndex + i].position; 25496 array[offset] = spritePosition.x, array[offset + 1] = spritePosition.y, array[offset + stride] = spritePosition.x, array[offset + stride + 1] = spritePosition.y, array[offset + stride * 2] = spritePosition.x, array[offset + stride * 2 + 1] = spritePosition.y, array[offset + stride * 3] = spritePosition.x, array[offset + stride * 3 + 1] = spritePosition.y, offset += stride * 4; 25497 } 25498 } 25499 /** 25500 * Uploads the rotation. 25501 * @param children - the array of sprites to render 25502 * @param startIndex - the index to start from in the children array 25503 * @param amount - the amount of children that will have their rotation uploaded 25504 * @param array - The vertices to upload. 25505 * @param stride - Stride to use for iteration. 25506 * @param offset - Offset to start at. 25507 */ 25508 uploadRotation(children, startIndex, amount, array, stride, offset) { 25509 for (let i = 0; i < amount; i++) { 25510 const spriteRotation = children[startIndex + i].rotation; 25511 array[offset] = spriteRotation, array[offset + stride] = spriteRotation, array[offset + stride * 2] = spriteRotation, array[offset + stride * 3] = spriteRotation, offset += stride * 4; 25512 } 25513 } 25514 /** 25515 * Uploads the UVs. 25516 * @param children - the array of sprites to render 25517 * @param startIndex - the index to start from in the children array 25518 * @param amount - the amount of children that will have their rotation uploaded 25519 * @param array - The vertices to upload. 25520 * @param stride - Stride to use for iteration. 25521 * @param offset - Offset to start at. 25522 */ 25523 uploadUvs(children, startIndex, amount, array, stride, offset) { 25524 for (let i = 0; i < amount; ++i) { 25525 const textureUvs = children[startIndex + i]._texture._uvs; 25526 textureUvs ? (array[offset] = textureUvs.x0, array[offset + 1] = textureUvs.y0, array[offset + stride] = textureUvs.x1, array[offset + stride + 1] = textureUvs.y1, array[offset + stride * 2] = textureUvs.x2, array[offset + stride * 2 + 1] = textureUvs.y2, array[offset + stride * 3] = textureUvs.x3, array[offset + stride * 3 + 1] = textureUvs.y3, offset += stride * 4) : (array[offset] = 0, array[offset + 1] = 0, array[offset + stride] = 0, array[offset + stride + 1] = 0, array[offset + stride * 2] = 0, array[offset + stride * 2 + 1] = 0, array[offset + stride * 3] = 0, array[offset + stride * 3 + 1] = 0, offset += stride * 4); 25527 } 25528 } 25529 /** 25530 * Uploads the tint. 25531 * @param children - the array of sprites to render 25532 * @param startIndex - the index to start from in the children array 25533 * @param amount - the amount of children that will have their rotation uploaded 25534 * @param array - The vertices to upload. 25535 * @param stride - Stride to use for iteration. 25536 * @param offset - Offset to start at. 25537 */ 25538 uploadTint(children, startIndex, amount, array, stride, offset) { 25539 for (let i = 0; i < amount; ++i) { 25540 const sprite = children[startIndex + i], result = Color.shared.setValue(sprite._tintRGB).toPremultiplied(sprite.alpha, sprite.texture.baseTexture.alphaMode > 0); 25541 array[offset] = result, array[offset + stride] = result, array[offset + stride * 2] = result, array[offset + stride * 3] = result, offset += stride * 4; 25542 } 25543 } 25544 /** Destroys the ParticleRenderer. */ 25545 destroy() { 25546 super.destroy(), this.shader && (this.shader.destroy(), this.shader = null), this.tempMatrix = null; 25547 } 25548} 25549ParticleRenderer.extension = { 25550 name: "particle", 25551 type: ExtensionType.RendererPlugin 25552}; 25553extensions$1.add(ParticleRenderer); 25554 25555var TEXT_GRADIENT = /* @__PURE__ */ ((TEXT_GRADIENT2) => (TEXT_GRADIENT2[TEXT_GRADIENT2.LINEAR_VERTICAL = 0] = "LINEAR_VERTICAL", TEXT_GRADIENT2[TEXT_GRADIENT2.LINEAR_HORIZONTAL = 1] = "LINEAR_HORIZONTAL", TEXT_GRADIENT2))(TEXT_GRADIENT || {}); 25556 25557const contextSettings = { 25558 // TextMetrics requires getImageData readback for measuring fonts. 25559 willReadFrequently: !0 25560}, _TextMetrics = class _TextMetrics2 { 25561 /** 25562 * Checking that we can use modern canvas 2D API. 25563 * 25564 * Note: This is an unstable API, Chrome < 94 use `textLetterSpacing`, later versions use `letterSpacing`. 25565 * @see PIXI.TextMetrics.experimentalLetterSpacing 25566 * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/letterSpacing 25567 * @see https://developer.chrome.com/origintrials/#/view_trial/3585991203293757441 25568 */ 25569 static get experimentalLetterSpacingSupported() { 25570 let result = _TextMetrics2._experimentalLetterSpacingSupported; 25571 if (result !== void 0) { 25572 const proto = settings.ADAPTER.getCanvasRenderingContext2D().prototype; 25573 result = _TextMetrics2._experimentalLetterSpacingSupported = "letterSpacing" in proto || "textLetterSpacing" in proto; 25574 } 25575 return result; 25576 } 25577 /** 25578 * @param text - the text that was measured 25579 * @param style - the style that was measured 25580 * @param width - the measured width of the text 25581 * @param height - the measured height of the text 25582 * @param lines - an array of the lines of text broken by new lines and wrapping if specified in style 25583 * @param lineWidths - an array of the line widths for each line matched to `lines` 25584 * @param lineHeight - the measured line height for this style 25585 * @param maxLineWidth - the maximum line width for all measured lines 25586 * @param {PIXI.IFontMetrics} fontProperties - the font properties object from TextMetrics.measureFont 25587 */ 25588 constructor(text, style, width, height, lines, lineWidths, lineHeight, maxLineWidth, fontProperties) { 25589 this.text = text, this.style = style, this.width = width, this.height = height, this.lines = lines, this.lineWidths = lineWidths, this.lineHeight = lineHeight, this.maxLineWidth = maxLineWidth, this.fontProperties = fontProperties; 25590 } 25591 /** 25592 * Measures the supplied string of text and returns a Rectangle. 25593 * @param text - The text to measure. 25594 * @param style - The text style to use for measuring 25595 * @param wordWrap - Override for if word-wrap should be applied to the text. 25596 * @param canvas - optional specification of the canvas to use for measuring. 25597 * @returns Measured width and height of the text. 25598 */ 25599 static measureText(text, style, wordWrap, canvas = _TextMetrics2._canvas) { 25600 wordWrap = wordWrap ?? style.wordWrap; 25601 const font = style.toFontString(), fontProperties = _TextMetrics2.measureFont(font); 25602 fontProperties.fontSize === 0 && (fontProperties.fontSize = style.fontSize, fontProperties.ascent = style.fontSize); 25603 const context = canvas.getContext("2d", contextSettings); 25604 context.font = font; 25605 const lines = (wordWrap ? _TextMetrics2.wordWrap(text, style, canvas) : text).split(/(?:\r\n|\r|\n)/), lineWidths = new Array(lines.length); 25606 let maxLineWidth = 0; 25607 for (let i = 0; i < lines.length; i++) { 25608 const lineWidth = _TextMetrics2._measureText(lines[i], style.letterSpacing, context); 25609 lineWidths[i] = lineWidth, maxL
vendor: 9,983 bytes, lines 25609-25841
25609ineWidth = Math.max(maxLineWidth, lineWidth); 25610 } 25611 let width = maxLineWidth + style.strokeThickness; 25612 style.dropShadow && (width += style.dropShadowDistance); 25613 const lineHeight = style.lineHeight || fontProperties.fontSize + style.strokeThickness; 25614 let height = Math.max(lineHeight, fontProperties.fontSize + style.strokeThickness * 2) + style.leading + (lines.length - 1) * (lineHeight + style.leading); 25615 return style.dropShadow && (height += style.dropShadowDistance), new _TextMetrics2( 25616 text, 25617 style, 25618 width, 25619 height, 25620 lines, 25621 lineWidths, 25622 lineHeight + style.leading, 25623 maxLineWidth, 25624 fontProperties 25625 ); 25626 } 25627 static _measureText(text, letterSpacing, context) { 25628 let useExperimentalLetterSpacing = !1; 25629 _TextMetrics2.experimentalLetterSpacingSupported && (_TextMetrics2.experimentalLetterSpacing ? (context.letterSpacing = `${letterSpacing}px`, context.textLetterSpacing = `${letterSpacing}px`, useExperimentalLetterSpacing = !0) : (context.letterSpacing = "0px", context.textLetterSpacing = "0px")); 25630 let width = context.measureText(text).width; 25631 return width > 0 && (useExperimentalLetterSpacing ? width -= letterSpacing : width += (_TextMetrics2.graphemeSegmenter(text).length - 1) * letterSpacing), width; 25632 } 25633 /** 25634 * Applies newlines to a string to have it optimally fit into the horizontal 25635 * bounds set by the Text object's wordWrapWidth property. 25636 * @param text - String to apply word wrapping to 25637 * @param style - the style to use when wrapping 25638 * @param canvas - optional specification of the canvas to use for measuring. 25639 * @returns New string with new lines applied where required 25640 */ 25641 static wordWrap(text, style, canvas = _TextMetrics2._canvas) { 25642 const context = canvas.getContext("2d", contextSettings); 25643 let width = 0, line = "", lines = ""; 25644 const cache = /* @__PURE__ */ Object.create(null), { letterSpacing, whiteSpace } = style, collapseSpaces = _TextMetrics2.collapseSpaces(whiteSpace), collapseNewlines = _TextMetrics2.collapseNewlines(whiteSpace); 25645 let canPrependSpaces = !collapseSpaces; 25646 const wordWrapWidth = style.wordWrapWidth + letterSpacing, tokens = _TextMetrics2.tokenize(text); 25647 for (let i = 0; i < tokens.length; i++) { 25648 let token = tokens[i]; 25649 if (_TextMetrics2.isNewline(token)) { 25650 if (!collapseNewlines) { 25651 lines += _TextMetrics2.addLine(line), canPrependSpaces = !collapseSpaces, line = "", width = 0; 25652 continue; 25653 } 25654 token = " "; 25655 } 25656 if (collapseSpaces) { 25657 const currIsBreakingSpace = _TextMetrics2.isBreakingSpace(token), lastIsBreakingSpace = _TextMetrics2.isBreakingSpace(line[line.length - 1]); 25658 if (currIsBreakingSpace && lastIsBreakingSpace) 25659 continue; 25660 } 25661 const tokenWidth = _TextMetrics2.getFromCache(token, letterSpacing, cache, context); 25662 if (tokenWidth > wordWrapWidth) 25663 if (line !== "" && (lines += _TextMetrics2.addLine(line), line = "", width = 0), _TextMetrics2.canBreakWords(token, style.breakWords)) { 25664 const characters = _TextMetrics2.wordWrapSplit(token); 25665 for (let j = 0; j < characters.length; j++) { 25666 let char = characters[j], lastChar = char, k = 1; 25667 for (; characters[j + k]; ) { 25668 const nextChar = characters[j + k]; 25669 if (!_TextMetrics2.canBreakChars(lastChar, nextChar, token, j, style.breakWords)) 25670 char += nextChar; 25671 else 25672 break; 25673 lastChar = nextChar, k++; 25674 } 25675 j += k - 1; 25676 const characterWidth = _TextMetrics2.getFromCache(char, letterSpacing, cache, context); 25677 characterWidth + width > wordWrapWidth && (lines += _TextMetrics2.addLine(line), canPrependSpaces = !1, line = "", width = 0), line += char, width += characterWidth; 25678 } 25679 } else { 25680 line.length > 0 && (lines += _TextMetrics2.addLine(line), line = "", width = 0); 25681 const isLastToken = i === tokens.length - 1; 25682 lines += _TextMetrics2.addLine(token, !isLastToken), canPrependSpaces = !1, line = "", width = 0; 25683 } 25684 else 25685 tokenWidth + width > wordWrapWidth && (canPrependSpaces = !1, lines += _TextMetrics2.addLine(line), line = "", width = 0), (line.length > 0 || !_TextMetrics2.isBreakingSpace(token) || canPrependSpaces) && (line += token, width += tokenWidth); 25686 } 25687 return lines += _TextMetrics2.addLine(line, !1), lines; 25688 } 25689 /** 25690 * Convienience function for logging each line added during the wordWrap method. 25691 * @param line - The line of text to add 25692 * @param newLine - Add new line character to end 25693 * @returns A formatted line 25694 */ 25695 static addLine(line, newLine = !0) { 25696 return line = _TextMetrics2.trimRight(line), line = newLine ? `${line} 25697` : line, line; 25698 } 25699 /** 25700 * Gets & sets the widths of calculated characters in a cache object 25701 * @param key - The key 25702 * @param letterSpacing - The letter spacing 25703 * @param cache - The cache 25704 * @param context - The canvas context 25705 * @returns The from cache. 25706 */ 25707 static getFromCache(key, letterSpacing, cache, context) { 25708 let width = cache[key]; 25709 return typeof width != "number" && (width = _TextMetrics2._measureText(key, letterSpacing, context) + letterSpacing, cache[key] = width), width; 25710 } 25711 /** 25712 * Determines whether we should collapse breaking spaces. 25713 * @param whiteSpace - The TextStyle property whiteSpace 25714 * @returns Should collapse 25715 */ 25716 static collapseSpaces(whiteSpace) { 25717 return whiteSpace === "normal" || whiteSpace === "pre-line"; 25718 } 25719 /** 25720 * Determines whether we should collapse newLine chars. 25721 * @param whiteSpace - The white space 25722 * @returns should collapse 25723 */ 25724 static collapseNewlines(whiteSpace) { 25725 return whiteSpace === "normal"; 25726 } 25727 /** 25728 * Trims breaking whitespaces from string. 25729 * @param text - The text 25730 * @returns Trimmed string 25731 */ 25732 static trimRight(text) { 25733 if (typeof text != "string") 25734 return ""; 25735 for (let i = text.length - 1; i >= 0; i--) { 25736 const char = text[i]; 25737 if (!_TextMetrics2.isBreakingSpace(char)) 25738 break; 25739 text = text.slice(0, -1); 25740 } 25741 return text; 25742 } 25743 /** 25744 * Determines if char is a newline. 25745 * @param char - The character 25746 * @returns True if newline, False otherwise. 25747 */ 25748 static isNewline(char) { 25749 return typeof char != "string" ? !1 : _TextMetrics2._newlines.includes(char.charCodeAt(0)); 25750 } 25751 /** 25752 * Determines if char is a breaking whitespace. 25753 * 25754 * It allows one to determine whether char should be a breaking whitespace 25755 * For example certain characters in CJK langs or numbers. 25756 * It must return a boolean. 25757 * @param char - The character 25758 * @param [_nextChar] - The next character 25759 * @returns True if whitespace, False otherwise. 25760 */ 25761 static isBreakingSpace(char, _nextChar) { 25762 return typeof char != "string" ? !1 : _TextMetrics2._breakingSpaces.includes(char.charCodeAt(0)); 25763 } 25764 /** 25765 * Splits a string into words, breaking-spaces and newLine characters 25766 * @param text - The text 25767 * @returns A tokenized array 25768 */ 25769 static tokenize(text) { 25770 const tokens = []; 25771 let token = ""; 25772 if (typeof text != "string") 25773 return tokens; 25774 for (let i = 0; i < text.length; i++) { 25775 const char = text[i], nextChar = text[i + 1]; 25776 if (_TextMetrics2.isBreakingSpace(char, nextChar) || _TextMetrics2.isNewline(char)) { 25777 token !== "" && (tokens.push(token), token = ""), tokens.push(char); 25778 continue; 25779 } 25780 token += char; 25781 } 25782 return token !== "" && tokens.push(token), tokens; 25783 } 25784 /** 25785 * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior. 25786 * 25787 * It allows one to customise which words should break 25788 * Examples are if the token is CJK or numbers. 25789 * It must return a boolean. 25790 * @param _token - The token 25791 * @param breakWords - The style attr break words 25792 * @returns Whether to break word or not 25793 */ 25794 static canBreakWords(_token, breakWords) { 25795 return breakWords; 25796 } 25797 /** 25798 * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior. 25799 * 25800 * It allows one to determine whether a pair of characters 25801 * should be broken by newlines 25802 * For example certain characters in CJK langs or numbers. 25803 * It must return a boolean. 25804 * @param _char - The character 25805 * @param _nextChar - The next character 25806 * @param _token - The token/word the characters are from 25807 * @param _index - The index in the token of the char 25808 * @param _breakWords - The style attr break words 25809 * @returns whether to break word or not 25810 */ 25811 static canBreakChars(_char, _nextChar, _token, _index, _breakWords) { 25812 return !0; 25813 } 25814 /** 25815 * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior. 25816 * 25817 * It is called when a token (usually a word) has to be split into separate pieces 25818 * in order to determine the point to break a word. 25819 * It must return an array of characters. 25820 * @param token - The token to split 25821 * @returns The characters of the token 25822 * @see TextMetrics.graphemeSegmenter 25823 */ 25824 static wordWrapSplit(token) { 25825 return _TextMetrics2.graphemeSegmenter(token); 25826 } 25827 /** 25828 * Calculates the ascent, descent and fontSize of a given font-style 25829 * @param font - String representing the style of the font 25830 * @returns Font properties object 25831 */ 25832 static measureFont(font) { 25833 if (_TextMetrics2._fonts[font]) 25834 return _TextMetrics2._fonts[font]; 25835 const properties = { 25836 ascent: 0, 25837 descent: 0, 25838 fontSize: 0 25839 }, canvas = _TextMetrics2._canvas, context = _TextMetrics2._context; 25840 context.font = font; 25841 const metricsString = _TextMetrics2.METRICS_STRING + _TextMetrics2.BASELINE_SYMBOL, width = Math.ceil(context.measureText(metricsString).width);
25842 let baseline = Math.ceil(context.measureText(_TextMetrics2.BASELINE_SYMBOL).width); 25843 const height = Math.ceil(_TextMetrics2.HEIGHT_MULTIPLIER * baseline); 25844 if (baseline = baseline * _TextMetrics2.BASELINE_MULTIPLIER | 0, width === 0 || height === 0) 25845 return _TextMetrics2._fonts[font] = properties, properties; 25846 canvas.width = width, canvas.height = height, context.fillStyle = "#f00", context.fillRect(0, 0, width, height), context.font = font, context.textBaseline = "alphabetic", context.fillStyle = "#000", context.fillText(metricsString, 0, baseline); 25847 const imagedata = context.getImageData(0, 0, width, height).data, pixels = imagedata.length, line = width * 4; 25848 let i = 0, idx = 0, stop = !1; 25849 for (i = 0; i < baseline; ++i) { 25850 for (let j = 0; j < line; j += 4) 25851 if (imagedata[idx + j] !== 255) { 25852 stop = !0; 25853 break; 25854 } 25855 if (!stop) 25856 idx += line; 25857 else 25858 break; 25859 } 25860 for (properties.ascent = baseline - i, idx = pixels - line, stop = !1, i = height; i > baseline; --i) { 25861 for (let j = 0; j < line; j += 4) 25862 if (imagedata[idx + j] !== 255) { 25863 stop = !0; 25864 break; 25865 } 25866 if (!stop) 25867 idx -= line; 25868 else 25869 break; 25870 } 25871 return properties.descent = i - baseline, properties.fontSize = properties.ascent + properties.descent, _TextMetrics2._fonts[font] = properties, properties; 25872 } 25873 /** 25874 * Clear font metrics in metrics cache. 25875 * @param {string} [font] - font name. If font name not set then clear cache for all fonts. 25876 */ 25877 static clearMetrics(font = "") { 25878 font ? delete _TextMetrics2._fonts[font] : _TextMetrics2._fonts = {}; 25879 } 25880 /** 25881 * Cached canvas element for measuring text 25882 * TODO: this should be private, but isn't because of backward compat, will fix later. 25883 * @ignore 25884 */ 25885 static get _canvas() { 25886 if (!_TextMetrics2.__canvas) { 25887 let canvas; 25888 try { 25889 const c = new OffscreenCanvas(0, 0); 25890 if (c.getContext("2d", contextSettings)?.measureText) 25891 return _TextMetrics2.__canvas = c, c; 25892 canvas = settings.ADAPTER.createCanvas(); 25893 } catch { 25894 canvas = settings.ADAPTER.createCanvas(); 25895 } 25896 canvas.width = canvas.height = 10, _TextMetrics2.__canvas = canvas; 25897 } 25898 return _TextMetrics2.__canvas; 25899 } 25900 /** 25901 * TODO: this should be private, but isn't because of backward compat, will fix later. 25902 * @ignore 25903 */ 25904 static get _context() { 25905 return _TextMetrics2.__context || (_TextMetrics2.__context = _TextMetrics2._canvas.getContext("2d", contextSettings)), _TextMetrics2.__context; 25906 } 25907}; 25908_TextMetrics.METRICS_STRING = "|\xC9q\xC5", /** Baseline symbol for calculate font metrics. */ 25909_TextMetrics.BASELINE_SYMBOL = "M", /** Baseline multiplier for calculate font metrics. */ 25910_TextMetrics.BASELINE_MULTIPLIER = 1.4, /** Height multiplier for setting height of canvas to calculate font metrics. */ 25911_TextMetrics.HEIGHT_MULTIPLIER = 2, /** 25912* A Unicode "character", or "grapheme cluster", can be composed of multiple Unicode code points, 25913* such as letters with diacritical marks (e.g. `'\u0065\u0301'`, letter e with acute) 25914* or emojis with modifiers (e.g. `'\uD83E\uDDD1\u200D\uD83D\uDCBB'`, technologist). 25915* The new `Intl.Segmenter` API in ES2022 can split the string into grapheme clusters correctly. If it is not available, 25916* PixiJS will fallback to use the iterator of String, which can only spilt the string into code points. 25917* If you want to get full functionality in environments that don't support `Intl.Segmenter` (such as Firefox), 25918* you can use other libraries such as [grapheme-splitter]{@link https://www.npmjs.com/package/grapheme-splitter} 25919* or [graphemer]{@link https://www.npmjs.com/package/graphemer} to create a polyfill. Since these libraries can be 25920* relatively large in size to handle various Unicode grapheme clusters properly, PixiJS won't use them directly. 25921*/ 25922_TextMetrics.graphemeSegmenter = (() => { 25923 if (typeof Intl?.Segmenter == "function") { 25924 const segmenter = new Intl.Segmenter(); 25925 return (s) => [...segmenter.segment(s)].map((x) => x.segment); 25926 } 25927 return (s) => [...s]; 25928})(), /** 25929* New rendering behavior for letter-spacing which uses Chrome's new native API. This will 25930* lead to more accurate letter-spacing results because it does not try to manually draw 25931* each character. However, this Chrome API is experimental and may not serve all cases yet. 25932* @see PIXI.TextMetrics.experimentalLetterSpacingSupported 25933*/ 25934_TextMetrics.experimentalLetterSpacing = !1, /** Cache of {@see PIXI.TextMetrics.FontMetrics} objects. */ 25935_TextMetrics._fonts = {}, /** Cache of new line chars. */ 25936_TextMetrics._newlines = [ 25937 10, 25938 // line feed 25939 13 25940 // carriage return
vendor: 29,827 bytes, lines 25941-26694
25941], /** Cache of breaking spaces. */ 25942_TextMetrics._breakingSpaces = [ 25943 9, 25944 // character tabulation 25945 32, 25946 // space 25947 8192, 25948 // en quad 25949 8193, 25950 // em quad 25951 8194, 25952 // en space 25953 8195, 25954 // em space 25955 8196, 25956 // three-per-em space 25957 8197, 25958 // four-per-em space 25959 8198, 25960 // six-per-em space 25961 8200, 25962 // punctuation space 25963 8201, 25964 // thin space 25965 8202, 25966 // hair space 25967 8287, 25968 // medium mathematical space 25969 12288 25970 // ideographic space 25971]; 25972let TextMetrics = _TextMetrics; 25973 25974const genericFontFamilies = [ 25975 "serif", 25976 "sans-serif", 25977 "monospace", 25978 "cursive", 25979 "fantasy", 25980 "system-ui" 25981], _TextStyle = class _TextStyle2 { 25982 /** 25983 * @param style - TextStyle properties to be set on the text. See {@link PIXI.TextStyle.defaultStyle} 25984 * for the default values. 25985 */ 25986 constructor(style) { 25987 this.styleID = 0, this.reset(), deepCopyProperties(this, style, style); 25988 } 25989 /** 25990 * Creates a new TextStyle object with the same values as this one. 25991 * Note that the only the properties of the object are cloned. 25992 * 25993 * @return New cloned TextStyle object 25994 */ 25995 clone() { 25996 const clonedProperties = {}; 25997 return deepCopyProperties(clonedProperties, this, _TextStyle2.defaultStyle), new _TextStyle2(clonedProperties); 25998 } 25999 /** Resets all properties to the defaults specified in TextStyle.prototype._default */ 26000 reset() { 26001 deepCopyProperties(this, _TextStyle2.defaultStyle, _TextStyle2.defaultStyle); 26002 } 26003 /** 26004 * Alignment for multiline text, does not affect single line text. 26005 * 26006 * @member {'left'|'center'|'right'|'justify'} 26007 */ 26008 get align() { 26009 return this._align; 26010 } 26011 set align(align) { 26012 this._align !== align && (this._align = align, this.styleID++); 26013 } 26014 /** Indicates if lines can be wrapped within words, it needs wordWrap to be set to true. */ 26015 get breakWords() { 26016 return this._breakWords; 26017 } 26018 set breakWords(breakWords) { 26019 this._breakWords !== breakWords && (this._breakWords = breakWords, this.styleID++); 26020 } 26021 /** Set a drop shadow for the text. */ 26022 get dropShadow() { 26023 return this._dropShadow; 26024 } 26025 set dropShadow(dropShadow) { 26026 this._dropShadow !== dropShadow && (this._dropShadow = dropShadow, this.styleID++); 26027 } 26028 /** Set alpha for the drop shadow. */ 26029 get dropShadowAlpha() { 26030 return this._dropShadowAlpha; 26031 } 26032 set dropShadowAlpha(dropShadowAlpha) { 26033 this._dropShadowAlpha !== dropShadowAlpha && (this._dropShadowAlpha = dropShadowAlpha, this.styleID++); 26034 } 26035 /** Set a angle of the drop shadow. */ 26036 get dropShadowAngle() { 26037 return this._dropShadowAngle; 26038 } 26039 set dropShadowAngle(dropShadowAngle) { 26040 this._dropShadowAngle !== dropShadowAngle && (this._dropShadowAngle = dropShadowAngle, this.styleID++); 26041 } 26042 /** Set a shadow blur radius. */ 26043 get dropShadowBlur() { 26044 return this._dropShadowBlur; 26045 } 26046 set dropShadowBlur(dropShadowBlur) { 26047 this._dropShadowBlur !== dropShadowBlur && (this._dropShadowBlur = dropShadowBlur, this.styleID++); 26048 } 26049 /** A fill style to be used on the dropshadow e.g., 'red', '#00FF00'. */ 26050 get dropShadowColor() { 26051 return this._dropShadowColor; 26052 } 26053 set dropShadowColor(dropShadowColor) { 26054 const outputColor = getColor(dropShadowColor); 26055 this._dropShadowColor !== outputColor && (this._dropShadowColor = outputColor, this.styleID++); 26056 } 26057 /** Set a distance of the drop shadow. */ 26058 get dropShadowDistance() { 26059 return this._dropShadowDistance; 26060 } 26061 set dropShadowDistance(dropShadowDistance) { 26062 this._dropShadowDistance !== dropShadowDistance && (this._dropShadowDistance = dropShadowDistance, this.styleID++); 26063 } 26064 /** 26065 * A canvas fillstyle that will be used on the text e.g., 'red', '#00FF00'. 26066 * 26067 * Can be an array to create a gradient e.g., `['#000000','#FFFFFF']` 26068 * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle|MDN} 26069 * 26070 * @member {string|string[]|number|number[]|CanvasGradient|CanvasPattern} 26071 */ 26072 get fill() { 26073 return this._fill; 26074 } 26075 set fill(fill) { 26076 const outputColor = getColor(fill); 26077 this._fill !== outputColor && (this._fill = outputColor, this.styleID++); 26078 } 26079 /** 26080 * If fill is an array of colours to create a gradient, this can change the type/direction of the gradient. 26081 * 26082 * @type {PIXI.TEXT_GRADIENT} 26083 */ 26084 get fillGradientType() { 26085 return this._fillGradientType; 26086 } 26087 set fillGradientType(fillGradientType) { 26088 this._fillGradientType !== fillGradientType && (this._fillGradientType = fillGradientType, this.styleID++); 26089 } 26090 /** 26091 * If fill is an array of colours to create a gradient, this array can set the stop points 26092 * (numbers between 0 and 1) for the color, overriding the default behaviour of evenly spacing them. 26093 */ 26094 get fillGradientStops() { 26095 return this._fillGradientStops; 26096 } 26097 set fillGradientStops(fillGradientStops) { 26098 areArraysEqual(this._fillGradientStops, fillGradientStops) || (this._fillGradientStops = fillGradientStops, this.styleID++); 26099 } 26100 /** 26101 * The font family, can be a single font name, or a list of names where the first 26102 * is the preferred font. 26103 */ 26104 get fontFamily() { 26105 return this._fontFamily; 26106 } 26107 set fontFamily(fontFamily) { 26108 this.fontFamily !== fontFamily && (this._fontFamily = fontFamily, this.styleID++); 26109 } 26110 /** 26111 * The font size 26112 * (as a number it converts to px, but as a string, equivalents are '26px','20pt','160%' or '1.6em') 26113 */ 26114 get fontSize() { 26115 return this._fontSize; 26116 } 26117 set fontSize(fontSize) { 26118 this._fontSize !== fontSize && (this._fontSize = fontSize, this.styleID++); 26119 } 26120 /** 26121 * The font style. 26122 * 26123 * @member {'normal'|'italic'|'oblique'} 26124 */ 26125 get fontStyle() { 26126 return this._fontStyle; 26127 } 26128 set fontStyle(fontStyle) { 26129 this._fontStyle !== fontStyle && (this._fontStyle = fontStyle, this.styleID++); 26130 } 26131 /** 26132 * The font variant. 26133 * 26134 * @member {'normal'|'small-caps'} 26135 */ 26136 get fontVariant() { 26137 return this._fontVariant; 26138 } 26139 set fontVariant(fontVariant) { 26140 this._fontVariant !== fontVariant && (this._fontVariant = fontVariant, this.styleID++); 26141 } 26142 /** 26143 * The font weight. 26144 * 26145 * @member {'normal'|'bold'|'bolder'|'lighter'|'100'|'200'|'300'|'400'|'500'|'600'|'700'|'800'|'900'} 26146 */ 26147 get fontWeight() { 26148 return this._fontWeight; 26149 } 26150 set fontWeight(fontWeight) { 26151 this._fontWeight !== fontWeight && (this._fontWeight = fontWeight, this.styleID++); 26152 } 26153 /** The amount of spacing between letters, default is 0. */ 26154 get letterSpacing() { 26155 return this._letterSpacing; 26156 } 26157 set letterSpacing(letterSpacing) { 26158 this._letterSpacing !== letterSpacing && (this._letterSpacing = letterSpacing, this.styleID++); 26159 } 26160 /** The line height, a number that represents the vertical space that a letter uses. */ 26161 get lineHeight() { 26162 return this._lineHeight; 26163 } 26164 set lineHeight(lineHeight) { 26165 this._lineHeight !== lineHeight && (this._lineHeight = lineHeight, this.styleID++); 26166 } 26167 /** The space between lines. */ 26168 get leading() { 26169 return this._leading; 26170 } 26171 set leading(leading) { 26172 this._leading !== leading && (this._leading = leading, this.styleID++); 26173 } 26174 /** 26175 * The lineJoin property sets the type of corner created, it can resolve spiked text issues. 26176 * Default is 'miter' (creates a sharp corner). 26177 * 26178 * @member {'miter'|'round'|'bevel'} 26179 */ 26180 get lineJoin() { 26181 return this._lineJoin; 26182 } 26183 set lineJoin(lineJoin) { 26184 this._lineJoin !== lineJoin && (this._lineJoin = lineJoin, this.styleID++); 26185 } 26186 /** 26187 * The miter limit to use when using the 'miter' lineJoin mode. 26188 * 26189 * This can reduce or increase the spikiness of rendered text. 26190 */ 26191 get miterLimit() { 26192 return this._miterLimit; 26193 } 26194 set miterLimit(miterLimit) { 26195 this._miterLimit !== miterLimit && (this._miterLimit = miterLimit, this.styleID++); 26196 } 26197 /** 26198 * Occasionally some fonts are cropped. Adding some padding will prevent this from happening 26199 * by adding padding to all sides of the text. 26200 */ 26201 get padding() { 26202 return this._padding; 26203 } 26204 set padding(padding) { 26205 this._padding !== padding && (this._padding = padding, this.styleID++); 26206 } 26207 /** 26208 * A canvas fillstyle that will be used on the text stroke, e.g., 'blue', '#FCFF00' 26209 */ 26210 get stroke() { 26211 return this._stroke; 26212 } 26213 set stroke(stroke) { 26214 const outputColor = getColor(stroke); 26215 this._stroke !== outputColor && (this._stroke = outputColor, this.styleID++); 26216 } 26217 /** 26218 * A number that represents the thickness of the stroke. 26219 * 26220 * @default 0 26221 */ 26222 get strokeThickness() { 26223 return this._strokeThickness; 26224 } 26225 set strokeThickness(strokeThickness) { 26226 this._strokeThickness !== strokeThickness && (this._strokeThickness = strokeThickness, this.styleID++); 26227 } 26228 /** 26229 * The baseline of the text that is rendered. 26230 * 26231 * @member {'alphabetic'|'top'|'hanging'|'middle'|'ideographic'|'bottom'} 26232 */ 26233 get textBaseline() { 26234 return this._textBaseline; 26235 } 26236 set textBaseline(textBaseline) { 26237 this._textBaseline !== textBaseline && (this._textBaseline = textBaseline, this.styleID++); 26238 } 26239 /** Trim transparent borders. */ 26240 get trim() { 26241 return this._trim; 26242 } 26243 set trim(trim) { 26244 this._trim !== trim && (this._trim = trim, this.styleID++); 26245 } 26246 /** 26247 * How newlines and spaces should be handled. 26248 * Default is 'pre' (preserve, preserve). 26249 * 26250 * value | New lines | Spaces 26251 * --- | --- | --- 26252 * 'normal' | Collapse | Collapse 26253 * 'pre' | Preserve | Preserve 26254 * 'pre-line' | Preserve | Collapse 26255 * 26256 * @member {'normal'|'pre'|'pre-line'} 26257 */ 26258 get whiteSpace() { 26259 return this._whiteSpace; 26260 } 26261 set whiteSpace(whiteSpace) { 26262 this._whiteSpace !== whiteSpace && (this._whiteSpace = whiteSpace, this.styleID++); 26263 } 26264 /** Indicates if word wrap should be used. */ 26265 get wordWrap() { 26266 return this._wordWrap; 26267 } 26268 set wordWrap(wordWrap) { 26269 this._wordWrap !== wordWrap && (this._wordWrap = wordWrap, this.styleID++); 26270 } 26271 /** The width at which text will wrap, it needs wordWrap to be set to true. */ 26272 get wordWrapWidth() { 26273 return this._wordWrapWidth; 26274 } 26275 set wordWrapWidth(wordWrapWidth) { 26276 this._wordWrapWidth !== wordWrapWidth && (this._wordWrapWidth = wordWrapWidth, this.styleID++); 26277 } 26278 /** 26279 * Generates a font style string to use for `TextMetrics.measureFont()`. 26280 * 26281 * @return Font style string, for passing to `TextMetrics.measureFont()` 26282 */ 26283 toFontString() { 26284 const fontSizeString = typeof this.fontSize == "number" ? `${this.fontSize}px` : this.fontSize; 26285 let fontFamilies = this.fontFamily; 26286 Array.isArray(this.fontFamily) || (fontFamilies = this.fontFamily.split(",")); 26287 for (let i = fontFamilies.length - 1; i >= 0; i--) { 26288 let fontFamily = fontFamilies[i].trim(); 26289 !/([\"\'])[^\'\"]+\1/.test(fontFamily) && !genericFontFamilies.includes(fontFamily) && (fontFamily = `"${fontFamily}"`), fontFamilies[i] = fontFamily; 26290 } 26291 return `${this.fontStyle} ${this.fontVariant} ${this.fontWeight} ${fontSizeString} ${fontFamilies.join(",")}`; 26292 } 26293}; 26294_TextStyle.defaultStyle = { 26295 /** 26296 * See {@link PIXI.TextStyle.align} 26297 * @type {'left'|'center'|'right'|'justify'} 26298 */ 26299 align: "left", 26300 /** See {@link PIXI.TextStyle.breakWords} */ 26301 breakWords: !1, 26302 /** See {@link PIXI.TextStyle.dropShadow} */ 26303 dropShadow: !1, 26304 /** See {@link PIXI.TextStyle.dropShadowAlpha} */ 26305 dropShadowAlpha: 1, 26306 /** 26307 * See {@link PIXI.TextStyle.dropShadowAngle} 26308 * @type {number} 26309 * @default Math.PI / 6 26310 */ 26311 dropShadowAngle: Math.PI / 6, 26312 /** See {@link PIXI.TextStyle.dropShadowBlur} */ 26313 dropShadowBlur: 0, 26314 /** 26315 * See {@link PIXI.TextStyle.dropShadowColor} 26316 * @type {string|number} 26317 */ 26318 dropShadowColor: "black", 26319 /** See {@link PIXI.TextStyle.dropShadowDistance} */ 26320 dropShadowDistance: 5, 26321 /** 26322 * See {@link PIXI.TextStyle.fill} 26323 * @type {string|string[]|number|number[]|CanvasGradient|CanvasPattern} 26324 */ 26325 fill: "black", 26326 /** 26327 * See {@link PIXI.TextStyle.fillGradientType} 26328 * @type {PIXI.TEXT_GRADIENT} 26329 * @default PIXI.TEXT_GRADIENT.LINEAR_VERTICAL 26330 */ 26331 fillGradientType: TEXT_GRADIENT.LINEAR_VERTICAL, 26332 /** 26333 * See {@link PIXI.TextStyle.fillGradientStops} 26334 * @type {number[]} 26335 * @default [] 26336 */ 26337 fillGradientStops: [], 26338 /** 26339 * See {@link PIXI.TextStyle.fontFamily} 26340 * @type {string|string[]} 26341 */ 26342 fontFamily: "Arial", 26343 /** 26344 * See {@link PIXI.TextStyle.fontSize} 26345 * @type {number|string} 26346 */ 26347 fontSize: 26, 26348 /** 26349 * See {@link PIXI.TextStyle.fontStyle} 26350 * @type {'normal'|'italic'|'oblique'} 26351 */ 26352 fontStyle: "normal", 26353 /** 26354 * See {@link PIXI.TextStyle.fontVariant} 26355 * @type {'normal'|'small-caps'} 26356 */ 26357 fontVariant: "normal", 26358 /** 26359 * See {@link PIXI.TextStyle.fontWeight} 26360 * @type {'normal'|'bold'|'bolder'|'lighter'|'100'|'200'|'300'|'400'|'500'|'600'|'700'|'800'|'900'} 26361 */ 26362 fontWeight: "normal", 26363 /** See {@link PIXI.TextStyle.leading} */ 26364 leading: 0, 26365 /** See {@link PIXI.TextStyle.letterSpacing} */ 26366 letterSpacing: 0, 26367 /** See {@link PIXI.TextStyle.lineHeight} */ 26368 lineHeight: 0, 26369 /** 26370 * See {@link PIXI.TextStyle.lineJoin} 26371 * @type {'miter'|'round'|'bevel'} 26372 */ 26373 lineJoin: "miter", 26374 /** See {@link PIXI.TextStyle.miterLimit} */ 26375 miterLimit: 10, 26376 /** See {@link PIXI.TextStyle.padding} */ 26377 padding: 0, 26378 /** 26379 * See {@link PIXI.TextStyle.stroke} 26380 * @type {string|number} 26381 */ 26382 stroke: "black", 26383 /** See {@link PIXI.TextStyle.strokeThickness} */ 26384 strokeThickness: 0, 26385 /** 26386 * See {@link PIXI.TextStyle.textBaseline} 26387 * @type {'alphabetic'|'top'|'hanging'|'middle'|'ideographic'|'bottom'} 26388 */ 26389 textBaseline: "alphabetic", 26390 /** See {@link PIXI.TextStyle.trim} */ 26391 trim: !1, 26392 /** 26393 * See {@link PIXI.TextStyle.whiteSpace} 26394 * @type {'normal'|'pre'|'pre-line'} 26395 */ 26396 whiteSpace: "pre", 26397 /** See {@link PIXI.TextStyle.wordWrap} */ 26398 wordWrap: !1, 26399 /** See {@link PIXI.TextStyle.wordWrapWidth} */ 26400 wordWrapWidth: 100 26401}; 26402let TextStyle = _TextStyle; 26403function getColor(color) { 26404 const temp = Color.shared, format = (color2) => { 26405 const res = temp.setValue(color2); 26406 return res.alpha === 1 ? res.toHex() : res.toRgbaString(); 26407 }; 26408 return Array.isArray(color) ? color.map(format) : format(color); 26409} 26410function areArraysEqual(array1, array2) { 26411 if (!Array.isArray(array1) || !Array.isArray(array2) || array1.length !== array2.length) 26412 return !1; 26413 for (let i = 0; i < array1.length; ++i) 26414 if (array1[i] !== array2[i]) 26415 return !1; 26416 return !0; 26417} 26418function deepCopyProperties(target, source, propertyObj) { 26419 for (const prop in propertyObj) 26420 Array.isArray(source[prop]) ? target[prop] = source[prop].slice() : target[prop] = source[prop]; 26421} 26422 26423const defaultDestroyOptions = { 26424 texture: !0, 26425 children: !1, 26426 baseTexture: !0 26427}, _Text = class _Text2 extends Sprite { 26428 /** 26429 * @param text - The string that you would like the text to display 26430 * @param style - The style parameters 26431 * @param canvas - The canvas element for drawing text 26432 */ 26433 constructor(text, style, canvas) { 26434 let ownCanvas = !1; 26435 canvas || (canvas = settings.ADAPTER.createCanvas(), ownCanvas = !0), canvas.width = 3, canvas.height = 3; 26436 const texture = Texture.from(canvas); 26437 texture.orig = new Rectangle(), texture.trim = new Rectangle(), super(texture), this._ownCanvas = ownCanvas, this.canvas = canvas, this.context = canvas.getContext("2d", { 26438 // required for trimming to work without warnings 26439 willReadFrequently: !0 26440 }), this._resolution = _Text2.defaultResolution ?? settings.RESOLUTION, this._autoResolution = _Text2.defaultAutoResolution, this._text = null, this._style = null, this._styleListener = null, this._font = "", this.text = text, this.style = style, this.localStyleID = -1; 26441 } 26442 /** 26443 * @see PIXI.TextMetrics.experimentalLetterSpacing 26444 * @deprecated since 7.1.0 26445 */ 26446 static get experimentalLetterSpacing() { 26447 return TextMetrics.experimentalLetterSpacing; 26448 } 26449 static set experimentalLetterSpacing(value) { 26450 deprecation( 26451 "7.1.0", 26452 "Text.experimentalLetterSpacing is deprecated, use TextMetrics.experimentalLetterSpacing" 26453 ), TextMetrics.experimentalLetterSpacing = value; 26454 } 26455 /** 26456 * Renders text to its canvas, and updates its texture. 26457 * 26458 * By default this is used internally to ensure the texture is correct before rendering, 26459 * but it can be used called externally, for example from this class to 'pre-generate' the texture from a piece of text, 26460 * and then shared across multiple Sprites. 26461 * @param respectDirty - Whether to abort updating the text if the Text isn't dirty and the function is called. 26462 */ 26463 updateText(respectDirty) { 26464 const style = this._style; 26465 if (this.localStyleID !== style.styleID && (this.dirty = !0, this.localStyleID = style.styleID), !this.dirty && respectDirty) 26466 return; 26467 this._font = this._style.toFontString(); 26468 const context = this.context, measured = TextMetrics.measureText(this._text || " ", this._style, this._style.wordWrap, this.canvas), width = measured.width, height = measured.height, lines = measured.lines, lineHeight = measured.lineHeight, lineWidths = measured.lineWidths, maxLineWidth = measured.maxLineWidth, fontProperties = measured.fontProperties; 26469 this.canvas.width = Math.ceil(Math.ceil(Math.max(1, width) + style.padding * 2) * this._resolution), this.canvas.height = Math.ceil(Math.ceil(Math.max(1, height) + style.padding * 2) * this._resolution), context.scale(this._resolution, this._resolution), context.clearRect(0, 0, this.canvas.width, this.canvas.height), context.font = this._font, context.lineWidth = style.strokeThickness, context.textBaseline = style.textBaseline, context.lineJoin = style.lineJoin, context.miterLimit = style.miterLimit; 26470 let linePositionX, linePositionY; 26471 const passesCount = style.dropShadow ? 2 : 1; 26472 for (let i = 0; i < passesCount; ++i) { 26473 const isShadowPass = style.dropShadow && i === 0, dsOffsetText = isShadowPass ? Math.ceil(Math.max(1, height) + style.padding * 2) : 0, dsOffsetShadow = dsOffsetText * this._resolution; 26474 if (isShadowPass) { 26475 context.fillStyle = "black", context.strokeStyle = "black"; 26476 const dropShadowColor = style.dropShadowColor, dropShadowBlur = style.dropShadowBlur * this._resolution, dropShadowDistance = style.dropShadowDistance * this._resolution; 26477 context.shadowColor = Color.shared.setValue(dropShadowColor).setAlpha(style.dropShadowAlpha).toRgbaString(), context.shadowBlur = dropShadowBlur, context.shadowOffsetX = Math.cos(style.dropShadowAngle) * dropShadowDistance, context.shadowOffsetY = Math.sin(style.dropShadowAngle) * dropShadowDistance + dsOffsetShadow; 26478 } else 26479 context.fillStyle = this._generateFillStyle(style, lines, measured), context.strokeStyle = style.stroke, context.shadowColor = "black", context.shadowBlur = 0, context.shadowOffsetX = 0, context.shadowOffsetY = 0; 26480 let linePositionYShift = (lineHeight - fontProperties.fontSize) / 2; 26481 lineHeight - fontProperties.fontSize < 0 && (linePositionYShift = 0); 26482 for (let i2 = 0; i2 < lines.length; i2++) 26483 linePositionX = style.strokeThickness / 2, linePositionY = style.strokeThickness / 2 + i2 * lineHeight + fontProperties.ascent + linePositionYShift, style.align === "right" ? linePositionX += maxLineWidth - lineWidths[i2] : style.align === "center" && (linePositionX += (maxLineWidth - lineWidths[i2]) / 2), style.stroke && style.strokeThickness && this.drawLetterSpacing( 26484 lines[i2], 26485 linePositionX + style.padding, 26486 linePositionY + style.padding - dsOffsetText, 26487 !0 26488 ), style.fill && this.drawLetterSpacing( 26489 lines[i2], 26490 linePositionX + style.padding, 26491 linePositionY + style.padding - dsOffsetText 26492 ); 26493 } 26494 this.updateTexture(); 26495 } 26496 /** 26497 * Render the text with letter-spacing. 26498 * @param text - The text to draw 26499 * @param x - Horizontal position to draw the text 26500 * @param y - Vertical position to draw the text 26501 * @param isStroke - Is this drawing for the outside stroke of the 26502 * text? If not, it's for the inside fill 26503 */ 26504 drawLetterSpacing(text, x, y, isStroke = !1) { 26505 const letterSpacing = this._style.letterSpacing; 26506 let useExperimentalLetterSpacing = !1; 26507 if (TextMetrics.experimentalLetterSpacingSupported && (TextMetrics.experimentalLetterSpacing ? (this.context.letterSpacing = `${letterSpacing}px`, this.context.textLetterSpacing = `${letterSpacing}px`, useExperimentalLetterSpacing = !0) : (this.context.letterSpacing = "0px", this.context.textLetterSpacing = "0px")), letterSpacing === 0 || useExperimentalLetterSpacing) { 26508 isStroke ? this.context.strokeText(text, x, y) : this.context.fillText(text, x, y); 26509 return; 26510 } 26511 let currentPosition = x; 26512 const stringArray = TextMetrics.graphemeSegmenter(text); 26513 let previousWidth = this.context.measureText(text).width, currentWidth = 0; 26514 for (let i = 0; i < stringArray.length; ++i) { 26515 const currentChar = stringArray[i]; 26516 isStroke ? this.context.strokeText(currentChar, currentPosition, y) : this.context.fillText(currentChar, currentPosition, y); 26517 let textStr = ""; 26518 for (let j = i + 1; j < stringArray.length; ++j) 26519 textStr += stringArray[j]; 26520 currentWidth = this.context.measureText(textStr).width, currentPosition += previousWidth - currentWidth + letterSpacing, previousWidth = currentWidth; 26521 } 26522 } 26523 /** Updates texture size based on canvas size. */ 26524 updateTexture() { 26525 const canvas = this.canvas; 26526 if (this._style.trim) { 26527 const trimmed = trimCanvas(canvas); 26528 trimmed.data && (canvas.width = trimmed.width, canvas.height = trimmed.height, this.context.putImageData(trimmed.data, 0, 0)); 26529 } 26530 const texture = this._texture, style = this._style, padding = style.trim ? 0 : style.padding, baseTexture = texture.baseTexture; 26531 texture.trim.width = texture._frame.width = canvas.width / this._resolution, texture.trim.height = texture._frame.height = canvas.height / this._resolution, texture.trim.x = -padding, texture.trim.y = -padding, texture.orig.width = texture._frame.width - padding * 2, texture.orig.height = texture._frame.height - padding * 2, this._onTextureUpdate(), baseTexture.setRealSize(canvas.width, canvas.height, this._resolution), texture.updateUvs(), this.dirty = !1; 26532 } 26533 /** 26534 * Renders the object using the WebGL renderer 26535 * @param renderer - The renderer 26536 */ 26537 _render(renderer) { 26538 this._autoResolution && this._resolution !== renderer.resolution && (this._resolution = renderer.resolution, this.dirty = !0), this.updateText(!0), super._render(renderer); 26539 } 26540 /** Updates the transform on all children of this container for rendering. */ 26541 updateTransform() { 26542 this.updateText(!0), super.updateTransform(); 26543 } 26544 getBounds(skipUpdate, rect) { 26545 return this.updateText(!0), this._textureID === -1 && (skipUpdate = !1), super.getBounds(skipUpdate, rect); 26546 } 26547 /** 26548 * Gets the local bounds of the text object. 26549 * @param rect - The output rectangle. 26550 * @returns The bounds. 26551 */ 26552 getLocalBounds(rect) { 26553 return this.updateText(!0), super.getLocalBounds.call(this, rect); 26554 } 26555 /** Calculates the bounds of the Text as a rectangle. The bounds calculation takes the worldTransform into account. */ 26556 _calculateBounds() { 26557 this.calculateVertices(), this._bounds.addQuad(this.vertexData); 26558 } 26559 /** 26560 * Generates the fill style. Can automatically generate a gradient based on the fill style being an array 26561 * @param style - The style. 26562 * @param lines - The lines of text. 26563 * @param metrics 26564 * @returns The fill style 26565 */ 26566 _generateFillStyle(style, lines, metrics) { 26567 const fillStyle = style.fill; 26568 if (Array.isArray(fillStyle)) { 26569 if (fillStyle.length === 1) 26570 return fillStyle[0]; 26571 } else 26572 return fillStyle; 26573 let gradient; 26574 const dropShadowCorrection = style.dropShadow ? style.dropShadowDistance : 0, padding = style.padding || 0, width = this.canvas.width / this._resolution - dropShadowCorrection - padding * 2, height = this.canvas.height / this._resolution - dropShadowCorrection - padding * 2, fill = fillStyle.slice(), fillGradientStops = style.fillGradientStops.slice(); 26575 if (!fillGradientStops.length) { 26576 const lengthPlus1 = fill.length + 1; 26577 for (let i = 1; i < lengthPlus1; ++i) 26578 fillGradientStops.push(i / lengthPlus1); 26579 } 26580 if (fill.unshift(fillStyle[0]), fillGradientStops.unshift(0), fill.push(fillStyle[fillStyle.length - 1]), fillGradientStops.push(1), style.fillGradientType === TEXT_GRADIENT.LINEAR_VERTICAL) { 26581 gradient = this.context.createLinearGradient(width / 2, padding, width / 2, height + padding); 26582 const textHeight = metrics.fontProperties.fontSize + style.strokeThickness; 26583 for (let i = 0; i < lines.length; i++) { 26584 const lastLineBottom = metrics.lineHeight * (i - 1) + textHeight, thisLineTop = metrics.lineHeight * i; 26585 let thisLineGradientStart = thisLineTop; 26586 i > 0 && lastLineBottom > thisLineTop && (thisLineGradientStart = (thisLineTop + lastLineBottom) / 2); 26587 const thisLineBottom = thisLineTop + textHeight, nextLineTop = metrics.lineHeight * (i + 1); 26588 let thisLineGradientEnd = thisLineBottom; 26589 i + 1 < lines.length && nextLineTop < thisLineBottom && (thisLineGradientEnd = (thisLineBottom + nextLineTop) / 2); 26590 const gradStopLineHeight = (thisLineGradientEnd - thisLineGradientStart) / height; 26591 for (let j = 0; j < fill.length; j++) { 26592 let lineStop = 0; 26593 typeof fillGradientStops[j] == "number" ? lineStop = fillGradientStops[j] : lineStop = j / fill.length; 26594 let globalStop = Math.min(1, Math.max( 26595 0, 26596 thisLineGradientStart / height + lineStop * gradStopLineHeight 26597 )); 26598 globalStop = Number(globalStop.toFixed(5)), gradient.addColorStop(globalStop, fill[j]); 26599 } 26600 } 26601 } else { 26602 gradient = this.context.createLinearGradient(padding, height / 2, width + padding, height / 2); 26603 const totalIterations = fill.length + 1; 26604 let currentIteration = 1; 26605 for (let i = 0; i < fill.length; i++) { 26606 let stop; 26607 typeof fillGradientStops[i] == "number" ? stop = fillGradientStops[i] : stop = currentIteration / totalIterations, gradient.addColorStop(stop, fill[i]), currentIteration++; 26608 } 26609 } 26610 return gradient; 26611 } 26612 /** 26613 * Destroys this text object. 26614 * 26615 * Note* Unlike a Sprite, a Text object will automatically destroy its baseTexture and texture as 26616 * the majority of the time the texture will not be shared with any other Sprites. 26617 * @param options - Options parameter. A boolean will act as if all options 26618 * have been set to that value 26619 * @param {boolean} [options.children=false] - if set to true, all the children will have their 26620 * destroy method called as well. 'options' will be passed on to those calls. 26621 * @param {boolean} [options.texture=true] - Should it destroy the current texture of the sprite as well 26622 * @param {boolean} [options.baseTexture=true] - Should it destroy the base texture of the sprite as well 26623 */ 26624 destroy(options) { 26625 typeof options == "boolean" && (options = { children: options }), options = Object.assign({}, defaultDestroyOptions, options), super.destroy(options), this._ownCanvas && (this.canvas.height = this.canvas.width = 0), this.context = null, this.canvas = null, this._style = null; 26626 } 26627 /** The width of the Text, setting this will actually modify the scale to achieve the value set. */ 26628 get width() { 26629 return this.updateText(!0), Math.abs(this.scale.x) * this._texture.orig.width; 26630 } 26631 set width(value) { 26632 this.updateText(!0); 26633 const s = sign(this.scale.x) || 1; 26634 this.scale.x = s * value / this._texture.orig.width, this._width = value; 26635 } 26636 /** The height of the Text, setting this will actually modify the scale to achieve the value set. */ 26637 get height() { 26638 return this.updateText(!0), Math.abs(this.scale.y) * this._texture.orig.height; 26639 } 26640 set height(value) { 26641 this.updateText(!0); 26642 const s = sign(this.scale.y) || 1; 26643 this.scale.y = s * value / this._texture.orig.height, this._height = value; 26644 } 26645 /** 26646 * Set the style of the text. 26647 * 26648 * Set up an event listener to listen for changes on the style object and mark the text as dirty. 26649 * 26650 * If setting the `style` can also be partial {@link PIXI.ITextStyle}. 26651 */ 26652 get style() { 26653 return this._style; 26654 } 26655 set style(style) { 26656 style = style || {}, style instanceof TextStyle ? this._style = style : this._style = new TextStyle(style), this.localStyleID = -1, this.dirty = !0; 26657 } 26658 /** Set the copy for the text object. To split a line you can use '\n'. */ 26659 get text() { 26660 return this._text; 26661 } 26662 set text(text) { 26663 text = String(text ?? ""), this._text !== text && (this._text = text, this.dirty = !0); 26664 } 26665 /** 26666 * The resolution / device pixel ratio of the canvas. 26667 * 26668 * This is set to automatically match the renderer resolution by default, but can be overridden by setting manually. 26669 * @default 1 26670 */ 26671 get resolution() { 26672 return this._resolution; 26673 } 26674 set resolution(value) { 26675 this._autoResolution = !1, this._resolution !== value && (this._resolution = value, this.dirty = !0); 26676 } 26677}; 26678_Text.defaultAutoResolution = !0; 26679let Text = _Text; 26680 26681class CountLimiter { 26682 /** 26683 * @param maxItemsPerFrame - The maximum number of items that can be prepared each frame. 26684 */ 26685 constructor(maxItemsPerFrame) { 26686 this.maxItemsPerFrame = maxItemsPerFrame, this.itemsLeft = 0; 26687 } 26688 /** Resets any counting properties to start fresh on a new frame. */ 26689 beginFrame() { 26690 this.itemsLeft = this.maxItemsPerFrame; 26691 } 26692 /** 26693 * Checks to see if another item can be uploaded. This should only be called once per item. 26694 * @returns If the item is allowed to be uploaded.
26695 */ 26696 allowedToUpload() { 26697 return this.itemsLeft-- > 0; 26698 } 26699} 26700 26701function findMultipleBaseTextures(item, queue) { 26702 let result = !1; 26703 if (item?._textures?.length) { 26704 for (let i = 0; i < item._textures.length; i++) 26705 if (item._textures[i] instanceof Texture) { 26706 const baseTexture = item._textures[i].baseTexture; 26707 queue.includes(baseTexture) || (queue.push(baseTexture), result = !0); 26708 } 26709 } 26710 return result; 26711} 26712function findBaseTexture(item, queue) { 26713 if (item.baseTexture instanceof BaseTexture) { 26714 const texture = item.baseTexture; 26715 return queue.includes(texture) || queue.push(texture), !0; 26716 } 26717 return !1; 26718} 26719function findTexture(item, queue) { 26720 if (item._texture && item._texture instanceof Texture) { 26721 const texture = item._texture.baseTexture; 26722 return queue.includes(texture) || queue.push(texture), !0; 26723 } 26724 return !1; 26725} 26726function drawText(_helper, item) { 26727 return item instanceof Text ? (item.updateText(!0), !0) : !1; 26728} 26729function calculateTextStyle(_helper, item) { 26730 if (item instanceof TextStyle) { 26731 const font = item.toFontString(); 26732 return TextMetrics.measureFont(font), !0; 26733 } 26734 return !1; 26735} 26736function findText(item, queue) { 26737 if (item instanceof Text) { 26738 queue.includes(item.style) || queue.push(item.style), queue.includes(item) || queue.push(item); 26739 const texture = item._texture.baseTexture; 26740 return queue.includes(texture) || queue.push(texture), !0; 26741 } 26742 return !1; 26743} 26744function findTextStyle(item, queue) { 26745 return item instanceof TextStyle ? (queue.includes(item) || queue.push(item), !0) : !1; 26746} 26747const _BasePrepare = class _BasePrepare2 { 26748 /** 26749 * @param {PIXI.IRenderer} renderer - A reference to the current renderer 26750 */ 26751 constructor(renderer) { 26752 this.limiter = new CountLimiter(_BasePrepare2.uploadsPerFrame), this.renderer = renderer, this.uploadHookHelper = null, this.queue = [], this.addHooks = [], this.uploadHooks = [], this.completes = [], this.ticking = !1, this.delayedTick = () => { 26753 this.queue && this.prepareItems(); 26754 }, this.registerFindHook(findText), this.registerFindHook(findTextStyle), this.registerFindHook(findMultipleBaseTextures), this.registerFindHook(findBaseTexture), this.registerFindHook(findTexture), this.registerUploadHook(drawText), this.registerUploadHook(calculateTextStyle); 26755 } 26756 /** 26757 * Upload all the textures and graphics to the GPU. 26758 * @method PIXI.BasePrepare#upload 26759 * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text} [item] - 26760 * Container or display object to search for items to upload or the items to upload themselves, 26761 * or optionally ommitted, if items have been added using {@link PIXI.BasePrepare#add `prepare.add`}. 26762 */ 26763 upload(item) { 26764 return new Promise((resolve) => { 26765 item && this.add(item), this.queue.length ? (this.completes.push(resolve), this.ticking || (this.ticking = !0, Ticker.system.addOnce(this.tick, this, UPDATE_PRIORITY.UTILITY))) : resolve(); 26766 }); 26767 } 26768 /** 26769 * Handle tick update 26770 * @private 26771 */ 26772 tick() { 26773 setTimeout(this.delayedTick, 0); 26774 } 26775 /** 26776 * Actually prepare items. This is handled outside of the tick because it will take a while 26777 * and we do NOT want to block the current animation frame from rendering. 26778 * @private 26779 */ 26780 prepareItems() { 26781 for (this.limiter.beginFrame(); this.queue.length && this.limiter.allowedToUpload(); ) { 26782 const item = this.queue[0]; 26783 let uploaded = !1; 26784 if (item && !item._destroyed) { 26785 for (let i = 0, len = this.uploadHooks.length; i < len; i++) 26786 if (this.uploadHooks[i](this.uploadHookHelper, item)) { 26787 this.queue.shift(), uploaded = !0; 26788 break; 26789 } 26790 } 26791 uploaded || this.queue.shift(); 26792 } 26793 if (this.queue.length) 26794 Ticker.system.addOnce(this.tick, this, UPDATE_PRIORITY.UTILITY); 26795 else { 26796 this.ticking = !1; 26797 const completes = this.completes.slice(0); 26798 this.completes.length = 0; 26799 for (let i = 0, len = completes.length; i < len; i++) 26800 completes[i](); 26801 } 26802 } 26803 /** 26804 * Adds hooks for finding items. 26805 * @param {Function} addHook - Function call that takes two parameters: `item:*, queue:Array` 26806 * function must return `true` if it was able to add item to the queue. 26807 * @returns Instance of plugin for chaining. 26808 */ 26809 registerFindHook(addHook) { 26810 return addHook && this.addHooks.push(addHook), this; 26811 } 26812 /** 26813 * Adds hooks for uploading items. 26814 * @param {Function} uploadHook - Function call that takes two parameters: `prepare:CanvasPrepare, item:*` and 26815 * function must return `true` if it was able to handle upload of item. 26816 * @returns Instance of plugin for chaining. 26817 */ 26818 registerUploadHook(uploadHook) { 26819 return uploadHook && this.uploadHooks.push(uploadHook), this; 26820 } 26821 /** 26822 * Manually add an item to the uploading queue. 26823 * @param {PIXI.DisplayObject|PIXI.Container|PIXI.BaseTexture|PIXI.Texture|PIXI.Graphics|PIXI.Text|*} item - Object to 26824 * add to the queue 26825 * @returns Instance of plugin for chaining. 26826 */ 26827 add(item) { 26828 for (let i = 0, len = this.addHooks.length; i < len && !this.addHooks[i](item, this.queue); i++) 26829 ; 26830 if (item instanceof Container) 26831 for (let i = item.children.length - 1; i >= 0; i--) 26832 this.add(item.children[i]); 26833 return this; 26834 } 26835 /** Destroys the plugin, don't use after this. */ 26836 destroy() { 26837 this.ticking && Ticker.system.remove(this.tick, this), this.ticking = !1, this.addHooks = null, this.uploadHooks = null, this.renderer = null, this.completes = null, this.queue = null, this.limiter = null, this.uploadHookHelper = null; 26838 } 26839}; 26840_BasePrepare.uploadsPerFrame = 4; 26841let BasePrepare = _BasePrepare; 26842 26843Object.defineProperties(settings, { 26844 /** 26845 * Default number of uploads per frame using prepare plugin. 26846 * @static 26847 * @memberof PIXI.settings 26848 * @name UPLOADS_PER_FRAME 26849 * @deprecated since 7.1.0 26850 * @see PIXI.BasePrepare.uploadsPerFrame 26851 * @type {number} 26852 */ 26853 UPLOADS_PER_FRAME: { 26854 get() { 26855 return BasePrepare.uploadsPerFrame; 26856 }, 26857 set(value) { 26858 deprecation("7.1.0", "settings.UPLOADS_PER_FRAME is deprecated, use prepare.BasePrepare.uploadsPerFrame"), BasePrepare.uploadsPerFrame = value; 26859 } 26860 } 26861}); 26862 26863function uploadBaseTextures(renderer, item) { 26864 return item instanceof BaseTexture ? (item._glTextures[renderer.CONTEXT_UID] || renderer.texture.bind(item), !0) : !1; 26865} 26866function uploadGraphics(renderer, item) { 26867 if (!(item instanceof Graphics)) 26868 return !1; 26869 const { geometry } = item; 26870 item.finishPoly(), geometry.updateBatches(); 26871 const { batches } = geometry; 26872 for (let i = 0; i < batches.length; i++) { 26873 const { texture } = batches[i].style; 26874 texture && uploadBaseTextures(renderer, texture.baseTexture); 26875 } 26876 return geometry.batchable || renderer.geometry.bind(geometry, item._resolveDirectShader(renderer)), !0; 26877} 26878function findGraphics(item, queue) { 26879 return item instanceof Graphics ? (queue.push(item), !0) : !1; 26880} 26881class Prepare extends BasePrepare { 26882 /** 26883 * @param {PIXI.Renderer} renderer - A reference to the current renderer 26884 */ 26885 constructor(renderer) { 26886 super(renderer), this.uploadHookHelper = this.renderer, this.registerFindHook(findGraphics), this.registerUploadHook(uploadBaseTextures), this.registerUploadHook(uploadGraphics); 26887 } 26888} 26889Prepare.extension = { 26890 name: "prepare", 26891 type: ExtensionType.RendererSystem 26892}; 26893extensions$1.add(Prepare); 26894 26895var gl2FragmentSrc = `#version 300 es 26896#define SHADER_NAME Tiling-Sprite-100 26897 26898precision lowp float; 26899 26900in vec2 vTextureCoord; 26901 26902out vec4 fragmentColor; 26903 26904uniform sampler2D uSampler; 26905uniform vec4 uColor; 26906uniform mat3 uMapCoord; 26907uniform vec4 uClampFrame; 26908uniform vec2 uClampOffset; 26909 26910void main(void) 26911{ 26912 vec2 coord = vTextureCoord + ceil(uClampOffset - vTextureCoord); 26913 coord = (uMapCoord * vec3(coord, 1.0)).xy;
26914 vec2 unclamped = coord; 26915 coord = clamp(coord, uClampFrame.xy, uClampFrame.zw); 26916 26917 vec4 texSample = texture(uSampler, coord, unclamped == coord ? 0.0f : -32.0f);// lod-bias very negative to force lod 0 26918 26919 fragmentColor = texSample * uColor; 26920} 26921`; 26922 26923var gl2VertexSrc = `#version 300 es 26924#define SHADER_NAME Tiling-Sprite-300 26925 26926precision lowp float; 26927 26928in vec2 aVertexPosition; 26929in vec2 aTextureCoord; 26930 26931uniform mat3 projectionMatrix; 26932uniform mat3 translationMatrix; 26933uniform mat3 uTransform; 26934 26935out vec2 vTextureCoord; 26936 26937void main(void) 26938{ 26939 gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); 26940 26941 vTextureCoord = (uTransform * vec3(aTextureCoord, 1.0)).xy; 26942} 26943`; 26944 26945var gl1FragmentSrc = `#version 100 26946#ifdef GL_EXT_shader_texture_lod 26947 #extension GL_EXT_shader_texture_lod : enable 26948#endif 26949#define SHADER_NAME Tiling-Sprite-100 26950 26951precision lowp float; 26952 26953varying vec2 vTextureCoord; 26954 26955uniform sampler2D uSampler; 26956uniform vec4 uColor; 26957uniform mat3 uMapCoord; 26958uniform vec4 uClampFrame; 26959uniform vec2 uClampOffset; 26960 26961void main(void) 26962{ 26963 vec2 coord = vTextureCoord + ceil(uClampOffset - vTextureCoord); 26964 coord = (uMapCoord * vec3(coord, 1.0)).xy; 26965 vec2 unclamped = coord; 26966 coord = clamp(coord, uClampFrame.xy, uClampFrame.zw); 26967 26968 #ifdef GL_EXT_shader_texture_lod 26969 vec4 texSample = unclamped == coord 26970 ? texture2D(uSampler, coord) 26971 : texture2DLodEXT(uSampler, coord, 0); 26972 #else 26973 vec4 texSample = texture2D(uSampler, coord); 26974 #endif 26975 26976 gl_FragColor = texSample * uColor; 26977} 26978`; 26979 26980var gl1VertexSrc = `#version 100 26981#define SHADER_NAME Tiling-Sprite-100 26982 26983precision lowp float; 26984 26985attribute vec2 aVertexPosition; 26986attribute vec2 aTextureCoord; 26987 26988uniform mat3 projectionMatrix; 26989uniform mat3 translationMatrix; 26990uniform mat3 uTransform; 26991 26992varying vec2 vTextureCoord; 26993 26994void main(void) 26995{ 26996 gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0
26996)).xy, 0.0, 1.0); 26997 26998 vTextureCoord = (uTransform * vec3(aTextureCoord, 1.0)).xy; 26999} 27000`; 27001 27002var fragmentSimpleSrc = `#version 100 27003#define SHADER_NAME Tiling-Sprite-Simple-100 27004 27005precision lowp float; 27006 27007varying vec2 vTextureCoord; 27008 27009uniform sampler2D uSampler; 27010uniform vec4 uColor; 27011 27012void main(void) 27013{ 27014 vec4 texSample = texture2D(uSampler, vTextureCoord); 27015 gl_FragColor = texSample * uColor; 27016} 27017`; 27018 27019const tempMat = new Matrix(); 27020class TilingSpriteRenderer extends ObjectRenderer { 27021 /** 27022 * constructor for renderer 27023 * @param {PIXI.Renderer} renderer - The renderer this tiling awesomeness works for. 27024 */ 27025 constructor(renderer) { 27026 super(renderer), renderer.runners.contextChange.add(this), this.quad = new QuadUv(), this.state = State.for2d(); 27027 } 27028 /** Creates shaders when context is initialized. */ 27029 contextChange() { 27030 const renderer = this.renderer, uniforms = { globals: renderer.globalUniforms }; 27031 this.simpleShader = Shader.from(gl1VertexSrc, fragmentSimpleSrc, uniforms), this.shader = renderer.context.webGLVersion > 1 ? Shader.from(gl2VertexSrc, gl2FragmentSrc, uniforms) : Shader.from(gl1VertexSrc, gl1FragmentSrc, uniforms); 27032 } 27033 /** 27034 * @param {PIXI.TilingSprite} ts - tilingSprite to be rendered 27035 */ 27036 render(ts) { 27037 const renderer = this.renderer, quad = this.quad; 27038 let vertices = quad.vertices; 27039 vertices[0] = vertices[6] = ts._width * -ts.anchor.x, vertices[1] = vertices[3] = ts._height * -ts.anchor.y, vertices[2] = vertices[4] = ts._width * (1 - ts.anchor.x), vertices[5] = vertices[7] = ts._height * (1 - ts.anchor.y); 27040 const anchorX = ts.uvRespectAnchor ? ts.anchor.x : 0, anchorY = ts.uvRespectAnchor ? ts.anchor.y : 0; 27041 vertices = quad.uvs, vertices[0] = vertices[6] = -anchorX, vertices[1] = vertices[3] = -anchorY, vertices[2] = vertices[4] = 1 - anchorX, vertices[5] = vertices[7] = 1 - anchorY, quad.invalidate(); 27042 const tex = ts._texture, baseTex = tex.baseTexture, premultiplied = baseTex.alphaMode > 0, lt = ts.tileTransform.localTransform, uv = ts.uvMatrix; 27043 let isSimple = baseTex.isPowerOfTwo && tex.frame.width === baseTex.width && tex.frame.height === baseTex.height; 27044 isSimple && (baseTex._glTextures[renderer.CONTEXT_UID] ? isSimple = baseTex.wrapMode !== WRAP_MODES.CLAMP : baseTex.wrapMode === WRAP_MODES.CLAMP && (baseTex.wrapMode = WRAP_MODES.REPEAT)); 27045 const shader = isSimple ? this.simpleShader : this.shader, w = tex.width, h = tex.height, W = ts._width, H = ts._height; 27046 tempMat.set( 27047 lt.a * w / W, 27048 lt.b * w / H, 27049 lt.c * h / W, 27050 lt.d * h / H, 27051 lt.tx / W, 27052 lt.ty / H 27053 ), tempMat.invert(), isSimple ? tempMat.prepend(uv.mapCoord) : (shader.uniforms.uMapCoord = uv.mapCoord.toArray(!0), shader.uniforms.uClampFrame = uv.uClampFrame, shader.uniforms.uClampOffset = uv.uClampOffset), shader.uniforms.uTransform = tempMat.toArray(!0), shader.uniforms.uColor = Color.shared.setValue(ts.tint).premultiply(ts.worldAlpha, premultiplied).toArray(shader.uniforms.uColor), shader.uniforms.translationMatrix = ts.transform.worldTransform.toArray(!0), shader.uniforms.uSampler = tex, renderer.shader.bind(shader), renderer.geometry.bind(quad), this.state.blendMode = correctBlendMode(ts.blendMode, premultiplied), renderer.state.set(this.state), renderer.geometry.draw(this.renderer.gl.TRIANGLES, 6, 0); 27054 } 27055} 27056TilingSpriteRenderer.extension = { 27057 name: "tilingSprite", 27058 type: ExtensionType.RendererPlugin 27059}; 27060extensions$1.add(TilingSpriteRenderer); 27061 27062const _Spritesheet = class _Spritesheet2 { 27063 /** 27064 * @param texture - Reference to the source BaseTexture object. 27065 * @param {object} data - Spritesheet image data. 27066 * @param resolutionFilename - The filename to consider when determining 27067 * the resolution of the spritesheet. If not provided, the imageUrl will 27068 * be used on the BaseTexture. 27069 */ 27070 constructor(texture, data, resolutionFilename = null) { 27071 this.linkedSheets = [], this._texture = texture instanceof Texture ? texture : null, this.baseTexture = texture instanceof BaseTexture ? texture : this._texture.baseTexture, this.textures = {}, this.animations = {}, this.data = data; 27072 const resource = this.baseTexture.resource; 27073 this.resolution = this._updateResolution(resolutionFilename || (resource ? resource.url : null)), this._frames = this.data.frames, this._frameKeys = Object.keys(this._frames), this._batchIndex = 0, this._callback = null; 27074 } 27075 /** 27076 * Generate the resolution from the filename or fallback 27077 * to the meta.scale field of the JSON data. 27078 * @param resolutionFilename - The filename to use for resolving 27079 * the default resolution. 27080 * @returns Resolution to use for spritesheet. 27081 */ 27082 _updateResolution(resolutionFilename = null) { 27083 const { scale } = this.data.meta; 27084 let resolution = getResolutionOfUrl(resolutionFilename, null); 27085 return resolution === null && (resolution = parseFloat(scale ?? "1")), resolution !== 1 && this.baseTexture.setRe
27085solution(resolution), resolution; 27086 } 27087 /** 27088 * Parser spritesheet from loaded data. This is done asynchronously 27089 * to prevent creating too many Texture within a single process. 27090 * @method PIXI.Spritesheet#parse 27091 */ 27092 parse() { 27093 return new Promise((resolve) => { 27094 this._callback = resolve, this._batchIndex = 0, this._frameKeys.length <= _Spritesheet2.BATCH_SIZE ? (this._processFrames(0), this._processAnimations(), this._parseComplete()) : this._nextBatch(); 27095 }); 27096 } 27097 /** 27098 * Process a batch of frames 27099 * @param initialFrameIndex - The index of frame to start. 27100 */ 27101 _processFrames(initialFrameIndex) { 27102 let frameIndex = initialFrameIndex; 27103 const maxFrames = _Spritesheet2.BATCH_SIZE; 27104 for (; frameIndex - initialFrameIndex < maxFrames && frameIndex < this._frameKeys.length; ) { 27105 const i = this._frameKeys[frameIndex], data = this._frames[i], rect = data.frame; 27106 if (rect) { 27107 let frame = null, trim = null; 27108 const sourceSize = data.trimmed !== !1 && data.sourceSize ? data.sourceSize : data.frame, orig = new Rectangle( 27109 0, 27110 0, 27111 Math.floor(sourceSize.w) / this.resolution, 27112 Math.floor(sourceSize.h) / this.resolution 27113 ); 27114 data.rotated ? frame = new Rectangle( 27115 Math.floor(rect.x) / this.resolution, 27116 Math.floor(rect.y) / this.resolution, 27117 Math.floor(rect.h) / this.resolution, 27118 Math.floor(rect.w) / this.resolution 27119 ) : frame = new Rectangle( 27120 Math.floor(rect.x) / this.resolution, 27121 Math.floor(rect.y) / this.resolution, 27122 Math.floor(rect.w) / this.resolution, 27123 Math.floor(rect.h) / this.resolution 27124 ), data.trimmed !== !1 && data.spriteSourceSize && (trim = new Rectangle( 27125 Math.floor(data.spriteSourceSize.x) / this.resolution, 27126 Math.floor(data.spriteSourceSize.y) / this.resolution, 27127 Math.floor(rect.w) / this.resolution, 27128 Math.floor(rect.h) / this.resolution 27129 )), this.textures[i] = new Texture( 27130 this.baseTexture, 27131 frame, 27132 orig, 27133 trim, 27134 data.rotated ? 2 : 0, 27135 data.anchor, 27136 data.borders 27137 ), Texture.addToCache(this.textures[i], i.toString()); 27138 } 27139 frameIndex++; 27140 } 27141 } 27142 /** Parse animations config. */ 27143 _processAnimations() { 27144 const animations = this.data.animations || {}; 27145 for (const animName in animations) { 27146 this.animations[animName] = []; 27147 for (let i = 0; i < animations[animName].length; i++) { 27148 const frameName = animations[animName][i]; 27149 this.animations[animName].push(this.textures[frameName]); 27150 } 27151 } 27152 } 27153 /** The parse has completed. */ 27154 _parseComplete() { 27155 const callback = this._callback; 27156 this._callback = null, this._batchIndex = 0, callback.call(this, this.textures); 27157 } 27158 /** Begin the next batch of textures. */ 27159 _nextBatch() { 27160 this._processFrames(this._batchIndex * _Spritesheet2.BATCH_SIZE), this._batchIndex++, setTimeout(() => { 27161 this._batchIndex * _Spritesheet2.BATCH_SIZE < this._frameKeys.length ? this._nextBatch() : (this._processAnimations(), this._parseComplete()); 27162 }, 0); 27163 } 27164 /** 27165 * Destroy Spritesheet and don't use after this. 27166 * @param {boolean} [destroyBase=false] - Whether to destroy the base texture as well 27167 */ 27168 destroy(destroyBase = !1) { 27169 for (const i in this.textures) 27170 this.textures[i].destroy(); 27171 this._frames = null, this._frameKeys = null, this.data = null, this.textures = null, destroyBase && (this._texture?.destroy(), this.baseTexture.destroy()), this._texture = null, this.baseTexture = null, this.linkedSheets = []; 27172 } 27173}; 27174_Spritesheet.BATCH_SIZE = 1e3; 27175let Spritesheet = _Spritesheet; 27176 27177const validImages = ["jpg", "png", "jpeg", "avif", "webp"]; 27178function getCacheableAssets(keys, asset, ignoreMultiPack) { 27179 const out = {}; 27180 if (keys.forEach((key) => { 27181 out[key] = asset; 27182 }), Object.keys(asset.textures).forEach((key) => { 27183 out[key] = asset.textures[key]; 27184 }), !ignoreMultiPack) { 27185 const basePath = path.dirname(keys[0]);
27186 asset.linkedSheets.forEach((item, i) => { 27187 const out2 = getCacheableAssets([`${basePath}/${asset.data.meta.related_multi_packs[i]}`], item, !0); 27188 Object.assign(out, out2); 27189 }); 27190 } 27191 return out; 27192} 27193const spritesheetAsset = { 27194 extension: ExtensionType.Asset, 27195 /** Handle the caching of the related Spritesheet Textures */ 27196 cache: { 27197 test: (asset) => asset instanceof Spritesheet, 27198 getCacheableAssets: (keys, asset) => getCacheableAssets(keys, asset, !1) 27199 }, 27200 /** Resolve the the resolution of the asset. */ 27201 resolver: { 27202 test: (value) => { 27203 const split = value.split("?")[0].split("."), extension = split.pop(), format = split.pop(); 27204 return extension === "json" && validImages.includes(format); 27205 }, 27206 parse: (value) => { 27207 const split = value.split("."); 27208 return { 27209 resolution: parseFloat(settings.RETINA_PREFIX.exec(value)?.[1] ?? "1"), 27210 format: split[split.length - 2], 27211 src: value 27212 }; 27213 } 27214 }, 27215 /** 27216 * Loader plugin that parses sprite sheets! 27217 * once the JSON has been loaded this checks to see if the JSON is spritesheet data. 27218 * If it is, we load the spritesheets image and parse the data into PIXI.Spritesheet 27219 * All textures in the sprite sheet are then added to the cache 27220 * @ignore 27221 */ 27222 loader: { 27223 name: "spritesheetLoader", 27224 extension: { 27225 type: ExtensionType.LoadParser, 27226 priority: LoaderParserPriority.Normal 27227 }, 27228 async testParse(asset, options) { 27229 return path.extname(options.src).toLowerCase() === ".json" && !!asset.frames; 27230 }, 27231 async parse(asset, options, loader) { 27232 let basePath = path.dirname(options.src); 27233 basePath && basePath.lastIndexOf("/") !== basePath.length - 1 && (basePath += "/"); 27234 let imagePath = basePath + asset.meta.image; 27235 imagePath = copySearchParams(imagePath, options.src); 27236 const texture = (await loader.load([imagePath]))[imagePath], spritesheet = new Spritesheet( 27237 texture.baseTexture, 27238 asset, 27239 options.src 27240 ); 27241 await spritesheet.parse(); 27242 const multiPacks = asset?.meta?.related_multi_packs; 27243 if (Array.isArray(multiPacks)) { 27244 const promises = []; 27245 for (const item of multiPacks) { 27246 if (typeof item != "string") 27247 continue; 27248 let itemUrl = basePath + item; 27249 options.data?.ignoreMultiPack || (itemUrl = copySearchParams(itemUrl, options.src), promises.push(loader.load({ 27250 src: itemUrl, 27251 data: { 27252 ignoreMultiPack: !0 27253 } 27254 }))); 27255 } 27256 const res = await Promise.all(promises); 27257 spritesheet.linkedSheets = res, res.forEach((item) => { 27258 item.linkedSheets = [spritesheet].concat(spritesheet.linkedSheets.filter((sp) => sp !== item)); 27259 }); 27260 } 27261 return spritesheet; 27262 }, 27263 unload(spritesheet) { 27264 spritesheet.destroy(!0); 27265 } 27266 } 27267}; 27268extensions$1.add(spritesheetAsset); 27269 27270class BitmapFontData { 27271 constructor() { 27272 this.info = [], this.common = [], this.page = [], this.char = [], this.kerning = [], this.distanceField = []; 27273 } 27274} 27275 27276class TextFormat { 27277 /** 27278 * Check if resource refers to txt font data. 27279 * @param data 27280 * @returns - True if resource could be treated as font data, false otherwise. 27281 */ 27282 static test(data) { 27283 return typeof data == "string" && data.startsWith("info face="); 27284 } 27285 /** 27286 * Convert text font data to a javascript object. 27287 * @param txt - Raw string data to be converted 27288 * @returns - Parsed font data 27289 */ 27290 static parse(txt) { 27291 const items = txt.match(/^[a-z]+\s+.+$/gm), rawData = { 27292 info: [], 27293 common: [], 27294 page: [], 27295 char: [], 27296 chars: [], 27297 kerning: [], 27298 kernings: [], 27299 distanceField: [] 27300 }; 27301 for (const i in items) { 27302 const name = items[i].match(/^[a-z]+/gm)[0], attributeList = items[i].match(/[a-zA-Z]+=([^\s"']+|"([^"]*)")/gm), itemData = {}; 27303 for (const i2 in attributeList) { 27304 const split = attributeList[i2].split("="), key = split[0], strValue = split[1].replace(/"/gm, ""), floatValue = parseFloat(strValue), value = isNaN(floatValue) ? strValue : floatValue; 27305 itemData[key] = value; 27306 } 27307 rawData[name].push(itemData); 27308 } 27309 const font = new BitmapFontData(); 27310 return rawData.info.forEach((info) => font.info.push({ 27311 face: info.face, 27312 size: parseInt(info.size, 10) 27313 })), rawData.common.forEach((common) => font.common.push({ 27314 lineHeight: parseInt(common.lineHeight, 10) 27315 })), rawData.page.forEach((page) => font.page.push({ 27316 id: parseInt(page.id, 10), 27317 file: page.file 27318 })), rawData.char.forEach((char) => font.char.push({ 27319 id: parseInt(char.id, 10), 27320 page: parseInt(char.page, 10), 27321 x: parseInt(char.x, 10), 27322 y: parseInt(char.y, 10), 27323 width: parseInt(char.width, 10), 27324 height: parseInt(char.height, 10), 27325 xoffset: parseInt(char.xoffset, 10), 27326 yoffset: parseInt(char.yoffset, 10), 27327 xadvance: parseInt(char.xadvance, 10) 27328 })), rawData.kerning.forEach((kerning) => font.kerning.push({ 27329 first: parseInt(kerning.first, 10), 27330 second: parseInt(kerning.second, 10), 27331 amount: parseInt(kerning.amount, 10) 27332 })), rawData.distanceField.forEach((df) => font.distanceField.push({ 27333 distanceRange: parseInt(df.distanceRange, 10), 27334 fieldType: df.fieldType 27335 })), font; 27336 } 27337} 27338 27339class XMLFormat { 27340 /** 27341 * Check if resource refers to xml font data. 27342 * @param data 27343 * @returns - True if resource could be treated as font data, false otherwise. 27344 */ 27345 static test(data) { 27346 const xml = data; 27347 return typeof data != "string" && "getElementsByTagName" in data && xml.getElementsByTagName("page").length && xml.getElementsByTagName("info")[0].getAttribute("face") !== null; 27348 } 27349 /** 27350 * Convert the XML into BitmapFontData that we can use. 27351 * @param xml 27352 * @returns - Data to use for BitmapFont 27353 */ 27354 static parse(xml) { 27355 const data = new BitmapFontData(), info = xml.getElementsByTagName("info"), common = xml.getElementsByTagName("common"), page = xml.getElementsByTagName("page"), char = xml.getElementsByTagName("char"), kerning = xml.getElementsByTagName("kerning"), distanceField = xml.getElementsByTagName("distanceField"); 27356 for (let i = 0; i < info.length; i++) 27357 data.info.push({ 27358 face: info[i].getAttribute("face"), 27359 size: parseInt(info[i].getAttribute("size"), 10) 27360 }); 27361 for (let i = 0; i < common.length; i++) 27362 data.common.push({ 27363 lineHeight: parseInt(common[i].getAttribute("lineHeight"), 10) 27364 }); 27365 for (let i = 0; i < page.length; i++) 27366 data.page.push({ 27367 id: parseInt(page[i].getAttribute("id"), 10) || 0, 27368 file: page[i].getAttribute("file") 27369 }); 27370 for (let i = 0; i < char.length; i++) { 27371 const letter = char[i]; 27372 data.char.push({ 27373 id: parseInt(letter.getAttribute("id"), 10), 27374 page: parseInt(letter.getAttribute("page"), 10) || 0, 27375 x: parseInt(letter.getAttribute("x"), 10), 27376 y: parseInt(letter.getAttribute("y"), 10), 27377 width: parseInt(letter.getAttribute("width"), 10), 27378 height: parseInt(letter.getAttribute("height"), 10), 27379 xoffset: parseInt(letter.getAttribute("xoffset"), 10), 27380 yoffset: parseInt(letter.getAttribute("yoffset"), 10), 27381 xadvance: parseInt(letter.getAttribute("xadvance"), 10) 27382 }); 27383 } 27384 for (let i = 0; i < kerning.length; i++) 27385 data.kerning.push({ 27386 first: parseInt(kerning[i].getAttribute("first"), 10), 27387 second: parseInt(kerning[i].getAttribute("second"), 10), 27388 amount: parseInt(kerning[i].getAttribute("amount"), 10) 27389 }); 27390 for (let i = 0; i < distanceField.length; i++) 27391 data.distanceField.push({ 27392 fieldType: distanceField[i].getAttribute("fieldType"), 27393 distanceRange: parseInt(distanceField[i].getAttribute("distanceRange"), 10) 27394 }); 27395 return data; 27396 } 27397} 27398 27399class XMLStringFormat { 27400 /** 27401 * Check if resource refers to text xml font data. 27402 * @param data 27403 * @returns - True if resource could be treated as font data, false otherwise. 27404 */ 27405 static test(data) { 27406 return typeof data == "string" && data.includes("<font>") ? XMLFormat.test(settings.ADAPTER.parseXML(data)) : !1; 27407 } 27408 /** 27409 * Convert the text XML into BitmapFontData that we can use. 27410 * @param xmlTxt 27411 * @returns - Data to use for BitmapFont 27412 */ 27413 static parse(xmlTxt) { 27414 return XMLFormat.parse(settings.ADAPTER.parseXML(xmlTxt)); 27415 } 27416} 27417 27418const formats = [ 27419 TextFormat,
27420 XMLFormat, 27421 XMLStringFormat 27422]; 27423function autoDetectFormat(data) { 27424 for (let i = 0; i < formats.length; i++) 27425 if (formats[i].test(data)) 27426 return formats[i]; 27427 return null; 27428} 27429 27430function generateFillStyle(canvas, context, style, resolution, lines, metrics) { 27431 const fillStyle = style.fill; 27432 if (Array.isArray(fillStyle)) { 27433 if (fillStyle.length === 1) 27434 return fillStyle[0]; 27435 } else 27436 return fillStyle; 27437 let gradient; 27438 const dropShadowCorrection = style.dropShadow ? style.dropShadowDistance : 0, padding = style.padding || 0, width = canvas.width / resolution - dropShadowCorrection - padding * 2, height = canvas.height / resolution - dropShadowCorrection - padding * 2, fill = fillStyle.slice(), fillGradientStops = style.fillGradientStops.slice(); 27439 if (!fillGradientStops.length) { 27440 const lengthPlus1 = fill.length + 1; 27441 for (let i = 1; i < lengthPlus1; ++i) 27442 fillGradientStops.push(i / lengthPlus1); 27443 } 27444 if (fill.unshift(fillStyle[0]), fillGradientStops.unshift(0), fill.push(fillStyle[fillStyle.length - 1]), fillGradientStops.push(1), style.fillGradientType === TEXT_GRADIENT.LINEAR_VERTICAL) { 27445 gradient = context.createLinearGradient(width / 2, padding, width / 2, height + padding); 27446 let lastIterationStop = 0; 27447 const gradStopLineHeight = (metrics.fontProperties.fontSize + style.strokeThickness) / height; 27448 for (let i = 0; i < lines.length; i++) { 27449 const thisLineTop = metrics.lineHeight * i; 27450 for (let j = 0; j < fill.length; j++) { 27451 let lineStop = 0; 27452 typeof fillGradientStops[j] == "number" ? lineStop = fillGradientStops[j] : lineStop = j / fill.length; 27453 const globalStop = thisLineTop / height + lineStop * gradStopLineHeight; 27454 let clampedStop = Math.max(lastIterationStop, globalStop); 27455 clampedStop = Math.min(clampedStop, 1), gradient.addColorStop(clampedStop, fill[j]), lastIterationStop = clampedStop; 27456 } 27457 } 27458 } else { 27459 gradient = context.createLinearGradient(padding, height / 2, width + padding, height / 2); 27460 const totalIterations = fill.length + 1; 27461 let currentIteration = 1; 27462 for (let i = 0; i < fill.length; i++) { 27463 let stop; 27464 typeof fillGradientStops[i] == "number" ? stop = fillGradientStops[i] : stop = currentIteration / totalIterations, gradient.addColorStop(stop, fill[i]), currentIteration++; 27465 } 27466 } 27467 return gradient; 27468} 27469 27470function drawGlyph(canvas, context, metrics, x, y, resolution, style) { 27471 const char = metrics.text, fontProperties = metrics.fontProperties; 27472 context.translate(x, y), context.scale(resolution, resolution); 27473 const tx = style.strokeThickness / 2, ty = -(style.strokeThickness / 2); 27474 if (context.font = style.toFontString(), context.lineWidth = style.strokeThickness, context.textBaseline = style.textBaseline, context.lineJoin = style.lineJoin, c
27474ontext.miterLimit = style.miterLimit, context.fillStyle = generateFillStyle(canvas, context, style, resolution, [char], metrics), context.strokeStyle = style.stroke, style.dropShadow) { 27475 const dropShadowColor = style.dropShadowColor, dropShadowBlur = style.dropShadowBlur * resolution, dropShadowDistance = style.dropShadowDistance * resolution; 27476 context.shadowColor = Color.shared.setValue(dropShadowColor).setAlpha(style.dropShadowAlpha).toRgbaString(), context.shadowBlur = dropShadowBlur, context.shadowOffsetX = Math.cos(style.dropShadowAngle) * dropShadowDistance, context.shadowOffsetY = Math.sin(style.dropShadowAngle) * dropShadowDistance; 27477 } else 27478 context.shadowColor = "black", context.shadowBlur = 0, context.shadowOffsetX = 0, context.shadowOffsetY = 0; 27479 style.stroke && style.strokeThickness && context.strokeText(char, tx, ty + metrics.lineHeight - fontProperties.descent), style.fill && context.fillText(char, tx, ty + metrics.lineHeight - fontProperties.descent), context.setTransform(1, 0, 0, 1, 0, 0), context.fillStyle = "rgba(0, 0, 0, 0)"; 27480} 27481 27482function extractCharCode(str) { 27483 return str.codePointAt ? str.codePointAt(0) : str.charCodeAt(0); 27484} 27485 27486function splitTextToCharacters(text) { 27487 return Array.from ? Array.from(text) : text.split(""); 27488} 27489 27490function resolveCharacters(chars) { 27491 typeof chars == "string" && (chars = [chars]); 27492 const result = []; 27493 for (let i = 0, j = chars.length; i < j; i++) { 27494 const item = chars[i]; 27495 if (Array.isArray(item)) { 27496 if (item.length !== 2) 27497 throw new Error(`[BitmapFont]: Invalid character range length, expecting 2 got ${item.length}.`); 27498 const startCode = item[0].charCodeAt(0), endCode = item[1].charCodeAt(0); 27499 if (endCode < startCode) 27500 throw new Error("[BitmapFont]: Invalid character range."); 27501 for (let i2 = startCode, j2 = endCode; i2 <= j2; i2++) 27502 result.push(String.fromCharCode(i2)); 27503 } else 27504 result.push(...splitTextToCharacters(item)); 27505 } 27506 if (result.length === 0) 27507 throw new Error("[BitmapFont]: Empty set when resolving characters."); 27508 return result; 27509} 27510 27511const _BitmapFont = class _BitmapFont2 { 27512 /** 27513 * @param data 27514 * @param textures 27515 * @param ownsTextures - Setting to `true` will destroy page textures 27516 * when the font is uninstalled. 27517 */ 27518 constructor(data, textures, ownsTextures) { 27519 const [info] = data.info, [common] = data.common, [page] = data.page, [distanceField] = data.distanceField, res = getResolutionOfUrl(page.file), pageTextures = {}; 27520 this._ownsTextures = ownsTextures, this.font = info.face, this.size = info.size, this.lineHeight = common.lineHeight / res, this.chars = {}, this.pageTextures = pageTextures; 27521 for (let i = 0; i < data.page.length; i++) { 27522 const { id, file } = data.page[i]; 27523 pageTextures[id] = textures instanceof Array ? textures[i] : textures[file], distanceField?.fieldType && distanceField.fieldType !== "none" && (pageTextures[id].baseTexture.alphaMode = ALPHA_MODES.NO_PREMULTIPLIED_ALPHA, pageTextures[id].baseTexture.mipmap = MIPMAP_MODES.OFF); 27524 } 27525 for (let i = 0; i < data.char.length; i++) { 27526 const { id, page: page2 } = data.char[i]; 27527 let { x, y, width, height, xoffset, yoffset, xadvance } = data.char[i]; 27528 x /= res, y /= res, width /= res, height /= res, xoffset /= res, yoffset /= res, xadvance /= res; 27529 const rect = new Rectangle( 27530 x + pageTextures[page2].frame.x / res, 27531 y + pageTextures[page2].frame.y / res, 27532 width, 27533 height 27534 ); 27535 this.chars[id] = { 27536 xOffset: xoffset, 27537 yOffset: yoffset, 27538 xAdvance: xadvance, 27539 kerning: {}, 27540 texture: new Texture( 27541 pageTextures[page2].baseTexture, 27542 rect 27543 ), 27544 page: page2 27545 }; 27546 } 27547 for (let i = 0; i < data.kerning.length; i++) { 27548 let { first, second, amount } = data.kerning[i]; 27549 first /= res, second /= res, amount /= res, this.chars[second] && (this.chars[second].kerning[first] = amount); 27550 } 27551 this.distanceFieldRange = distanceField?.distanceRange, this.distanceFieldType = distanceField?.fieldType?.toLowerCase() ?? "none"; 27552 } 27553 /** Remove references to created glyph textures. */ 27554 destroy() { 27555 for (const id in this.chars) 27556 this.chars[id].texture.destroy(), this.chars[id].texture = null; 27557 for (const id in this.pageTextures) 27558 this._ownsTextures && this.pageTextures[id].destroy(!0), this.pageTextures[id] = null; 27559 this.chars = null, this.pageTextures = null; 27560 } 27561 /** 27562 * Register a new bitmap font. 27563 * @param data - The 27564 * characters map that could be provided as xml or raw
27564string. 27565 * @param textures - List of textures for each page. 27566 * @param ownsTextures - Set to `true` to destroy page textures 27567 * when the font is uninstalled. By default fonts created with 27568 * `BitmapFont.from` or from the `BitmapFontLoader` are `true`. 27569 * @returns {PIXI.BitmapFont} Result font object with font, size, lineHeight 27570 * and char fields. 27571 */ 27572 static install(data, textures, ownsTextures) { 27573 let fontData; 27574 if (data instanceof BitmapFontData) 27575 fontData = data; 27576 else { 27577 const format = autoDetectFormat(data); 27578 if (!format) 27579 throw new Error("Unrecognized data format for font."); 27580 fontData = format.parse(data); 27581 } 27582 textures instanceof Texture && (textures = [textures]); 27583 const font = new _BitmapFont2(fontData, textures, ownsTextures); 27584 return _BitmapFont2.available[font.font] = font, font; 27585 } 27586 /** 27587 * Remove bitmap font by name. 27588 * @param name - Name of the font to uninstall. 27589 */ 27590 static uninstall(name) { 27591 const font = _BitmapFont2.available[name]; 27592 if (!font) 27593 throw new Error(`No font found named '${name}'`); 27594 font.destroy(), delete _BitmapFont2.available[name]; 27595 } 27596 /** 27597 * Generates a bitmap-font for the given style and character set. This does not support 27598 * kernings yet. With `style` properties, only the following non-layout properties are used: 27599 * 27600 * - {@link PIXI.TextStyle#dropShadow|dropShadow} 27601 * - {@link PIXI.TextStyle#dropShadowDistance|dropShadowDistance} 27602 * - {@link PIXI.TextStyle#dropShadowColor|dropShadowColor} 27603 * - {@link PIXI.TextStyle#dropShadowBlur|dropShadowBlur} 27604 * - {@link PIXI.TextStyle#dropShadowAngle|dropShadowAngle} 27605 * - {@link PIXI.TextStyle#fill|fill} 27606 * - {@link PIXI.TextStyle#fillGradientStops|fillGradientStops} 27607 * - {@link PIXI.TextStyle#fillGradientType|fillGradientType} 27608 * - {@link PIXI.TextStyle#fontFamily|fontFamily} 27609 * - {@link PIXI.TextStyle#fontSize|fontSize} 27610 * - {@link PIXI.TextStyle#fontVariant|fontVariant} 27611 * - {@link PIXI.TextStyle#fontWeight|fontWeight} 27612 * - {@link PIXI.TextStyle#lineJoin|lineJoin} 27613 * - {@link PIXI.TextStyle#miterLimit|miterLimit} 27614 * - {@link PIXI.TextStyle#stroke|stroke} 27615 * - {@link PIXI.TextStyle#strokeThickness|strokeThickness} 27616 * - {@link PIXI.TextStyle#textBaseline|textBaseline} 27617 * @param name - The name of the custom font to use with BitmapText. 27618 * @param textStyle - Style options to render with BitmapFont. 27619 * @param options - Setup options for font or name of the font. 27620 * @returns Font generated by style options. 27621 * @example 27622 * import { BitmapFont, BitmapText } from 'pixi.js'; 27623 * 27624 * BitmapFont.from('TitleFont', { 27625 * fontFamily: 'Arial', 27626 * fontSize: 12, 27627 * strokeThickness: 2, 27628 * fill: 'purple', 27629 * }); 27630 * 27631 * const title = new BitmapText('This is the title', { fontName: 'TitleFont' }); 27632 */ 27633 static from(name, textStyle, options) { 27634 if (!name) 27635 throw new Error("[BitmapFont] Property `name` is required."); 27636 const { 27637 chars, 27638 padding, 27639 resolution, 27640 textureWidth, 27641 textureHeight, 27642 ...baseOptions 27643 } = Object.assign({}, _BitmapFont2.defaultOptions, options), charsList = resolveCharacters(chars), style = textStyle instanceof TextStyle ? textStyle : new TextStyle(textStyle), lineWidth = textureWidth, fontData = new BitmapFontData(); 27644 fontData.info[0] = { 27645 face: style.fontFamily, 27646 size: style.fontSize 27647 }, fontData.common[0] = { 27648 lineHeight: style.fontSize 27649 }; 27650 let positionX = 0, positionY = 0, canvas, context, baseTexture, maxCharHeight = 0; 27651 const textures = []; 27652 for (let i = 0; i < charsList.length; i++) { 27653 canvas || (canvas = settings.ADAPTER.createCanvas(), canvas.width = textureWidth, canvas.height = textureHeight, context = canvas.getContext("2d"), baseTexture = new BaseTexture(canvas, { resolution, ...baseOptions }), textures.push(new Texture(baseTexture)), fontData.page.push({ 27654 id: textures.length - 1, 27655 file: "" 27656 })); 27657 const character = charsList[i], metrics = TextMetrics.measureText(c
27657haracter, style, !1, canvas), width = metrics.width, height = Math.ceil(metrics.height), textureGlyphWidth = Math.ceil((style.fontStyle === "italic" ? 2 : 1) * width); 27658 if (positionY >= textureHeight - height * resolution) { 27659 if (positionY === 0) 27660 throw new Error(`[BitmapFont] textureHeight ${textureHeight}px is too small (fontFamily: '${style.fontFamily}', fontSize: ${style.fontSize}px, char: '${character}')`); 27661 --i, canvas = null, context = null, baseTexture = null, positionY = 0, positionX = 0, maxCharHeight = 0; 27662 continue; 27663 } 27664 if (maxCharHeight = Math.max(height + metrics.fontProperties.descent, maxCharHeight), textureGlyphWidth * resolution + positionX >= lineWidth) { 27665 if (positionX === 0) 27666 throw new Error(`[BitmapFont] textureWidth ${textureWidth}px is too small (fontFamily: '${style.fontFamily}', fontSize: ${style.fontSize}px, char: '${character}')`); 27667 --i, positionY += maxCharHeight * resolution, positionY = Math.ceil(positionY), positionX = 0, maxCharHeight = 0; 27668 continue; 27669 } 27670 drawGlyph(canvas, context, metrics, positionX, positionY, resolution, style); 27671 const id = extractCharCode(metrics.text); 27672 fontData.char.push({ 27673 id, 27674 page: textures.length - 1, 27675 x: positionX / resolution, 27676 y: positionY / resolution, 27677 width: textureGlyphWidth, 27678 height, 27679 xoffset: 0, 27680 yoffset: 0, 27681 xadvance: width - (style.dropShadow ? style.dropShadowDistance : 0) - (style.stroke ? style.strokeThickness : 0) 27682 }), positionX += (textureGlyphWidth + 2 * padding) * resolution, positionX = Math.ceil(positionX); 27683 } 27684 if (!options?.skipKerning) 27685 for (let i = 0, len = charsList.length; i < len; i++) { 27686 const first = charsList[i]; 27687 for (let j = 0; j < len; j++) { 27688 const second = charsList[j], c1 = context.measureText(first).width, c2 = context.measureText(second).width, amount = context.measureText(first + second).width - (c1 + c2); 27689 amount && fontData.kerning.push({ 27690 first: extractCharCode(first), 27691 second: extractCharCode(second), 27692 amount 27693 }); 27694 } 27695 } 27696 const font = new _BitmapFont2(fontData, textures, !0); 27697 return _BitmapFont2.available[name] !== void 0 && _BitmapFont2.uninstall(name), _BitmapFont2.available[name] = font, font; 27698 } 27699}; 27700_BitmapFont.ALPHA = [["a", "z"], ["A", "Z"], " "], /** 27701* This character set includes all decimal digits (from 0 to 9). 27702* @type {string[][]} 27703* @example 27704* BitmapFont.from('ExampleFont', style, { chars: BitmapFont.NUMERIC }) 27705*/ 27706_BitmapFont.NUMERIC = [["0", "9"]], /** 27707* This character set is the union of `BitmapFont.ALPHA` and `BitmapFont.NUMERIC`. 27708* @type {string[][]} 27709*/ 27710_BitmapFont.ALPHANUMERIC = [["a", "z"], ["A", "Z"], ["0", "9"], " "], /** 27711* This character set consists of all the ASCII table. 27712* @member {string[][]} 27713* @see http://www.asciitable.com/ 27714*/ 27715_BitmapFont.ASCII = [[" ", "~"]], /** 27716* Collection of default options when using `BitmapFont.from`. 27717* @property {number} [resolution=1] - 27718* @property {number} [textureWidth=512] - 27719* @property {number} [textureHeight=512] - 27720* @property {number} [padding=4] - 27721* @property {string|string[]|string[][]} chars = PIXI.BitmapFont.ALPHANUMERIC 27722*/ 27723_BitmapFont.defaultOptions = { 27724 resolution: 1, 27725 textureWidth: 512, 27726 textureHeight: 512, 27727 padding: 4, 27728 chars: _BitmapFont.ALPHANUMERIC 27729}, /** Collection of available/installed fonts. */ 27730_BitmapFont.available = {}; 27731let BitmapFont = _BitmapFont; 27732 27733var msdfFrag = `// Pixi texture info\r 27734varying vec2 vTextureCoord;\r 27735uniform sampler2D uSampler;\r 27736\r 27737// Tint\r 27738uniform vec4 uColor;\r 27739\r 27740// on 2D applications fwidth is screenScale / glyphAtlasScale * distanceFieldRange\r 27741uniform float uFWidth;\r 27742\r 27743void main(void) {\r 27744\r 27745 // To stack MSDF and SDF we need a non-pre-multiplied-alpha texture.\r 27746 vec4 texColor = texture2D(uSampler, vTextureCoord);\r 27747\r 27748 // MSDF\r 27749 float median = texColor.r + texColor.g + texColor.b -\r 27750 min(texColor.r, min(texColor.g, texColor.b)) -\r 27751 max(texColor.r, max(texColor.g, texColor.b));\r 27752 // SDF\r 27753 median = min(median, texColor.a);\r 27754\r 27755 float screenPxDistance = uFWidth * (median - 0.5);\r 27756 float alpha = clamp(screenPxDistance + 0.5, 0.0, 1.0);\r 27757 if (median < 0.01) {\r
27758 alpha = 0.0;\r 27759 } else if (median > 0.99) {\r 27760 alpha = 1.0;\r 27761 }\r 27762\r 27763 // Gamma correction for coverage-like alpha\r 27764 float luma = dot(uColor.rgb, vec3(0.299, 0.587, 0.114));\r 27765 float gamma = mix(1.0, 1.0 / 2.2, luma);\r 27766 float coverage = pow(uColor.a * alpha, gamma); \r 27767\r 27768 // NPM Textures, NPM outputs\r 27769 gl_FragColor = vec4(uColor.rgb, coverage);\r 27770}\r 27771`; 27772 27773var msdfVert = `// Mesh material default fragment\r 27774attribute vec2 aVertexPosition;\r 27775attribute vec2 aTextureCoord;\r 27776\r 27777uniform mat3 projectionMatrix;\r 27778uniform mat3 translationMatrix;\r 27779uniform mat3 uTextureMatrix;\r 27780\r 27781varying vec2 vTextureCoord;\r 27782\r 27783void main(void)\r 27784{\r 27785 gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\r 27786\r 27787 vTextureCoord = (uTextureMatrix * vec3(aTextureCoord, 1.0)).xy;\r 27788}\r 27789`; 27790 27791const pageMeshDataDefaultPageMeshData = [], pageMeshDataMSDFPageMeshData = [], charRenderDataPool = [], _BitmapText = class _BitmapText2 extends Container { 27792 /** 27793 * @param text - A string that you would like the text to display. 27794 * @param style - The style parameters. 27795 * @param {string} style.fontName - The installed BitmapFont name. 27796 * @param {number} [style.fontSize] - The size of the font in pixels, e.g. 24. If undefined, 27797 *. this will default to the BitmapFont size. 27798 * @param {string} [style.align='left'] - Alignment for multiline text ('left', 'center', 'right' or 'justify'), 27799 * does not affect single line text. 27800 * @param {PIXI.ColorSource} [style.tint=0xFFFFFF] - The tint color. 27801 * @param {number} [style.letterSpacing=0] - The amount of spacing between letters. 27802 * @param {number} [style.maxWidth=0] - The max width of the text before line wrapping. 27803 */ 27804 constructor(text, style = {}) { 27805 super(); 27806 const { align, tint, maxWidth, letterSpacing, fontName, fontSize } = Object.assign( 27807 {}, 27808 _BitmapText2.styleDefaults, 27809 style 27810 ); 27811 if (!BitmapFont.available[fontName]) 27812 throw new Error(`Missing BitmapFont "${fontName}"`); 27813 this._activePagesMeshData = [], this._textWidth = 0, this._textHeight = 0, this._align = align, this._tintColor = new Color(tint), this._font = void 0, this._fontName = fontName, this._fontSize = fontSize, this.text = text, this._maxWidth = maxWidth, this._maxLineHeight = 0, this._letterSpacing = letterSpacing, this._anchor = new ObservablePoint(() => { 27814 this.dirty = !0; 27815 }, this, 0, 0), this._roundPixels = settings.ROUND_PIXELS, this.dirty = !0, this._resolution = settings.RESOLUTION, this._autoResolution = !0, this._textureCache = {}; 27816 } 27817 /** Renders text and updates it when needed. This should only be called if the BitmapFont is regenerated. */ 27818 updateText() { 27819 const data = BitmapFont.available[this._fontName], fontSize = this.fontSize, scale = fontSize / data.size, pos = new Point(), chars = [], lineWidths = [], lineSpaces = [], text = this._text.replace(/(?:\r\n|\r)/g, ` 27820`) || " ", charsInput = splitTextToCharacters(text), maxWidth = this._maxWidth * data.size / fontSize, pageMeshDataPool = data.distanceFieldType === "none" ? pageMeshDataDefaultPageMeshData : pageMeshDataMSDFPageMeshData; 27821 let prevCharCode = null, lastLineWidth = 0, maxLineWidth = 0, line = 0, lastBreakPos = -1, lastBreakWidth = 0, spacesRemoved = 0, maxLineHeight = 0, spaceCount = 0; 27822 for (let i = 0; i < charsInput.length; i++) { 27823 const char = charsInput[i], charCode = extractCharCode(char); 27824 if (/(?:\s)/.test(char) && (lastBreakPos = i, lastBreakWidth = lastLineWidth, spaceCount++), char === "\r" || char === ` 27825`) { 27826 lineWidths.push(lastLineWidth), lineSpaces.push(-1), maxLineWidth = Math.max(maxLineWidth, lastLineWidth), ++line, ++spacesRemoved, pos.x = 0, pos.y += data.lineHeight, prevCharCode = null, spaceCount = 0; 27827 continue; 27828 } 27829 const charData = data.chars[charCode]; 27830 if (!charData) 27831 continue; 27832 prevCharCode && charData.kerning[prevCharCode] && (pos.x += charData.kerning[prevCharCode]); 27833 const charRenderData = charRenderDataPool.pop() || { 27834 texture: Texture.EMPTY, 27835 line: 0,
27836 charCode: 0, 27837 prevSpaces: 0, 27838 position: new Point() 27839 }; 27840 charRenderData.texture = charData.texture, charRenderData.line = line, charRenderData.charCode = charCode, charRenderData.position.x = Math.round(pos.x + charData.xOffset + this._letterSpacing / 2), charRenderData.position.y = Math.round(pos.y + charData.yOffset), charRenderData.prevSpaces = spaceCount, chars.push(charRenderData), lastLineWidth = charRenderData.position.x + Math.max(charData.xAdvance - charData.xOffset, charData.texture.orig.width), pos.x += charData.xAdvance + this._letterSpacing, maxLineHeight = Math.max(maxLineHeight, charData.yOffset + charData.texture.height), prevCharCode = charCode, lastBreakPos !== -1 && maxWidth > 0 && pos.x > maxWidth && (++spacesRemoved, removeItems(chars, 1 + lastBreakPos - spacesRemoved, 1 + i - lastBreakPos), i = lastBreakPos, lastBreakPos = -1, lineWidths.push(lastBreakWidth), lineSpaces.push(chars.length > 0 ? chars[chars.length - 1].prevSpaces : 0), maxLineWidth = Math.max(maxLineWidth, lastBreakWidth), line++, pos.x = 0, pos.y += data.lineHeight, prevCharCode = null, spaceCount = 0); 27841 } 27842 const lastChar = charsInput[charsInput.length - 1]; 27843 lastChar !== "\r" && lastChar !== ` 27844` && (/(?:\s)/.test(lastChar) && (lastLineWidth = lastBreakWidth), lineWidths.push(lastLineWidth), maxLineWidth = Math.max(maxLineWidth, lastLineWidth), lineSpaces.push(-1)); 27845 const lineAlignOffsets = []; 27846 for (let i = 0; i <= line; i++) { 27847 let alignOffset = 0; 27848 this._align === "right" ? alignOffset = maxLineWidth - lineWidths[i] : this._align === "center" ? alignOffset = (maxLineWidth - lineWidths[i]) / 2 : this._align === "justify" && (alignOffset = lineSpaces[i] < 0 ? 0 : (maxLineWidth - lineWidths[i]) / lineSpaces[i]), lineAlignOffsets.push(alignOffset); 27849 } 27850 const lenChars = chars.length, pagesMeshData = {}, newPagesMeshData = [], activePagesMeshData = this._activePagesMeshData; 27851 pageMeshDataPool.push(...activePagesMeshData); 27852 for (let i = 0; i < lenChars; i++) { 27853 const texture = chars[i].texture, baseTextureUid = texture.baseTexture.uid; 27854 if (!pagesMeshData[baseTextureUid]) { 27855 let pageMeshData = pageMeshDataPool.pop(); 27856 if (!pageMeshData) { 27857 const geometry = new MeshGeometry(); 27858 let material, meshBlendMode; 27859 data.distanceFieldType === "none" ? (material = new MeshMaterial(Texture.EMPTY), meshBlendMode = BLEND_MODES.NORMAL) : (material = new MeshMaterial( 27860 Texture.EMPTY, 27861 { program: Program.from(msdfVert, msdfFrag), uniforms: { uFWidth: 0 } } 27862 ), meshBlendMode = BLEND_MODES.NORMAL_NPM); 27863 const mesh = new Mesh(geometry, material); 27864 mesh.blendMode = meshBlendMode, pageMeshData = { 27865 index: 0, 27866 indexCount: 0, 27867 vertexCount: 0, 27868 uvsCount: 0, 27869 total: 0, 27870 mesh, 27871 vertices: null, 27872 uvs: null, 27873 indices: null 27874 }; 27875 } 27876 pageMeshData.index = 0, pageMeshData.indexCount = 0, pageMeshData.vertexCount = 0, pageMeshData.uvsCount = 0, pageMeshData.total = 0; 27877 const { _textureCache } = this; 27878 _textureCache[baseTextureUid] = _textureCache[baseTextureUid] || new Texture(texture.baseTexture), pageMeshData.mesh.texture = _textureCache[baseTextureUid], pageMeshData.mesh.tint = this._tintColor.value, newPagesMeshData.push(pageMeshData), pagesMeshData[baseTextureUid] = pageMeshData; 27879 } 27880 pagesMeshData[baseTextureUid].total++; 27881 } 27882 for (let i = 0; i < activePagesMeshData.length; i++) 27883 newPagesMeshData.includes(activePagesMeshData[i]) || this.removeChild(activePagesMeshData[i].mesh); 27884 for (let i = 0; i < newPagesMeshData.length; i++) 27885 newPagesMeshData[i].mesh.parent !== this && this.addChild(newPagesMeshData[i].mesh); 27886 this._activePagesMeshData = newPagesMeshData; 27887 for (const i in pagesMeshData) { 27888 const pageMeshData = pagesMeshData[i], total = pageMeshData.total; 27889 if (!(pageMeshData.indices?.length > 6 * total) || pageMeshData.vertices.length < Mesh.BATCHABLE_SIZE * 2) 27890 pageMeshData.vertices = new Float32Array(4 * 2 * total), pageMeshData.uvs = new Float32Array(4 * 2 * total), pageMeshData.indices = new Uint16Array(6 * total); 27891 else { 27892 const total2 = pageMeshData.total, vertices = pageMeshData.vertices; 27893 for (let i2 = total2 * 4 * 2; i2 < vertices.length; i2++) 27894 vertices[i2] = 0; 27895 } 27896 pageMeshData.mesh.size = 6 * total; 27897 } 27898 for (let i = 0; i < lenChars; i++) { 27899 const char = chars[i]; 27900 let offset = char.position.x + lineAlignOffsets[char.line] * (this._align === "
27900justify" ? char.prevSpaces : 1); 27901 this._roundPixels && (offset = Math.round(offset)); 27902 const xPos = offset * scale, yPos = char.position.y * scale, texture = char.texture, pageMesh = pagesMeshData[texture.baseTexture.uid], textureFrame = texture.frame, textureUvs = texture._uvs, index = pageMesh.index++; 27903 pageMesh.indices[index * 6 + 0] = 0 + index * 4, pageMesh.indices[index * 6 + 1] = 1 + index * 4, pageMesh.indices[index * 6 + 2] = 2 + index * 4, pageMesh.indices[index * 6 + 3] = 0 + index * 4, pageMesh.indices[index * 6 + 4] = 2 + index * 4, pageMesh.indices[index * 6 + 5] = 3 + index * 4, pageMesh.vertices[index * 8 + 0] = xPos, pageMesh.vertices[index * 8 + 1] = yPos, pageMesh.vertices[index * 8 + 2] = xPos + textureFrame.width * scale, pageMesh.vertices[index * 8 + 3] = yPos, pageMesh.vertices[index * 8 + 4] = xPos + textureFrame.width * scale, pageMesh.vertices[index * 8 + 5] = yPos + textureFrame.height * scale, pageMesh.vertices[index * 8 + 6] = xPos, pageMesh.vertices[index * 8 + 7] = yPos + textureFrame.height * scale, pageMesh.uvs[index * 8 + 0] = textureUvs.x0, pageMesh.uvs[index * 8 + 1] = textureUvs.y0, pageMesh.uvs[index * 8 + 2] = textureUvs.x1, pageMesh.uvs[index * 8 + 3] = textureUvs.y1, pageMesh.uvs[index * 8 + 4] = textureUvs.x2, pageMesh.uvs[index * 8 + 5] = textureUvs.y2, pageMesh.uvs[index * 8 + 6] = textureUvs.x3, pageMesh.uvs[index * 8 + 7] = textureUvs.y3; 27904 } 27905 this._textWidth = maxLineWidth * scale, this._textHeight = (pos.y + data.lineHeight) * scale; 27906 for (const i in pagesMeshData) { 27907 const pageMeshData = pagesMeshData[i]; 27908 if (this.anchor.x !== 0 || this.anchor.y !== 0) { 27909 let vertexCount = 0; 27910 const anchorOffsetX = this._textWidth * this.anchor.x, anchorOffsetY = this._textHeight * this.anchor.y; 27911 for (let i2 = 0; i2 < pageMeshData.total; i2++) 27912 pageMeshData.vertices[vertexCount++] -= anchorOffsetX, pageMeshData.vertices[vertexCount++] -= anchorOffsetY, pageMeshData.vertices[vertexCount++] -= anchorOffsetX, pageMeshData.vertices[vertexCount++] -= anchorOffsetY, pageMeshData.vertices[vertexCount++] -= anchorOffsetX, pageMeshData.vertices[vertexCount++] -= anchorOffsetY, pageMeshData.vertices[vertexCount++] -= anchorOffsetX, pageMeshData.vertices[vertexCount++] -= anchorOffsetY; 27913 } 27914 this._maxLineHeight = maxLineHeight * scale; 27915 const vertexBuffer = pageMeshData.mesh.geometry.getBuffer("aVertexPosition"), textureBuffer = pageMeshData.mesh.geometry.getBuffer("aTextureCoord"), indexBuffer = pageMeshData.mesh.geometry.getIndex(); 27916 vertexBuffer.data = pageMeshData.vertices, textureBuffer.data = pageMeshData.uvs, indexBuffer.data = pageMeshData.indices, vertexBuffer.update(), textureBuffer.update(), indexBuffer.update(); 27917 } 27918 for (let i = 0; i < chars.length; i++) 27919 charRenderDataPool.push(chars[i]); 27920 this._font = data, this.dirty = !1; 27921 } 27922 updateTransform() { 27923 this.validate(), this.containerUpdateTransform(); 27924 } 27925 _render(renderer) { 27926 this._autoResolution && this._resolution !== renderer.resolution && (this._resolution = renderer.resolution, this.dirty = !0); 27927 const { distanceFieldRange, distanceFieldType, size } = BitmapFont.available[this._fontName]; 27928 if (distanceFieldType !== "none") { 27929 const { a, b, c, d } = this.worldTransform, dx = Math.sqrt(a * a + b * b), dy = Math.sqrt(c * c + d * d), worldScale = (Math.abs(dx) + Math.abs(dy)) / 2, fontScale = this.fontSize / size, resolution = renderer._view.resolution; 27930 for (const mesh of this._activePagesMeshData) 27931 mesh.mesh.shader.uniforms.uFWidth = worldScale * distanceFieldRange * fontScale * resolution; 27932 } 27933 super._render(renderer); 27934 } 27935 /** 27936 * Validates text before calling parent's getLocalBounds 27937 * @returns - The rectangular bounding area 27938 */ 27939 getLocalBounds() { 27940 return this.validate(), super.getLocalBounds(); 27941 } 27942 /** 27943 * Updates text when needed 27944 * @private 27945 */ 27946 validate() { 27947 const font = BitmapFont.available[this._fontName]; 27948 if (!font) 27949 throw new Error(`Missing BitmapFont "${this._fontName}"`); 27950 this._font !== font && (this.dirty = !0), this.dirty && this.updateText(); 27951 } 27952 /** 27953 * The tint of the BitmapText object. 27954 * @default 0xffffff 27955 */ 27956 get tint() { 27957 return this._tintColor.value; 27958 } 27959 set tint(value) { 27960 if (this.tint !== value) { 27961 this._tintColor.setValue(value); 27962 for (let i = 0; i < this._activePagesMeshData.length; i++) 27963 this._activePagesMeshData[i].mesh.tint = value; 27964 } 27965 } 27966 /** 27967 * The alignment of the BitmapText object. 27968 * @member {string} 27969 * @default 'left' 27970 */ 27971 get align() { 27972 return this._align; 27973 } 27974 set align(value) { 27975 this._align !== value && (this._align = value, this.dirty = !0); 27976 } 27977 /** The name of the BitmapFont. */ 27978 get fontName() { 27979 return this._fontName; 27980 } 27981 set fontName(value) { 27982 if (!BitmapFont.available[value]) 27983 throw new Error(`Missing BitmapFont "${value}"`); 27984 this._fontName !== value && (this._fontName = value, this.dirty = !0); 27985 } 27986 /** The size of the font to display. */ 27987 get fontSize() { 27988 return this._fontSize ?? BitmapFont.available[this._fontName].size; 27989 } 27990 set fontSize(value) { 27991 this._fontSize !== value && (this._fontSize = value, this.dirty = !0); 27992 } 27993 /** 27994 * The anchor sets the origin point of the text. 27995 * 27996 * The default is `(0,0)`, this means the text's origin is the top left. 27997 *
27998 * Setting the anchor to `(0.5,0.5)` means the text's origin is centered. 27999 * 28000 * Setting the anchor to `(1,1)` would mean the text's origin point will be the bottom right corner. 28001 */ 28002 get anchor() { 28003 return this._anchor; 28004 } 28005 set anchor(value) { 28006 typeof value == "number" ? this._anchor.set(value) : this._anchor.copyFrom(value); 28007 } 28008 /** The text of the BitmapText object. */ 28009 get text() { 28010 return this._text; 28011 } 28012 set text(text) { 28013 text = String(text ?? ""), this._text !== text && (this._text = text, this.dirty = !0); 28014 } 28015 /** 28016 * The max width of this bitmap text in pixels. If the text provided is longer than the 28017 * value provided, line breaks will be automatically inserted in the last whitespace. 28018 * Disable by setting the value to 0. 28019 */ 28020 get maxWidth() { 28021 return this._maxWidth; 28022 } 28023 set maxWidth(value) { 28024 this._maxWidth !== value && (this._maxWidth = value, this.dirty = !0); 28025 } 28026 /** 28027 * The max line height. This is useful when trying to use the total height of the Text, 28028 * i.e. when trying to vertically align. 28029 * @readonly 28030 */ 28031 get maxLineHeight() { 28032 return this.validate(), this._maxLineHeight; 28033 } 28034 /** 28035 * The width of the overall text, different from fontSize, 28036 * which is defined in the style object. 28037 * @readonly 28038 */ 28039 get textWidth() { 28040 return this.validate(), this._textWidth; 28041 } 28042 /** Additional space between characters. */ 28043 get letterSpacing() { 28044 return this._letterSpacing; 28045 } 28046 set letterSpacing(value) { 28047 this._letterSpacing !== value && (this._letterSpacing = value, this.dirty = !0); 28048 } 28049 /** 28050 * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation. 28051 * Advantages can include sharper image quality (like text) and faster rendering on canvas. 28052 * The main disadvantage is movement of objects may appear less smooth. 28053 * To set the global default, change {@link PIXI.settings.ROUND_PIXELS} 28054 * @default PIXI.settings.ROUND_PIXELS 28055 */ 28056 get roundPixels() { 28057 return this._roundPixels; 28058 } 28059 set roundPixels(value) { 28060 value !== this._roundPixels && (this._roundPixels = value, this.dirty = !0); 28061 } 28062 /** 28063 * The height of the overall text, different from fontSize, 28064 * which is defined in the style object. 28065 * @readonly 28066 */ 28067 get textHeight() { 28068 return this.validate(), this._textHeight; 28069 } 28070 /** 28071 * The resolution / device pixel ratio of the canvas. 28072 * 28073 * This is set to automatically match the renderer resolution by default, but can be overridden by setting manually. 28074 * @default 1 28075 */ 28076 get resolution() { 28077 return this._resolution; 28078 } 28079 set resolution(value) { 28080 this._autoResolution = !1, this._resolution !== value && (this._resolution = value, this.dirty = !0); 28081 } 28082 destroy(options) { 28083 const { _textureCache } = this, pageMeshDataPool = BitmapFont.available[this._fontName].distanceFieldType === "none" ? pageMeshDataDefaultPageMeshData : pageMeshDataMSDFPageMeshData; 28084 pageMeshDataPool.push(...this._activePagesMeshData); 28085 for (const pageMeshData of this._activePagesMeshData) 28086 this.removeChild(pageMeshData.mesh); 28087 this._activePagesMeshData = [], pageMeshDataPool.filter((page) => _textureCache[page.mesh.texture.baseTexture.uid]).forEach((page) => { 28088 page.mesh.texture = Texture.EMPTY; 28089 }); 28090 for (const id in _textureCache) 28091 _textureCache[id].destroy(), delete _textureCache[id]; 28092 this._font = null, this._tintColor = null, this._textureCache = null, super.destroy(options); 28093 } 28094}; 28095_BitmapText.styleDefaults = { 28096 align: "left", 28097 tint: 16777215, 28098 maxWidth: 0, 28099 letterSpacing: 0 28100}; 28101 28102const validExtensions = [".xml", ".fnt"], loadBitmapFont = { 28103 extension: { 28104 type: ExtensionType.LoadParser, 28105 priority: LoaderParserPriority.Normal 28106 }, 28107 name: "loadBitmapFont", 28108 test(url) { 28109 return validExtensions.includes(path.extname(url).toLowerCase()); 28110 }, 28111 async testParse(data) { 28112 return TextFormat.test(data) || XMLStringFormat.test(data); 28113 }, 28114 async parse(asset, data, loader) { 28115 const fontData = TextFormat.test(asset) ? TextFormat.parse(asset) : XMLStringFormat.parse(asset), { src } = data, { page: pages } = fontData, textureUrls = []; 28116 for (let i = 0; i < pages.length; ++i) { 28117 const pageFile = pages[i].file; 28118 let imagePath = path.join(path.dirname(src), pageFile); 28119 imagePath = copySearchParams(imagePath, src), textureUrls.push(imagePath); 28120 } 28121 const loadedTextures = await loader.load(textureUrls), textures = textureUrls.map((url) => loadedTextures[url]); 28122 return BitmapFont.install(fontData, textures, !0); 28123 }, 28124 async load(url, _options) { 28125 return (await settings.ADAPTER.fetch(url)).text(); 28126 }, 28127 unload(bitmapFont) { 28128 bitmapFont.destroy(); 28129 } 28130}; 28131extensions$1.add(loadBitmapFont); 28132 28133const _HTMLTextStyle = class _HTMLTextStyle2 extends TextStyle { 28134 constructor() { 28135 super(...arguments), this._fonts = [], this._overrides = [], this._stylesheet = "", this.fontsDirt
28135y = !1; 28136 } 28137 /** 28138 * Convert a TextStyle to HTMLTextStyle 28139 * @param originalStyle 28140 * @example 28141 * import {TextStyle } from 'pixi.js'; 28142 * import {HTMLTextStyle} from '@pixi/text-html'; 28143 * const style = new TextStyle(); 28144 * const htmlStyle = HTMLTextStyle.from(style); 28145 */ 28146 static from(originalStyle) { 28147 return new _HTMLTextStyle2( 28148 Object.keys(_HTMLTextStyle2.defaultOptions).reduce((obj, prop) => ({ ...obj, [prop]: originalStyle[prop] }), {}) 28149 ); 28150 } 28151 /** Clear the current font */ 28152 cleanFonts() { 28153 this._fonts.length > 0 && (this._fonts.forEach((font) => { 28154 URL.revokeObjectURL(font.src), font.refs--, font.refs === 0 && (font.fontFace && document.fonts.delete(font.fontFace), delete _HTMLTextStyle2.availableFonts[font.originalUrl]); 28155 }), this.fontFamily = "Arial", this._fonts.length = 0, this.styleID++, this.fontsDirty = !0); 28156 } 28157 /** 28158 * Because of how HTMLText renders, fonts need to be imported 28159 * @param url 28160 * @param options 28161 */ 28162 loadFont(url, options = {}) { 28163 const { availableFonts } = _HTMLTextStyle2; 28164 if (availableFonts[url]) { 28165 const font = availableFonts[url]; 28166 return this._fonts.push(font), font.refs++, this.styleID++, this.fontsDirty = !0, Promise.resolve(); 28167 } 28168 return settings.ADAPTER.fetch(url).then((response) => response.blob()).then(async (blob) => new Promise((resolve, reject) => { 28169 const src = URL.createObjectURL(blob), reader = new FileReader(); 28170 reader.onload = () => resolve([src, reader.result]), reader.onerror = reject, reader.readAsDataURL(blob); 28171 })).then(async ([src, dataSrc]) => { 28172 const font = Object.assign({ 28173 family: path.basename(url, path.extname(url)), 28174 weight: "normal", 28175 style: "normal", 28176 display: "auto", 28177 src, 28178 dataSrc, 28179 refs: 1, 28180 originalUrl: url, 28181 fontFace: null 28182 }, options); 28183 availableFonts[url] = font, this._fonts.push(font), this.styleID++; 28184 const fontFace = new FontFace(font.family, `url(${font.src})`, { 28185 weight: font.weight, 28186 style: font.style, 28187 display: font.display 28188 }); 28189 font.fontFace = fontFace, await fontFace.load(), document.fonts.add(fontFace), await document.fonts.ready, this.styleID++, this.fontsDirty = !0; 28190 }); 28191 } 28192 /** 28193 * Add a style override, this can be any CSS property 28194 * it will override any built-in style. This is the 28195 * property and the value as a string (e.g., `color: red`). 28196 * This will override any other internal style. 28197 * @param {string} value - CSS style(s) to add. 28198 * @example 28199 * style.addOverride('background-color: red'); 28200 */ 28201 addOverride(...value) { 28202 const toAdd = value.filter((v) => !this._overrides.includes(v)); 28203 toAdd.length > 0 && (this._overrides.push(...toAdd), this.styleID++); 28204 } 28205 /** 28206 * Remove any overrides that match the value. 28207 * @param {string} value - CSS style to remove. 28208 * @example 28209 * style.removeOverride('background-color: red'); 28210 */ 28211 removeOverride(...value) { 28212 const toRemove = value.filter((v) => this._overrides.includes(v)); 28213 toRemove.length > 0 && (this._overrides = this._overrides.filter((v) => !toRemove.includes(v
vendor: 2,524 bytes, lines 28213-28279
28213)), this.styleID++); 28214 } 28215 /** 28216 * Internally converts all of the style properties into CSS equivalents. 28217 * @param scale 28218 * @returns The CSS style string, for setting `style` property of root HTMLElement. 28219 */ 28220 toCSS(scale) { 28221 return [ 28222 `transform: scale(${scale})`, 28223 "transform-origin: top left", 28224 "display: inline-block", 28225 `color: ${this.normalizeColor(this.fill)}`, 28226 `font-size: ${this.fontSize}px`, 28227 `font-family: ${this.fontFamily}`, 28228 `font-weight: ${this.fontWeight}`, 28229 `font-style: ${this.fontStyle}`, 28230 `font-variant: ${this.fontVariant}`, 28231 `letter-spacing: ${this.letterSpacing}px`, 28232 `text-align: ${this.align}`, 28233 `padding: ${this.padding}px`, 28234 `white-space: ${this.whiteSpace}`, 28235 ...this.lineHeight ? [`line-height: ${this.lineHeight}px`] : [], 28236 ...this.wordWrap ? [ 28237 `word-wrap: ${this.breakWords ? "break-all" : "break-word"}`, 28238 `max-width: ${this.wordWrapWidth}px` 28239 ] : [], 28240 ...this.strokeThickness ? [ 28241 `-webkit-text-stroke-width: ${this.strokeThickness}px`, 28242 `-webkit-text-stroke-color: ${this.normalizeColor(this.stroke)}`, 28243 `text-stroke-width: ${this.strokeThickness}px`, 28244 `text-stroke-color: ${this.normalizeColor(this.stroke)}`, 28245 "paint-order: stroke" 28246 ] : [], 28247 ...this.dropShadow ? [this.dropShadowToCSS()] : [], 28248 ...this._overrides 28249 ].join(";"); 28250 } 28251 /** Get the font CSS styles from the loaded font, If available. */ 28252 toGlobalCSS() { 28253 return this._fonts.reduce((result, font) => `${result} 28254 @font-face { 28255 font-family: "${font.family}"; 28256 src: url('${font.dataSrc}'); 28257 font-weight: ${font.weight}; 28258 font-style: ${font.style}; 28259 font-display: ${font.display}; 28260 }`, this._stylesheet); 28261 } 28262 /** Internal stylesheet contents, useful for creating rules for rendering */ 28263 get stylesheet() { 28264 return this._stylesheet; 28265 } 28266 set stylesheet(value) { 28267 this._stylesheet !== value && (this._stylesheet = value, this.styleID++); 28268 } 28269 /** 28270 * Convert numerical colors into hex-strings 28271 * @param color 28272 */ 28273 normalizeColor(color) { 28274 return Array.isArray(color) && (color = rgb2hex(color)), typeof color == "number" ? hex2string(color) : color; 28275 } 28276 /** Convert the internal drop-shadow settings to CSS text-shadow */ 28277 dropShadowToCSS() { 28278 let color = this.normalizeColor(this.dropShadowColor); 28279 const alpha = this.dropShadowAlpha, x
28279 = Math.round(Math.cos(this.dropShadowAngle) * this.dropShadowDistance), y = Math.round(Math.sin(this.dropShadowAngle) * this.dropShadowDistance); 28280 color.startsWith("#") && alpha < 1 && (color += (alpha * 255 | 0).toString(16).padStart(2, "0")); 28281 const position = `${x}px ${y}px`; 28282 return this.dropShadowBlur > 0 ? `text-shadow: ${position} ${this.dropShadowBlur}px ${color}` : `text-shadow: ${position} ${color}`; 28283 } 28284 /** Resets all properties to the defaults specified in TextStyle.prototype._default */ 28285 reset() { 28286 Object.assign(this, _HTMLTextStyle2.defaultOptions); 28287 } 28288 /** 28289 * Called after the image is loaded but before drawing to the canvas. 28290 * Mostly used to handle Safari's font loading bug. 28291 * @ignore 28292 */ 28293 onBeforeDraw() { 28294 const { fontsDirty: prevFontsDirty } = this; 28295 return this.fontsDirty = !1, this.isSafari && this._fonts.length > 0 && prevFontsDirty ? new Promise((resolve) => setTimeout(resolve, 100)) : Promise.resolve(); 28296 } 28297 /** 28298 * Proving that Safari is the new IE 28299 * @ignore 28300 */ 28301 get isSafari() { 28302 const { userAgent } = settings.ADAPTER.getNavigator(); 28303 return /^((?!chrome|android).)*safari/i.test(userAgent); 28304 } 28305 set fillGradientStops(_value) { 28306 console.warn("[HTMLTextStyle] fillGradientStops is not supported by HTMLText"); 28307 } 28308 get fillGradientStops() { 28309 return super.fillGradientStops; 28310 } 28311 set fillGradientType(_value) { 28312 console.warn("[HTMLTextStyle] fillGradientType is not supported by HTMLText"); 28313 } 28314 get fillGradientType() { 28315 return super.fillGradientType; 28316 } 28317 set miterLimit(_value) { 28318 console.warn("[HTMLTextStyle] miterLimit is not supported by HTMLText"); 28319 } 28320 get miterLimit() { 28321 return super.miterLimit; 28322 } 28323 set trim(_value) { 28324 console.warn("[HTMLTextStyle] trim is not supported by HTMLText"); 28325 } 28326 get trim() { 28327 return super.trim; 28328 } 28329 set textBaseline(_value) { 28330 console.warn("[HTMLTextStyle] textBaseline is not supported by HTMLText"); 28331 } 28332 get textBaseline() { 28333 return super.textBaseline; 28334 } 28335 set leading(_value) { 28336 console.warn("[HTMLTextStyle] leading is not supported by HTMLText"); 28337 } 28338 get leading() { 28339 return super.leading; 28340 } 28341 set lineJoin(_value) { 28342 console.warn("[HTMLTextStyle] lineJoin is not supported by HTMLText"); 28343 } 28344 get lineJoin() { 28345 return super.lineJoin; 28346 } 28347}; 28348_HTMLTextStyle.availableFonts = {}, /** 28349* List of default options, these are largely the same as TextStyle, 28350* with the exception of whiteSpace, which is set to 'normal' by default. 28351*/ 28352_HTMLTextStyle.defaultOptions = { 28353 /** Align */ 28354 align: "left", 28355 /** Break words */ 28356 breakWords: !1, 28357 /** Drop shadow */ 28358 dropShadow: !1, 28359 /** Drop shadow alpha */ 28360 dropShadowAlpha: 1, 28361 /** 28362 * Drop shadow angle 28363 * @type {number} 28364 * @default Math.PI / 6 28365 */ 28366 dropShadowAngle: Math.PI / 6, 28367 /** Drop shadow blur */ 28368 dropShadowBlur: 0, 28369 /** Drop shadow color */ 28370 dropShadowColor: "black", 28371 /** Drop shadow distance */ 28372 dropShadowDistance: 5, 28373 /** Fill */ 28374 fill: "black", 28375 /** Font family */ 28376 fontFamily: "Arial", 28377 /** Font size */ 28378 fontSize: 26, 28379 /** Font style */ 28380 fontStyle: "normal", 28381 /** Font variant */ 28382 fontVariant: "normal", 28383 /** Font weight */ 28384 fontWeight: "normal", 28385 /** Letter spacing */ 28386 letterSpacing: 0, 28387 /** Line height */ 28388 lineHeight: 0, 28389 /** Padding */ 28390 padding: 0, 28391 /** Stroke */ 28392 stroke: "black", 28393 /** Stroke thickness */ 28394 strokeThickness: 0, 28395 /** White space */ 28396 whiteSpace: "normal", 28397 /** Word wrap */ 28398 wordWrap: !1, 28399 /** Word wrap width */ 28400 wordWrapWidth: 100 28401}; 28402let HTMLTextStyle = _HTMLTextStyle; 28403 28404const _HTMLText = class _HTMLText2 extends Sprite { 28405 /** 28406 * @param {string} [text] - Text contents 28407 * @param {PIXI.HTMLTextStyle|PIXI.TextStyle|PIXI.ITextStyle} [style] - Style setting to use. 28408 * Strongly recommend using an HTMLTextStyle object. Providing a PIXI.TextStyle 28409 * will convert the TextStyle to an HTMLTextStyle and will no longer be linked. 28410 */ 28411 constructor(text = "", style = {}) { 28412 super(Texture.EMPTY), this._text = null, this._style = null, this._autoResolution = !0, this.localStyleID = -1, this.dirty = !1, this._updateID = 0, this.ownsStyle = !1; 28413 const image = new Image(), texture = Texture.from(image, { 28414 scaleMode: settings.SCALE_MODE, 28415 resourceOptions: { 28416 autoLoad: !1 28417 } 28418 }); 28419 texture.orig = new Rectangle(), texture.trim = new Rectangle(), this.texture = texture; 28420 const nssvg = "http://www.w3.org/2000/svg", nsxhtml = "http://www.w3.org/1999/xhtml", svgRoot = document.createElementNS(nssvg, "svg"), foreignObject = document.createElementNS(nssvg, "foreignObject"), domElement = document.createElementNS(nsxhtml, "div"), styleElement = document.createElementNS(nsxhtml, "style"); 28421 foreignObject.setAttribute("width", "10000"), foreignObject.setAttribute("height", "10000"), foreignObject.style.overflow = "hidden", svgRoot.appendChild(foreignObject), this.maxWidth = _HTMLText2.defaultMaxWidth, this.maxHeight = _HTMLText2.defaultMaxHeight, this._domElement = domElement, this._styleElement = styleElement, this._svgRoot = svgRoot, this._foreignObject = foreignObject, this._foreignObject.appendChild(styleElement), this._foreignObject.appendChild(domElement), this._image = image, this._loadImage = new Image(), this._autoResolution = _HTMLText2.defaultAutoResolution, this._resolution = _HTMLText2.defaultResolution ?? settings.RESOLUTION, this.text = text, this.style = style; 28422 } 28423 /** 28424 * Calculate the size of the output text without actually drawing it. 28425 * This includes the `padding` in the `style` object. 28426 * This can be used as a fast-pass to do things like text-fitting. 28427 * @param {object} [overrides] - Overrides for the text, style, and resolution. 28428 * @param {string} [overrides.text] - The text to measure, if not specified, the current text is used. 28429 * @param {PIXI.HTMLTextStyle} [overrides.style] - The style to measure, if not specified, the current style is used. 28430 * @param {number} [overrides.resolution] - The resolution to measure, if not specified, the current resolution is used. 28431 * @returns {PIXI.ISize} Width and height of the measured text. 28432 */ 28433 measureText(overrides) { 28434 const { text, style, resolution } = Object.assign({ 28435 text: this._text, 28436 style: this._style, 28437 resolution: this._resolution 28438 }, overrides);
28439 Object.assign(this._domElement, { 28440 innerHTML: text, 28441 style: style.toCSS(resolution) 28442 }), this._styleElement.textContent = style.toGlobalCSS(), document.body.appendChild(this._svgRoot); 28443 const contentBounds = this._domElement.getBoundingClientRect(); 28444 this._svgRoot.remove(); 28445 const { width, height } = contentBounds; 28446 (width > this.maxWidth || height > this.maxHeight) && console.warn("[HTMLText] Large expanse of text, increase HTMLText.maxWidth or HTMLText.maxHeight property."); 28447 const contentWidth = Math.min(this.maxWidth, Math.ceil(width)), contentHeight = Math.min(this.maxHeight, Math.ceil(height)); 28448 return this._svgRoot.setAttribute("width", contentWidth.toString()), this._svgRoot.setAttribute("height", contentHeight.toString()), text !== this._text && (this._domElement.innerHTML = this._text), style !== this._style && (Object.assign(this._domElement, { style: this._style?.toCSS(resolution) }), this._styleElement.textContent = this._style?.toGlobalCSS()), { 28449 width: contentWidth + style.padding * 2, 28450 height: contentHeight + style.padding * 2 28451 }; 28452 } 28453 /** 28454 * Manually refresh the text. 28455 * @public 28456 * @param {boolean} respectDirty - Whether to abort updating the 28457 * text if the Text isn't dirty and the function is called. 28458 */ 28459 async updateText(respectDirty = !0) { 28460 const { style, _image: image, _loadImage: loadImage } = this; 28461 if (this.localStyleID !== style.styleID && (this.dirty = !0, this.localStyleID = style.styleID), !this.dirty && respectDirty) 28462 return; 28463 const { width, height } = this.measureText(); 28464 image.width = loadImage.width = Math.ceil(Math.max(1, width)), image.height = loadImage.height = Math.ceil(Math.max(1, height)), this._updateID++; 28465 const updateID = this._updateID; 28466 await new Promise((resolve) => { 28467 loadImage.onload = async () => { 28468 if (updateID < this._updateID) { 28469 resolve(); 28470 return; 28471 } 28472 await style.onBeforeDraw(), image.src = loadImage.src, loadImage.onload = null, loadImage.src = "", this.updateTexture(), resolve(); 28473 }; 28474 const svgURL = new XMLSerializer().serializeToString(this._svgRoot); 28475 loadImage.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(svgURL)}`; 28476 }); 28477 } 28478 /** The raw image element that is rendered under-the-hood. */ 28479 get source() { 28480 return this._image; 28481 } 28482 /** 28483 * Update the texture resource. 28484 * @private 28485 */ 28486 updateTexture() { 28487 const { style, texture, _image: image, resolution } = this, { padding } = style, { baseTexture } = texture; 28488 texture.trim.width = texture._frame.width = image.width / resolution, texture.trim.height = texture._frame.height = image.height / resolution, texture.trim.x = -padding, texture.trim.y = -padding, texture.orig.width = texture._frame.width - padding * 2, texture.orig.height = texture._frame.height - padding * 2, this._onTextureUpdate(), baseTexture.setRealSize(image.width, image.height, resolution), this.dirty = !1; 28489 } 28490 /** 28491 * Renders the object using the WebGL renderer 28492 * @param {PIXI.Renderer} renderer - The renderer 28493 * @private 28494 */ 28495 _render(renderer) { 28496 this._autoResolution && this._resolution !== renderer.resolution && (this._resolution = renderer.resolution, this.dirty = !0), this.updateText(!0), super._render(renderer); 28497 } 28498 /** 28499 * Renders the object using the Canvas Renderer. 28500 * @private 28501 * @param {PIXI.CanvasRenderer} renderer - The renderer 28502 */ 28503 _renderCanvas(renderer) { 28504 this._autoResolution && this._resolution !== renderer.resolution && (this._resolution = renderer.resolution, this.dirty = !0), this.updateText(!0), super._renderCanvas(renderer); 28505 } 28506 /** 28507 * Get the local bounds. 28508 * @param {PIXI.Rectangle} rect - Input rectangle. 28509 * @returns {PIXI.Rectangle} Local bounds 28510 */ 28511 getLocalBounds(rect) { 28512 return this.updateText(!0), super.getLocalBounds(rect); 28513 } 28514 _calculateBounds() { 28515 this.updateText(!0), this.calculateVertices(), this._bounds.addQuad(this.vertexData); 28516 } 28517 /** 28518 * Handle dirty style changes 28519 * @private 28520 */ 28521 _onStyleChange() { 28522 this.dirty = !0; 28523 } 28524 /** 28525 * Destroy this Text object. Don't use after calling. 28526 * @param {boolean|object} options - Same as Sprite destroy options. 28527 */ 28528 destroy(options) { 28529 typeof options == "boolean" && (options = { children: options }), options = Object.assign({}, _HTMLText2.defaultDestroyOptions, options), super.destroy(options); 28530 const forceClear = null; 28531 this.ownsStyle && this._style?.cleanFonts(), this._style = forceClear, this._svgRoot?.remove(), this._svgRoot = forceClear, this._domElement?.remove(), this._domElement = forceClear, this._foreignObject?.remove(), this._foreignObject = forceClear, this._styleElement?.remove(), this._styleElement = forceClear, this._loadImage.src = "", this._loadImage.onload = null, this._loadImage = forceClear, this._image.src = "", this._image = forceClear; 28532 } 28533 /** 28534 * Get the width in pixels. 28535 * @member {number} 28536 */ 28537 get width() { 28538 return this.updateText(!0), Math.abs(this.scale.x) * this._image.width / this.resolution; 28539 } 28540 set width(value) { 28541 this.updateText(!0); 28542 const s = sign(this.scale.x) || 1; 28543 this.scale.x = s * value / this._image.width / this.resolution, this._width = value; 28544 } 28545 /** 28546 * Get the height in pixels. 28547 * @member {number} 28548 */ 28549 get height() { 28550 return this.updateText(!0), Math.abs(this.scale.y) * this._image.height / this.resolution; 28551 } 28552 set height(value) { 28553 this.updateText(!0); 28554 const s = sign(this.scale.y) || 1; 28555 this.scale.y = s * value / this._image.height / this.resolution, this._height = value; 28556 } 28557 /** The base style to render with text. */ 28558 get style() { 28559 return this._style; 28560 } 28561 set style(style) { 28562 this._style !== style && (style = style || {}, style instanceof HTMLTextStyle ? (this.ownsStyle = !1, this._style = style) : style instanceof TextStyle ? (console.warn("[HTMLText] Cloning TextStyle, if this is not what you want, use HTMLTextStyle"), this.ownsStyle = !0, this._style = HTMLTextStyle.from(style)) : (this.ownsStyle = !0, this._style = new HTMLTextStyle(style)), this.localStyleID = -1, this.dirty = !0); 28563 } 28564 /** 28565 * Contents of text. This can be HTML text and include tags. 28566 * @example 28567 * const text = new HTMLText('This is a <em>styled</em> text!'); 28568 * @member {string} 28569 */ 28570 get text() { 28571 return this._text; 28572 } 28573 set text(text) { 28574 text = String(text === "" || text === null || text === void 0 ? " " : text), text = this.sanitiseText(text), this._text !== text && (this._text = text, this.dirty = !0); 28575 } 28576 /** 28577 * The resolution / device pixel ratio of the canvas. 28578 * This is set to automatically match the renderer resolution by default, but can be overridden by setting manually. 28579 * @member {number} 28580 * @default 1 28581 */ 28582 get resolution() { 28583 return this._resolution; 28584 } 28585 set resolution(value) { 28586 this._autoResolution = !1, this._resolution !== value && (this._resolution = value, this.dirty = !0); 28587 } 28588 /** 28589 * Sanitise text - replace `<br>` with `<br/>`, ` ` with ` ` 28590 * @param text 28591 * @see https://www.sitepoint.com/community/t/xhtml-1-0-transitional-xml-parsing-error-entity-nbsp-not-defined/3392/3 28592 */ 28593 sanitiseText(text) { 28594 return text.replace(/<br>/gi, "<br/>").replace(/<hr>/gi, "<hr/>").replace(/ /gi, " "); 28595 } 28596}; 28597_HTMLText.defaultDestroyOptions = { 28598 texture: !0, 28599 children: !1, 28600 baseTexture: !0 28601}, /** Default maxWidth, set at construction */ 28602_HTMLText.defaultMaxWidth = 2024, /** Default maxHeight, set at construction */ 28603_HTMLText.defaultMaxHeight = 2024, /** Default autoResolution for all HTMLText objects */ 28604_HTMLText.defaultAutoResolution = !0; 28605 28606function create_pixi_app(target, width, height, antialias) { 28607 const ratio = window.devicePixelRatio || 1; 28608 const app = new Application({ 28609 width, 28610 height, 28611 antialias, 28612 backgroundAlpha: 0, 28613 eventMode: "static" 28614 }); 28615 const view = app.view; 28616 app.stage.sortableChildren = true; 28617 view.style.maxWidth = `${width / ratio}px`; 28618 view.style.maxHeight = `${height / ratio}px`; 28619 view.style.width = "100%"; 28620 view.style.height = "100%"; 28621 target.appendChild(app.view); 28622 const background_container = new Container(); 28623 background_container.zIndex = 0; 28624 const layer_container = new Container(); 28625 layer_container.zIndex = 1; 28626 layer_container.sortableChildren = true; 28627 const mask_container = new Container(); 28628 mask_container.zIndex = 1; 28629 const composite_container = new Container(); 28630 composite_container.zIndex = 0; 28631 mask_container.addChild(background_container); 28632 mask_container.addChild(layer_container); 28633 app.stage.addChild(mask_container); 28634 app.stage.addChild(composite_container); 28635 const mask = new Graphics(); 28636 let text = RenderTexture.create({ 28637 width, 28638 height 28639 }); 28640 const sprite = new Sprite(text); 28641 mask_container.mask = sprite; 28642 app.render(); 28643 function reset_mask(width2, height2) { 28644 background_container.removeChildren(); 28645 mask.beginFill(16777215, 1); 28646 mask.drawRect(0, 0, width2, height2); 28647 mask.endFill(); 28648 text = RenderTexture.create({ 28649 width: width2, 28650 height: height2 28651 }); 28652 app.renderer.render(mask, { 28653 renderTexture: text 28654 }); 28655 const sprite2 = new Sprite(text); 28656 mask_container.mask = sprite2; 28657 } 28658 function resize(width2, height2) { 28659 app.renderer.resize(width2, height2); 28660 view.style.maxWidth = `${width2 / ratio}px`; 28661 view.style.maxHeight = `${height2 / ratio}px`; 28662 reset_mask(width2, height2); 28663 } 28664 async function get_blobs(_layers, bounds, [w, h]) { 28665 const background2 = await get_canvas_blob( 28666 app.renderer, 28667 background_container, 28668 bounds, 28669 w, 28670 h 28671 ); 28672 const layers = await Promise.all( 28673 _layers.map( 28674 (layer) => get_canvas_blob( 28675 app.renderer, 28676 layer.composite, 28677 bounds, 28678 w, 28679 h 28680 ) 28681 ) 28682 ); 28683 const composite = await get_canvas_blob( 28684 app.renderer, 28685 mask_container, 28686 bounds, 28687 w, 28688 h 28689 ); 28690 return { 28691 background: background2, 28692 layers, 28693 composite 28694 }; 28695 } 28696 return { 28697 layer_container, 28698 renderer: app.renderer, 28699 destroy: () => app.destroy(true), 28700 view: app.view, 28701 background_container, 28702 mask_container, 28703 resize, 28704 get_blobs 28705 }; 28706} 28707function make_graphics(z_index) { 28708 const graphics = new Graphics(); 28709 graphics.eventMode = "none"; 28710 graphics.zIndex = z_index; 28711 return graphics; 28712} 28713function clamp(n, min, max) { 28714 return n < min ? min : n > max ? max : n; 28715} 28716function get_canvas_blob(renderer, obj, bounds, width, height) { 28717 return new Promise((resolve) => { 28718 const src_canvas = renderer.extract.canvas( 28719 obj, 28720 new Rectangle(0, 0, width, height) 28721 ); 28722 let dest_canvas = document.createElement("canvas"); 28723 dest_canvas.width = bounds.width; 28724 dest_canvas.height = bounds.height; 28725 let dest_ctx = dest_canvas.getContext("2d"); 28726 if (!dest_ctx) { 28727 resolve(null); 28728 throw new Error("Could not create canvas context"); 28729 } 28730 dest_ctx.drawImage( 28731 src_canvas, 28732 // this is the area of the source that we want to copy (the crop box) 28733 bounds.x, 28734 bounds.y, 28735 bounds.width, 28736 bounds.height, 28737 // this is where we want to draw the crop box on the destination canvas 28738 0, 28739 0, 28740 bounds.width, 28741 bounds.height 28742 ); 28743 dest_canvas.toBlob?.((blob) => { 28744 if (!blob) { 28745 resolve(null); 28746 } 28747 resolve(blob); 28748 }); 28749 }); 28750} 28751 28752function drawCircle(graphics, x, y, brush_color = new Color("black"), brush_size) { 28753 const color = new Color(brush_color); 28754 graphics.beginFill(color); 28755 graphics.drawCircle(x, y, brush_size); 28756 graphics.endFill(); 28757} 28758function interpolate(point1, point2) { 28759 let points = []; 28760 const dx = point2.x - point1.x; 28761 const dy = point2.y - point1.y; 28762 const distance = Math.sqrt(dx * dx + dy * dy); 28763 const steps = Math.ceil(distance / 2); 28764 const stepX = dx / steps; 28765 const stepY = dy / steps; 28766 for (let j = 0; j < steps; j++) { 28767 const x = point1.x + j * stepX; 28768 const y = point1.y + j * stepY; 28769 points.push({ x, y }); 28770 } 28771 return points; 28772} 28773function draw_path(renderer, stage, layer, mode) { 28774 const paths = []; 28775 let initial_path; 28776 let graphics; 28777 let InitialTexture;
28778 let has_drawn = false; 28779 let id = 0; 28780 return { 28781 drawing: false, 28782 start: function({ 28783 x, 28784 y, 28785 size, 28786 color = new Color("black"), 28787 opacity, 28788 set_initial_texture = true 28789 }) { 28790 if (set_initial_texture) { 28791 InitialTexture = RenderTexture.create({ 28792 width: layer.draw_texture.width, 28793 height: layer.draw_texture.height 28794 }); 28795 renderer.render(layer.composite, { 28796 renderTexture: InitialTexture 28797 }); 28798 } 28799 initial_path = { x, y, size, color, opacity }; 28800 paths.push({ x, y }); 28801 graphics = make_graphics(id++); 28802 drawCircle(graphics, x, y, color, size); 28803 renderer.render(graphics, { 28804 renderTexture: mode === "draw" ? layer.draw_texture : layer.erase_texture, 28805 clear: false 28806 }); 28807 this.drawing = true; 28808 }, 28809 continue: function({ x, y }) { 28810 const last_point = paths[paths.length - 1]; 28811 const new_points = interpolate(last_point, { x, y }); 28812 for (let i = 0; i < new_points.length; i++) { 28813 const { x: x2, y: y2 } = new_points[i]; 28814 drawCircle(graphics, x2, y2, initial_path.color, initial_path.size); 28815 paths.push({ x: x2, y: y2 }); 28816 } 28817 renderer.render(graphics, { 28818 renderTexture: mode === "draw" ? layer.draw_texture : layer.erase_texture, 28819 clear: false 28820 }); 28821 graphics.clear(); 28822 }, 28823 stop: function() { 28824 const current_sketch = RenderTexture.create({ 28825 width: layer.draw_texture.width, 28826 height: layer.draw_texture.height 28827 }); 28828 renderer.render(layer.composite, { 28829 renderTexture: current_sketch 28830 }); 28831 renderer.render(new Sprite(current_sketch), { 28832 renderTexture: layer.draw_texture 28833 }); 28834 const clear_graphics = new Graphics().beginFill(0, 0).drawRect(0, 0, layer.erase_texture.width, layer.erase_texture.height).endFill(); 28835 renderer.render(clear_graphics, { 28836 renderTexture: layer.erase_texture, 28837 clear: true 28838 }); 28839 has_drawn = true; 28840 this.drawing = false; 28841 }, 28842 execute: function() { 28843 if (!has_drawn) { 28844 for (let i = 1; i < paths.length; i++) { 28845 const { x, y } = paths[i]; 28846 drawCircle(graphics, x, y, initial_path.color, initial_path.size); 28847 } 28848 renderer.render(graphics, { 28849 renderTexture: mode === "draw" ? layer.draw_texture : layer.erase_texture, 28850 clear: false 28851 }); 28852 this.stop(); 28853 } 28854 }, 28855 undo: function() { 28856 const clear_graphics = new Graphics().beginFill(0, 0).drawRect(0, 0, layer.erase_texture.width, layer.erase_texture.height).endFill(); 28857 renderer.render(new Sprite(InitialTexture), { 28858 renderTexture: layer.draw_texture 28859 }); 28860 renderer.render(clear_graphics, { 28861 renderTexture: layer.erase_texture, 28862 clear: true 28863 }); 28864 this.stop(); 28865 has_drawn = false; 28866 } 28867 }; 28868} 28869 28870function click_outside(node, callback) { 28871 const handle_click = (event) => { 28872 if (node && !node.contains(event.target) && !event.defaultPrevented) { 28873 callback(event); 28874 } 28875 }; 28876 document.addEventListener("mousedown", handle_click, true); 28877 return { 28878 destroy() { 28879 document.removeEventListener("mousedown", handle_click, true); 28880 } 28881 }; 28882} 28883 28884const ColorPicker_svelte_svelte_type_style_lang = ''; 28885 28886/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/ColorPicker.svelte generated by Svelte v4.2.2 */ 28887const { 28888 SvelteComponent: SvelteComponent$e, 28889 append: append$b, 28890 attr: attr$c, 28891 binding_callbacks: binding_callbacks$9, 28892 detach: detach$e, 28893 element: element$c, 28894 init: init$e, 28895 insert: insert$e, 28896 listen: listen$a, 28897 noop: noop$4, 28898 run_all: run_all$6, 28899 safe_not_equal: safe_not_equal$e, 28900 set_style: set_style$7, 28901 space: space$b 28902} = window.__gradio__svelte__internal; 28903const { tick: tick$6 } = window.__gradio__svelte__internal; 28904function create_fragment$e(ctx) { 28905 let div1; 28906 let div0; 28907 let style_transform = `translate(${/*sl_marker_pos*/ ctx[1][0]}px,${/*sl_marker_pos*/ ctx[1][1]}px)`; 28908 let t; 28909 let div3; 28910 let div2; 28911 let style_transform_1 = `translateX(${/*hue_marker_pos*/ ctx[3]}px)`; 28912 let mounted; 28913 let dispose; 28914 28915 return { 28916 c() { 28917 div1 = element$c("div"); 28918 div0 = element$c("div"); 28919 t = space$b(); 28920 div3 = element$c("div"); 28921 div2 = element$c("div"); 28922 attr$c(div0, "class", "marker svelte-90y9cx"); 28923 set_style$7(div0, "transform", style_transform); 28924 set_style$7(div0, "background", /*color*/ ctx[0]); 28925 attr$c(div1, "class", "color-gradient svelte-90y9cx"); 28926 set_style$7(div1, "--hue", /*hue*/ ctx[2]); 28927 attr$c(div2, "class", "marker svelte-90y9cx"); 28928 set_style$7(div2, "background", "hsl(" + /*hue*/ ctx[2] + ", 100%, 50%)"); 28929 set_style$7(div2, "transform", style_transform_1); 28930 attr$c(div3, "class", "hue-slider svelte-90y9cx"); 28931 }, 28932 m(target, anchor) { 28933 insert$e(target, div1, anchor); 28934 append$b(div1, div0); 28935 /*div1_binding*/ ctx[10](div1); 28936 insert$e(target, t, anchor);
28937 insert$e(target, div3, anchor); 28938 append$b(div3, div2); 28939 /*div3_binding*/ ctx[11](div3); 28940 28941 if (!mounted) { 28942 dispose = [ 28943 listen$a(window, "mousemove", /*handle_move*/ ctx[8]), 28944 listen$a(window, "mouseup", /*handle_end*/ ctx[9]), 28945 listen$a(div1, "mousedown", /*handle_sl_down*/ ctx[7]), 28946 listen$a(div3, "mousedown", /*handle_hue_down*/ ctx[6]) 28947 ]; 28948 28949 mounted = true; 28950 } 28951 }, 28952 p(ctx, [dirty]) { 28953 if (dirty & /*sl_marker_pos*/ 2 && style_transform !== (style_transform = `translate(${/*sl_marker_pos*/ ctx[1][0]}px,${/*sl_marker_pos*/ ctx[1][1]}px)`)) { 28954 set_style$7(div0, "transform", style_transform); 28955 } 28956 28957 if (dirty & /*color*/ 1) { 28958 set_style$7(div0, "background", /*color*/ ctx[0]); 28959 } 28960 28961 if (dirty & /*hue*/ 4) { 28962 set_style$7(div1, "--hue", /*hue*/ ctx[2]); 28963 } 28964 28965 if (dirty & /*hue*/ 4) { 28966 set_style$7(div2, "background", "hsl(" + /*hue*/ ctx[2] + ", 100%, 50%)"); 28967 } 28968 28969 if (dirty & /*hue_marker_pos*/ 8 && style_transform_1 !== (style_transform_1 = `translateX(${/*hue_marker_pos*/ ctx[3]}px)`)) { 28970 set_style$7(div2, "transform", style_transform_1); 28971 } 28972 }, 28973 i: noop$4, 28974 o: noop$4, 28975 d(detaching) { 28976 if (detaching) { 28977 detach$e(div1); 28978 detach$e(t); 28979 detach$e(div3); 28980 } 28981 28982 /*div1_binding*/ ctx[10](null); 28983 /*div3_binding*/ ctx[11](null); 28984 mounted = false; 28985 run_all$6(dispose); 28986 } 28987 }; 28988} 28989 28990function hsva_to_rgba(hsva) { 28991 const saturation = hsva.s; 28992 const value = hsva.v; 28993 let chroma = saturation * value; 28994 const hue_by_60 = hsva.h / 60; 28995 let x = chroma * (1 - Math.abs(hue_by_60 % 2 - 1)); 28996 const m = value - chroma; 28997 chroma = chroma + m; 28998 x = x + m; 28999 const index = Math.floor(hue_by_60) % 6; 29000 const red = [chroma, x, m, m, x, chroma][index]; 29001 const green = [x, chroma, chroma, x, m, m][index]; 29002 const blue = [m, m, x, chroma, chroma, x][index]; 29003 return `rgba(${red * 255}, ${green * 255}, ${blue * 255}, ${hsva.a}
29003)`; 29004} 29005 29006function instance$e($$self, $$props, $$invalidate) { 29007 let { color = "rgb(255, 255, 255)" } = $$props; 29008 let sl_marker_pos = [0, 0]; 29009 let sl_rect = null; 29010 let sl_moving = false; 29011 let sl = [0, 0]; 29012 let hue = 0; 29013 let hue_marker_pos = 0; 29014 let hue_rect = null; 29015 let hue_moving = false; 29016 29017 function handle_hue_down(event) { 29018 hue_rect = event.currentTarget.getBoundingClientRect(); 29019 hue_moving = true; 29020 update_hue_from_mouse(event.clientX); 29021 } 29022 29023 function update_hue_from_mouse(x) { 29024 if (!hue_rect) return; 29025 const _x = clamp(x - hue_rect.left, 0, hue_rect.width); // Get the x-coordinate relative to the box 29026 $$invalidate(3, hue_marker_pos = _x); 29027 const _hue = _x / hue_rect.width * 360; // Scale the x position to a hue value (0-360) 29028 $$invalidate(2, hue = _hue); 29029 $$invalidate(0, color = hsva_to_rgba({ h: _hue, s: sl[0], v: sl[1], a: 1 })); 29030 } 29031 29032 function update_color_from_mouse(x, y) { 29033 if (!sl_rect) return; 29034 const _x = clamp(x - sl_rect.left, 0, sl_rect.width); 29035 const _y = clamp(y - sl_rect.top, 0, sl_rect.height); 29036 $$invalidate(1, sl_marker_pos = [_x, _y]); 29037 29038 const _hsva = { 29039 h: hue * 1, 29040 s: _x / sl_rect.width, 29041 v: 1 - _y / sl_rect.height, 29042 a: 1 29043 }; 29044 29045 sl = [_hsva.s, _hsva.v]; 29046 $$invalidate(0, color = hsva_to_rgba(_hsva)); 29047 } 29048 29049 function handle_sl_down(event) { 29050 sl_moving = true; 29051 sl_rect = event.currentTarget.getBoundingClientRect(); 29052 update_color_from_mouse(event.clientX, event.clientY); 29053 } 29054 29055 function handle_move(event) { 29056 if (sl_moving) update_color_from_mouse(event.clientX, event.clientY); 29057 if (hue_moving) update_hue_from_mouse(event.clientX); 29058 } 29059 29060 function handle_end() { 29061 if (sl_moving) sl_moving = false; 29062 if (hue_moving) hue_moving = false; 29063 } 29064 29065 async function update_mouse_from_color(color) { 29066 if (sl_moving || hue_moving) return; 29067 await tick$6(); 29068 if (!color) return; 29069 29070 if (!sl_rect) { 29071 sl_rect = sl_wrap.getBoundingClientRect(); 29072 } 29073 29074 if (!hue_rect) { 29075 hue_rect = hue_wrap.getBoundingClientRect(); 29076 } 29077 29078 const hsva = tinycolor(color).toHsv(); 29079 const _x = hsva.s * sl_rect.width;
29080 const _y = (1 - hsva.v) * sl_rect.height; 29081 $$invalidate(1, sl_marker_pos = [_x, _y]); 29082 sl = [hsva.s, hsva.v]; 29083 $$invalidate(2, hue = hsva.h); 29084 $$invalidate(3, hue_marker_pos = hsva.h / 360 * hue_rect.width); 29085 } 29086 29087 let sl_wrap; 29088 let hue_wrap; 29089 29090 function div1_binding($$value) { 29091 binding_callbacks$9[$$value ? 'unshift' : 'push'](() => { 29092 sl_wrap = $$value; 29093 $$invalidate(4, sl_wrap); 29094 }); 29095 } 29096 29097 function div3_binding($$value) { 29098 binding_callbacks$9[$$value ? 'unshift' : 'push'](() => { 29099 hue_wrap = $$value; 29100 $$invalidate(5, hue_wrap); 29101 }); 29102 } 29103 29104 $$self.$$set = $$props => { 29105 if ('color' in $$props) $$invalidate(0, color = $$props.color); 29106 }; 29107 29108 $$self.$$.update = () => { 29109 if ($$self.$$.dirty & /*color*/ 1) { 29110 update_mouse_from_color(color); 29111 } 29112 }; 29113 29114 return [ 29115 color, 29116 sl_marker_pos, 29117 hue, 29118 hue_marker_pos, 29119 sl_wrap, 29120 hue_wrap, 29121 handle_hue_down, 29122 handle_sl_down, 29123 handle_move, 29124 handle_end, 29125 div1_binding, 29126 div3_binding 29127 ]; 29128} 29129 29130class ColorPicker extends SvelteComponent$e { 29131 constructor(options) { 29132 super(); 29133 init$e(this, options, instance$e, create_fragment$e, safe_not_equal$e, { color: 0 }); 29134 } 29135} 29136 29137const ColorSwatch_svelte_svelte_type_style_lang = ''; 29138 29139/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/ColorSwatch.svelte generated by Svelte v4.2.2 */ 29140const { 29141 SvelteComponent: SvelteComponent$d, 29142 append: append$a, 29143 attr: attr$b, 29144 destroy_each: destroy_each$2, 29145 detach: detach$d, 29146 element: element$b, 29147 ensure_array_like: ensure_array_like$3, 29148 init: init$d, 29149 insert: insert$d, 29150 listen: listen$9, 29151 noop: noop$3, 29152 safe_not_equal: safe_not_equal$d, 29153 set_style: set_style$6, 29154 space: space$a, 29155 toggle_class: toggle_class$6 29156} = window.__gradio__svelte__internal;const { createEventDispatcher: createEventDispatcher$8 } = window.__gradio__svelte__internal; 29157function get_each_context$3(ctx, list, i) { 29158 const child_ctx = ctx.slice(); 29159 child_ctx[14] = list[i]; 29160 child_ctx[16] = i; 29161 return child_ctx; 29162} 29163 29164function get_each_context_1$1(ctx, list, i) { 29165 const child_ctx = ctx.slice(); 29166 child_ctx[14] = list[i]; 29167 child_ctx[16] = i; 29168 return child_ctx; 29169} 29170 29171// (32:0) {#if user_colors} 29172function create_if_block$9(ctx) { 29173 let div; 29174 let t; 29175 let button; 29176 let mounted; 29177 let dispose; 29178 let each_value_1 = ensure_array_like$3(/*user_colors*/ ctx[1]); 29179 let each_blocks = []; 29180 29181 for (let i = 0; i < each_value_1.length; i += 1) { 29182 each_blocks[i] = create_each_block_1$1(get_each_context_1$1(ctx, each_value_1, i)); 29183 } 29184 29185 return { 29186 c() { 29187 div = element$b("div"); 29188 29189 for (let i = 0; i < each_blocks.length; i += 1) { 29190 each_blocks[i].c(); 29191 } 29192 29193 t = space$a(); 29194 button = element$b("button"); 29195 attr$b(button, "class", "color colorpicker svelte-1kud5by"); 29196 toggle_class$6(button, "hidden", !/*color_picker*/ ctx[0]); 29197 attr$b(div, "class", "swatch svelte-1kud5by"); 29198 }, 29199 m(target, anchor) { 29200 insert$d(target, div, anchor); 29201 29202 for (let i = 0; i < each_blocks.length; i += 1) { 29203 if (each_blocks[i]) { 29204 each_blocks[i].m(div, null); 29205 } 29206 } 29207 29208 append$a(div, t); 29209 append$a(div, button); 29210 29211 if (!mounted) { 29212 dispose = listen$9(button, "click", /*handle_picker_click*/ ctx[5]); 29213 mounted = true; 29214 } 29215 }, 29216 p(ctx, dirty) { 29217 if (dirty & /*user_colors, current_index, handle_select*/ 22) { 29218 each_value_1 = ensure_array_like$3(/*user_colors*/ ctx[1]); 29219 let i; 29220 29221 for (i = 0; i < each_value_1.length; i += 1) { 29222 const child_ctx = get_each_context_1$1(ctx, each_value_1, i); 29223 29224 if (each_blocks[i]) { 29225 each_blocks[i].p(child_ctx, dirty); 29226 } else { 29227 each_blocks[i] = create_each_block_1$1(child_ctx); 29228 each_blocks[i].c(); 29229 each_blocks[i].m(div, t); 29230 } 29231 } 29232 29233 for (; i < each_blocks.length; i += 1) { 29234 each_blocks[i].d(1); 29235 } 29236 29237 each_blocks.length = each_value_1.length; 29238 } 29239 29240 if (dirty & /*color_picker*/ 1) { 29241 toggle_class$6(button, "hidden", !/*color_picker*/ ctx[0]); 29242 } 29243 }, 29244 d(detaching) { 29245 if (detaching) { 29246 detach$d(div); 29247 } 29248 29249 destroy_each$2(each_blocks, detaching); 29250 mounted = false; 29251 dispose(); 29252 } 29253 }; 29254} 29255 29256// (34:2) {#each user_colors as color, i} 29257function create_each_block_1$1(ctx) { 29258 let button; 29259 let mounted; 29260 let dispose; 29261 29262 function click_handler() { 29263 return /*click_handler*/ ctx[10](/*i*/ ctx[16], /*color*/ ctx[14]); 29264 } 29265 29266 return { 29267 c() { 29268 button = element$b("button"); 29269 attr$b(button, "class", "color svelte-1kud5by"); 29270 set_style$6(button, "background-color", /*color*/ ctx[14]); 29271 toggle_class$6(button, "empty", /*color*/ ctx[14] === null); 29272 toggle_class$6(button, "selected", `edit-${/*i*/ ctx[16]}` === /*current_index*/ ctx[2]); 29273 }, 29274 m(target, anchor) { 29275 insert$d(target, button, anchor); 29276 29277 if (!mounted) { 29278 dispose = listen$9(button, "click", click_handler); 29279 mounted = true; 29280 } 29281 }, 29282 p(new_ctx, dirty) { 29283 ctx = new_ctx; 29284
29285 if (dirty & /*user_colors*/ 2) { 29286 set_style$6(button, "background-color", /*color*/ ctx[14]); 29287 } 29288 29289 if (dirty & /*user_colors*/ 2) { 29290 toggle_class$6(button, "empty", /*color*/ ctx[14] === null); 29291 } 29292 29293 if (dirty & /*current_index*/ 4) { 29294 toggle_class$6(button, "selected", `edit-${/*i*/ ctx[16]}` === /*current_index*/ ctx[2]); 29295 } 29296 }, 29297 d(detaching) { 29298 if (detaching) { 29299 detach$d(button); 29300 } 29301 29302 mounted = false; 29303 dispose(); 29304 } 29305 }; 29306} 29307 29308// (52:1) {#each _colors as color, i} 29309function create_each_block$3(ctx) { 29310 let button; 29311 let mounted; 29312 let dispose; 29313 29314 function click_handler_1() { 29315 return /*click_handler_1*/ ctx[11](/*i*/ ctx[16], /*color*/ ctx[14]); 29316 } 29317 29318 return { 29319 c() { 29320 button = element$b("button"); 29321 attr$b(button, "class", "color svelte-1kud5by"); 29322 set_style$6(button, "background-color", /*color*/ ctx[14]); 29323 toggle_class$6(button, "empty", /*color*/ ctx[14] === null); 29324 toggle_class$6(button, "selected", `select-${/*i*/ ctx[16]}` === /*current_index*/ ctx[2]); 29325 }, 29326 m(target, anchor) { 29327 insert$d(target, button, anchor); 29328 29329 if (!mounted) { 29330 dispose = listen$9(button, "click", click_handler_1); 29331 mounted = true; 29332 } 29333 }, 29334 p(new_ctx, dirty) { 29335 ctx = new_ctx; 29336 29337 if (dirty & /*_colors*/ 8) { 29338 set_style$6(button, "background-color", /*color*/ ctx[14]); 29339 } 29340 29341 if (dirty & /*_colors*/ 8) { 29342 toggle_class$6(button, "empty", /*color*/ ctx[14] === null); 29343 } 29344 29345 if (dirty & /*current_index*/ 4) { 29346 toggle_class$6(button, "selected", `select-${/*i*/ ctx[16]}` === /*current_index*/ ctx[2]); 29347 } 29348 }, 29349 d(detaching) { 29350 if (detaching) { 29351 detach$d(button); 29352 } 29353 29354 mounted = false; 29355 dispose(); 29356 } 29357 }; 29358} 29359 29360function create_fragment$d(ctx) { 29361 let t; 29362 let menu; 29363 let if_block = /*user_colors*/ ctx[1] && create_if_block$9(ctx); 29364 let each_value = ensure_array_like$3(/*_colors*/ ctx[3]); 29365 let each_blocks = []; 29366 29367 for (let i = 0; i < each_value.length; i += 1) { 29368 each_blocks[i] = create_each_block$3(get_each_context$3(ctx, each_value, i)); 29369 } 29370 29371 return { 29372 c() { 29373 if (if_block) if_block.c(); 29374 t = space$a(); 29375 menu = element$b("menu"); 29376 29377 for (let i = 0; i < each_blocks.length; i += 1) { 29378 each_blocks[i].c(); 29379 } 29380 29381 attr$b(menu, "class", "swatch svelte-1kud5by"); 29382 }, 29383 m(target, anchor) { 29384 if (if_block) if_block.m(target, anchor); 29385 insert$d(target, t, anchor); 29386 insert$d(target, menu, anchor); 29387 29388 for (let i = 0; i < each_blocks.length; i += 1) { 29389 if (each_blocks[i]) { 29390 each_blocks[i].m(menu, null); 29391 } 29392 } 29393 }, 29394 p(ctx, [dirty]) { 29395 if (/*user_colors*/ ctx[1]) { 29396 if (if_block) { 29397 if_block.p(ctx, dirty); 29398 } else { 29399 if_block = create_if_block$9(ctx); 29400 if_block.c(); 29401 if_block.m(t.parentNode, t); 29402 } 29403 } else if (if_block) { 29404 if_block.d(1); 29405 if_block = null; 29406 } 29407 29408 if (dirty & /*_colors, current_index, handle_select*/ 28) { 29409 each_value = ensure_array_like$3(/*_colors*/ ctx[3]); 29410 let i; 29411 29412 for (i = 0; i < each_value.length; i += 1) { 29413 const child_ctx = get_each_context$3(ctx, each_value, i); 29414 29415 if (each_blocks[i]) { 29416 each_blocks[i].p(child_ctx, dirty); 29417 } else { 29418 each_blocks[i] = create_each_block$3(child_ctx); 29419 each_blocks[i].c(); 29420 each_blocks[i].m(menu, null); 29421 } 29422 } 29423 29424 for (; i < each_blocks.length; i += 1) { 29425 each_blocks[i].d(1); 29426 } 29427 29428 each_blocks.length = each_value.length; 29429 } 29430 }, 29431 i: noop$3, 29432 o: noop$3, 29433 d(detaching) { 29434 if (detaching) { 29435 detach$d(t); 29436 detach$d(menu); 29437 } 29438 29439 if (if_block) if_block.d(detaching); 29440 destroy_each$2(each_blocks, detaching); 29441 } 29442 }; 29443} 29444 29445function instance$d($$self, $$props, $$invalidate) { 29446 let _colors; 29447 let { selected_color } = $$props; 29448 let { colors } = $$props; 29449 let { user_colors = [] } = $$props; 29450 let { show_empty = false } = $$props; 29451 let { current_mode = "hex" } = $$props; 29452 let { color_picker = false } = $$props; 29453 const dispatch = createEventDispatcher$8(); 29454 29455 function get_formatted_color(color, mode) { 29456 if (mode === "hex") { 29457 return tinycolor(color).toHexString(); 29458 } else if (mode === "rgb") { 29459 return tinycolor(color).toRgbString(); 29460 } 29461 29462 return tinycolor(color).toHslString(); 29463 } 29464 29465 let current_index = `select-${colors.findIndex(c => get_formatted_color(c, current_mode) === get_formatted_color(selected_color, current_mode))}`; 29466 29467 function handle_select(type, detail) {
29468 $$invalidate(2, current_index = `${type}-${detail.index}`); 29469 dispatch(type, detail); 29470 } 29471 29472 function handle_picker_click() { 29473 dispatch("select", { index: null, color: selected_color }); 29474 $$invalidate(0, color_picker = !color_picker); 29475 } 29476 29477 const click_handler = (i, color) => handle_select("edit", { index: i, color }); 29478 const click_handler_1 = (i, color) => handle_select("select", { index: i, color }); 29479 29480 $$self.$$set = $$props => { 29481 if ('selected_color' in $$props) $$invalidate(6, selected_color = $$props.selected_color); 29482 if ('colors' in $$props) $$invalidate(7, colors = $$props.colors); 29483 if ('user_colors' in $$props) $$invalidate(1, user_colors = $$props.user_colors); 29484 if ('show_empty' in $$props) $$invalidate(8, show_empty = $$props.show_empty); 29485 if ('current_mode' in $$props) $$invalidate(9, current_mode = $$props.current_mode); 29486 if ('color_picker' in $$props) $$invalidate(0, color_picker = $$props.color_picker); 29487 }; 29488 29489 $$self.$$.update = () => { 29490 if ($$self.$$.dirty & /*show_empty, colors*/ 384) { 29491 $$invalidate(3, _colors = show_empty ? colors : colors.filter(c => c)); 29492 } 29493 }; 29494 29495 return [ 29496 color_picker, 29497 user_colors, 29498 current_index, 29499 _colors, 29500 handle_select, 29501 handle_picker_click, 29502 selected_color, 29503 colors, 29504 show_empty, 29505 current_mode, 29506 click_handler, 29507 click_handler_1 29508 ]; 29509} 29510 29511class ColorSwatch extends SvelteComponent$d { 29512 constructor(options) { 29513 super(); 29514 29515 init$d(this, options, instance$d, create_fragment$d, safe_not_equal$d, { 29516 selected_color: 6, 29517 colors: 7, 29518 user_colors: 1, 29519 show_empty: 8, 29520 current_mode: 9, 29521 color_picker: 0 29522 }); 29523 } 29524} 29525 29526const ColorField_svelte_svelte_type_style_lang = ''; 29527 29528/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/ColorField.svelte generated by Svelte v4.2.2 */ 29529const { 29530 SvelteComponent: SvelteComponent$c, 29531 append: append$9, 29532 attr: attr$a, 29533 create_component: create_component$a, 29534 destroy_component: destroy_component$a, 29535 destroy_each: destroy_each$1, 29536 detach: detach$c, 29537 element: element$a, 29538 ensure_array_like: ensure_array_like$2, 29539 init: init$c, 29540 insert: insert$c, 29541 listen: listen$8, 29542 mount_component: mount_component$a, 29543 run_all: run_all$5, 29544 safe_not_equal: safe_not_equal$c, 29545 set_style: set_style$5, 29546 space: space$9, 29547 toggle_class: toggle_class$5, 29548 transition_in: transition_in$a, 29549 transition_out: transition_out$a 29550} = window.__gradio__svelte__internal;const { createEventDispatcher: createEventDispatcher$7 } = window.__gradio__svelte__internal; 29551function get_each_context$2(ctx, list, i) { 29552 const child_ctx = ctx.slice(); 29553 child_ctx[11] = list[i][0]; 29554 child_ctx[12] = list[i][1]; 29555 return child_ctx; 29556} 29557 29558// (50:4) {#if eyedropper_supported} 29559function create_if_block$8(ctx) { 29560 let eyedropper; 29561 let current; 29562 eyedropper = new Eyedropper({}); 29563 29564 return { 29565 c() { 29566 create_component$a(eyedropper.$$.fragment); 29567 }, 29568 m(target, anchor) { 29569 mount_component$a(eyedropper, target, anchor); 29570 current = true; 29571 }, 29572 i(local) { 29573 if (current) return; 29574 transition_in$a(eyedropper.$$.fragment, local); 29575 current = true; 29576 }, 29577 o(local) { 29578 transition_out$a(eyedropper.$$.fragment, local); 29579 current = false; 29580 }, 29581 d(detaching) { 29582 destroy_component$a(eyedropper, detaching); 29583 } 29584 }; 29585} 29586 29587// (56:3) {#each modes as [label, value]} 29588function create_each_block$2(ctx) { 29589 let button; 29590 let mounted; 29591 let dispose; 29592 29593 function click_handler() { 29594 return /*click_handler*/ ctx[8](/*value*/ ctx[12]); 29595 } 29596 29597 return { 29598 c() { 29599 button = element$a("button"); 29600 button.textContent = `${/*label*/ ctx[11]}`; 29601 attr$a(button, "class", "button svelte-w84deg"); 29602 toggle_class$5(button, "active", /*current_mode*/ ctx[1] === /*value*/ ctx[12]); 29603 }, 29604 m(target, anchor) { 29605 insert$c(target, button, anchor); 29606 29607 if (!mounted) { 29608 dispose = listen$8(button, "click", click_handler); 29609 mounted = true; 29610 } 29611 }, 29612 p(new_ctx, dirty) { 29613 ctx = new_ctx; 29614 29615 if (dirty & /*current_mode, modes*/ 10) { 29616 toggle_class$5(button, "active", /*current_mode*/ ctx[1] === /*value*/ ctx[12]); 29617 } 29618 }, 29619 d(detaching) { 29620 if (detaching) { 29621 detach$c(button); 29622 } 29623 29624 mounted = false; 29625 dispose(); 29626 } 29627 }; 29628} 29629 29630function create_fragment$c(ctx) { 29631 let div3; 29632 let button0; 29633 let t0; 29634 let div2; 29635 let div0; 29636 let input; 29637 let t1; 29638 let button1; 29639 let t2; 29640 let div1; 29641 let current; 29642 let mounted; 29643 let dispose; 29644 let if_block = /*eyedropper_supported*/ ctx[5] && create_if_block$8(
29644); 29645 let each_value = ensure_array_like$2(/*modes*/ ctx[3]); 29646 let each_blocks = []; 29647 29648 for (let i = 0; i < each_value.length; i += 1) { 29649 each_blocks[i] = create_each_block$2(get_each_context$2(ctx, each_value, i)); 29650 } 29651 29652 return { 29653 c() { 29654 div3 = element$a("div"); 29655 button0 = element$a("button"); 29656 t0 = space$9(); 29657 div2 = element$a("div"); 29658 div0 = element$a("div"); 29659 input = element$a("input"); 29660 t1 = space$9(); 29661 button1 = element$a("button"); 29662 if (if_block) if_block.c(); 29663 t2 = space$9(); 29664 div1 = element$a("div"); 29665 29666 for (let i = 0; i < each_blocks.length; i += 1) { 29667 each_blocks[i].c(); 29668 } 29669 29670 attr$a(button0, "class", "swatch svelte-w84deg"); 29671 set_style$5(button0, "background", /*color*/ ctx[0]); 29672 attr$a(input, "type", "text"); 29673 input.value = /*color_string*/ ctx[2]; 29674 attr$a(input, "class", "svelte-w84deg"); 29675 attr$a(button1, "class", "eyedropper svelte-w84deg"); 29676 attr$a(div0, "class", "input-wrap svelte-w84deg"); 29677 attr$a(div1, "class", "buttons svelte-w84deg"); 29678 attr$a(div3, "class", "input svelte-w84deg"); 29679 }, 29680 m(target, anchor) { 29681 insert$c(target, div3, anchor); 29682 append$9(div3, button0); 29683 append$9(div3, t0); 29684 append$9(div3, div2); 29685 append$9(div2, div0); 29686 append$9(div0, input); 29687 append$9(div0, t1); 29688 append$9(div0, button1); 29689 if (if_block) if_block.m(button1, null); 29690 append$9(div2, t2); 29691 append$9(div2, div1); 29692 29693 for (let i = 0; i < each_blocks.length; i += 1) { 29694 if (each_blocks[i]) { 29695 each_blocks[i].m(div1, null); 29696 } 29697 } 29698 29699 current = true; 29700 29701 if (!mounted) { 29702 dispose = [ 29703 listen$8(button0, "click", /*handle_click*/ ctx[6]), 29704 listen$8(input, "change", /*change_handler*/ ctx[7]), 29705 listen$8(button1, "click", /*request_eyedropper*/ ctx[4]) 29706 ]; 29707 29708 mounted = true; 29709 } 29710 }, 29711 p(ctx, [dirty]) { 29712 if (dirty & /*color*/ 1) { 29713 set_style$5(button0, "background", /*color*/ ctx[0]); 29714 } 29715 29716 if (!current || dirty & /*color_string*/ 4 && input.value !== /*color_string*/ ctx[2]) { 29717 input.value = /*color_string*/ ctx[2]; 29718 } 29719 29720 if (dirty & /*current_mode, modes*/ 10) { 29721 each_value = ensure_array_like$2(/*modes*/ ctx[3]); 29722 let i; 29723 29724 for (i = 0; i < each_value.length; i += 1) { 29725 const child_ctx = get_each_context$2(ctx, each_value, i); 29726 29727 if (each_blocks[i]) { 29728 each_blocks[i].p(child_ctx, dirty); 29729 } else { 29730 each_blocks[i] = create_each_block$2(child_ctx); 29731 each_blocks[i].c(); 29732 each_blocks[i].m(div1, null); 29733 } 29734 } 29735 29736 for (; i < each_blocks.length; i += 1) { 29737 each_blocks[i].d(1); 29738 } 29739 29740 each_blocks.length = each_value.length; 29741 } 29742 }, 29743 i(local) { 29744 if (current) return; 29745 transition_in$a(if_block); 29746 current = true; 29747 }, 29748 o(local) { 29749 transition_out$a(if_block); 29750 current = false; 29751 }, 29752 d(detaching) { 29753 if (detaching) { 29754 detach$c(div3); 29755 } 29756 29757 if (if_block) if_block.d(); 29758 destroy_each$1(each_blocks, detaching); 29759 mounted = false; 29760 run_all$5(dispose); 29761 } 29762 }; 29763} 29764 29765function instance$c($$self, $$props, $$invalidate) { 29766 let color_string; 29767 let { color } = $$props; 29768 let { current_mode = "hex" } = $$props; 29769 const dispatch = createEventDispatcher$7(); 29770 const modes = [["Hex", "hex"], ["RGB", "rgb"], ["HSL", "hsl"]]; 29771 29772 function format_color(color, mode) { 29773 if (mode === "hex") { 29774 return tinycolor(color).toHexString(); 29775 } else if (mode === "rgb") { 29776 return tinycolor(color).toRgbString(); 29777 } 29778 29779 return tinycolor(color).toHslString(); 29780 } 29781 29782 function request_eyedropper() { 29783 // @ts-ignore 29784 const eyeDropper = new EyeDropper(); 29785 29786 eyeDropper.open().then(result => { 29787 $$invalidate(0, color = result.sRGBHex); 29788 }); 29789 } 29790 29791 //@ts-ignore 29792 const eyedropper_supported = !!window.EyeDropper; 29793 29794 function handle_click() { 29795 dispatch("selected", color_string); 29796 dispatch("close"); 29797 } 29798 29799 const change_handler = e => $$invalidate(0, color = e.currentTarget.value); 29800 const click_handler = value => $$invalidate(1, current_mode = value); 29801 29802 $$self.$$set = $$props => {
29803 if ('color' in $$props) $$invalidate(0, color = $$props.color); 29804 if ('current_mode' in $$props) $$invalidate(1, current_mode = $$props.current_mode); 29805 }; 29806 29807 $$self.$$.update = () => { 29808 if ($$self.$$.dirty & /*color, current_mode*/ 3) { 29809 $$invalidate(2, color_string = format_color(color, current_mode)); 29810 } 29811 29812 if ($$self.$$.dirty & /*color_string*/ 4) { 29813 color_string && dispatch("selected", color_string); 29814 } 29815 }; 29816 29817 return [ 29818 color, 29819 current_mode, 29820 color_string, 29821 modes, 29822 request_eyedropper, 29823 eyedropper_supported, 29824 handle_click, 29825 change_handler, 29826 click_handler 29827 ]; 29828} 29829 29830class ColorField extends SvelteComponent$c { 29831 constructor(options) { 29832 super(); 29833 init$c(this, options, instance$c, create_fragment$c, safe_not_equal$c, { color: 0, current_mode: 1 }); 29834 } 29835} 29836 29837const BrushColor_svelte_svelte_type_style_lang = ''; 29838 29839/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/BrushColor.svelte generated by Svelte v4.2.2 */ 29840const { 29841 SvelteComponent: SvelteComponent$b, 29842 action_destroyer: action_destroyer$2, 29843 add_flush_callback: add_flush_callback$3, 29844 add_iframe_resize_listener: add_iframe_resize_listener$1, 29845 add_render_callback: add_render_callback$1, 29846 append: append$8, 29847 attr: attr$9, 29848 bind: bind$3, 29849 binding_callbacks: binding_callbacks$8, 29850 check_outros: check_outros$7, 29851 create_component: create_component$9, 29852 destroy_component: destroy_component$9, 29853 detach: detach$b, 29854 element: element$9, 29855 empty: empty$5, 29856 group_outros: group_outros$7, 29857 init: init$b, 29858 insert: insert$b, 29859 listen: listen$7, 29860 mount_component: mount_component$9, 29861 run_all: run_all$4, 29862 safe_not_equal: safe_not_equal$b, 29863 space: space$8, 29864 toggle_class: toggle_class$4, 29865 transition_in: transition_in$9, 29866 transition_out: transition_out$9 29867} = window.__gradio__svelte__internal; 29868const { createEventDispatcher: createEventDispatcher$6 } = window.__gradio__svelte__internal; 29869function create_if_block$7(ctx) { 29870 let if_block_anchor; 29871 let current; 29872 let if_block = /*color_picker*/ ctx[9] && create_if_block_1$3(ctx); 29873 29874 return { 29875 c() { 29876 if (if_block) if_block.c(); 29877 if_block_anchor = empty$5(); 29878 }, 29879 m(target, anchor) { 29880 if (if_block) if_block.m(target, anchor); 29881 insert$b(target, if_block_anchor, anchor); 29882 current = true; 29883 }, 29884 p(ctx, dirty) { 29885 if (/*color_picker*/ ctx[9]) { 29886 if (if_block) { 29887 if_block.p(ctx, dirty); 29888 29889 if (dirty & /*color_picker*/ 512) { 29890 transition_in$9(if_block, 1); 29891 } 29892 } else { 29893 if_block = create_if_block_1$3(ctx); 29894 if_block.c(); 29895 transition_in$9(if_block, 1); 29896 if_block.m(if_block_anchor.parentNode, if_block_anchor); 29897 } 29898 } else if (if_block) { 29899 group_outros$7(); 29900 29901 transition_out$9(if_block, 1, 1, () => { 29902 if_block = null; 29903 }); 29904 29905 check_outros$7(); 29906 } 29907 }, 29908 i(local) { 29909 if (current) return; 29910 transition_in$9(if_block); 29911 current = true; 29912 }, 29913 o(local) { 29914 transition_out$9(if_block); 29915 current = false; 29916 }, 29917 d(detaching) { 29918 if (detaching) { 29919 detach$b(if_block_anchor); 29920 } 29921 29922 if (if_block) if_block.d(detaching); 29923 } 29924 }; 29925} 29926 29927// (63:2) {#if color_picker} 29928function create_if_block_1$3(ctx) { 29929 let colorpicker; 29930 let updating_color; 29931 let t; 29932 let colorfield; 29933 let updating_current_mode; 29934 let current; 29935 29936 function colorpicker_color_binding(value) { 29937 /*colorpicker_color_binding*/ ctx[16](value); 29938 } 29939 29940 let colorpicker_props = {}; 29941 29942 if (/*selected_color*/ ctx[0] !== void 0) { 29943 colorpicker_props.color = /*selected_color*/ ctx[0]; 29944 } 29945 29946 colorpicker = new ColorPicker({ props: colorpicker_props }); 29947 binding_callbacks$8.push(() => bind$3(colorpicker, 'color', colorpicker_color_binding)); 29948 29949 function colorfield_current_mode_binding(value) { 29950 /*colorfield_current_mode_binding*/ ctx[17](value); 29951 } 29952 29953 let colorfield_props = { color: /*selected_color*/ ctx[0] }; 29954 29955 if (/*current_mode*/ ctx[10] !== void 0) { 29956 colorfield_props.current_mode = /*current_mode*/ ctx[10]; 29957 } 29958 29959 colorfield = new ColorField({ props: colorfield_props }); 29960 binding_callbacks$8.push(() => bind$3(colorfield, 'current_mode', colorfield_current_mode_binding)); 29961 colorfield.$on("close", /*close_handler*/ ctx[18]); 29962 colorfield.$on("selected", /*selected_handler*/ ctx[19]); 29963 29964 return { 29965 c() { 29966 create_component$9(colorpicker.$$.fragment); 29967 t = space$8(); 29968 create_component$9(colorfield.$$.fragment); 29969 }, 29970 m(target, anchor) { 29971 mount_component$9(colorpicker, target, anchor); 29972 insert$b(target, t, anchor);
29973 mount_component$9(colorfield, target, anchor); 29974 current = true; 29975 }, 29976 p(ctx, dirty) { 29977 const colorpicker_changes = {}; 29978 29979 if (!updating_color && dirty & /*selected_color*/ 1) { 29980 updating_color = true; 29981 colorpicker_changes.color = /*selected_color*/ ctx[0]; 29982 add_flush_callback$3(() => updating_color = false); 29983 } 29984 29985 colorpicker.$set(colorpicker_changes); 29986 const colorfield_changes = {}; 29987 if (dirty & /*selected_color*/ 1) colorfield_changes.color = /*selected_color*/ ctx[0]; 29988 29989 if (!updating_current_mode && dirty & /*current_mode*/ 1024) { 29990 updating_current_mode = true; 29991 colorfield_changes.current_mode = /*current_mode*/ ctx[10]; 29992 add_flush_callback$3(() => updating_current_mode = false); 29993 } 29994 29995 colorfield.$set(colorfield_changes); 29996 }, 29997 i(local) { 29998 if (current) return; 29999 transition_in$9(colorpicker.$$.fragment, local); 30000 transition_in$9(colorfield.$$.fragment, local); 30001 current = true; 30002 }, 30003 o(local) { 30004 transition_out$9(colorpicker.$$.fragment, local); 30005 transition_out$9(colorfield.$$.fragment, local); 30006 current = false; 30007 }, 30008 d(detaching) { 30009 if (detaching) { 30010 detach$b(t); 30011 } 30012 30013 destroy_component$9(colorpicker, detaching); 30014 destroy_component$9(colorfield, detaching); 30015 } 30016 }; 30017} 30018 30019function create_fragment$b(ctx) { 30020 let div; 30021 let t; 30022 let colorswatch; 30023 let updating_color_picker; 30024 let div_resize_listener; 30025 let current; 30026 let mounted; 30027 let dispose; 30028 add_render_callback$1(/*onwindowresize*/ ctx[15]); 30029 let if_block = /*color_mode*/ ctx[3] === "defaults" && create_if_block$7(ctx); 30030 30031 function colorswatch_color_picker_binding(value) { 30032 /*colorswatch_color_picker_binding*/ ctx[20](value); 30033 } 30034 30035 let colorswatch_props = { 30036 colors: /*colors*/ ctx[2], 30037 user_colors: /*color_mode*/ ctx[3] === "defaults" 30038 ? /*recent_colors*/ ctx[1] 30039 : null, 30040 selected_color: /*selected_color*/ ctx[0], 30041 current_mode: /*current_mode*/ ctx[10] 30042 }; 30043 30044 if (/*color_picker*/ ctx[9] !== void 0) { 30045 colorswatch_props.color_picker = /*color_picker*/ ctx[9]; 30046 } 30047 30048 colorswatch = new ColorSwatch({ props: colorswatch_props }); 30049 binding_callbacks$8.push(() => bind$3(colorswatch, 'color_picker', colorswatch_color_picker_binding)); 30050 colorswatch.$on("select", /*select_handler*/ ctx[21]); 30051 colorswatch.$on("edit", /*edit_handler*/ ctx[22]); 30052 30053 return { 30054 c() { 30055 div = element$9("div"); 30056 if (if_block) if_block.c(); 30057 t = space$8(); 30058 create_component$9(colorswatch.$$.fragment); 30059 attr$9(div, "class", "wrap svelte-1pyj3ft"); 30060 add_render_callback$1(() => /*div_elementresize_handler*/ ctx[25].call(div)); 30061 toggle_class$4(div, "padded", !/*color_picker*/ ctx[9]); 30062 toggle_class$4(div, "right", /*anchor_right*/ ctx[11]); 30063 toggle_class$4(div, "top", /*anchor_top*/ ctx[12]); 30064 toggle_class$4(div, "bottom", !/*anchor_top*/ ctx[12]); 30065 }, 30066 m(target, anchor) { 30067 insert$b(target, div, anchor); 30068 if (if_block) if_block.m(div, null); 30069 append$8(div, t); 30070 mount_component$9(colorswatch, div, null); 30071 /*div_binding*/ ctx[24](div); 30072 div_resize_listener = add_iframe_resize_listener$1(div, /*div_elementresize_handler*/ ctx[25].bind(div)); 30073 current = true; 30074 30075 if (!mounted) { 30076 dispose = [ 30077 listen$7(window, "resize", /*onwindowresize*/ ctx[15]), 30078 action_destroyer$2(click_outside.call(null, div, /*click_outside_function*/ ctx[23])) 30079 ]; 30080 30081 mounted = true; 30082 } 30083 }, 30084 p(ctx, [dirty]) { 30085 if (/*color_mode*/ ctx[3] === "defaults") { 30086 if (if_block) { 30087 if_block.p(ctx, dirty); 30088 30089 if (dirty & /*color_mode*/ 8) { 30090 transition_in$9(if_block, 1); 30091 } 30092 } else { 30093 if_block = create_if_block$7(ctx); 30094 if_block.c(); 30095 transition_in$9(if_block, 1); 30096 if_block.m(div, t); 30097 } 30098 } else if (if_block) { 30099 group_outros$7(); 30100 30101 transition_out$9(if_block, 1, 1, () => { 30102 if_block = null; 30103 }); 30104 30105 check_outros$7(); 30106 } 30107 30108 const colorswatch_changes = {}; 30109 if (dirty & /*colors*/ 4) colorswatch_changes.colors = /*colors*/ ctx[2]; 30110 30111 if (dirty & /*color_mode, recent_colors*/ 10) colorswatch_changes.user_colors = /*color_mode*/ ctx[3] === "defaults" 30112 ? /*recent_colors*/ ctx[1] 30113 : null; 30114
30115 if (dirty & /*selected_color*/ 1) colorswatch_changes.selected_color = /*selected_color*/ ctx[0]; 30116 if (dirty & /*current_mode*/ 1024) colorswatch_changes.current_mode = /*current_mode*/ ctx[10]; 30117 30118 if (!updating_color_picker && dirty & /*color_picker*/ 512) { 30119 updating_color_picker = true; 30120 colorswatch_changes.color_picker = /*color_picker*/ ctx[9]; 30121 add_flush_callback$3(() => updating_color_picker = false); 30122 } 30123 30124 colorswatch.$set(colorswatch_changes); 30125 30126 if (!current || dirty & /*color_picker*/ 512) { 30127 toggle_class$4(div, "padded", !/*color_picker*/ ctx[9]); 30128 } 30129 30130 if (!current || dirty & /*anchor_right*/ 2048) { 30131 toggle_class$4(div, "right", /*anchor_right*/ ctx[11]); 30132 } 30133 30134 if (!current || dirty & /*anchor_top*/ 4096) { 30135 toggle_class$4(div, "top", /*anchor_top*/ ctx[12]); 30136 } 30137 30138 if (!current || dirty & /*anchor_top*/ 4096) { 30139 toggle_class$4(div, "bottom", !/*anchor_top*/ ctx[12]); 30140 } 30141 }, 30142 i(local) { 30143 if (current) return; 30144 transition_in$9(if_block); 30145 transition_in$9(colorswatch.$$.fragment, local); 30146 current = true; 30147 }, 30148 o(local) { 30149 transition_out$9(if_block); 30150 transition_out$9(colorswatch.$$.fragment, local); 30151 current = false; 30152 }, 30153 d(detaching) { 30154 if (detaching) { 30155 detach$b(div); 30156 } 30157 30158 if (if_block) if_block.d(); 30159 destroy_component$9(colorswatch); 30160 /*div_binding*/ ctx[24](null); 30161 div_resize_listener();
30162 mounted = false; 30163 run_all$4(dispose); 30164 } 30165 }; 30166} 30167 30168function instance$b($$self, $$props, $$invalidate) { 30169 let { colors } = $$props; 30170 let { selected_color } = $$props; 30171 let { color_mode = undefined } = $$props; 30172 let { recent_colors = [] } = $$props; 30173 let color_picker = false; 30174 let current_mode = "hex"; 30175 let editing_index = null; 30176 const dispatch = createEventDispatcher$6(); 30177 30178 function handle_color_selection({ index, color }, type) { 30179 if (type === "user" && !color) { 30180 editing_index = index; 30181 $$invalidate(9, color_picker = true); 30182 } 30183 30184 if (!color) return; 30185 $$invalidate(0, selected_color = color); 30186 30187 if (type === "core") { 30188 $$invalidate(9, color_picker = false); 30189 } 30190 } 30191 30192 function handle_color_change(color) { 30193 if (editing_index === null) return; 30194 $$invalidate(1, recent_colors[editing_index] = color, recent_colors); 30195 } 30196 30197 let width = 0; 30198 let height = 0; 30199 let c_width = 0; 30200 let c_height = 0; 30201 let wrap_el; 30202 let anchor_right = false; 30203 let anchor_top = false; 30204 30205 function onwindowresize() { 30206 $$invalidate(5, height = window.innerHeight); 30207 $$invalidate(4, width = window.innerWidth); 30208 } 30209 30210 function colorpicker_color_binding(value) { 30211 selected_color = value; 30212 $$invalidate(0, selected_color); 30213 } 30214 30215 function colorfield_current_mode_binding(value) { 30216 current_mode = value; 30217 $$invalidate(10, current_mode); 30218 } 30219 30220 const close_handler = () =>
30220 $$invalidate(9, color_picker = false); 30221 const selected_handler = ({ detail }) => $$invalidate(0, selected_color = detail); 30222 30223 function colorswatch_color_picker_binding(value) { 30224 color_picker = value; 30225 $$invalidate(9, color_picker); 30226 } 30227 30228 const select_handler = ({ detail }) => handle_color_selection(detail, "core"); 30229 const edit_handler = ({ detail }) => handle_color_selection(detail, "user"); 30230 const click_outside_function = () => dispatch("click_outside"); 30231 30232 function div_binding($$value) { 30233 binding_callbacks$8[$$value ? 'unshift' : 'push'](() => { 30234 wrap_el = $$value; 30235 $$invalidate(8, wrap_el); 30236 }); 30237 } 30238 30239 function div_elementresize_handler() { 30240 c_width = this.clientWidth; 30241 c_height = this.clientHeight; 30242 $$invalidate(6, c_width); 30243 $$invalidate(7, c_height); 30244 } 30245 30246 $$self.$$set = $$props => { 30247 if ('colors' in $$props) $$invalidate(2, colors = $$props.colors); 30248 if ('selected_color' in $$props) $$invalidate(0, selected_color = $$props.selected_color); 30249 if ('color_mode' in $$props) $$invalidate(3, color_mode = $$props.color_mode);
30250 if ('recent_colors' in $$props) $$invalidate(1, recent_colors = $$props.recent_colors); 30251 }; 30252 30253 $$self.$$.update = () => { 30254 if ($$self.$$.dirty & /*selected_color*/ 1) { 30255 handle_color_change(selected_color); 30256 } 30257 30258 if ($$self.$$.dirty & /*wrap_el, width, height, c_height, c_width*/ 496) { 30259 { 30260 if (wrap_el && (width || height || c_height || c_width)) { 30261 const box = wrap_el.getBoundingClientRect(); 30262 $$invalidate(11, anchor_right = box.width + 30 > width / 2); 30263 $$invalidate(12, anchor_top = box.y < 80); 30264 } 30265 } 30266 } 30267 }; 30268 30269 return [ 30270 selected_color, 30271 recent_colors, 30272 colors, 30273 color_mode, 30274 width, 30275 height, 30276 c_width, 30277 c_height, 30278 wrap_el, 30279 color_picker, 30280 current_mode, 30281 anchor_right, 30282 anchor_top, 30283 dispatch, 30284 handle_color_selection, 30285 onwindowresize, 30286 colorpicker_color_binding, 30287 colorfield_current_mode_binding, 30288 close_handler, 30289 selected_handler, 30290 colorswatch_color_picker_binding, 30291 select_handler, 30292 edit_handler, 30293 click_outside_function, 30294 div_binding, 30295 div_elementresize_handler 30296 ]; 30297} 30298 30299class BrushColor extends SvelteComponent$b { 30300 constructor(options) { 30301 super(); 30302 30303 init$b(this, options, instance$b, create_fragment$b, safe_not_equal$b, { 30304 colors: 2, 30305 selected_color: 0, 30306 color_mode: 3, 30307 recent_colors: 1 30308 }); 30309 } 30310} 30311 30312const BrushSize_svelte_svelte_type_style_lang = ''; 30313 30314/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/BrushSize.svelte generated by Svelte v4.2.2 */ 30315const { 30316 SvelteComponent: SvelteComponent$a, 30317 action_destroyer: action_destroyer$1, 30318 add_iframe_resize_listener, 30319 add_render_callback, 30320 append: append$7, 30321 attr: attr$8,
30322 binding_callbacks: binding_callbacks$7, 30323 detach: detach$a, 30324 element: element$8, 30325 init: init$a, 30326 insert: insert$a, 30327 listen: listen$6, 30328 noop: noop$2, 30329 run_all: run_all$3, 30330 safe_not_equal: safe_not_equal$a, 30331 set_input_value, 30332 to_number, 30333 toggle_class: toggle_class$3 30334} = window.__gradio__svelte__internal;const { createEventDispatcher: createEventDispatcher$5 } = window.__gradio__svelte__internal; 30335function create_fragment$a(ctx) { 30336 let div; 30337 let input; 30338 let div_resize_listener; 30339 let mounted; 30340 let dispose; 30341 add_render_callback(/*onwindowresize*/ ctx[11]); 30342 30343 return { 30344 c() { 30345 div = element$8("div"); 30346 input = element$8("input"); 30347 attr$8(input, "type", "range"); 30348 attr$8(input, "min", /*min*/ ctx[1]); 30349 attr$8(input, "max", /*max*/ ctx[2]); 30350 attr$8(input, "step", 1); 30351 attr$8(div, "class", "wrap svelte-b3dw9m"); 30352 add_render_callback(() => /*div_elementresize_handler*/ ctx[15].call(div)); 30353 toggle_class$3(div, "right", /*anchor_right*/ ctx[8]); 30354 toggle_class$3(div, "top", /*anchor_top*/ ctx[9]); 30355 toggle_class$3(div, "bottom", !/*anchor_top*/ ctx[9]); 30356 }, 30357 m(target, anchor) { 30358 insert$a(target, div, anchor); 30359 append$7(div, input); 30360 set_input_value(input, /*selected_size*/ ctx[0]); 30361 /*div_binding*/ ctx[14](div); 30362 div_resize_listener = add_iframe_resize_listener(div, /*div_elementresize_handler*/ ctx[15].bind(div)); 30363 30364 if (!mounted) { 30365 dispose = [ 30366 listen$6(window, "resize", /*onwindowresize*/ ctx[11]), 30367 listen$6(input, "change", /*input_change_input_handler*/ ctx[12]), 30368 listen$6(input, "input", /*input_change_input_handler*/ ctx[12]), 30369 action_destroyer$1(click_outside.call(null, div, /*click_outside_function*/ ctx[13])) 30370 ]; 30371 30372 mounted = true; 30373 } 30374 }, 30375 p(ctx, [dirty]) { 30376 if (dirty & /*min*/ 2) { 30377 attr$8(input, "min", /*min*/ ctx[1]); 30378 } 30379 30380 if (dirty & /*max*/ 4) { 30381 attr$8(input, "max", /*max*/ ctx[2]); 30382 } 30383 30384 if (dirty & /*selected_size*/ 1) { 30385 set_input_value(input, /*selected_size*/ ctx[0]); 30386 } 30387 30388 if (dirty & /*anchor_right*/ 256) { 30389 toggle_class$3(div, "right", /*anchor_right*/ ctx[8]); 30390 } 30391 30392 if (dirty & /*anchor_top*/ 512) { 30393 toggle_class$3(div, "top", /*anchor_top*/ ctx[9]); 30394 } 30395 30396 if (dirty & /*anchor_top*/ 512) { 30397 toggle_class$3(div, "bottom", !/*anchor_top*/ ctx[9]); 30398 } 30399 }, 30400 i: noop$2, 30401 o: noop$2, 30402 d(detaching) { 30403 if (detaching) { 30404 detach$a(div); 30405 } 30406 30407 /*div_binding*/ ctx[14](null); 30408 div_resize_listener();
30409 mounted = false; 30410 run_all$3(dispose); 30411 } 30412 }; 30413} 30414 30415function instance$a($$self, $$props, $$invalidate) { 30416 let { selected_size } = $$props; 30417 let { min } = $$props; 30418 let { max } = $$props; 30419 const dispatch = createEventDispatcher$5(); 30420 let width = 0; 30421 let height = 0; 30422 let c_width = 0; 30423 let c_height = 0; 30424 let wrap_el; 30425 let anchor_right = false; 30426 let anchor_top = false; 30427 30428 function onwindowresize() { 30429 $$invalidate(4, height = window.innerHeight); 30430 $$invalidate(3, width = window.innerWidth); 30431 } 30432 30433 function input_change_input_handler() { 30434 selected_size = to_number(this.value); 30435 $$invalidate(0, selected_size); 30436 } 30437 30438 const click_outside_function = () => dispatch("click_outside"); 30439 30440 function div_binding($$value) { 30441 binding_callbacks$7[$$value ? 'unshift' : 'push'](() => { 30442 wrap_el = $$value; 30443 $$invalidate(7, wrap_el); 30444 }); 30445 } 30446 30447 function div_elementresize_handler() { 30448 c_width = this.clientWidth; 30449 c_height = this.clientHeight; 30450 $$invalidate(5, c_width); 30451 $$invalidate(6, c_height); 30452 } 30453 30454 $$self.$$set = $$props => {
30455 if ('selected_size' in $$props) $$invalidate(0, selected_size = $$props.selected_size); 30456 if ('min' in $$props) $$invalidate(1, min = $$props.min); 30457 if ('max' in $$props) $$invalidate(2, max = $$props.max); 30458 }; 30459 30460 $$self.$$.update = () => { 30461 if ($$self.$$.dirty & /*wrap_el, width, height, c_height, c_width*/ 248) { 30462 { 30463 if (wrap_el && (width || height || c_height || c_width)) { 30464 const box = wrap_el.getBoundingClientRect(); 30465 $$invalidate(8, anchor_right = box.width + 30 > width / 2); 30466 $$invalidate(9, anchor_top = box.y < 80); 30467 } 30468 } 30469 } 30470 }; 30471 30472 return [ 30473 selected_size, 30474 min, 30475 max, 30476 width, 30477 height, 30478 c_width, 30479 c_height, 30480 wrap_el, 30481 anchor_right, 30482 anchor_top, 30483 dispatch, 30484 onwindowresize, 30485 input_change_input_handler, 30486 click_outside_function, 30487 div_binding, 30488 div_elementresize_handler 30489 ]; 30490} 30491 30492class BrushSize extends SvelteComponent$a { 30493 constructor(options) { 30494 super(); 30495 init$a(this, options, instance$a, create_fragment$a, safe_not_equal$a, { selected_size: 0, min: 1, max: 2 }); 30496 } 30497} 30498 30499const Brush_svelte_svelte_type_style_lang = ''; 30500 30501/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/Brush.svelte generated by Svelte v4.2.2 */ 30502const { 30503 SvelteComponent: SvelteComponent$9, 30504 add_flush_callback: add_flush_callback$2, 30505 attr: attr$7, 30506 bind: bind$2, 30507 binding_callbacks: binding_callbacks$6, 30508 check_outros: check_outros$6, 30509 component_subscribe: component_subscribe$4, 30510 create_component: create_component$8, 30511 destroy_component: destroy_component$8, 30512 detach: detach$9, 30513 element: element$7, 30514 empty: empty$4, 30515 group_outros: group_outros$6, 30516 init: init$9, 30517 insert: insert$9, 30518 listen: listen$5, 30519 mount_component: mount_component$8, 30520 safe_not_equal: safe_not_equal$9, 30521 set_style: set_style$4, 30522 space: space$7, 30523 transition_in: transition_in$8, 30524 transition_out: transition_out$8 30525} = window.__gradio__svelte__internal;const { getContext: getContext$3, onMount: onMount$4, tick: tick$5 } = window.__gradio__svelte__internal; 30526function create_if_block_1$2(ctx) { 30527 let brushsize; 30528 let updating_selected_size; 30529 let current; 30530 30531 function brushsize_selected_size_binding(value) { 30532 /*brushsize_selected_size_binding*/ ctx[26](value); 30533 } 30534 30535 let brushsize_props = { 30536 max: /*$dimensions*/ ctx[5][0] / 10, 30537 min: 1 30538 }; 30539 30540 if (/*selected_size*/ ctx[3] !== void 0) { 30541 brushsize_props.selected_size = /*selected_size*/ ctx[3]; 30542 } 30543 30544 brushsize = new BrushSize({ props: brushsize_props }); 30545 binding_callbacks$6.push(() => bind$2(brushsize, 'selected_size', brushsize_selected_size_binding)); 30546 brushsize.$on("click_outside", /*click_outside_handler_1*/ ctx[27]); 30547 30548 return { 30549 c() { 30550 create_component$8(brushsize.$$.fragment); 30551 }, 30552 m(target, anchor) { 30553 mount_component$8(brushsize, target, anchor); 30554 current = true; 30555 }, 30556 p(ctx, dirty) { 30557 const brushsize_changes = {}; 30558 if (dirty[0] & /*$dimensions*/ 32) brushsize_changes.max = /*$dimensions*/ ctx[5][0] / 10; 30559 30560 if (!updating_selected_size && dirty[0] & /*selected_size*/ 8) { 30561 updating_selected_size = true; 30562 brushsize_changes.selected_size = /*selected_size*/ ctx[3]; 30563 add_flush_callback$2(() => updating_selected_size = false); 30564 } 30565 30566 brushsize.$set(brushsize_changes); 30567 }, 30568 i(local) { 30569 if (current) return; 30570 transition_in$8(brushsize.$$.fragment, local); 30571 current = true; 30572 }, 30573 o(local) { 30574 transition_out$8(brushsize.$$.fragment, local); 30575 current = false; 30576 }, 30577 d(detaching) { 30578 destroy_component$8(brushsize, detaching); 30579 } 30580 }; 30581} 30582 30583// (180:0) {#if current_option === "color" && colors} 30584function create_if_block$6(ctx) { 30585 let div; 30586 let brushcolor; 30587 let updating_selected_color; 30588 let updating_recent_colors; 30589 let current; 30590 30591 function brushcolor_selected_color_binding(value) { 30592 /*brushcolor_selected_color_binding*/ ctx[23](value); 30593 } 30594 30595 function brushcolor_recent_colors_binding(value) { 30596 /*brushcolor_recent_colors_binding*/ ctx[24](value); 30597 } 30598 30599 let brushcolor_props = { 30600 colors: /*processed_colors*/ ctx[11], 30601 color_mode: /*color_mode*/ ctx[1] 30602 }; 30603 30604 if (/*selected_color*/ ctx[2] !== void 0) { 30605 brushcolor_props.selected_color = /*selected_color*/ ctx[2]; 30606 } 30607 30608 if (/*recent_colors*/ ctx[8] !== void 0) { 30609 brushcolor_props.recent_colors = /*recent_colors*/ ctx[8]; 30610 } 30611 30612 brushcolor = new BrushColor({ props: brushcolor_props }); 30613 binding_callbacks$6.push(() => bind$2(brushcolor, 'selected_color', brushcolor_selected_color_binding)); 30614 binding_callbacks$6.push(() => bind$2(brushcolor, 'recent_colors', brushcolor_recent_colors_binding)); 30615 brushcolor.$on("click_outside", /*click_outside_handler*/ ctx[25]); 30616 30617 return { 30618 c() { 30619 div = element$7("div"); 30620 create_component$8(brushcolor.$$.fragment); 30621 }, 30622 m(target, anchor) { 30623 insert$9(target, div, anchor);
30624 mount_component$8(brushcolor, div, null); 30625 current = true; 30626 }, 30627 p(ctx, dirty) { 30628 const brushcolor_changes = {}; 30629 if (dirty[0] & /*color_mode*/ 2) brushcolor_changes.color_mode = /*color_mode*/ ctx[1]; 30630 30631 if (!updating_selected_color && dirty[0] & /*selected_color*/ 4) { 30632 updating_selected_color = true; 30633 brushcolor_changes.selected_color = /*selected_color*/ ctx[2]; 30634 add_flush_callback$2(() => updating_selected_color = false); 30635 } 30636 30637 if (!updating_recent_colors && dirty[0] & /*recent_colors*/ 256) { 30638 updating_recent_colors = true; 30639 brushcolor_changes.recent_colors = /*recent_colors*/ ctx[8]; 30640 add_flush_callback$2(() => updating_recent_colors = false); 30641 } 30642 30643 brushcolor.$set(brushcolor_changes); 30644 }, 30645 i(local) { 30646 if (current) return; 30647 transition_in$8(brushcolor.$$.fragment, local); 30648 current = true; 30649 }, 30650 o(local) { 30651 transition_out$8(brushcolor.$$.fragment, local); 30652 current = false; 30653 }, 30654 d(detaching) { 30655 if (detaching) { 30656 detach$9(div); 30657 } 30658 30659 destroy_component$8(brushcolor); 30660 } 30661 }; 30662} 30663 30664function create_fragment$9(ctx) { 30665 let span; 30666 let style_transform = `translate(${/*pos*/ ctx[9].x}px, ${/*pos*/ ctx[9].y}px)`; 30667 let style_top = `${/*$editor_box*/ ctx[4].child_top - /*$editor_box*/ ctx[4].parent_top - /*brush_size*/ ctx[10] / 2}px`; 30668 let style_left = `${/*$editor_box*/ ctx[4].child_left - /*$editor_box*/ ctx[4].parent_left - /*brush_size*/ ctx[10] / 2}px`; 30669 let style_width = `${/*brush_size*/ ctx[10]}px`; 30670 let style_height = `${/*brush_size*/ ctx[10]}px`; 30671 let t; 30672 let current_block_type_index; 30673 let if_block; 30674 let if_block_anchor; 30675 let current; 30676 let mounted; 30677 let dispose; 30678 const if_block_creators = [create_if_block$6, create_if_block_1$2]; 30679 const if_blocks = []; 30680 30681 function select_block_type(ctx, dirty) { 30682 if (/*current_option*/ ctx[6] === "color" && /*colors*/ ctx[0]) return 0; 30683 if (/*current_option*/ ctx[6] === "size") return 1; 30684 return -1; 30685 } 30686 30687 if (~(current_block_type_index = select_block_type(ctx))) { 30688 if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); 30689 } 30690 30691 return { 30692 c() { 30693 span = element$7("span"); 30694 t = space$7(); 30695 if (if_block) if_block.c(); 30696 if_block_anchor = empty$4(); 30697 attr$7(span, "class", "svelte-btgkrd"); 30698 set_style$4(span, "transform", style_transform); 30699 set_style$4(span, "top", style_top); 30700 set_style$4(span, "left", style_left); 30701 set_style$4(span, "width", style_width); 30702 set_style$4(span, "height", style_height);
30703 set_style$4(span, "opacity", /*brush_cursor*/ ctx[7] ? 1 : 0); 30704 }, 30705 m(target, anchor) { 30706 insert$9(target, span, anchor); 30707 insert$9(target, t, anchor); 30708 30709 if (~current_block_type_index) { 30710 if_blocks[current_block_type_index].m(target, anchor); 30711 } 30712 30713 insert$9(target, if_block_anchor, anchor); 30714 current = true; 30715 30716 if (!mounted) { 30717 dispose = listen$5(window, "keydown", /*keydown_handler*/ ctx[22]); 30718 mounted = true; 30719 } 30720 }, 30721 p(ctx, dirty) { 30722 if (dirty[0] & /*pos*/ 512 && style_transform !== (style_transform = `translate(${/*pos*/ ctx[9].x}px, ${/*pos*/ ctx[9].y}px)`)) { 30723 set_style$4(span, "transform", style_transform); 30724 } 30725 30726 if (dirty[0] & /*$editor_box, brush_size*/ 1040 && style_top !== (style_top = `${/*$editor_box*/ ctx[4].child_top - /*$editor_box*/ ctx[4].parent_top - /*brush_size*/ ctx[10] / 2}px`)) { 30727 set_style$4(span, "top", style_top); 30728 } 30729 30730 if (dirty[0] & /*$editor_box, brush_size*/ 1040 && style_left !== (style_left = `${/*$editor_box*/ ctx[4].child_left - /*$editor_box*/ ctx[4].parent_left - /*brush_size*/ ctx[10] / 2}px`)) { 30731 set_style$4(span, "left", style_left); 30732 } 30733 30734 if (dirty[0] & /*brush_size*/ 1024 && style_width !== (style_width = `${/*brush_size*/ ctx[10]}px`)) { 30735 set_style$4(span, "width", style_width); 30736 } 30737 30738 if (dirty[0] & /*brush_size*/ 1024 && style_height !== (style_height = `${/*brush_size*/ ctx[10]}px`)) { 30739 set_style$4(span, "height", style_height); 30740 } 30741
30742 if (dirty[0] & /*brush_cursor*/ 128) { 30743 set_style$4(span, "opacity", /*brush_cursor*/ ctx[7] ? 1 : 0); 30744 } 30745 30746 let previous_block_index = current_block_type_index; 30747 current_block_type_index = select_block_type(ctx); 30748 30749 if (current_block_type_index === previous_block_index) { 30750 if (~current_block_type_index) { 30751 if_blocks[current_block_type_index].p(ctx, dirty); 30752 } 30753 } else { 30754 if (if_block) { 30755 group_outros$6(); 30756 30757 transition_out$8(if_blocks[previous_block_index], 1, 1, () => { 30758 if_blocks[previous_block_index] = null; 30759 }); 30760 30761 check_outros$6(); 30762 } 30763 30764 if (~current_block_type_index) { 30765 if_block = if_blocks[current_block_type_index]; 30766 30767 if (!if_block) { 30768 if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); 30769 if_block.c(); 30770 } else { 30771 if_block.p(ctx, dirty); 30772 } 30773 30774 transition_in$8(if_block, 1); 30775 if_block.m(if_block_anchor.parentNode, if_block_anchor); 30776 } else { 30777 if_block = null; 30778 } 30779 } 30780 }, 30781 i(local) { 30782 if (current) return; 30783 transition_in$8(if_block); 30784 current = true; 30785 }, 30786 o(local) { 30787 transition_out$8(if_block); 30788 current = false; 30789 }, 30790 d(detaching) { 30791 if (detaching) { 30792 detach$9(span); 30793 detach$9(t); 30794 detach$9(if_block_anchor); 30795 } 30796 30797 if (~current_block_type_index) { 30798 if_blocks[current_block_type_index].d(detaching); 30799 } 30800 30801 mounted = false; 30802 dispose(); 30803 } 30804 }; 30805} 30806 30807function instance$9($$self, $$props, $$invalidate) { 30808 let brush_size; 30809 let $editor_box; 30810 let $dimensions; 30811 let $active_tool; 30812 let $pixi; 30813 let $crop; 30814 let $current_layer; 30815 let { default_size } = $$props; 30816 let { default_color = undefined } = $$props; 30817 let { colors = undefined } = $$props; 30818 let { color_mode = undefined } = $$props; 30819 let { mode } = $$props; 30820 30821 const processed_colors = colors 30822 ? colors.map(process_color).filter((_, i) => i < 5) 30823 : []; 30824 30825 let selected_color = default_color === "auto" 30826 ? processed_colors[0] 30827 : !default_color ? "black" : process_color(default_color); 30828 30829 const paint_meta = { 30830 color: { 30831 icon: Palette, 30832 label: "Color", 30833 order: 0, 30834 id: "brush_color", 30835 cb() { 30836 $$invalidate(6, current_option = "color"); 30837 } 30838 }, 30839 size: { 30840 icon: BrushSize$1, 30841 label: "Size", 30842 order: 1, 30843 id: "brush_size", 30844 cb() { 30845 $$invalidate(6, current_option = "size"); 30846 } 30847 } 30848 }; 30849 30850 let brush_options; 30851 let current_option = null; 30852 const { pixi, dimensions, current_layer, command_manager, register_context, editor_box, crop } = getContext$3(EDITOR_KEY); 30853 component_subscribe$4($$self, pixi, value => $$invalidate(31, $pixi = value)); 30854 component_subscribe$4($$self, dimensions, value => $$invalidate(5, $dimensions = value)); 30855 component_subscribe$4($$self, current_layer, value => $$invalidate(33, $current_layer = value)); 30856 component_subscribe$4($$self, editor_box, value => $$invalidate(4, $editor_box = value)); 30857 component_subscribe$4($$self, crop, value => $$invalidate(32, $crop = value)); 30858 const { active_tool, register_tool, current_color } = getContext$3(TOOL_KEY); 30859 component_subscribe$4($$self, active_tool, value => $$invalidate(21, $active_tool = value)); 30860 let drawing = false; 30861 let draw; 30862 30863 function generate_sizes(x, y) { 30864 const min = clamp(Math.min(x, y), 500, 1000); 30865 return Math.round(min * 2 / 100); 30866 } 30867 30868 let selected_size = default_size === "auto" 30869 ? generate_sizes(...$dimensions) 30870 : default_size; 30871 30872 function pointer_down_handler(event) { 30873 if ($active_tool !== mode) { 30874 return; 30875 } 30876 30877 drawing = true; 30878 30879 if (!$pixi || !$current_layer) { 30880 return; 30881 } 30882 30883 draw = draw_path($pixi.renderer, $pixi.layer_container, $current_layer, mode); 30884 30885 draw.start({ 30886 x: event.screen.x, 30887 y: event.screen.y, 30888 color: selected_color || undefined, 30889 size: selected_size, 30890 opacity: 1 30891 }); 30892 } 30893 30894 function pointer_up_handler(event) { 30895 if (!$pixi || !$current_layer) { 30896 return; 30897 } 30898 30899 if ($active_tool !== mode) { 30900 return; 30901 } 30902 30903 draw.stop(); 30904 command_manager.execute(draw); 30905 drawing = false; 30906 } 30907 30908 function pointer_move_handler(event) { 30909 if ($active_tool !== mode) { 30910 return; 30911 } 30912 30913 if (drawing) { 30914 draw.continue({ x: event.screen.x, y: event.screen.y }); 30915 } 30916 30917 const x_bound = $crop[0] * $dimensions[0]; 30918 const y_bound = $crop[1] * $dimensions[1]; 30919 30920 if (x_bound > event.screen.x || y_bound > event.screen.y || event.screen.x >
30920 x_bound + $crop[2] * $dimensions[0] || event.screen.y > y_bound + $crop[3] * $dimensions[1]) { 30921 $$invalidate(7, brush_cursor = false); 30922 document.body.style.cursor = "auto"; 30923 } else { 30924 $$invalidate(7, brush_cursor = true); 30925 document.body.style.cursor = "none"; 30926 } 30927 30928 if (brush_cursor) { 30929 $$invalidate(9, pos = { 30930 x: event.clientX - $editor_box.child_left, 30931 y: event.clientY - $editor_box.child_top 30932 }); 30933 } 30934 } 30935 30936 let brush_cursor = false; 30937 30938 async function toggle_listeners(on_off) { 30939 $pixi?.layer_container[on_off]("pointerdown", pointer_down_handler); 30940 $pixi?.layer_container[on_off]("pointerup", pointer_up_handler); 30941 $pixi?.layer_container[on_off]("pointermove", pointer_move_handler); 30942 30943 $pixi?.layer_container[on_off]("pointerenter", event => { 30944 if ($active_tool === mode) { 30945 $$invalidate(7, brush_cursor = true); 30946 document.body.style.cursor = "none"; 30947 } 30948 }); 30949 30950 $pixi?.layer_container[on_off]("pointerleave", () => ($$invalidate(7, brush_cursor = false), document.body.style.cursor = "auto")); 30951 } 30952 30953 register_context(mode, { 30954 init_fn: () => { 30955 toggle_listeners("on"); 30956 }, 30957 reset_fn: () => { 30958 toggle_listeners("off"); 30959 } 30960 }); 30961 30962 onMount$4(() => { 30963 const unregister = register_tool(mode, { default: null, options: brush_options }); 30964 30965 return () => { 30966 unregister(); 30967 toggle_listeners("off"); 30968 }; 30969 }); 30970 30971 let recent_colors = [null, null, null]; 30972 30973 function process_color(color) { 30974 return tinycolor(color).toRgbString(); 30975 } 30976 30977 let pos = { x: 0, y: 0 }; 30978 const keydown_handler = ({ key }) => key === "Escape" && $$invalidate(6, current_option = null); 30979 30980 function brushcolor_selected_color_binding(value) { 30981 selected_color = value; 30982 $$invalidate(2, selected_color); 30983 } 30984 30985 function brushcolor_recent_colors_binding(value) { 30986 recent_colors = value; 30987 $$invalidate(8, recent_colors); 30988 } 30989 30990 const click_outside_handler = () =>
30990 $$invalidate(6, current_option = null); 30991 30992 function brushsize_selected_size_binding(value) { 30993 selected_size = value; 30994 $$invalidate(3, selected_size); 30995 } 30996 30997 const click_outside_handler_1 = () => $$invalidate(6, current_option = null); 30998 30999 $$self.$$set = $$props => { 31000 if ('default_size' in $$props) $$invalidate(18, default_size = $$props.default_size); 31001 if ('default_color' in $$props) $$invalidate(19, default_color = $$props.default_color); 31002 if ('colors' in $$props) $$invalidate(0, colors = $$props.colors); 31003 if ('color_mode' in $$props) $$invalidate(1, color_mode = $$props.color_mode); 31004 if ('mode' in $$props) $$invalidate(20, mode = $$props.mode); 31005 }; 31006 31007 $$self.$$.update = () => { 31008 if ($$self.$$.dirty[0] & /*mode*/ 1048576) { 31009 brush_options = mode === "draw" 31010 ? Object.values(paint_meta) 31011 : [paint_meta.size]; 31012 } 31013 31014 if ($$self.$$.dirty[0] & /*mode, selected_color*/ 1048580) { 31015 mode === "draw" && current_color.set(selected_color); 31016 } 31017 31018 if ($$self.$$.dirty[0] & /*$active_tool, mode*/ 3145728) { 31019 { 31020 if ($active_tool !== mode) { 31021 $$invalidate(6, current_option = null); 31022 } 31023 } 31024 } 31025 31026 if ($$self.$$.dirty[0] & /*selected_size, $dimensions, $editor_box*/ 56) { 31027 $$invalidate(10, brush_size = selected_size / $dimensions[0] * $editor_box.child_width * 2); 31028 } 31029 }; 31030 31031 return [ 31032 colors, 31033 color_mode, 31034 selected_color, 31035 selected_size, 31036 $editor_box, 31037 $dimensions, 31038 current_option, 31039 brush_cursor, 31040 recent_colors, 31041 pos, 31042 brush_size, 31043 processed_colors, 31044 pixi, 31045 dimensions, 31046 current_layer, 31047 editor_box, 31048 crop, 31049 active_tool, 31050 default_size, 31051 default_color, 31052 mode, 31053 $active_tool, 31054 keydown_handler, 31055 brushcolor_selected_color_binding, 31056 brushcolor_recent_colors_binding, 31057 click_outside_handler, 31058 brushsize_selected_size_binding, 31059 click_outside_handler_1 31060 ]; 31061} 31062 31063class Brush extends SvelteComponent$9 { 31064 constructor(options) { 31065 super(); 31066 31067 init$9( 31068 this, 31069 options, 31070 instance$9, 31071 create_fragment$9, 31072 safe_not_equal$9, 31073 { 31074 default_size: 18, 31075 default_color: 19, 31076 colors: 0, 31077 color_mode: 1, 31078 mode: 20 31079 }, 31080 null, 31081 [-1, -1] 31082 ); 31083 } 31084} 31085 31086function crop_canvas(renderer, mask_container, crop, current_opacity = 0) { 31087 let text; 31088 let sprite; 31089 const mask_graphics = new Graphics(); 31090 let previous_crop; 31091 let final_crop; 31092 let width; 31093 let height; 31094 let alpha_spring = spring(current_opacity, { 31095 stiffness: 0.1, 31096 damping: 0.5 31097 }); 31098 let spring_value = current_opacity; 31099 alpha_spring.subscribe((value) => { 31100 if (!final_crop) 31101 return; 31102 spring_value = value; 31103 crop_mask(width, height, final_crop, true); 31104 }); 31105 function crop_mask(width2, height2, crop_size, preview) { 31106 mask_graphics.clear(); 31107 if (preview) { 31108 mask_graphics.beginFill(16777215, spring_value); 31109 mask_graphics.drawRect(0, 0, width2, height2); 31110 mask_graphics.endFill(); 31111 } 31112 mask_graphics.beginFill(16777215, 1); 31113 mask_graphics.drawRect(...crop_size); 31114 mask_graphics.endFill(); 31115 renderer.render(mask_graphics, { 31116 renderTexture: text 31117 }); 31118 } 31119 let clean = true; 31120 let stopped = false; 31121 return { 31122 start: (_width, _height, _previous_crop, set_previous = true) => { 31123 clean = false; 31124 text = RenderTexture.create({ 31125 width: _width, 31126 height: _height 31127 }); 31128 crop_mask(_width, _height, _previous_crop, true); 31129 sprite = new Sprite(text); 31130 mask_container.mask = sprite; 31131 width = _width; 31132 height = _height; 31133 if (set_previous) 31134 previous_crop = JSON.parse(JSON.stringify(_previous_crop)); 31135 }, 31136 continue: (crop_size) => { 31137 final_crop = JSON.parse(JSON.stringify(crop_size)); 31138 if (spring_value === 0.2) { 31139 crop_mask(width, height, final_crop, true); 31140 } else { 31141 alpha_spring.set(0.2); 31142 } 31143 }, 31144 undo() { 31145 this.start(width, height, previous_crop, false); 31146 crop.set([ 31147 previous_crop[0] / width, 31148 previous_crop[1] / height, 31149 previous_crop[2] / width, 31150 previous_crop[3] / height 31151 ]); 31152 clean = true; 31153 }, 31154 stop() { 31155 stopped = true; 31156 return spring_value; 31157 }, 31158 execute() { 31159 if (clean) { 31160 this.start(width, height, final_crop, false); 31161 crop.set([ 31162 final_crop[0] / width, 31163 final_crop[1] / height, 31164 final_crop[2] / width, 31165 final_crop[3] / height 31166 ]); 31167 clean = true; 31168 } else { 31169 if (!stopped) { 31170 alpha_spring.set(0); 31171 } 31172 crop.set([ 31173 final_crop[0] / width, 31174 final_crop[1] / height, 31175 final_crop[2] / width, 31176 final_crop[3] / height 31177 ]); 31178 clean = true; 31179 } 31180 } 31181 }; 31182} 31183function resize_and_reposition(original_width, original_height, anchor, aspect_ratio, max_width, max_height) { 31184 let new_width = original_width; 31185 let new_height = original_height; 31186 if (anchor.includes("t") || anchor.includes("b") || anchor == "c") { 31187 new_width = original_height * aspect_ratio; 31188 } 31189 if (anchor.includes("l") || anchor.includes("r") || anchor == "c") { 31190 new_height = original_width / aspect_ratio; 31191 } 31192 new_height = new_height || new_width / aspect_ratio; 31193 new_width = new_width || new_height * aspect_ratio; 31194 if (new_width > max_width) { 31195 new_width = max_width; 31196 new_height = new_width / aspect_ratio; 31197 } 31198 if (new_height > max_height) { 31199 new_height = max_height; 31200 new_width = new_height * aspect_ratio; 31201 } 31202 let x_offset = 0; 31203 let y_offset = 0; 31204 if (anchor.includes("r")) { 31205 x_offset = original_width - new_width; 31206 } else if (anchor.includes("l")) { 31207 x_offset = 0; 31208 } else { 31209 x_offset = (original_width - new_width) / 2; 31210 } 31211 if (anchor.includes("b")) { 31212 y_offset = original_height - new_height; 31213 } else if (anchor.includes("t")) { 31214 y_offset = 0; 31215 } else { 31216 y_offset = (original_height - new_height) / 2; 31217 } 31218 return { 31219 new_width, 31220 new_height, 31221 x_offset, 31222 y_offset 31223 }; 31224} 31225 31226const Handle_svelte_svelte_type_style_lang = ''; 31227 31228/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/Handle.svelte generated by Svelte v4.2.2 */ 31229const { 31230 SvelteComponent: SvelteComponent$8, 31231 append: append$6, 31232 attr: attr$6, 31233 binding_callbacks: binding_callbacks$5, 31234 detach: detach$8, 31235 element: element$6, 31236 init: init$8, 31237 insert: insert$8, 31238 listen: listen$4,
31239 noop: noop$1, 31240 run_all: run_all$2, 31241 safe_not_equal: safe_not_equal$8, 31242 set_style: set_style$3 31243} = window.__gradio__svelte__internal; 31244const { tick: tick$4, createEventDispatcher: createEventDispatcher$4 } = window.__gradio__svelte__internal; 31245function create_fragment$8(ctx) { 31246 let div1; 31247 let div0; 31248 let div0_class_value; 31249 let div1_class_value; 31250 let mounted; 31251 let dispose; 31252 31253 return { 31254 c() { 31255 div1 = element$6("div"); 31256 div0 = element$6("div"); 31257 attr$6(div0, "class", div0_class_value = "handle " + /*type*/ ctx[0] + " " + /*location*/ ctx[1] + " svelte-29tqs9"); 31258 attr$6(div1, "class", div1_class_value = "hitbox " + /*location*/ ctx[1] + " svelte-29tqs9"); 31259 set_style$3(div1, "transform", /*transform*/ ctx[3]); 31260 }, 31261 m(target, anchor) { 31262 insert$8(target, div1, anchor); 31263 append$6(div1, div0); 31264 /*div0_binding*/ ctx[12](div0); 31265 31266 if (!mounted) { 31267 dispose = [ 31268 listen$4(window, "mousemove", /*handle_mousemove*/ ctx[5]), 31269 listen$4(window, "mouseup", /*handle_mouseup*/ ctx[6]), 31270 listen$4(div1, "mousedown", /*handle_mousedown*/ ctx[4]) 31271 ]; 31272 31273 mounted = true; 31274 } 31275 }, 31276 p(ctx, [dirty]) { 31277 if (dirty & /*type, location*/ 3 && div0_class_value !== (div0_class_value = "handle " + /*type*/ ctx[0] + " " + /*location*/ ctx[1] + " svelte-29tqs9")) { 31278 attr$6(div0, "class", div0_class_value); 31279 } 31280 31281 if (dirty & /*location*/ 2 && div1_class_value !== (div1_class_value = "hitbox " + /*location*/ ctx[1] + " svelte-29tqs9")) { 31282 attr$6(div1, "class", div1_class_value); 31283 } 31284 31285 if (dirty & /*transform*/ 8) { 31286 set_style$3(div1, "transform", /*transform*/ ctx[3]); 31287 } 31288 }, 31289 i: noop$1, 31290 o: noop$1, 31291 d(detaching) { 31292 if (detaching) { 31293 detach$8(div1); 31294 } 31295 31296 /*div0_binding*/ ctx[12](null); 31297 mounted = false; 31298 run_all$2(dispose); 31299 } 31300 }; 31301} 31302 31303function instance$8($$self, $$props, $$invalidate) { 31304 let transform; 31305 let { type = "corner" } = $$props; 31306 let { location } = $$props; 31307 let { x1 = 0 } = $$props; 31308 let { y1 = 0 } = $$props; 31309 let { x2 = 0 } = $$props; 31310 let { y2 = 0 } = $$props; 31311 let box; 31312 let y_offset = 0; 31313 let x_offset = 0; 31314 let active = false; 31315 const dispatch = createEventDispatcher$4(); 31316 let { dragging = false } = $$props; 31317 let el; 31318 31319 function handle_mousedown(e) { 31320 box = el.getBoundingClientRect(); 31321 active = true; 31322 $$invalidate(11, dragging = true); 31323 if (["tl", "bl", "l"].includes(location)) x_offset = e.clientX - box.right; 31324 if (["tl", "tr", "t"].includes(location)) y_offset = e.clientY - box.bottom; 31325 if (["tr", "r", "br"].includes(location)) x_offset = e.clientX - box.left; 31326 if (["br", "b", "bl"].includes(location)) y_offset = e.clientY - box.top; 31327 } 31328 31329 function handle_mousemove(e) { 31330 if (!active) return; 31331 const top_pos = e.clientY - y_offset; 31332 const bottom_pos = e.clientY - y_offset; 31333 const left_pos = e.clientX - x_offset; 31334 const right_pos = e.clientX - x_offset; 31335 31336 if (["tl", "bl", "l"].includes(location)) { 31337 $$invalidate(7, x1 = left_pos); 31338 } 31339 31340 if (["tl", "tr", "t"].includes(location)) { 31341 $$invalidate(8, y1 = top_pos); 31342 } 31343 31344 if (["tr", "r", "br"].includes(location)) { 31345 $$invalidate(9, x2 = right_pos); 31346 } 31347 31348 if (["br", "b", "bl"].includes(location)) { 31349 $$invalidate(10, y2 = bottom_pos); 31350 } 31351 } 31352 31353 async function handle_mouseup(e) { 31354 await tick$4(); 31355 active = false; 31356 $$invalidate(11, dragging = false); 31357 } 31358 31359 function make_transform(_location, x1, x2, y1, y2) { 31360 let t = undefined; 31361 let l = undefined; 31362 let r = undefined; 31363 let b = undefined; 31364 31365 if (box) { 31366 if (["tl", "l", "bl"].includes(_location)) { 31367 l = x1; 31368 } 31369 31370 if (["tl", "t", "tr"].includes(_location)) { 31371 t = y1; 31372 } 31373 31374 if (["tr", "r", "br"].includes(_location)) { 31375 r = x2; 31376 } 31377 31378 if (["br", "b", "bl"].includes(_location)) { 31379 b = y2; 31380 } 31381 } 31382 31383 dispatch("change", { top: t, bottom: b, left: l, right: r }); 31384 return ""; 31385 } 31386 31387 function div0_binding($$value) { 31388 binding_callbacks$5[$$value ? 'unshift' : 'push'](() => { 31389 el = $$value; 31390 $$invalidate(2, el); 31391 }); 31392 } 31393 31394 $$self.$$set = $$props => {
31395 if ('type' in $$props) $$invalidate(0, type = $$props.type); 31396 if ('location' in $$props) $$invalidate(1, location = $$props.location); 31397 if ('x1' in $$props) $$invalidate(7, x1 = $$props.x1); 31398 if ('y1' in $$props) $$invalidate(8, y1 = $$props.y1); 31399 if ('x2' in $$props) $$invalidate(9, x2 = $$props.x2); 31400 if ('y2' in $$props) $$invalidate(10, y2 = $$props.y2); 31401 if ('dragging' in $$props) $$invalidate(11, dragging = $$props.dragging); 31402 }; 31403 31404 $$self.$$.update = () => { 31405 if ($$self.$$.dirty & /*location, x1, x2, y1, y2*/ 1922) { 31406 $$invalidate(3, transform = make_transform(location, x1, x2, y1, y2)); 31407 } 31408 }; 31409 31410 return [ 31411 type, 31412 location, 31413 el, 31414 transform, 31415 handle_mousedown, 31416 handle_mousemove, 31417 handle_mouseup, 31418 x1, 31419 y1, 31420 x2, 31421 y2, 31422 dragging, 31423 div0_binding 31424 ]; 31425} 31426 31427class Handle extends SvelteComponent$8 { 31428 constructor(options) { 31429 super(); 31430 31431 init$8(this, options, instance$8, create_fragment$8, safe_not_equal$8, { 31432 type: 0, 31433 location: 1, 31434 x1: 7, 31435 y1: 8, 31436 x2: 9, 31437 y2: 10, 31438 dragging: 11 31439 }); 31440 } 31441} 31442 31443const Cropper_svelte_svelte_type_style_lang = ''; 31444 31445/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/Cropper.svelte generated by Svelte v4.2.2 */ 31446const { 31447 SvelteComponent: SvelteComponent$7, 31448 add_flush_callback: add_flush_callback$1, 31449 append: append$5, 31450 attr: attr$5, 31451 bind: bind$1, 31452 binding_callbacks: binding_callbacks$4, 31453 check_outros: check_outros$5, 31454 create_component: create_component$7, 31455 destroy_component: destroy_component$7, 31456 destroy_each, 31457 detach: detach$7, 31458 element: element$5, 31459 ensure_array_like: ensure_array_like$1, 31460 group_outros: group_outros$5, 31461 init: init$7, 31462 insert: insert$7, 31463 listen: listen$3, 31464 mount_component: mount_component$7, 31465 noop, 31466 run_all: run_all$1, 31467 safe_not_equal: safe_not_equal$7, 31468 set_style: set_style$2, 31469 space: space$6, 31470 subscribe, 31471 toggle_class: toggle_class$2, 31472 transition_in: transition_in$7, 31473 transition_out: transition_out$7 31474} = window.__gradio__svelte__internal; 31475const { createEventDispatcher: createEventDispatcher$3 } = window.__gradio__svelte__internal; 31476function get_each_context$1(ctx, list, i) { 31477 const child_ctx = ctx.slice(); 31478 child_ctx[30] = list[i]; 31479 return child_ctx; 31480} 31481 31482function get_each_context_1(ctx, list, i) { 31483 const child_ctx = ctx.slice(); 31484 child_ctx[33] = list[i]; 31485 return child_ctx; 31486} 31487 31488// (174:2) {#each positions as position} 31489function create_each_block_1(ctx) { 31490 let handle; 31491 let updating_dragging; 31492 let current; 31493 31494 function handle_dragging_binding(value) { 31495 /*handle_dragging_binding*/ ctx[20](value); 31496 } 31497 31498 function change_handler(...args) { 31499 return /*change_handler*/ ctx[21](/*position*/ ctx[33], ...args); 31500 } 31501 31502 let handle_props = { location: /*position*/ ctx[33] }; 31503 31504 if (/*dragging*/ ctx[1] !== void 0) { 31505 handle_props.dragging = /*dragging*/ ctx[1]; 31506 } 31507 31508 handle = new Handle({ props: handle_props }); 31509 binding_callbacks$4.push(() => bind$1(handle, 'dragging', handle_dragging_binding)); 31510 handle.$on("change", change_handler); 31511 31512 return { 31513 c() { 31514 create_component$7(handle.$$.fragment); 31515 }, 31516 m(target, anchor) { 31517 mount_component$7(handle, target, anchor); 31518 current = true; 31519 }, 31520 p(new_ctx, dirty) { 31521 ctx = new_ctx; 31522 const handle_changes = {}; 31523 31524 if (!updating_dragging && dirty[0] & /*dragging*/ 2) { 31525 updating_dragging = true; 31526 handle_changes.dragging = /*dragging*/ ctx[1]; 31527 add_flush_callback$1(() => updating_dragging = false); 31528 } 31529 31530 handle.$set(handle_changes); 31531 }, 31532 i(local) { 31533 if (current) return; 31534 transition_in$7(handle.$$.fragment, local); 31535 current = true; 31536 }, 31537 o(local) { 31538 transition_out$7(handle.$$.fragment, local); 31539 current = false; 31540 }, 31541 d(detaching) { 31542 destroy_component$7(handle, detaching); 31543 } 31544 }; 31545} 31546 31547// (184:3) {#each { length: 25 } as _} 31548function create_each_block$1(ctx) { 31549 let div; 31550 31551 return { 31552 c() { 31553 div = element$5("div"); 31554 attr$5(div, "class", "svelte-ae5ytx"); 31555 }, 31556 m(target, anchor) { 31557 insert$7(target, div, anchor); 31558 }, 31559 p: noop, 31560 d(detaching) { 31561 if (detaching) { 31562 detach$7(div); 31563 } 31564 } 31565 }; 31566} 31567 31568function create_fragment$7(ctx) { 31569 let div2; 31570 let div1; 31571 let t; 31572 let div0; 31573 let style_width = `${/*_width*/ ctx[3]}px`; 31574 let style_height = `${/*_height*/ ctx[2]}px`; 31575 let style_top = `${/*_top*/ ctx[4]}px`; 31576 let style_left = `${/*_left*/ ctx[5]}px`; 31577 let current; 31578 let mounted; 31579 let dispose; 31580 let each_value_1 = ensure_array_like$1(/*positions*/ ctx[7]); 31581 let each_blocks_1 = []; 31582 31583 for (let i = 0; i < each_value_1.length; i += 1) { 31584 each_blocks_1[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i)); 31585 } 31586 31587 const out = i => transition_out$7(each_blocks_1[i], 1, 1, () => { 31588 each_blocks_1[i] = null; 31589 }); 31590 31591 let each_value = ensure_array_like$1({ length: 25 }); 31592 let each_blocks = []; 31593 31594 for (let i = 0; i < each_value.length; i += 1) { 31595 each_blocks[i] = create_each_block$1(get_each_context$1(ctx, each_value, i)); 31596 } 31597 31598 return { 31599 c() { 31600 div2 = element$5("div"); 31601 div1 = element$5("div"); 31602 31603 for (let i = 0; i < each_blocks_1.length; i += 1) { 31604 each_blocks_1[i].c(); 31605 } 31606 31607 t = space$6(); 31608 div0 = element$5("div"); 31609 31610 for (let i = 0; i < each_blocks.length; i += 1) { 31611 each_blocks[i].c(); 31612 } 31613 31614 attr$5(div0, "class", "grid svelte-ae5ytx"); 31615 toggle_class$2(div0, "finished", /*finished*/ ctx[6]); 31616 attr$5(div1, "class", "box svelte-ae5ytx"); 31617 set_style$2(div1, "width", style_width); 31618 set_style$2(div1, "height", style_height); 31619 set_style$2(div1, "top", style_top); 31620 set_style$2(div1, "left", style_left); 31621 attr$5(div2, "class", "wrap svelte-ae5ytx"); 31622 }, 31623 m(target, anchor) { 31624 insert$7(target, div2, anchor); 31625 append$5(div2, div1); 31626 31627 for (let i = 0; i < each_blocks_1.length; i += 1) { 31628 if (each_blocks_1[i]) { 31629 each_blocks_1[i].m(div1, null); 31630 } 31631 } 31632 31633 append$5(div1, t); 31634 append$5(div1, div0); 31635 31636 for (let i = 0; i < each_blocks.length; i += 1) { 31637 if (each_blocks[i]) { 31638 each_blocks[i].m(div0, null); 31639 } 31640 } 31641 31642 current = true; 31643 31644 if (!mounted) { 31645 dispose = [ 31646 listen$3(window, "mousemove", /*handle_dragging*/ ctx[11]), 31647 listen$3(window, "mouseup", /*handle_drag_end*/ ctx[10]), 31648 listen$3(div0, "mousedown", /*handle_drag_start*/ ctx[9]) 31649 ]; 31650 31651 mounted = true; 31652 } 31653 }, 31654 p(ctx, dirty) {
31655 if (dirty[0] & /*positions, dragging, handle_change*/ 386) { 31656 each_value_1 = ensure_array_like$1(/*positions*/ ctx[7]); 31657 let i; 31658 31659 for (i = 0; i < each_value_1.length; i += 1) { 31660 const child_ctx = get_each_context_1(ctx, each_value_1, i); 31661 31662 if (each_blocks_1[i]) { 31663 each_blocks_1[i].p(child_ctx, dirty); 31664 transition_in$7(each_blocks_1[i], 1); 31665 } else { 31666 each_blocks_1[i] = create_each_block_1(child_ctx); 31667 each_blocks_1[i].c(); 31668 transition_in$7(each_blocks_1[i], 1); 31669 each_blocks_1[i].m(div1, t); 31670 } 31671 } 31672 31673 group_outros$5(); 31674 31675 for (i = each_value_1.length; i < each_blocks_1.length; i += 1) { 31676 out(i); 31677 } 31678 31679 check_outros$5(); 31680 } 31681 31682 if (!current || dirty[0] & /*finished*/ 64) { 31683 toggle_class$2(div0, "finished", /*finished*/ ctx[6]); 31684 } 31685 31686 if (dirty[0] & /*_width*/ 8 && style_width !== (style_width = `${/*_width*/ ctx[3]}px`)) { 31687 set_style$2(div1, "width", style_width); 31688 } 31689 31690 if (dirty[0] & /*_height*/ 4 && style_height !== (style_height = `${/*_height*/ ctx[2]}px`)) { 31691 set_style$2(div1, "height", style_height); 31692 } 31693 31694 if (dirty[0] & /*_top*/ 16 && style_top !== (style_top = `${/*_top*/ ctx[4]}px`)) { 31695 set_style$2(div1, "top", style_top); 31696 } 31697 31698 if (dirty[0] & /*_left*/ 32 && style_left !== (style_left = `${/*_left*/ ctx[5]}px`)) { 31699 set_style$2(div1, "left", style_left); 31700 } 31701 }, 31702 i(local) { 31703 if (current) return; 31704 31705 for (let i = 0; i < each_value_1.length; i += 1) { 31706 transition_in$7(each_blocks_1[i]); 31707 } 31708 31709 current = true; 31710 }, 31711 o(local) { 31712 each_blocks_1 = each_blocks_1.filter(Boolean); 31713 31714 for (let i = 0; i < each_blocks_1.length; i += 1) { 31715 transition_out$7(each_blocks_1[i]); 31716 } 31717 31718 current = false; 31719 }, 31720 d(detaching) { 31721 if (detaching) { 31722 detach$7(div2); 31723 } 31724 31725 destroy_each(each_blocks_1, detaching); 31726 destroy_each(each_blocks, detaching); 31727 mounted = false; 31728 run_all$1(dispose); 31729 } 31730 }; 31731} 31732 31733function instance$7($$self, $$props, $$invalidate) { 31734 let $editor_box, 31735 $$unsubscribe_editor_box = noop,
31736 $$subscribe_editor_box = () => ($$unsubscribe_editor_box(), $$unsubscribe_editor_box = subscribe(editor_box, $$value => $$invalidate(19, $editor_box = $$value)), editor_box); 31737 31738 $$self.$$.on_destroy.push(() => $$unsubscribe_editor_box()); 31739 let { editor_box } = $$props; 31740 $$subscribe_editor_box(); 31741 let { crop_constraint } = $$props; 31742 const dispatch = createEventDispatcher$3(); 31743 let _height = $editor_box.child_height; 31744 let _width = $editor_box.child_width; 31745 let _top = $editor_box.child_top - $editor_box.parent_top; 31746 let _left = $editor_box.child_left - $editor_box.parent_left; 31747 let _right = $editor_box.child_right - $editor_box.parent_left; 31748 let _bottom = 0; 31749 let dragging = false; 31750 let { w_p } = $$props; 31751 let { h_p } = $$props; 31752 let { l_p } = $$props; 31753 let { t_p } = $$props; 31754 const positions = ["tl", "br", "tr", "bl", "t", "b", "l", "r"]; 31755 let finished; 31756 let timer; 31757 let triggered = false; 31758 31759 function set_finished_with_timeout_and_delay() { 31760 if (timer) { 31761 clearTimeout(timer); 31762 } 31763 31764 $$invalidate(17, timer = setTimeout( 31765 () => { 31766 if (triggered) { 31767 dispatch("crop_end", { x: l_p, y: t_p, width: w_p, height: h_p }); 31768 triggered = false; 31769 } 31770 31771 $$invalidate(6, finished = true); 31772 $$invalidate(18, position_drag = false); 31773 }, 31774 1000 31775 )); 31776 } 31777 31778 function handle_change({ top, bottom, left, right }, position) { 31779 $$invalidate(4, _top = clamp(top ? top - $editor_box.parent_top : _top, $editor_box.child_top - $editor_box.parent_top, $editor_box.child_bottom - $editor_box.parent_top)); 31780 $$invalidate(5, _left = clamp(left ? left - $editor_box.parent_left : _left, $editor_box.child_left - $editor_box.parent_left, $editor_box.child_right - $editor_box.parent_left)); 31781 _right = clamp(right ? right - $editor_box.parent_left : _right, $editor_box.child_left - $editor_box.parent_left, $editor_box.child_right - $editor_box.parent_left); 31782 _bottom = clamp(bottom ? bottom - $editor_box.parent_top : _bottom, $editor_box.child_top - $editor_box.parent_top, $editor_box.child_bottom - $editor_box.parent_top); 31783 $$invalidate(3, _width = clamp(right ? right - _left - $editor_box.parent_left : _width, 0, _right - _left)); 31784 $$invalidate(3, _width = clamp(left ? _right - left + $editor_box.parent_left : _width, 0, _right - _left)); 31785 31786 $$invalidate(2, _height = clamp( 31787 bottom 31788 ? bottom - _top - $editor_box.parent_top 31789 : _height, 31790 0, 31791 _bottom - _top 31792 )); 31793 31794 $$invalidate(2, _height = clamp(top ? _bottom - top + $editor_box.parent_top : _height, 0, _bottom - _top)); 31795 31796 const anchors_for_position = { 31797 tl: "br", 31798 tr: "bl", 31799 bl: "tr", 31800 br: "tl", 31801 t: "b", 31802 b: "t", 31803 l: "r", 31804 r: "l", 31805 c: "c" 31806 }; 31807 31808 if (crop_constraint) { 31809 const max_w = ["t", "b"].includes(position) 31810 ? $editor_box.child_width 31811 : _right - _left; 31812 31813 const max_h = ["l", "r"].includes(position) 31814 ? $editor_box.child_height 31815 : _bottom - _top; 31816 31817 let result = resize_and_reposition(_width, _height, anchors_for_position[position], crop_constraint, max_w, max_h); 31818 $$invalidate(3, _width = result.new_width); 31819 $$invalidate(2, _height = result.new_height); 31820 $$invalidate(5, _left = _left + result.x_offset); 31821 $$invalidate(4, _top = _top + result.y_offset); 31822 _right = _left + _width; 31823 _bottom = _top + _height; 31824 } 31825 31826 $$invalidate(12, w_p = _width / $editor_box.child_width); 31827 $$invalidate(13, h_p = _height / $editor_box.child_height); 31828 $$invalidate(14, l_p = (_left - $editor_box.child_left + $editor_box.parent_left) / $editor_box.child_width); 31829 $$invalidate(15, t_p = (_top - $editor_box.child_top + $editor_box.parent_top) / $editor_box.child_height); 31830 dispatch(triggered ? "crop_continue" : "crop_start", { x: l_p, y: t_p, width: w_p, height: h_p }); 31831 triggered = true; 31832 } 31833 31834 function resize() { 31835 $$invalidate(3, _width = w_p * $editor_box.child_width); 31836 $$invalidate(2, _height = h_p * $editor_box.child_height); 31837 $$invalidate(5, _left = l_p * $editor_box.child_width + ($editor_box.child_left - $editor_box.parent_left)); 31838 $$invalidate(4, _top = t_p * $editor_box.child_height + ($editor_box.child_top - $editor_box.parent_top)); 31839 _right = _left + _width; 31840 _bottom = _top + _height; 31841 } 31842 31843 let start_x = 0; 31844 let start_y = 0; 31845 let position_drag = false;
31846 31847 function handle_drag_start(e) { 31848 $$invalidate(18, position_drag = true); 31849 start_x = e.clientX; 31850 start_y = e.clientY; 31851 if (!finished) return; 31852 $$invalidate(6, finished = false); 31853 dispatch("crop_start", { x: l_p, y: t_p, width: w_p, height: h_p }); 31854 } 31855 31856 function handle_drag_end(e) { 31857 if (!position_drag) return; 31858 $$invalidate(18, position_drag = false); 31859 } 31860 31861 function handle_dragging(e) { 31862 if (!position_drag) return; 31863 const x_delta = e.clientX - start_x; 31864 const y_delta = e.clientY - start_y; 31865 $$invalidate(5, _left = clamp(_left + x_delta, $editor_box.child_left - $editor_box.parent_left, $editor_box.child_right - $editor_box.parent_left - _width)); 31866 $$invalidate(4, _top = clamp(_top + y_delta, $editor_box.child_top - $editor_box.parent_top, $editor_box.child_bottom - $editor_box.parent_top - _height)); 31867 _right = _left + _width; 31868 _bottom = _top + _height; 31869 $$invalidate(14, l_p = (_left - $editor_box.child_left + $editor_box.parent_left) / $editor_box.child_width); 31870 $$invalidate(15, t_p = (_top - $editor_box.child_top + $editor_box.parent_top) / $editor_box.child_height); 31871 start_x = e.clientX; 31872 start_y = e.clientY; 31873 dispatch("crop_continue", { x: l_p, y: t_p, width: w_p, height: h_p }); 31874 triggered = true; 31875 } 31876 31877 function handle_dragging_binding(value) { 31878 dragging = value; 31879 $$invalidate(1, dragging); 31880 } 31881 31882 const change_handler = (position, { detail }) => handle_change(detail, position); 31883 31884 $$self.$$set = $$props => { 31885 if ('editor_box' in $$props) $$subscribe_editor_box($$invalidate(0, editor_box = $$props.editor_box));
31886 if ('crop_constraint' in $$props) $$invalidate(16, crop_constraint = $$props.crop_constraint); 31887 if ('w_p' in $$props) $$invalidate(12, w_p = $$props.w_p); 31888 if ('h_p' in $$props) $$invalidate(13, h_p = $$props.h_p); 31889 if ('l_p' in $$props) $$invalidate(14, l_p = $$props.l_p); 31890 if ('t_p' in $$props) $$invalidate(15, t_p = $$props.t_p); 31891 }; 31892 31893 $$self.$$.update = () => { 31894 if ($$self.$$.dirty[0] & /*dragging, position_drag, timer*/ 393218) { 31895 { 31896 if (dragging || position_drag) { 31897 clearTimeout(timer); 31898 $$invalidate(6, finished = false); 31899 } else { 31900 set_finished_with_timeout_and_delay(); 31901 } 31902 } 31903 } 31904 31905 if ($$self.$$.dirty[0] & /*$editor_box*/ 524288) { 31906 $editor_box && resize(); 31907 } 31908 }; 31909 31910 return [ 31911 editor_box, 31912 dragging, 31913 _height, 31914 _width, 31915 _top, 31916 _left, 31917 finished, 31918 positions, 31919 handle_change, 31920 handle_drag_start, 31921 handle_drag_end, 31922 handle_dragging, 31923 w_p, 31924 h_p, 31925 l_p, 31926 t_p, 31927 crop_constraint, 31928 timer, 31929 position_drag, 31930 $editor_box, 31931 handle_dragging_binding, 31932 change_handler 31933 ]; 31934} 31935 31936class Cropper extends SvelteComponent$7 { 31937 constructor(options) { 31938 super(); 31939 31940 init$7( 31941 this, 31942 options, 31943 instance$7, 31944 create_fragment$7, 31945 safe_not_equal$7, 31946 { 31947 editor_box: 0, 31948 crop_constraint: 16, 31949 w_p: 12, 31950 h_p: 13, 31951 l_p: 14, 31952 t_p: 15 31953 }, 31954 null, 31955 [-1, -1] 31956 ); 31957 } 31958} 31959 31960/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/Crop.svelte generated by Svelte v4.2.2 */ 31961const { 31962 SvelteComponent: SvelteComponent$6, 31963 check_outros: check_outros$4, 31964 component_subscribe: component_subscribe$3, 31965 create_component: create_component$6, 31966 destroy_component: destroy_component$6, 31967 detach: detach$6, 31968 empty: empty$3, 31969 group_outros: group_outros$4, 31970 init: init$6, 31971 insert: insert$6, 31972 mount_component: mount_component$6, 31973 safe_not_equal: safe_not_equal$6, 31974 transition_in: transition_in$6, 31975 transition_out: transition_out$6 31976} = window.__gradio__svelte__internal; 31977const { getContext: getContext$2, onDestroy, onMount: onMount$3, tick: tick$3 } = window.__gradio__svelte__internal; 31978function create_if_block$5(ctx) { 31979 let cropper_1; 31980 let current; 31981 31982 cropper_1 = new Cropper({ 31983 props: { 31984 crop_constraint: /*_crop_constraint*/ ctx[0], 31985 w_p: /*w_p*/ ctx[1], 31986 h_p: /*h_p*/ ctx[2], 31987 l_p: /*l_p*/ ctx[3], 31988 t_p: /*t_p*/ ctx[4], 31989 editor_box: /*editor_box*/ ctx[9] 31990 } 31991 }); 31992 31993 cropper_1.$on("crop_start", /*crop_start_handler*/ ctx[20]); 31994 cropper_1.$on("crop_continue", /*crop_continue_handler*/ ctx[21]); 31995 cropper_1.$on("crop_end", /*crop_end_handler*/ ctx[22]); 31996 31997 return { 31998 c() { 31999 create_component$6(cropper_1.$$.fragment); 32000 }, 32001 m(target, anchor) { 32002 mount_component$6(cropper_1, target, anchor); 32003 current = true; 32004 }, 32005 p(ctx, dirty) { 32006 const cropper_1_changes = {}; 32007 if (dirty[0] & /*_crop_constraint*/ 1) cropper_1_changes.crop_constraint = /*_crop_constraint*/ ctx[0]; 32008 if (dirty[0] & /*w_p*/ 2) cropper_1_changes.w_p = /*w_p*/ ctx[1]; 32009 if (dirty[0] & /*h_p*/ 4) cropper_1_changes.h_p = /*h_p*/ ctx[2]; 32010 if (dirty[0] & /*l_p*/ 8) cropper_1_changes.l_p = /*l_p*/ ctx[3]; 32011 if (dirty[0] & /*t_p*/ 16) cropper_1_changes.t_p = /*t_p*/ ctx[4]; 32012 cropper_1.$set(cropper_1_changes); 32013 }, 32014 i(local) { 32015 if (current) return; 32016 transition_in$6(cropper_1.$$.fragment, local); 32017 current = true; 32018 }, 32019 o(local) { 32020 transition_out$6(cropper_1.$$.fragment, local); 32021 current = false; 32022 }, 32023 d(detaching) { 32024 destroy_component$6(cropper_1, detaching); 32025 } 32026 }; 32027} 32028 32029function create_fragment$6(ctx) { 32030 let if_block_anchor; 32031 let current; 32032 let if_block = /*$active_tool*/ ctx[5] === "crop" && /*measured*/ ctx[6] && create_if_block$5(ctx); 32033 32034 return { 32035 c() { 32036 if (if_block) if_block.c(); 32037 if_block_anchor = empty$3(); 32038 }, 32039 m(target, anchor) { 32040 if (if_block) if_block.m(target, anchor); 32041 insert$6(target, if_block_anchor, anchor); 32042 current = true; 32043 }, 32044 p(ctx, dirty) { 32045 if (/*$active_tool*/ ctx[5] === "crop" && /*measured*/ ctx[6]) { 32046 if (if_block) { 32047 if_block.p(ctx, dirty); 32048 32049 if (dirty[0] & /*$active_tool, measured*/ 96) { 32050 transition_in$6(if_block, 1); 32051 } 32052 } else { 32053 if_block = create_if_block$5(ctx); 32054 if_block.c(); 32055 transition_in$6(if_block, 1); 32056 if_block.m(if_block_anchor.parentNode, if_block_anchor); 32057 } 32058 } else if (if_block) { 32059 group_outros$4(); 32060 32061 transition_out$6(if_block, 1, 1, () => { 32062 if_block = null; 32063 }); 32064 32065 check_outros$4(); 32066 } 32067 }, 32068 i(local) { 32069 if (current) return; 32070 transition_in$6(if_block); 32071 current = true; 32072 }, 32073 o(local) { 32074 transition_out$6(if_block); 32075 current = false;
32076 }, 32077 d(detaching) { 32078 if (detaching) { 32079 detach$6(if_block_anchor); 32080 } 32081 32082 if (if_block) if_block.d(detaching); 32083 } 32084 }; 32085} 32086 32087function instance$6($$self, $$props, $$invalidate) { 32088 let $editor_box; 32089 let $crop; 32090 let $dimensions; 32091 let $pixi; 32092 let $current_history; 32093 let $active_tool; 32094 const { active_tool, register_tool } = getContext$2(TOOL_KEY); 32095 component_subscribe$3($$self, active_tool, value => $$invalidate(5, $active_tool = value)); 32096 const { dimensions, editor_box, pixi, crop, command_manager, current_history } = getContext$2(EDITOR_KEY); 32097 component_subscribe$3($$self, dimensions, value => $$invalidate(18, $dimensions = value)); 32098 component_subscribe$3($$self, editor_box, value => $$invalidate(16, $editor_box = value)); 32099 component_subscribe$3($$self, pixi, value => $$invalidate(19, $pixi = value)); 32100 component_subscribe$3($$self, crop, value => $$invalidate(17, $crop = value)); 32101 component_subscribe$3($$self, current_history, value => $$invalidate(27, $current_history = value)); 32102 let cropper; 32103 let { crop_constraint } = $$props; 32104 let _crop_constraint = null; 32105 let w_p = 1; 32106 let h_p = 1; 32107 let l_p = 0; 32108 let t_p = 0; 32109 let current_opacity = 0; 32110 let manually_cropped = false; 32111 let c = null; 32112 32113 async function initial_crop() { 32114 if (c || $current_history.previous) return; 32115 const { new_height, new_width, x_offset, y_offset } = resize_and_reposition($editor_box.child_width, $editor_box.child_height, "c", _crop_constraint, $editor_box.child_width, $editor_box.child_height); 32116 $$invalidate(1, w_p = new_width / $editor_box.child_width); 32117 $$invalidate(2, h_p = new_height / $editor_box.child_height); 32118 $$invalidate(3, l_p = x_offset / $editor_box.child_width); 32119 $$invalidate(4, t_p = y_offset / $editor_box.child_height); 32120 c = crop_canvas($pixi.renderer, $pixi.mask_container, crop, 0.2); 32121 c.start(...$dimensions, current_crop); 32122 32123 c.continue([ 32124 l_p * $dimensions[0], 32125 t_p * $dimensions[1], 32126 w_p * $dimensions[0], 32127 h_p * $dimensions[1] 32128 ]); 32129 32130 c.stop(); 32131 c.execute(); 32132 c = null; 32133 current_opacity = 0; 32134 } 32135 32136 function handle_crop(type, { x, y, width, height }) { 32137 if (!$pixi) return; 32138 32139 if (type === "start") { 32140 if (cropper) { 32141 current_opacity = cropper.stop(); 32142 cropper = null; 32143 } 32144 32145 cropper = crop_canvas($pixi?.renderer, $pixi.mask_container, crop, current_opacity); 32146 cropper.start(...$dimensions, current_crop); 32147 } else if (type === "continue") { 32148 if (!cropper) return; 32149 32150 cropper.continue([ 32151 x * $dimensions[0], 32152 y * $dimensions[1], 32153 width * $dimensions[0], 32154 height * $dimensions[1] 32155 ]); 32156 } else if (type === "stop") { 32157 if (!cropper) return; 32158 command_manager.execute(cropper); 32159 } 32160 32161 $$invalidate(15, manually_cropped = true); 32162 } 32163 32164 let measured = false; 32165 32166 function get_measurements() { 32167 if (measured) return; 32168 if (!$editor_box.child_height) return; 32169 const _height = $editor_box.child_height; 32170 const _width = $editor_box.child_width;
32171 const _top = $editor_box.child_top - $editor_box.parent_top; 32172 const _left = $editor_box.child_left - $editor_box.parent_left; 32173 $$invalidate(1, w_p = _width / $editor_box.child_width); 32174 $$invalidate(2, h_p = _height / $editor_box.child_height); 32175 $$invalidate(3, l_p = (_left - $editor_box.child_left + $editor_box.parent_left) / $editor_box.child_width); 32176 $$invalidate(4, t_p = (_top - $editor_box.child_top + $editor_box.parent_top) / $editor_box.child_height); 32177 $$invalidate(6, measured = true); 32178 } 32179 32180 let current_crop; 32181 onMount$3(() => register_tool("crop", { default: "crop", options: [] })); 32182 const crop_start_handler = ({ detail }) => handle_crop("start", detail); 32183 const crop_continue_handler = ({ detail }) => handle_crop("continue", detail); 32184 const crop_end_handler = ({ detail }) => handle_crop("stop", detail); 32185 32186 $$self.$$set = $$props => { 32187 if ('crop_constraint' in $$props) $$invalidate(14, crop_constraint = $$props.crop_constraint); 32188 }; 32189 32190 $$self.$$.update = () => { 32191 if ($$self.$$.dirty[0] & /*crop_constraint*/ 16384) { 32192 { 32193 if (typeof crop_constraint === "string") { 32194 const [w, h] = crop_constraint.split(":"); 32195 $$invalidate(0, _crop_constraint = parseInt(w) / parseInt(h)); 32196 } else if (Array.isArray(crop_constraint)) { 32197 $$invalidate(0, _crop_constraint = crop_constraint[0] / crop_constraint[1]); 32198 } 32199 } 32200 } 32201 32202 if ($$self.$$.dirty[0] & /*manually_cropped, _crop_constraint, $pixi, $active_tool*/ 557089) { 32203 { 32204 if (!manually_cropped && _crop_constraint && $pixi && $active_tool) { 32205 requestAnimationFrame(() => { 32206 initial_crop(); 32207 }); 32208 } 32209 } 32210 } 32211 32212 if ($$self.$$.dirty[0] & /*$crop*/ 131072) { 32213 { 32214 $$invalidate(3, l_p = $crop[0]); 32215 $$invalidate(4, t_p = $crop[1]); 32216 $$invalidate(1, w_p = $crop[2]); 32217 $$invalidate(2, h_p = $crop[3]); 32218 } 32219 } 32220 32221 if ($$self.$$.dirty[0] & /*l_p, $dimensions, t_p, w_p, h_p*/ 262174) { 32222 current_crop = [ 32223 l_p * $dimensions[0], 32224 t_p * $dimensions[1], 32225 w_p * $dimensions[0], 32226 h_p * $dimensions[1] 32227 ]; 32228 } 32229 32230 if ($$self.$$.dirty[0] & /*$editor_box*/ 65536) { 32231 $editor_box && get_measurements(); 32232 } 32233 }; 32234 32235 return [ 32236 _crop_constraint, 32237 w_p, 32238 h_p, 32239 l_p, 32240 t_p, 32241 $active_tool, 32242 measured, 32243 active_tool, 32244 dimensions, 32245 editor_box, 32246 pixi, 32247 crop, 32248 current_history, 32249 handle_crop, 32250 crop_constraint, 32251 manually_cropped, 32252 $editor_box, 32253 $crop, 32254 $dimensions, 32255 $pixi, 32256 crop_start_handler, 32257 crop_continue_handler, 32258 crop_end_handler 32259 ]; 32260} 32261 32262class Crop extends SvelteComponent$6 { 32263 constructor(options) { 32264 super(); 32265 init$6(this, options, instance$6, create_fragment$6, safe_not_equal$6, { crop_constraint: 14 }, null, [-1, -1]); 32266 } 32267} 32268 32269function add_bg_image(container, renderer, background, resize) { 32270 let sprite; 32271 return { 32272 async start() { 32273 container.removeChildren(); 32274 const img = await createImageBitmap(background); 32275 const bitmap_texture = Texture.from(img); 32276 sprite = new Sprite(bitmap_texture); 32277 return [sprite.width, sprite.height]; 32278 }, 32279 async execute() { 32280 resize(sprite.width, sprite.height); 32281 sprite.zIndex = 0; 32282 container.addChild(sprite); 32283 }, 32284 undo() { 32285 container.removeChildAt(0); 32286 } 32287 }; 32288} 32289function add_bg_color(container, renderer, color, width, height, resize) { 32290 let sprite; 32291 return { 32292 start() { 32293 container.removeChildren(); 32294 const graphics = make_graphics(1); 32295 const texture = RenderTexture.create({ 32296 width, 32297 height 32298 }); 32299 graphics.beginFill(new Color(color)); 32300 graphics.drawRect(0, 0, width, height); 32301 graphics.endFill(); 32302 renderer.render(graphics, { renderTexture: texture }); 32303 sprite = new Sprite(texture); 32304 return [sprite.width, sprite.height]; 32305 }, 32306 async execute() { 32307 resize(sprite.width, sprite.height); 32308 sprite.zIndex = 1; 32309 container.addChild(sprite); 32310 }, 32311 undo() { 32312 container.removeChildren(); 32313 } 32314 }; 32315} 32316 32317const Sources_svelte_svelte_type_style_lang = ''; 32318 32319/* home/runner/work/gradio/gradio/js/imageeditor/shared/tools/Sources.svelte generated by Svelte v4.2.2 */ 32320const { 32321 SvelteComponent: SvelteComponent$5, 32322 append: append$4, 32323 attr: attr$4, 32324 binding_callbacks: binding_callbacks$3, 32325 bubble: bubble$2, 32326 check_outros: check_outros$3, 32327 component_subscribe: component_subscribe$2, 32328 create_component: create_component$5, 32329 destroy_component: destroy_component$5, 32330 detach: detach$5, 32331 element: element$4, 32332 empty: empty$2, 32333 group_outros: group_outros$3, 32334 init: init$5, 32335 insert: insert$5,
32336 listen: listen$2, 32337 mount_component: mount_component$5, 32338 safe_not_equal: safe_not_equal$5, 32339 set_store_value: set_store_value$2, 32340 set_style: set_style$1, 32341 space: space$5, 32342 transition_in: transition_in$5, 32343 transition_out: transition_out$5 32344} = window.__gradio__svelte__internal; 32345const { getContext: getContext$1, onMount: onMount$2, tick: tick$2 } = window.__gradio__svelte__internal; 32346function create_if_block$4(ctx) { 32347 let div; 32348 let upload_1; 32349 let t; 32350 let current; 32351 32352 let upload_1_props = { 32353 hidden: true, 32354 filetype: "image/*", 32355 root: /*root*/ ctx[0], 32356 disable_click: !/*sources*/ ctx[1].includes("upload"), 32357 format: "blob" 32358 }; 32359 32360 upload_1 = new Upload({ props: upload_1_props }); 32361 /*upload_1_binding*/ ctx[17](upload_1); 32362 upload_1.$on("load", /*handle_upload*/ ctx[12]); 32363 upload_1.$on("error", /*error_handler*/ ctx[18]); 32364 let if_block = /*active_mode*/ ctx[4] === "webcam" && create_if_block_1$1(ctx); 32365 32366 return { 32367 c() { 32368 div = element$4("div"); 32369 create_component$5(upload_1.$$.fragment); 32370 t = space$5(); 32371 if (if_block) if_block.c(); 32372 attr$4(div, "class", "upload-container"); 32373 }, 32374 m(target, anchor) { 32375 insert$5(target, div, anchor); 32376 mount_component$5(upload_1, div, null); 32377 append$4(div, t); 32378 if (if_block) if_block.m(div, null); 32379 current = true; 32380 }, 32381 p(ctx, dirty) { 32382 const upload_1_changes = {}; 32383 if (dirty[0] & /*root*/ 1) upload_1_changes.root = /*root*/ ctx[0]; 32384 if (dirty[0] & /*sources*/ 2) upload_1_changes.disable_click = !/*sources*/ ctx[1].includes("upload"); 32385 upload_1.$set(upload_1_changes); 32386 32387 if (/*active_mode*/ ctx[4] === "webcam") { 32388 if (if_block) { 32389 if_block.p(ctx, dirty); 32390 32391 if (dirty[0] & /*active_mode*/ 16) { 32392 transition_in$5(if_block, 1); 32393 } 32394 } else { 32395 if_block = create_if_block_1$1(ctx); 32396 if_block.c(); 32397 transition_in$5(if_block, 1); 32398 if_block.m(div, null); 32399 } 32400 } else if (if_block) { 32401 group_outros$3(); 32402 32403 transition_out$5(if_block, 1, 1, () => { 32404 if_block = null; 32405 }); 32406 32407 check_outros$3(); 32408 } 32409 }, 32410 i(local) { 32411 if (current) return; 32412 transition_in$5(upload_1.$$.fragment, local); 32413 transition_in$5(if_block); 32414 current = true; 32415 }, 32416 o(local) { 32417 transition_out$5(upload_1.$$.fragment, local); 32418 transition_out$5(if_block); 32419 current = false; 32420 }, 32421 d(detaching) { 32422 if (detaching) { 32423 detach$5(div); 32424 } 32425 32426 /*upload_1_binding*/ ctx[17](null); 32427 destroy_component$5(upload_1); 32428 if (if_block) if_block.d(); 32429 } 32430 }; 32431} 32432 32433// (134:2) {#if active_mode === "webcam"} 32434function create_if_block_1$1(ctx) { 32435 let div1; 32436 let div0; 32437 let webcam; 32438 let style_max_width = `${/*$editor_box*/ ctx[7].child_width}px`; 32439 let style_max_height = `${/*$editor_box*/ ctx[7].child_height}px`; 32440 let style_top = `${/*$editor_box*/ ctx[7].child_top - /*$editor_box*/ ctx[7].parent_top}px`; 32441 let current; 32442 32443 webcam = new Webcam({ 32444 props: { 32445 mirror_webcam: /*mirror_webcam*/ ctx[2], 32446 streaming: false, 32447 mode: "image", 32448 include_audio: false, 32449 i18n: /*i18n*/ ctx[3] 32450 } 32451 }); 32452 32453 webcam.$on("capture", /*handle_upload*/ ctx[12]); 32454 webcam.$on("error", /*error_handler_1*/ ctx[19]); 32455 webcam.$on("drag", /*drag_handler*/ ctx[20]); 32456 32457 return { 32458 c() { 32459 div1 = element$4("div"); 32460 div0 = element$4("div"); 32461 create_component$5(webcam.$$.fragment); 32462 attr$4(div0, "class", "modal-inner svelte-16d2e0q"); 32463 attr$4(div1, "class", "modal svelte-16d2e0q"); 32464 set_style$1(div1, "max-width", style_max_width); 32465 set_style$1(div1, "max-height", style_max_height); 32466 set_style$1(div1, "top", style_top); 32467 }, 32468 m(target, anchor) { 32469 insert$5(target, div1, anchor); 32470 append$4(div1, div0); 32471 mount_component$5(webcam, div0, null); 32472 current = true; 32473 }, 32474 p(ctx, dirty) { 32475 const webcam_changes = {}; 32476 if (dirty[0] & /*mirror_webcam*/ 4) webcam_changes.mirror_webcam = /*mirror_webcam*/ ctx[2]; 32477 if (dirty[0] & /*i18n*/ 8) webcam_changes.i18n = /*i18n*/ ctx[3]; 32478 webcam.$set(webcam_changes); 32479 32480 if (dirty[0] & /*$editor_box*/ 128 && style_max_width !== (style_max_width = `${/*$editor_box*/ ctx[7].child_width}px`)) { 32481 set_style$1(div1, "max-width", style_max_width); 32482 } 32483
32484 if (dirty[0] & /*$editor_box*/ 128 && style_max_height !== (style_max_height = `${/*$editor_box*/ ctx[7].child_height}px`)) { 32485 set_style$1(div1, "max-height", style_max_height); 32486 } 32487 32488 if (dirty[0] & /*$editor_box*/ 128 && style_top !== (style_top = `${/*$editor_box*/ ctx[7].child_top - /*$editor_box*/ ctx[7].parent_top}px`)) { 32489 set_style$1(div1, "top", style_top); 32490 } 32491 }, 32492 i(local) { 32493 if (current) return; 32494 transition_in$5(webcam.$$.fragment, local); 32495 current = true; 32496 }, 32497 o(local) { 32498 transition_out$5(webcam.$$.fragment, local); 32499 current = false; 32500 }, 32501 d(detaching) { 32502 if (detaching) { 32503 detach$5(div1); 32504 } 32505 32506 destroy_component$5(webcam); 32507 } 32508 }; 32509} 32510 32511function create_fragment$5(ctx) { 32512 let if_block_anchor; 32513 let current; 32514 let mounted; 32515 let dispose; 32516 let if_block = /*$active_tool*/ ctx[6] === "bg" && create_if_block$4(ctx); 32517 32518 return { 32519 c() { 32520 if (if_block) if_block.c(); 32521 if_block_anchor = empty$2(); 32522 }, 32523 m(target, anchor) { 32524 if (if_block) if_block.m(target, anchor); 32525 insert$5(target, if_block_anchor, anchor); 32526 current = true; 32527 32528 if (!mounted) { 32529 dispose = listen$2(window, "keydown", /*handle_key*/ ctx[13]); 32530 mounted = true; 32531 } 32532 }, 32533 p(ctx, dirty) { 32534 if (/*$active_tool*/ ctx[6] === "bg") { 32535 if (if_block) { 32536 if_block.p(ctx, dirty); 32537 32538 if (dirty[0] & /*$active_tool*/ 64) { 32539 transition_in$5(if_block, 1); 32540 } 32541 } else { 32542 if_block = create_if_block$4(ctx); 32543 if_block.c(); 32544 transition_in$5(if_block, 1); 32545 if_block.m(if_block_anchor.parentNode, if_block_anchor); 32546 } 32547 } else if (if_block) { 32548 group_outros$3(); 32549 32550 transition_out$5(if_block, 1, 1, () => { 32551 if_block = null; 32552 }); 32553 32554 check_outros$3(); 32555 } 32556 }, 32557 i(local) { 32558 if (current) return; 32559 transition_in$5(if_block); 32560 current = true; 32561 }, 32562 o(local) { 32563 transition_out$5(if_block); 32564 current = false; 32565 }, 32566 d(detaching) { 32567 if (detaching) { 32568 detach$5(if_block_anchor); 32569 } 32570 32571 if (if_block) if_block.d(detaching); 32572 mounted = false; 32573 dispose(); 32574 } 32575 }; 32576} 32577 32578function instance$5($$self, $$props, $$invalidate) { 32579 let sources_list; 32580 let $dimensions; 32581 let $pixi; 32582 let $active_tool; 32583 let $editor_box; 32584 let { background_file } = $$props; 32585 let { root } = $$props; 32586 let { sources = ["upload", "webcam", "clipboard"] } = $$props; 32587 let { mirror_webcam = true } = $$props; 32588 let { i18n } = $$props; 32589 const { active_tool, register_tool } = getContext$1(TOOL_KEY); 32590 component_subscribe$2($$self, active_tool, value => $$invalidate(6, $active_tool = value)); 32591 const { pixi, dimensions, register_context, reset, editor_box } = getContext$1(EDITOR_KEY); 32592 component_subscribe$2($$self, pixi, value => $$invalidate(24, $pixi = value)); 32593 component_subscribe$2($$self, dimensions, value => $$invalidate(23, $dimensions = value)); 32594 component_subscribe$2($$self, editor_box, value => $$invalidate(7, $editor_box = value)); 32595 let active_mode = null; 32596 let background; 32597 32598 const sources_meta = { 32599 upload: { 32600 icon: Upload$1, 32601 label: "Upload", 32602 order: 0, 32603 id: "bg_upload", 32604 cb() { 32605 upload.open_file_upload(); 32606 } 32607 }, 32608 webcam: { 32609 icon: Webcam$1, 32610 label: "Webcam", 32611 order: 1, 32612 id: "bg_webcam", 32613 cb() { 32614 $$invalidate(4, active_mode = "webcam"); 32615 } 32616 }, 32617 clipboard: { 32618 icon: ImagePaste, 32619 label: "Paste", 32620 order: 2, 32621 id: "bg_clipboard", 32622 cb() { 32623 process_clipboard(); 32624 } 32625 } 32626 }; 32627 32628 let upload; 32629 32630 async function process_clipboard() { 32631 const items = await navigator.clipboard.read(); 32632 32633 for (let i = 0; i < items.length; i++) { 32634 const type = items[i].types.find(t => t.startsWith("image/")); 32635 32636 if (type) { 32637 const blob = await items[i].getType(type); 32638 $$invalidate(16, background = blob || null); 32639 } 32640 } 32641 } 32642 32643 function handle_upload(e) { 32644 const file_data = e.detail; 32645 $$invalidate(16, background = file_data); 32646 $$invalidate(4, active_mode = null); 32647 } 32648 32649 let should_reset = true; 32650 32651 async function set_background() { 32652 if (!$pixi) return; 32653 32654 if (background) { 32655 const add_image = add_bg_image($pixi.background_container, $pixi.renderer, background, $pixi.resize); 32656 set_store_value$2(dimensions, $dimensions = await add_image.start(), $dimensions); 32657 32658 if (should_reset) { 32659 reset(false, $dimensions); 32660 } 32661 32662 add_image.execute(); 32663 should_reset = true; 32664 await tick$2();
32665 $$invalidate(14, bg = true); 32666 } 32667 } 32668 32669 async function process_bg_file(file) { 32670 if (!file || !file.url) return; 32671 should_reset = false; 32672 const blob_res = await fetch(file.url); 32673 const blob = await blob_res.blob(); 32674 $$invalidate(16, background = blob); 32675 } 32676 32677 function handle_key(e) { 32678 if (e.key === "Escape") { 32679 $$invalidate(4, active_mode = null); 32680 } 32681 } 32682 32683 let { bg = false } = $$props; 32684 32685 register_context("bg", { 32686 init_fn: () => { 32687 if (!$pixi) return; 32688 const add_image = add_bg_color($pixi.background_container, $pixi.renderer, "black", ...$dimensions, $pixi.resize); 32689 set_store_value$2(dimensions, $dimensions = add_image.start(), $dimensions); 32690 add_image.execute(); 32691 }, 32692 reset_fn: () => { 32693 32694 } 32695 }); 32696 32697 onMount$2(() => { 32698 return register_tool("bg", { 32699 default: "bg_upload", 32700 options: sources_list || [] 32701 }); 32702 }); 32703 32704 function upload_1_binding($$value) { 32705 binding_callbacks$3[$$value ? 'unshift' : 'push'](() => { 32706 upload = $$value; 32707 $$invalidate(5, upload); 32708 }); 32709 } 32710 32711 function error_handler(event) { 32712 bubble$2.call(this, $$self, event); 32713 } 32714 32715 function error_handler_1(event) { 32716 bubble$2.call(this, $$self, event); 32717 } 32718 32719 function drag_handler(event) { 32720 bubble$2.call(this, $$self, event); 32721 } 32722 32723 $$self.$$set = $$props => {
32724 if ('background_file' in $$props) $$invalidate(15, background_file = $$props.background_file); 32725 if ('root' in $$props) $$invalidate(0, root = $$props.root); 32726 if ('sources' in $$props) $$invalidate(1, sources = $$props.sources); 32727 if ('mirror_webcam' in $$props) $$invalidate(2, mirror_webcam = $$props.mirror_webcam); 32728 if ('i18n' in $$props) $$invalidate(3, i18n = $$props.i18n); 32729 if ('bg' in $$props) $$invalidate(14, bg = $$props.bg); 32730 }; 32731 32732 $$self.$$.update = () => { 32733 if ($$self.$$.dirty[0] & /*sources*/ 2) { 32734 sources_list = sources.map(src => sources_meta[src]).sort((a, b) => a.order - b.order); 32735 } 32736 32737 if ($$self.$$.dirty[0] & /*background*/ 65536) { 32738 background && set_background(); 32739 } 32740 32741 if ($$self.$$.dirty[0] & /*background_file*/ 32768) { 32742 process_bg_file(background_file); 32743 } 32744 }; 32745 32746 return [ 32747 root, 32748 sources, 32749 mirror_webcam, 32750 i18n, 32751 active_mode, 32752 upload, 32753 $active_tool, 32754 $editor_box, 32755 active_tool, 32756 pixi, 32757 dimensions, 32758 editor_box, 32759 handle_upload, 32760 handle_key, 32761 bg, 32762 background_file, 32763 background, 32764 upload_1_binding, 32765 error_handler, 32766 error_handler_1, 32767 drag_handler 32768 ]; 32769} 32770 32771class Sources extends SvelteComponent$5 { 32772 constructor(options) { 32773 super(); 32774 32775 init$5( 32776 this, 32777 options, 32778 instance$5, 32779 create_fragment$5, 32780 safe_not_equal$5, 32781 { 32782 background_file: 15, 32783 root: 0, 32784 sources: 1, 32785 mirror_webcam: 2, 32786 i18n: 3, 32787 bg: 14 32788 }, 32789 null, 32790 [-1, -1] 32791 ); 32792 } 32793} 32794 32795function command_node(command) { 32796 return { 32797 command: command || null, 32798 next: null, 32799 previous: null, 32800 push: function(command2) { 32801 const node = command_node(command2); 32802 node.previous = this; 32803 this.next = node; 32804 } 32805 }; 32806} 32807function command_manager() { 32808 let history = command_node(); 32809 const can_undo = writable(false); 32810 const can_redo = writable(false); 32811 const current_history = writable(history); 32812 return { 32813 undo: function() { 32814 if (history.previous) { 32815 history.command?.undo(); 32816 history = history.previous; 32817 } 32818 can_undo.set(!!history.previous); 32819 can_redo.set(!!history.next); 32820 current_history.set(history); 32821 }, 32822 redo: function() { 32823 if (history.next) { 32824 history.next.command?.execute(); 32825 history = history.next; 32826 } 32827 can_undo.set(!!history.previous); 32828 can_redo.set(!!history.next); 32829 current_history.set(history); 32830 }, 32831 execute: function(command) { 32832 command.execute(); 32833 history.push(command); 32834 history = history.next; 32835 can_undo.set(!!history.previous); 32836 can_redo.set(!!history.next); 32837 current_history.set(history); 32838 }, 32839 can_undo, 32840 can_redo, 32841 current_history, 32842 reset: function() { 32843 history = command_node(); 32844 can_undo.set(false); 32845 can_redo.set(false); 32846 current_history.set(history); 32847 } 32848 }; 32849} 32850 32851const erase_shader = ` 32852precision highp float; 32853 32854uniform sampler2D uDrawingTexture; 32855uniform sampler2D uEraserTexture; 32856 32857varying vec2 vTextureCoord; 32858 32859void main(void) { 32860 vec4 drawingColor = texture2D(uDrawingTexture,vTextureCoord); 32861 vec4 eraserColor = texture2D(uEraserTexture, vTextureCoord); 32862 32863 // Use the alpha of the eraser to determine how much to "erase" from the drawing 32864 float alpha = 1.0 - eraserColor.a; 32865 gl_FragColor = vec4(drawingColor.rgb * alpha, drawingColor.a * alpha); 32866}`; 32867function swap_adjacent(array, index) { 32868 if (index < 0 || index >= array.length - 1) { 32869 throw new Error("Index out of bounds"); 32870 } 32871 [array[index], array[index + 1]] = [array[index + 1], array[index]]; 32872} 32873function layer_manager() { 32874 let _layers = []; 32875 let position = 0; 32876 return { 32877 add_layer: function(container, renderer, width, height) { 32878 const layer_container = new Container(); 32879 position++; 32880 layer_container.zIndex = position; 32881 const composite_texture = RenderTexture.create({ 32882 width, 32883 height 32884 }); 32885 const composite = new Sprite(composite_texture); 32886 layer_container.addChild(composite); 32887 composite.zIndex = position; 32888 const layer_scene = { 32889 draw_texture: RenderTexture.create({ 32890 width, 32891 height 32892 }), 32893 erase_texture: RenderTexture.create({ 32894 width, 32895 height 32896 }), 32897 composite 32898 }; 32899 const erase_filter = new Filter(void 0, erase_shader, { 32900 uEraserTexture: layer_scene.erase_texture, 32901 uDrawingTexture: layer_scene.draw_texture 32902 }); 32903 composite.filters = [erase_filter]; 32904 container.addChild(layer_container); 32905 _layers.push(layer_scene); 32906 return [layer_scene, _layers]; 32907 }, 32908 swap_layers: function(layer, direction) { 32909 if (direction === "up") { 32910 swap_adjacent(_layers, layer); 32911 } else { 32912 swap_adjacent(_layers, layer - 1); 32913 } 32914 return _layers[layer]; 32915 }, 32916 change_active_layer: function(layer) { 32917 return _layers[layer]; 32918 }, 32919 reset() {
32920 _layers.forEach((layer) => { 32921 layer.draw_texture.destroy(true); 32922 layer.erase_texture.destroy(true); 32923 layer.composite.destroy(true); 32924 }); 32925 _layers = []; 32926 position = 0; 32927 }, 32928 async add_layer_from_blob(container, renderer, blob) { 32929 const img = await createImageBitmap(blob); 32930 const bitmap_texture = Texture.from(img); 32931 const sprite = new Sprite(bitmap_texture); 32932 sprite.zIndex = 0; 32933 const [layer, layers] = this.add_layer( 32934 container, 32935 renderer, 32936 sprite.width, 32937 sprite.height 32938 ); 32939 renderer.render(sprite, { 32940 renderTexture: layer.draw_texture 32941 }); 32942 return [layer, layers]; 32943 }, 32944 get_layers() { 32945 return _layers; 32946 } 32947 }; 32948} 32949 32950const Controls_svelte_svelte_type_style_lang = ''; 32951 32952/* home/runner/work/gradio/gradio/js/imageeditor/shared/Controls.svelte generated by Svelte v4.2.2 */ 32953const { 32954 SvelteComponent: SvelteComponent$4, 32955 append: append$3, 32956 attr: attr$3, 32957 check_outros: check_outros$2, 32958 create_component: create_component$4, 32959 destroy_component: destroy_component$4, 32960 detach: detach$4, 32961 element: element$3, 32962 group_outros: group_outros$2, 32963 init: init$4, 32964 insert: insert$4, 32965 mount_component: mount_component$4, 32966 safe_not_equal: safe_not_equal$4, 32967 space: space$4, 32968 transition_in: transition_in$4, 32969 transition_out: transition_out$4 32970} = window.__gradio__svelte__internal; 32971const { createEventDispatcher: createEventDispatcher$2 } = window.__gradio__svelte__internal; 32972function create_if_block$3(ctx) { 32973 let div; 32974 let iconbutton; 32975 let current; 32976 32977 iconbutton = new IconButton({ 32978 props: { 32979 disabled: !/*can_save*/ ctx[2], 32980 Icon: Check, 32981 label: "Save changes", 32982 background: "var(--color-green-500)", 32983 color: "#fff" 32984 } 32985 }); 32986 32987 iconbutton.$on("click", /*click_handler_3*/ ctx[8]); 32988 32989 return { 32990 c() { 32991 div = element$3("div"); 32992 create_component$4(iconbutton.$$.fragment); 32993 attr$3(div, "class", "row-wrap save svelte-1jbc3f8"); 32994 }, 32995 m(target, anchor) { 32996 insert$4(target, div, anchor); 32997 mount_component$4(iconbutton, div, null); 32998 current = true; 32999 }, 33000 p(ctx, dirty) { 33001 const iconbutton_changes = {}; 33002 if (dirty & /*can_save*/ 4) iconbutton_changes.disabled = !/*can_save*/ ctx[2]; 33003 iconbutton.$set(iconbutton_changes); 33004 }, 33005 i(local) { 33006 if (current) return; 33007 transition_in$4(iconbutton.$$.fragment, local); 33008 current = true; 33009 }, 33010 o(local) { 33011 transition_out$4(iconbutton.$$.fragment, local); 33012 current = false; 33013 }, 33014 d(detaching) { 33015 if (detaching) { 33016 detach$4(div); 33017 } 33018 33019 destroy_component$4(iconbutton); 33020 } 33021 }; 33022} 33023 33024function create_fragment$4(ctx) { 33025 let div1; 33026 let div0; 33027 let iconbutton0; 33028 let t0; 33029 let iconbutton1; 33030 let t1; 33031 let iconbutton2; 33032 let t2; 33033 let current; 33034 33035 iconbutton0 = new IconButton({ 33036 props: { 33037 disabled: !/*can_undo*/ ctx[0], 33038 Icon: Undo, 33039 label: "Undo" 33040 } 33041 }); 33042 33043 iconbutton0.$on("click", /*click_handler*/ ctx[5]); 33044 33045 iconbutton1 = new IconButton({ 33046 props: { 33047 disabled: !/*can_redo*/ ctx[1], 33048 Icon: Redo, 33049 label: "Redo" 33050 } 33051 }); 33052 33053 iconbutton1.$on("click", /*click_handler_1*/ ctx[6]); 33054 33055 iconbutton2 = new IconButton({ 33056 props: { Icon: Clear, label: "Clear canvas" } 33057 }); 33058 33059 iconbutton2.$on("click", /*click_handler_2*/ ctx[7]); 33060 let if_block = /*changeable*/ ctx[3] && create_if_block$3(ctx); 33061 33062 return { 33063 c() { 33064 div1 = element$3("div"); 33065 div0 = element$3("div"); 33066 create_component$4(iconbutton0.$$.fragment); 33067 t0 = space$4(); 33068 create_component$4(iconbutton1.$$.fragment); 33069 t1 = space$4(); 33070 create_component$4(iconbutton2.$$.fragment); 33071 t2 = space$4(); 33072 if (if_block) if_block.c(); 33073 attr$3(div0, "class", "row-wrap svelte-1jbc3f8"); 33074 attr$3(div1, "class", "controls-wrap svelte-1jbc3f8"); 33075 }, 33076 m(target, anchor) { 33077 insert$4(target, div1, anchor); 33078 append$3(div1, div0); 33079 mount_component$4(iconbutton0, div0, null); 33080 append$3(div0, t0);
33081 mount_component$4(iconbutton1, div0, null); 33082 append$3(div0, t1); 33083 mount_component$4(iconbutton2, div0, null); 33084 append$3(div1, t2); 33085 if (if_block) if_block.m(div1, null); 33086 current = true; 33087 }, 33088 p(ctx, [dirty]) { 33089 const iconbutton0_changes = {}; 33090 if (dirty & /*can_undo*/ 1) iconbutton0_changes.disabled = !/*can_undo*/ ctx[0]; 33091 iconbutton0.$set(iconbutton0_changes); 33092 const iconbutton1_changes = {}; 33093 if (dirty & /*can_redo*/ 2) iconbutton1_changes.disabled = !/*can_redo*/ ctx[1]; 33094 iconbutton1.$set(iconbutton1_changes); 33095 33096 if (/*changeable*/ ctx[3]) { 33097 if (if_block) { 33098 if_block.p(ctx, dirty); 33099 33100 if (dirty & /*changeable*/ 8) { 33101 transition_in$4(if_block, 1); 33102 } 33103 } else { 33104 if_block = create_if_block$3(ctx); 33105 if_block.c(); 33106 transition_in$4(if_block, 1); 33107 if_block.m(div1, null); 33108 } 33109 } else if (if_block) { 33110 group_outros$2(); 33111 33112 transition_out$4(if_block, 1, 1, () => { 33113 if_block = null; 33114 }); 33115 33116 check_outros$2(); 33117 } 33118 }, 33119 i(local) { 33120 if (current) return; 33121 transition_in$4(iconbutton0.$$.fragment, local); 33122 transition_in$4(iconbutton1.$$.fragment, local); 33123 transition_in$4(iconbutton2.$$.fragment, local); 33124 transition_in$4(if_block); 33125 current = true; 33126 }, 33127 o(local) { 33128 transition_out$4(iconbutton0.$$.fragment, local); 33129 transition_out$4(iconbutton1.$$.fragment, local); 33130 transition_out$4(iconbutton2.$$.fragment, local); 33131 transition_out$4(if_block); 33132 current = false; 33133 }, 33134 d(detaching) { 33135 if (detaching) { 33136 detach$4(div1); 33137 } 33138 33139 destroy_component$4(iconbutton0); 33140 destroy_component$4(iconbutton1); 33141 destroy_component$4(iconbutton2); 33142 if (if_block) if_block.d(); 33143 } 33144 }; 33145} 33146 33147function instance$4($$self, $$props, $$invalidate) { 33148 let { can_undo = false } = $$props; 33149 let { can_redo = false } = $$props; 33150 let { can_save = false } = $$props; 33151 let { changeable = false } = $$props; 33152 const dispatch = createEventDispatcher$2(); 33153 33154 const click_handler = event => { 33155 dispatch("undo"); 33156 event.stopPropagation(); 33157 }; 33158 33159 const click_handler_1 = event => { 33160 dispatch("redo"); 33161 event.stopPropagation(); 33162 }; 33163 33164 const click_handler_2 = event => { 33165 dispatch("remove_image"); 33166 event.stopPropagation(); 33167 }; 33168 33169 const click_handler_3 = event => { 33170 dispatch("save"); 33171 event.stopPropagation(); 33172 }; 33173 33174 $$self.$$set = $$props => {
33175 if ('can_undo' in $$props) $$invalidate(0, can_undo = $$props.can_undo); 33176 if ('can_redo' in $$props) $$invalidate(1, can_redo = $$props.can_redo); 33177 if ('can_save' in $$props) $$invalidate(2, can_save = $$props.can_save); 33178 if ('changeable' in $$props) $$invalidate(3, changeable = $$props.changeable); 33179 }; 33180 33181 return [ 33182 can_undo, 33183 can_redo, 33184 can_save, 33185 changeable, 33186 dispatch, 33187 click_handler, 33188 click_handler_1, 33189 click_handler_2, 33190 click_handler_3 33191 ]; 33192} 33193 33194class Controls extends SvelteComponent$4 { 33195 constructor(options) { 33196 super(); 33197 33198 init$4(this, options, instance$4, create_fragment$4, safe_not_equal$4, { 33199 can_undo: 0, 33200 can_redo: 1, 33201 can_save: 2, 33202 changeable: 3 33203 }); 33204 } 33205} 33206 33207const ImageEditor_svelte_svelte_type_style_lang = ''; 33208 33209/* home/runner/work/gradio/gradio/js/imageeditor/shared/ImageEditor.svelte generated by Svelte v4.2.2 */ 33210const { 33211 SvelteComponent: SvelteComponent$3, 33212 append: append$2, 33213 attr: attr$2, 33214 binding_callbacks: binding_callbacks$2, 33215 component_subscribe: component_subscribe$1, 33216 create_component: create_component$3, 33217 create_slot, 33218 destroy_component: destroy_component$3, 33219 detach: detach$3, 33220 element: element$2, 33221 get_all_dirty_from_scope, 33222 get_slot_changes, 33223 init: init$3, 33224 insert: insert$3, 33225 listen: listen$1, 33226 mount_component: mount_component$3, 33227 safe_not_equal: safe_not_equal$3, 33228 set_store_value: set_store_value$1, 33229 set_style, 33230 space: space$3, 33231 toggle_class: toggle_class$1, 33232 transition_in: transition_in$3, 33233 transition_out: transition_out$3, 33234 update_slot_base 33235} = window.__gradio__svelte__internal;const { onMount: onMount$1, setContext, createEventDispatcher: createEventDispatcher$1, tick: tick$1 } = window.__gradio__svelte__internal; 33236function create_fragment$3(ctx) { 33237 let div3; 33238 let controls; 33239 let t0; 33240 let div1; 33241 let div0; 33242 let style_transform = `translate(${/*$position_spring*/ ctx[6].x}px, ${/*$position_spring*/ ctx[6].y}px)`; 33243 let t1; 33244 let t2; 33245 let div2; 33246 let style_width = `${/*$crop*/ ctx[7][2] * /*$editor_box*/ ctx[9].child_width}px`; 33247 let style_height = `${/*$crop*/ ctx[7][3] * /*$editor_box*/ ctx[9].child_height}px`; 33248 let style_top = `${/*$crop*/ ctx[7][1] * /*$editor_box*/ ctx[9].child_height + (/*$editor_box*/ ctx[9].child_top - /*$editor_box*/ ctx[9].parent_top)}px`; 33249 let style_left = `${/*$crop*/ ctx[7][0] * /*$editor_box*/ ctx[9].child_width + (/*$editor_box*/ ctx[9].child_left - /*$editor_box*/ ctx[9].parent_left)}px`; 33250 let current; 33251 let mounted; 33252 let dispose; 33253 33254 controls = new Controls({ 33255 props: { 33256 can_undo: /*$can_undo*/ ctx[10], 33257 can_redo: /*$can_redo*/ ctx[11], 33258 can_save: /*saved_history*/ ctx[8] !== /*$current_history*/ ctx[5], 33259 changeable: /*changeable*/ ctx[1] 33260 } 33261 }); 33262 33263 controls.$on("undo", /*CommandManager*/ ctx[17].undo); 33264 controls.$on("redo", /*CommandManager*/ ctx[17].redo); 33265 controls.$on("remove_image", /*handle_remove*/ ctx[2]); 33266 controls.$on("save", /*handle_save*/ ctx[26]); 33267 const default_slot_template = /*#slots*/ ctx[36].default; 33268 const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[35], null); 33269 33270 return { 33271 c() { 33272 div3 = element$2("div"); 33273 create_component$3(controls.$$.fragment); 33274 t0 = space$3(); 33275 div1 = element$2("div"); 33276 div0 = element$2("div"); 33277 t1 = space$3(); 33278 if (default_slot) default_slot.c(); 33279 t2 = space$3(); 33280 div2 = element$2("div"); 33281 attr$2(div0, "class", "stage-wrap svelte-h1irw9"); 33282 toggle_class$1(div0, "bg", !/*bg*/ ctx[0]); 33283 set_style(div0, "transform", style_transform); 33284 attr$2(div1, "class", "wrap svelte-h1irw9"); 33285 attr$2(div2, "class", "border svelte-h1irw9"); 33286 set_style(div2, "width", style_width); 33287 set_style(div2, "height", style_height); 33288 set_style(div2, "top", style_top); 33289 set_style(div2, "left", style_left); 33290 attr$2(div3, "data-testid", "image"); 33291 attr$2(div3, "class", "image-container svelte-h1irw9"); 33292 }, 33293 m(target, anchor) { 33294 insert$3(target, div3, anchor); 33295 mount_component$3(controls, div3, null); 33296 append$2(div3, t0); 33297 append$2(div3, div1); 33298 append$2(div1, div0); 33299 /*div0_binding*/ ctx[38](div0); 33300 /*div1_binding*/ ctx[39](div1); 33301 append$2(div3, t1); 33302 33303 if (default_slot) { 33304 default_slot.m(div3, null); 33305 } 33306 33307 append$2(div3, t2); 33308 append$2(div3, div2); 33309 current = true; 33310 33311 if (!mounted) { 33312 dispose = listen$1(window, "scroll", /*scroll_handler*/ ctx[37]); 33313 mounted = true; 33314 } 33315 }, 33316 p(ctx, dirty) { 33317 const controls_changes = {};
33318 if (dirty[0] & /*$can_undo*/ 1024) controls_changes.can_undo = /*$can_undo*/ ctx[10]; 33319 if (dirty[0] & /*$can_redo*/ 2048) controls_changes.can_redo = /*$can_redo*/ ctx[11]; 33320 if (dirty[0] & /*saved_history, $current_history*/ 288) controls_changes.can_save = /*saved_history*/ ctx[8] !== /*$current_history*/ ctx[5]; 33321 if (dirty[0] & /*changeable*/ 2) controls_changes.changeable = /*changeable*/ ctx[1]; 33322 controls.$set(controls_changes); 33323 33324 if (!current || dirty[0] & /*bg*/ 1) { 33325 toggle_class$1(div0, "bg", !/*bg*/ ctx[0]); 33326 } 33327 33328 if (dirty[0] & /*$position_spring*/ 64 && style_transform !== (style_transform = `translate(${/*$position_spring*/ ctx[6].x}px, ${/*$position_spring*/ ctx[6].y}px)`)) { 33329 set_style(div0, "transform", style_transform); 33330 } 33331 33332 if (default_slot) { 33333 if (default_slot.p && (!current || dirty[1] & /*$$scope*/ 16)) { 33334 update_slot_base( 33335 default_slot, 33336 default_slot_template, 33337 ctx, 33338 /*$$scope*/ ctx[35], 33339 !current 33340 ? get_all_dirty_from_scope(/*$$scope*/ ctx[35]) 33341 : get_slot_changes(default_slot_template, /*$$scope*/ ctx[35], dirty, null), 33342 null 33343 ); 33344 } 33345 } 33346 33347 if (dirty[0] & /*$crop, $editor_box*/ 640 && style_width !== (style_width = `${/*$crop*/ ctx[7][2] * /*$editor_box*/ ctx[9].child_width}px`)) { 33348 set_style(div2, "width", style_width); 33349 } 33350 33351 if (dirty[0] & /*$crop, $editor_box*/ 640 && style_height !== (style_height = `${/*$crop*/ ctx[7][3] * /*$editor_box*/ ctx[9].child_height}px`)) { 33352 set_style(div2, "height", style_height); 33353 } 33354 33355 if (dirty[0] & /*$crop, $editor_box*/ 640 && style_top !== (style_top = `${/*$crop*/ ctx[7][1] * /*$editor_box*/ ctx[9].child_height + (/*$editor_box*/ ctx[9].child_top - /*$editor_box*/ ctx[9].parent_top)}px`)) { 33356 set_style(div2, "top", style_top); 33357 } 33358 33359 if (dirty[0] & /*$crop, $editor_box*/ 640 && style_left !== (style_left = `${/*$crop*/ ctx[7][0] * /*$editor_box*/ ctx[9].child_width + (/*$editor_box*/ ctx[9].child_left - /*$editor_box*/ ctx[9].parent_left)}px`)) { 33360 set_style(div2, "left", style_left); 33361 } 33362 }, 33363 i(local) { 33364 if (current) return;
33365 transition_in$3(controls.$$.fragment, local); 33366 transition_in$3(default_slot, local); 33367 current = true; 33368 }, 33369 o(local) { 33370 transition_out$3(controls.$$.fragment, local); 33371 transition_out$3(default_slot, local); 33372 current = false; 33373 }, 33374 d(detaching) { 33375 if (detaching) { 33376 detach$3(div3); 33377 } 33378 33379 destroy_component$3(controls); 33380 /*div0_binding*/ ctx[38](null); 33381 /*div1_binding*/ ctx[39](null); 33382 if (default_slot) default_slot.d(detaching); 33383 mounted = false; 33384 dispose(); 33385 } 33386 }; 33387} 33388 33389const EDITOR_KEY = Symbol("editor"); 33390 33391function instance$3($$self, $$props, $$invalidate) { 33392 let $active_tool; 33393 let $current_history; 33394 let $reset_context; 33395 let $contexts; 33396 let $pixi; 33397 let $dimensions; 33398 let $init_context; 33399 let $position_spring; 33400 let $crop; 33401 let $editor_box; 33402 let $can_undo; 33403 let $can_redo; 33404 let { $$slots: slots = {}, $$scope } = $$props; 33405 let { antialias = true } = $$props; 33406 let { crop_size = [800, 600] } = $$props; 33407 let { changeable = false } = $$props; 33408 let { history } = $$props; 33409 let { bg = false } = $$props; 33410 let { sources } = $$props; 33411 const dispatch = createEventDispatcher$1(); 33412 let { crop_constraint = false } = $$props; 33413 let dimensions = writable(crop_size); 33414 component_subscribe$1($$self, dimensions, value => $$invalidate(43, $dimensions = value)); 33415 33416 let editor_box = writable({ 33417 parent_width: 0, 33418 parent_height: 0, 33419 parent_top: 0, 33420 parent_left: 0, 33421 parent_right: 0, 33422 parent_bottom: 0, 33423 child_width: 0, 33424 child_height: 0, 33425 child_top: 0, 33426 child_left: 0, 33427 child_right: 0, 33428 child_bottom: 0 33429 }); 33430 33431 component_subscribe$1($$self, editor_box, value => $$invalidate(9, $editor_box = value)); 33432 const crop = writable([0, 0, 1, 1]); 33433 component_subscribe$1($$self, crop, value => $$invalidate(7, $crop = value)); 33434 const position_spring = spring({ x: 0, y: 0 }, { stiffness: 0.1, damping: 0.5 }); 33435 component_subscribe$1($$self, position_spring, value => $$invalidate(6, $position_spring = value)); 33436 const pixi = writable(null); 33437 component_subscribe$1($$self, pixi, value => $$invalidate(42, $pixi = value)); 33438 const CommandManager = command_manager(); 33439 const { can_redo, can_undo, current_history } = CommandManager; 33440 component_subscribe$1($$self, can_redo, value => $$invalidate(11, $can_redo = value)); 33441 component_subscribe$1($$self, can_undo, value => $$invalidate(10, $can_undo = value)); 33442 component_subscribe$1($$self, current_history, value => $$invalidate(5, $current_history = value)); 33443 const active_tool = writable("bg"); 33444 component_subscribe$1($$self, active_tool, value => $$invalidate(34, $active_tool = value)); 33445 const reset_context = writable({}); 33446 component_subscribe$1($$self, reset_context, value => $$invalidate(40, $reset_context = value)); 33447 const init_context = writable({}); 33448 component_subscribe$1($$self, init_context, value => $$invalidate(44, $init_context = value)); 33449 const contexts = writable([]); 33450 component_subscribe$1($$self, contexts, value => $$invalidate(41, $contexts = value)); 33451 const sort_order = ["bg", "layers", "crop", "draw", "erase"]; 33452 33453 const editor_context = setContext(EDITOR_KEY, { 33454 pixi, 33455 current_layer: writable(null), 33456 dimensions, 33457 editor_box, 33458 active_tool, 33459 crop, 33460 position_spring, 33461 command_manager: CommandManager, 33462 current_history, 33463 register_context: (type, { reset_fn, init_fn }) => { 33464 contexts.update(c => [...c, type]); 33465 init_context.update(c => ({ ...c, [type]: init_fn })); 33466 reset_context.update(c => ({ ...c, [type]: reset_fn })); 33467 }, 33468 reset: (clear_image, dimensions) => { 33469 $$invalidate(0, bg = false); 33470 33471 const _sorted_contexts = $contexts.sort((a, b) => { 33472 return sort_order.indexOf(a) - sort_order.indexOf(b); 33473 }); 33474 33475 for (const k of _sorted_contexts) { 33476 if (k in $reset_context && typeof $reset_context[k] === "function") { 33477 $reset_context[k]?.(); 33478 } 33479 } 33480 33481 for (const k of _sorted_contexts) { 33482 if (k in $init_context && typeof $init_context[k] === "function") { 33483 if (k === "bg" && !clear_image) { 33484 continue; 33485 } else { 33486 $init_context[k]?.(dimensions); 33487 } 33488 } 33489 33490 CommandManager.reset(); 33491 $pixi?.resize?.(...dimensions); 33492 } 33493 } 33494 }); 33495 33496 let pixi_target; 33497 let canvas_wrap; 33498 33499 function get_dimensions(parent, child) { 33500 if (!parent || !child) return; 33501 const { width: parent_width, height: parent_height, top: parent_top, left: parent_left, right: parent_right, bottom: parent_bottom } = canvas_wrap.getBoundingClientRect(); 33502 const { width: child_width, height: child_height, top: child_top, left: child_left, right: child_right, bottom: child_bottom } = child.getBoundingClientRect(); 33503 33504 editor_box.set({ 33505 child_width, 33506 child_height, 33507 child_left, 33508 child_right, 33509 child_top, 33510 child_bottom, 33511 parent_width, 33512 parent_height, 33513 parent_left, 33514 parent_right, 33515 parent_top, 33516 parent_bottom 33517 }); 33518 } 33519 33520 function set_crop() { 33521 requestAnimationFrame(() => { 33522 tick$1().then(v => set_store_value$1(active_tool, $active_tool = "crop", $active_tool)); 33523 }); 33524 } 33525 33526 function reposition_canvas() { 33527 if (!$editor_box) return; 33528 const [l, t, w, h] = $crop; 33529 const cx = l * $editor_box.child_width;
33530 const cy = t * $editor_box.child_height; 33531 const cw = w * $editor_box.child_width; 33532 const ch = h * $editor_box.child_height; 33533 const x = 0.5 * $editor_box.child_width - cx - cw / 2; 33534 const y = 0.5 * $editor_box.child_height - cy - ch / 2; 33535 position_spring.set({ x, y }); 33536 } 33537 33538 async function get_blobs() { 33539 if (!$pixi || !$pixi.get_layers) return { 33540 background: null, 33541 layers: [], 33542 composite: null 33543 }; 33544 33545 const [l, t, w, h] = $crop; 33546 return $pixi?.get_blobs($pixi.get_layers(), new Rectangle(l * $dimensions[0], t * $dimensions[1], w * $dimensions[0], h * $dimensions[1]), $dimensions); 33547 } 33548 33549 function handle_remove() { 33550 editor_context.reset(true, $dimensions); 33551 33552 if (!sources.length) { 33553 set_tool("draw"); 33554 } else { 33555 set_tool("bg"); 33556 } 33557 } 33558 33559 onMount$1(() => { 33560 const app = create_pixi_app(pixi_target, ...crop_size, antialias); 33561 33562 function resize(width, height) { 33563 app.resize(width, height); 33564 dimensions.set([width, height]); 33565 } 33566 33567 pixi.set({ ...app, resize }); 33568 33569 const resizer = new ResizeObserver(entries => { 33570 for (const entry of entries) { 33571 get_dimensions(canvas_wrap, pixi_target); 33572 } 33573 }); 33574 33575 resizer.observe(canvas_wrap); 33576 resizer.observe(pixi_target); 33577 33578 for (const k of $contexts) { 33579 if (k in $init_context && typeof $init_context[k] === "function") { 33580 $init_context[k]?.($dimensions); 33581 } 33582 } 33583 33584 resize(...$dimensions); 33585 33586 return () => { 33587 $pixi?.destroy(); 33588 resizer.disconnect(); 33589 33590 for (const k of $contexts) { 33591 if (k in $reset_context) { 33592 $reset_context[k]?.(); 33593 } 33594 } 33595 }; 33596 }); 33597 33598 let saved_history = $current_history; 33599 33600 function handle_save() { 33601 $$invalidate(8, saved_history = $current_history); 33602 dispatch("save"); 33603 } 33604 33605 function set_tool(tool) { 33606 set_store_value$1(active_tool, $active_tool = tool, $active_tool); 33607 } 33608 33609 const scroll_handler = () => get_dimensions(canvas_wrap, pixi_target); 33610 33611 function div0_binding($$value) { 33612 binding_callbacks$2[$$value ? 'unshift' : 'push'](() => { 33613 pixi_target = $$value; 33614 $$invalidate(3, pixi_target); 33615 }); 33616 } 33617 33618 function div1_binding($$value) { 33619 binding_callbacks$2[$$value ? 'unshift' : 'push'](() => { 33620 canvas_wrap = $$value; 33621 $$invalidate(4, canvas_wrap); 33622 }); 33623 } 33624 33625 $$self.$$set = $$props => {
33626 if ('antialias' in $$props) $$invalidate(28, antialias = $$props.antialias); 33627 if ('crop_size' in $$props) $$invalidate(29, crop_size = $$props.crop_size); 33628 if ('changeable' in $$props) $$invalidate(1, changeable = $$props.changeable); 33629 if ('history' in $$props) $$invalidate(27, history = $$props.history); 33630 if ('bg' in $$props) $$invalidate(0, bg = $$props.bg); 33631 if ('sources' in $$props) $$invalidate(30, sources = $$props.sources); 33632 if ('crop_constraint' in $$props) $$invalidate(31, crop_constraint = $$props.crop_constraint); 33633 if ('$$scope' in $$props) $$invalidate(35, $$scope = $$props.$$scope); 33634 }; 33635 33636 $$self.$$.update = () => { 33637 if ($$self.$$.dirty[0] & /*$current_history*/ 32 | $$self.$$.dirty[1] & /*$active_tool*/ 8) { 33638 { 33639 $$invalidate(27, history = !!$current_history.previous || $active_tool !== "bg"); 33640 } 33641 } 33642 33643 if ($$self.$$.dirty[0] & /*bg, history*/ 134217729 | $$self.$$.dirty[1] & /*crop_constraint*/ 1) { 33644 if (crop_constraint && bg && !history) { 33645 set_crop(); 33646 } 33647 } 33648 33649 if ($$self.$$.dirty[0] & /*$crop*/ 128) { 33650 $crop && reposition_canvas(); 33651 } 33652 33653 if ($$self.$$.dirty[0] & /*$position_spring, canvas_wrap, pixi_target*/ 88) { 33654 $position_spring && get_dimensions(canvas_wrap, pixi_target); 33655 } 33656 }; 33657 33658 return [ 33659 bg, 33660 changeable, 33661 handle_remove, 33662 pixi_target, 33663 canvas_wrap, 33664 $current_history, 33665 $position_spring, 33666 $crop, 33667 saved_history, 33668 $editor_box, 33669 $can_undo, 33670 $can_redo, 33671 dimensions, 33672 editor_box, 33673 crop, 33674 position_spring, 33675 pixi, 33676 CommandManager, 33677 can_redo, 33678 can_undo, 33679 current_history, 33680 active_tool, 33681 reset_context, 33682 init_context, 33683 contexts, 33684 get_dimensions, 33685 handle_save, 33686 history, 33687 antialias, 33688 crop_size, 33689 sources, 33690 crop_constraint, 33691 get_blobs, 33692 set_tool, 33693 $active_tool, 33694 $$scope, 33695 slots, 33696 scroll_handler, 33697 div0_binding, 33698 div1_binding 33699 ]; 33700} 33701 33702class ImageEditor extends SvelteComponent$3 { 33703 constructor(options) { 33704 super(); 33705 33706 init$3( 33707 this, 33708 options, 33709 instance$3, 33710 create_fragment$3, 33711 safe_not_equal$3, 33712 { 33713 antialias: 28, 33714 crop_size: 29, 33715 changeable: 1, 33716 history: 27, 33717 bg: 0, 33718 sources: 30, 33719 crop_constraint: 31, 33720 get_blobs: 32, 33721 handle_remove: 2, 33722 set_tool: 33 33723 }, 33724 null, 33725 [-1, -1] 33726 ); 33727 } 33728 33729 get get_blobs() { 33730 return this.$$.ctx[32]; 33731 } 33732 33733 get handle_remove() { 33734 return this.$$.ctx[2]; 33735 } 33736 33737 get set_tool() { 33738 return this.$$.ctx[33]; 33739 } 33740} 33741 33742const Layers_svelte_svelte_type_style_lang = ''; 33743 33744/* home/runner/work/gradio/gradio/js/imageeditor/shared/layers/Layers.svelte generated by Svelte v4.2.2 */ 33745const { 33746 SvelteComponent: SvelteComponent$2, 33747 action_destroyer, 33748 append: append$1, 33749 attr: attr$1, 33750 component_subscribe, 33751 create_component: create_component$2, 33752 destroy_block, 33753 destroy_component: destroy_component$2, 33754 detach: detach$2, 33755 element: element$1, 33756 ensure_array_like, 33757 init: init$2, 33758 insert: insert$2, 33759 is_function, 33760 listen, 33761 mount_component: mount_component$2, 33762 run_all, 33763 safe_not_equal: safe_not_equal$2, 33764 set_data, 33765 set_store_value, 33766 space: space$2, 33767 text, 33768 toggle_class, 33769 transition_in: transition_in$2, 33770 transition_out: transition_out$2, 33771 update_keyed_each 33772} = window.__gradio__svelte__internal; 33773const { createEventDispatcher, getContext, onMount, tick } = window.__gradio__svelte__internal; 33774function get_each_context(ctx, list, i) { 33775 const child_ctx = ctx.slice(); 33776 child_ctx[16] = list[i]; 33777 child_ctx[18] = i; 33778 return child_ctx; 33779} 33780 33781// (72:1) {#if show_layers} 33782function create_if_block$2(ctx) { 33783 let ul; 33784 let each_blocks = []; 33785 let each_1_lookup = new Map(); 33786 let t0; 33787 let li; 33788 let button; 33789 let mounted; 33790 let dispose; 33791 let each_value = ensure_array_like(/*layers*/ ctx[1]); 33792 const get_key = ctx => /*i*/ ctx[18]; 33793 33794 for (let i = 0; i < each_value.length; i += 1) { 33795 let child_ctx = get_each_context(ctx, each_value, i); 33796 let key = get_key(child_ctx); 33797 each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx)); 33798 } 33799 33800 return { 33801 c() { 33802 ul = element$1("ul"); 33803 33804 for (let i = 0; i < each_blocks.length; i += 1) { 33805 each_blocks[i].c(); 33806 } 33807 33808 t0 = space$2(); 33809 li = element$1("li"); 33810 button = element$1("button"); 33811 button.textContent = "+"; 33812 attr$1(button, "aria-label", "Add Layer"); 33813 attr$1(button, "class", "svelte-g7pfx4"); 33814 }, 33815 m(target, anchor) { 33816 insert$2(target, ul, anchor); 33817 33818 for (let i = 0; i < each_blocks.length; i += 1) { 33819 if (each_blocks[i]) { 33820 each_blocks[i].m(ul, null); 33821 } 33822 } 33823 33824 append$1(ul, t0); 33825 append$1(ul, li); 33826 append$1(li, button); 33827 33828 if (!mounted) { 33829 dispose = listen(button, "click", /*new_layer*/ ctx[7]); 33830 mounted = true; 33831 } 33832 }, 33833 p(ctx, dirty) {
33834 if (dirty & /*$current_layer, layers, LayerManager*/ 70) { 33835 each_value = ensure_array_like(/*layers*/ ctx[1]); 33836 each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, destroy_block, create_each_block, t0, get_each_context); 33837 } 33838 }, 33839 d(detaching) { 33840 if (detaching) { 33841 detach$2(ul); 33842 } 33843 33844 for (let i = 0; i < each_blocks.length; i += 1) { 33845 each_blocks[i].d(); 33846 } 33847 33848 mounted = false; 33849 dispose(); 33850 } 33851 }; 33852} 33853 33854// (74:3) {#each layers as layer, i (i)} 33855function create_each_block(key_1, ctx) { 33856 let li; 33857 let button; 33858 let t0; 33859 let t1_value = /*i*/ ctx[18] + 1 + ""; 33860 let t1; 33861 let mounted; 33862 let dispose; 33863 33864 function click_handler_1() { 33865 return /*click_handler_1*/ ctx[10](/*i*/ ctx[18]); 33866 } 33867 33868 return { 33869 key: key_1, 33870 first: null, 33871 c() { 33872 li = element$1("li"); 33873 button = element$1("button"); 33874 t0 = text("Layer "); 33875 t1 = text(t1_value); 33876 attr$1(button, "class", "svelte-g7pfx4"); 33877 toggle_class(button, "selected_layer", /*$current_layer*/ ctx[2] === /*layer*/ ctx[16]); 33878 this.first = li; 33879 }, 33880 m(target, anchor) { 33881 insert$2(target, li, anchor); 33882 append$1(li, button); 33883 append$1(button, t0); 33884 append$1(button, t1); 33885 33886 if (!mounted) { 33887 dispose = listen(button, "click", click_handler_1); 33888 mounted = true; 33889 } 33890 }, 33891 p(new_ctx, dirty) { 33892 ctx = new_ctx; 33893 if (dirty & /*layers*/ 2 && t1_value !== (t1_value = /*i*/ ctx[18] + 1 + "")) set_data(t1, t1_value); 33894 33895 if (dirty & /*$current_layer, layers*/ 6) { 33896 toggle_class(button, "selected_layer", /*$current_layer*/ ctx[2] === /*layer*/ ctx[16]); 33897 } 33898 }, 33899 d(detaching) { 33900 if (detaching) { 33901 detach$2(li); 33902 } 33903 33904 mounted = false; 33905 dispose(); 33906 } 33907 }; 33908} 33909 33910function create_fragment$2(ctx) { 33911 let div; 33912 let button; 33913 let t0; 33914 let span; 33915 let dropdownarrow; 33916 let t1; 33917 let click_outside_action; 33918 let current; 33919 let mounted; 33920 let dispose; 33921 dropdownarrow = new DropdownArrow({}); 33922 let if_block = /*show_layers*/ ctx[0] && create_if_block$2(ctx); 33923 33924 return { 33925 c() { 33926 div = element$1("div"); 33927 button = element$1("button"); 33928 t0 = text("Layers"); 33929 span = element$1("span"); 33930 create_component$2(dropdownarrow.$$.fragment); 33931 t1 = space$2(); 33932 if (if_block) if_block.c(); 33933 attr$1(span, "class", "layer-toggle svelte-g7pfx4"); 33934 attr$1(button, "aria-label", "Show Layers"); 33935 attr$1(button, "class", "svelte-g7pfx4"); 33936 attr$1(div, "class", "layer-wrap svelte-g7pfx4"); 33937 toggle_class(div, "closed", !/*show_layers*/ ctx[0]); 33938 }, 33939 m(target, anchor) { 33940 insert$2(target, div, anchor); 33941 append$1(div, button); 33942 append$1(button, t0); 33943 append$1(button, span); 33944 mount_component$2(dropdownarrow, span, null); 33945 append$1(div, t1); 33946 if (if_block) if_block.m(div, null); 33947 current = true; 33948 33949 if (!mounted) { 33950 dispose = [ 33951 listen(button, "click", /*click_handler*/ ctx[9]), 33952 action_destroyer(click_outside_action = click_outside.call(null, div, /*click_outside_function*/ ctx[11])) 33953 ]; 33954 33955 mounted = true; 33956 } 33957 }, 33958 p(ctx, [dirty]) { 33959 if (/*show_layers*/ ctx[0]) { 33960 if (if_block) { 33961 if_block.p(ctx, dirty); 33962 } else { 33963 if_block = create_if_block$2(ctx); 33964 if_block.c(); 33965 if_block.m(div, null); 33966 } 33967 } else if (if_block) { 33968 if_block.d(1); 33969 if_block = null; 33970 } 33971 33972 if (click_outside_action && is_function(click_outside_action.update) && dirty & /*show_layers*/ 1) click_outside_action.update.call(null, /*click_outside_function*/ ctx[11]); 33973 33974 if (!current || dirty & /*show_layers*/ 1) { 33975 toggle_class(div, "closed", !/*show_layers*/ ctx[0]); 33976 } 33977 }, 33978 i(local) { 33979 if (current) return; 33980 transition_in$2(dropdownarrow.$$.fragment, local); 33981 current = true; 33982 }, 33983 o(local) { 33984 transition_out$2(dropdownarrow.$$.fragment, local); 33985 current = false; 33986 }, 33987 d(detaching) { 33988 if (detaching) { 33989 detach$2(div); 33990 } 33991 33992 destroy_component$2(dropdownarrow); 33993 if (if_block) if_block.d(); 33994 mounted = false; 33995 run_all(dispose); 33996 } 33997 }; 33998} 33999 34000function is_not_null$1(x) { 34001 return x !== null; 34002} 34003 34004function instance$2($$self, $$props, $$invalidate) { 34005 let $pixi; 34006 let $current_layer; 34007 let $dimensions; 34008 let show_layers = false;
34009 let { layer_files = [] } = $$props; 34010 const { pixi, current_layer, dimensions, register_context } = getContext(EDITOR_KEY); 34011 component_subscribe($$self, pixi, value => $$invalidate(12, $pixi = value)); 34012 component_subscribe($$self, current_layer, value => $$invalidate(2, $current_layer = value)); 34013 component_subscribe($$self, dimensions, value => $$invalidate(13, $dimensions = value)); 34014 const LayerManager = layer_manager(); 34015 let layers = []; 34016 34017 register_context("layers", { 34018 init_fn: () => { 34019 new_layer(); 34020 }, 34021 reset_fn: () => { 34022 LayerManager.reset(); 34023 } 34024 }); 34025 34026 async function new_layer() { 34027 if (!$pixi) return; 34028 const [active_layer, all_layers] = LayerManager.add_layer($pixi.layer_container, $pixi.renderer, ...$dimensions); 34029 set_store_value(current_layer, $current_layer = active_layer, $current_layer); 34030 $$invalidate(1, layers = all_layers); 34031 } 34032 34033 async function render_layer_files(_layer_files) { 34034 await tick(); 34035 if (!_layer_files || _layer_files.length == 0) return; 34036 if (!$pixi) return; 34037 34038 const fetch_promises = await Promise.all(_layer_files.map(f => { 34039 if (!f || !f.url) return null; 34040 return fetch(f.url); 34041 })); 34042 34043 const blobs = await Promise.all(fetch_promises.map(p => { 34044 if (!p) return null; 34045 return p.blob(); 34046 })); 34047 34048 LayerManager.reset(); 34049 let last_layer = null; 34050 34051 for (const blob of blobs.filter(is_not_null$1)) { 34052 last_layer = await LayerManager.add_layer_from_blob($pixi.layer_container, $pixi.renderer, blob); 34053 } 34054 34055 if (!last_layer) return; 34056 set_store_value(current_layer, $current_layer = last_layer[0], $current_layer); 34057 $$invalidate(1, layers = last_layer[1]); 34058 } 34059 34060 onMount(async () => { 34061 await tick(); 34062 if (!$pixi) return; 34063 34064 set_store_value( 34065 pixi, 34066 $pixi = { 34067 ...$pixi, 34068 get_layers: LayerManager.get_layers 34069 }, 34070 $pixi 34071 ); 34072 }); 34073 34074 const click_handler = () =>
34074 $$invalidate(0, show_layers = !show_layers); 34075 const click_handler_1 = i => set_store_value(current_layer, $current_layer = LayerManager.change_active_layer(i), $current_layer); 34076 const click_outside_function = () => $$invalidate(0, show_layers = false); 34077 34078 $$self.$$set = $$props => { 34079 if ('layer_files' in $$props) $$invalidate(8, layer_files = $$props.layer_files); 34080 }; 34081 34082 $$self.$$.update = () => { 34083 if ($$self.$$.dirty & /*layer_files*/ 256) { 34084 render_layer_files(layer_files); 34085 } 34086 }; 34087 34088 return [ 34089 show_layers, 34090 layers, 34091 $current_layer, 34092 pixi, 34093 current_layer, 34094 dimensions, 34095 LayerManager, 34096 new_layer, 34097 layer_files, 34098 click_handler, 34099 click_handler_1, 34100 click_outside_function 34101 ]; 34102} 34103 34104class Layers extends SvelteComponent$2 { 34105 constructor(options) { 34106 super(); 34107 init$2(this, options, instance$2, create_fragment$2, safe_not_equal$2, { layer_files: 8 }); 34108 } 34109} 34110 34111const InteractiveImageEditor_svelte_svelte_type_style_lang = ''; 34112 34113/* home/runner/work/gradio/gradio/js/imageeditor/shared/InteractiveImageEditor.svelte generated by Svelte v4.2.2 */ 34114const { 34115 SvelteComponent: SvelteComponent$1, 34116 add_flush_callback, 34117 append, 34118 attr, 34119 bind, 34120 binding_callbacks: binding_callbacks$1, 34121 bubble: bubble$1, 34122 check_outros: check_outros$1, 34123 create_component: create_component$1, 34124 destroy_component: destroy_component$1, 34125 detach: detach$1, 34126 element, 34127 empty: empty$1, 34128 group_outros: group_outros$1, 34129 init: init$1, 34130 insert: insert$1, 34131 mount_component: mount_component$1, 34132 safe_not_equal: safe_not_equal$1, 34133 space: space$1, 34134 transition_in: transition_in$1, 34135 transition_out: transition_out$1 34136} = window.__gradio__svelte__internal; 34137function create_if_block_7(ctx) { 34138 let sources_1; 34139 let updating_bg; 34140 let current; 34141 34142 function sources_1_bg_binding(value) { 34143 /*sources_1_bg_binding*/ ctx[15](value); 34144 } 34145 34146 let sources_1_props = { 34147 i18n: /*i18n*/ ctx[3], 34148 root: /*root*/ ctx[4], 34149 sources: /*sources*/ ctx[2], 34150 background_file: normalise_file(/*value*/ ctx[7]?.background || null, /*root*/ ctx[4], /*proxy_url*/ ctx[5]) 34151 }; 34152 34153 if (/*bg*/ ctx[10] !== void 0) { 34154 sources_1_props.bg = /*bg*/ ctx[10]; 34155 } 34156 34157 sources_1 = new Sources({ props: sources_1_props }); 34158 binding_callbacks$1.push(() => bind(sources_1, 'bg', sources_1_bg_binding)); 34159 34160 return { 34161 c() { 34162 create_component$1(sources_1.$$.fragment); 34163 }, 34164 m(target, anchor) { 34165 mount_component$1(sources_1, target, anchor); 34166 current = true; 34167 }, 34168 p(ctx, dirty) { 34169 const sources_1_changes = {}; 34170 if (dirty & /*i18n*/ 8) sources_1_changes.i18n = /*i18n*/ ctx[3];
34171 if (dirty & /*root*/ 16) sources_1_changes.root = /*root*/ ctx[4]; 34172 if (dirty & /*sources*/ 4) sources_1_changes.sources = /*sources*/ ctx[2]; 34173 if (dirty & /*value, root, proxy_url*/ 176) sources_1_changes.background_file = normalise_file(/*value*/ ctx[7]?.background || null, /*root*/ ctx[4], /*proxy_url*/ ctx[5]); 34174 34175 if (!updating_bg && dirty & /*bg*/ 1024) { 34176 updating_bg = true; 34177 sources_1_changes.bg = /*bg*/ ctx[10]; 34178 add_flush_callback(() => updating_bg = false); 34179 } 34180 34181 sources_1.$set(sources_1_changes); 34182 }, 34183 i(local) { 34184 if (current) return; 34185 transition_in$1(sources_1.$$.fragment, local); 34186 current = true; 34187 }, 34188 o(local) { 34189 transition_out$1(sources_1.$$.fragment, local); 34190 current = false; 34191 }, 34192 d(detaching) { 34193 destroy_component$1(sources_1, detaching); 34194 } 34195 }; 34196} 34197 34198// (97:2) {#if transforms.includes("crop")} 34199function create_if_block_6(ctx) { 34200 let crop; 34201 let current; 34202 34203 crop = new Crop({ 34204 props: { 34205 crop_constraint: /*crop_constraint*/ ctx[12] 34206 } 34207 }); 34208 34209 return { 34210 c() { 34211 create_component$1(crop.$$.fragment); 34212 }, 34213 m(target, anchor) { 34214 mount_component$1(crop, target, anchor); 34215 current = true; 34216 }, 34217 p(ctx, dirty) { 34218 const crop_changes = {}; 34219 if (dirty & /*crop_constraint*/ 4096) crop_changes.crop_constraint = /*crop_constraint*/ ctx[12]; 34220 crop.$set(crop_changes); 34221 }, 34222 i(local) { 34223 if (current) return; 34224 transition_in$1(crop.$$.fragment, local); 34225 current = true; 34226 }, 34227 o(local) { 34228 transition_out$1(crop.$$.fragment, local); 34229 current = false; 34230 }, 34231 d(detaching) { 34232 destroy_component$1(crop, detaching); 34233 } 34234 }; 34235} 34236 34237// (100:2) {#if brush} 34238function create_if_block_5(ctx) { 34239 let brush_1; 34240 let current; 34241 34242 brush_1 = new Brush({ 34243 props: { 34244 color_mode: /*brush*/ ctx[0].color_mode, 34245 default_color: /*brush*/ ctx[0].default_color, 34246 default_size: /*brush*/ ctx[0].default_size, 34247 colors: /*brush*/ ctx[0].colors, 34248 mode: "draw" 34249 } 34250 }); 34251 34252 return { 34253 c() { 34254 create_component$1(brush_1.$$.fragment); 34255 }, 34256 m(target, anchor) { 34257 mount_component$1(brush_1, target, anchor); 34258 current = true; 34259 }, 34260 p(ctx, dirty) { 34261 const brush_1_changes = {}; 34262 if (dirty & /*brush*/ 1) brush_1_changes.color_mode = /*brush*/ ctx[0].color_mode; 34263 if (dirty & /*brush*/ 1) brush_1_changes.default_color = /*brush*/ ctx[0].default_color; 34264 if (dirty & /*brush*/ 1) brush_1_changes.default_size = /*brush*/ ctx[0].default_size; 34265 if (dirty & /*brush*/ 1) brush_1_changes.colors = /*brush*/ ctx[0].colors; 34266 brush_1.$set(brush_1_changes); 34267 }, 34268 i(local) { 34269 if (current) return; 34270 transition_in$1(brush_1.$$.fragment, local); 34271 current = true; 34272 }, 34273 o(local) { 34274 transition_out$1(brush_1.$$.fragment, local); 34275 current = false; 34276 }, 34277 d(detaching) { 34278 destroy_component$1(brush_1, detaching); 34279 } 34280 }; 34281} 34282 34283// (110:2) {#if brush && eraser} 34284function create_if_block_4(ctx) { 34285 let brush_1; 34286 let current; 34287 34288 brush_1 = new Brush({ 34289 props: { 34290 default_size: /*eraser*/ ctx[1].default_size, 34291 mode: "erase" 34292 } 34293 }); 34294 34295 return { 34296 c() { 34297 create_component$1(brush_1.$$.fragment); 34298 }, 34299 m(target, anchor) { 34300 mount_component$1(brush_1, target, anchor); 34301 current = true; 34302 }, 34303 p(ctx, dirty) { 34304 const brush_1_changes = {}; 34305 if (dirty & /*eraser*/ 2) brush_1_changes.default_size = /*eraser*/ ctx[1].default_size; 34306 brush_1.$set(brush_1_changes); 34307 }, 34308 i(local) { 34309 if (current) return; 34310 transition_in$1(brush_1.$$.fragment, local); 34311 current = true; 34312 }, 34313 o(local) { 34314 transition_out$1(brush_1.$$.fragment, local); 34315 current = false; 34316 }, 34317 d(detaching) { 34318 destroy_component$1(brush_1, detaching); 34319 } 34320 }; 34321} 34322 34323// (83:1) <Tools {i18n}> 34324function create_default_slot_1$1(ctx) { 34325 let t0; 34326 let show_if = /*transforms*/ ctx[8].includes("crop"); 34327 let t1; 34328 let t2; 34329 let if_block3_anchor; 34330 let current; 34331 let if_block0 = /*sources*/ ctx[2] && /*sources*/ ctx[2].length && create_if_block_7(ctx); 34332 let if_block1 = show_if && create_if_block_6(ctx); 34333 let if_block2 = /*brush*/ ctx[0] && create_if_block_5(ctx); 34334 let if_block3 = /*brush*/ ctx[0] && /*eraser*/ ctx[1] && create_if_block_4(ctx); 34335 34336 return { 34337 c() { 34338 if (if_block0) if_block0.c(); 34339 t0 = space$1(); 34340 if (if_block1) if_block1.c(); 34341 t1 = space$1(); 34342 if (if_block2) if_block2.c(); 34343 t2 = space$1(); 34344 if (if_block3) if_block3.c();
34345 if_block3_anchor = empty$1(); 34346 }, 34347 m(target, anchor) { 34348 if (if_block0) if_block0.m(target, anchor); 34349 insert$1(target, t0, anchor); 34350 if (if_block1) if_block1.m(target, anchor); 34351 insert$1(target, t1, anchor); 34352 if (if_block2) if_block2.m(target, anchor); 34353 insert$1(target, t2, anchor); 34354 if (if_block3) if_block3.m(target, anchor); 34355 insert$1(target, if_block3_anchor, anchor); 34356 current = true; 34357 }, 34358 p(ctx, dirty) { 34359 if (/*sources*/ ctx[2] && /*sources*/ ctx[2].length) { 34360 if (if_block0) { 34361 if_block0.p(ctx, dirty); 34362 34363 if (dirty & /*sources*/ 4) { 34364 transition_in$1(if_block0, 1); 34365 } 34366 } else { 34367 if_block0 = create_if_block_7(ctx); 34368 if_block0.c(); 34369 transition_in$1(if_block0, 1); 34370 if_block0.m(t0.parentNode, t0); 34371 } 34372 } else if (if_block0) { 34373 group_outros$1(); 34374 34375 transition_out$1(if_block0, 1, 1, () => { 34376 if_block0 = null; 34377 }); 34378 34379 check_outros$1(); 34380 } 34381 34382 if (dirty & /*transforms*/ 256) show_if = /*transforms*/ ctx[8].includes("crop"); 34383 34384 if (show_if) { 34385 if (if_block1) { 34386 if_block1.p(ctx, dirty); 34387 34388 if (dirty & /*transforms*/ 256) { 34389 transition_in$1(if_block1, 1); 34390 } 34391 } else { 34392 if_block1 = create_if_block_6(ctx); 34393 if_block1.c(); 34394 transition_in$1(if_block1, 1); 34395 if_block1.m(t1.parentNode, t1); 34396 } 34397 } else if (if_block1) { 34398 group_outros$1(); 34399 34400 transition_out$1(if_block1, 1, 1, () => { 34401 if_block1 = null; 34402 }); 34403 34404 check_outros$1(); 34405 } 34406 34407 if (/*brush*/ ctx[0]) { 34408 if (if_block2) { 34409 if_block2.p(ctx, dirty); 34410 34411 if (dirty & /*brush*/ 1) { 34412 transition_in$1(if_block2, 1); 34413 } 34414 } else { 34415 if_block2 = create_if_block_5(ctx); 34416 if_block2.c(); 34417 transition_in$1(if_block2, 1); 34418 if_block2.m(t2.parentNode, t2); 34419 } 34420 } else if (if_block2) { 34421 group_outros$1(); 34422 34423 transition_out$1(if_block2, 1, 1, () => { 34424 if_block2 = null; 34425 }); 34426 34427 check_outros$1(); 34428 } 34429 34430 if (/*brush*/ ctx[0] && /*eraser*/ ctx[1]) { 34431 if (if_block3) { 34432 if_block3.p(ctx, dirty); 34433 34434 if (dirty & /*brush, eraser*/ 3) { 34435 transition_in$1(if_block3, 1); 34436 } 34437 } else { 34438 if_block3 = create_if_block_4(ctx); 34439 if_block3.c(); 34440 transition_in$1(if_block3, 1); 34441 if_block3.m(if_block3_anchor.parentNode, if_block3_anchor); 34442 } 34443 } else if (if_block3) { 34444 group_outros$1(); 34445 34446 transition_out$1(if_block3, 1, 1, () => { 34447 if_block3 = null; 34448 }); 34449 34450 check_outros$1(); 34451 } 34452 }, 34453 i(local) { 34454 if (current) return; 34455 transition_in$1(if_block0); 34456 transition_in$1(if_block1); 34457 transition_in$1(if_block2); 34458 transition_in$1(if_block3); 34459 current = true; 34460 }, 34461 o(local) { 34462 transition_out$1(if_block0); 34463 transition_out$1(if_block1); 34464 transition_out$1(if_block2); 34465 transition_out$1(if_block3); 34466 current = false; 34467 }, 34468 d(detaching) { 34469 if (detaching) { 34470 detach$1(t0); 34471 detach$1(t1); 34472 detach$1(t2); 34473 detach$1(if_block3_anchor); 34474 } 34475 34476 if (if_block0) if_block0.d(detaching); 34477 if (if_block1) if_block1.d(detaching); 34478 if (if_block2) if_block2.d(detaching); 34479 if (if_block3) if_block3.d(detaching); 34480 } 34481 }; 34482} 34483 34484// (119:1) {#if !bg && !history} 34485function create_if_block$1(ctx) { 34486 let div; 34487 let t0; 34488 let t1; 34489 let if_block0 = /*sources*/ ctx[2] && /*sources*/ ctx[2].length && create_if_block_3(); 34490 let if_block1 = /*sources*/ ctx[2] && /*sources*/ ctx[2].length && /*brush*/ ctx[0] && create_if_block_2(); 34491 let if_block2 = /*brush*/ ctx[0] && create_if_block_1(); 34492 34493 return { 34494 c() { 34495 div = element("div"); 34496 if (if_block0) if_block0.c(); 34497 t0 = space$1(); 34498 if (if_block1) if_block1.c(); 34499 t1 = space$1(); 34500 if (if_block2) if_block2.c(); 34501 attr(div, "class", "empty wrap svelte-1dewo5e"); 34502 }, 34503 m(target, anchor) { 34504 insert$1(target, div, anchor); 34505 if (if_block0) if_block0.m(div, null); 34506 append(div, t0); 34507 if (if_block1) if_block1.m(div, null); 34508 append(div, t1); 34509 if (if_block2) if_block2.m(div, null); 34510 }, 34511 p(ctx, dirty) { 34512 if (/*sources*/ ctx[2] && /*sources*/ ctx[2].length) { 34513 if (if_block0) ; else { 34514 if_block0 = create_if_block_3(); 34515 if_block0.c(); 34516 if_block0.m(div, t0); 34517 } 34518 } else if (if_block0) { 34519 if_block0.d(1); 34520 if_block0 = null; 34521 } 34522 34523 if (/*sources*/ ctx[2] && /*sources*/ ctx[2].length && /*brush*/ ctx[0]) { 34524 if (if_block1) ; else { 34525 if_block1 = create_if_block_2(); 34526 if_block1.c(); 34527 if_block1.m(div, t1); 34528 } 34529 } else if (if_block1) { 34530 if_block1.d(1); 34531 if_block1 = null; 34532 } 34533 34534 if (/*brush*/ ctx[0]) { 34535 if (if_block2) ; else { 34536 if_block2 = create_if_block_1(); 34537 if_block2.c(); 34538 if_block2.m(div, null); 34539 } 34540 } else if (if_block2) { 34541 if_block2.d(1); 34542 if_block2 = null; 34543 } 34544 }, 34545 d(detaching) { 34546 if (detaching) { 34547 detach$1(div); 34548 } 34549 34550 if (if_block0) if_block0.d(); 34551 if (if_block1) if_block1.d(); 34552 if (if_block2) if_block2.d(); 34553 } 34554 }; 34555} 34556 34557// (121:3) {#if sources && sources.length} 34558function create_if_block_3(ctx) { 34559 let div; 34560 34561 return { 34562 c() { 34563 div = element("div"); 34564 div.textContent = "Upload an image"; 34565 }, 34566 m(target, anchor) { 34567 insert$1(target, div, anchor); 34568 }, 34569 d(detaching) { 34570 if (detaching) { 34571 detach$1(div); 34572 } 34573 } 34574 }; 34575} 34576 34577// (125:3) {#if sources && sources.length && brush} 34578function create_if_block_2(ctx) { 34579 let div; 34580 34581 return { 34582 c() { 34583 div = element("div"); 34584 div.textContent = "or"; 34585 attr(div, "class", "or svelte-1dewo5e"); 34586 }, 34587 m(target, anchor) { 34588 insert$1(target, div, anchor); 34589 }, 34590 d(detaching) { 34591 if (detaching) { 34592 detach$1(div); 34593 } 34594 } 34595 }; 34596} 34597 34598// (128:3) {#if brush} 34599function create_if_block_1(ctx) { 34600 let div; 34601 34602 return { 34603 c() { 34604 div = element("div"); 34605 div.textContent = "select the draw tool to start"; 34606 }, 34607 m(target, anchor) { 34608 insert$1(target, div, anchor); 34609 }, 34610 d(detaching) { 34611 if (detaching) { 34612 detach$1(div); 34613 } 34614 } 34615 }; 34616} 34617 34618// (74:0) <ImageEditor bind:this={editor} {changeable} on:save bind:history bind:bg {sources} crop_constraint={!!crop_constraint} > 34619function create_default_slot$1(ctx) { 34620 let tools; 34621 let t0; 34622 let layers; 34623 let t1; 34624 let if_block_anchor; 34625 let current; 34626 34627 tools = new Tools({ 34628 props: { 34629 i18n: /*i18n*/ ctx[3], 34630 $$slots: { default: [create_default_slot_1$1] }, 34631 $$scope: { ctx } 34632 } 34633 }); 34634
34635 layers = new Layers({ 34636 props: { 34637 layer_files: normalise_file(/*value*/ ctx[7]?.layers || null, /*root*/ ctx[4], /*proxy_url*/ ctx[5]) 34638 } 34639 }); 34640 34641 let if_block = !/*bg*/ ctx[10] && !/*history*/ ctx[11] && create_if_block$1(ctx); 34642 34643 return { 34644 c() { 34645 create_component$1(tools.$$.fragment); 34646 t0 = space$1(); 34647 create_component$1(layers.$$.fragment); 34648 t1 = space$1(); 34649 if (if_block) if_block.c(); 34650 if_block_anchor = empty$1(); 34651 }, 34652 m(target, anchor) { 34653 mount_component$1(tools, target, anchor); 34654 insert$1(target, t0, anchor); 34655 mount_component$1(layers, target, anchor); 34656 insert$1(target, t1, anchor); 34657 if (if_block) if_block.m(target, anchor); 34658 insert$1(target, if_block_anchor, anchor); 34659 current = true; 34660 }, 34661 p(ctx, dirty) { 34662 const tools_changes = {}; 34663 if (dirty & /*i18n*/ 8) tools_changes.i18n = /*i18n*/ ctx[3]; 34664 34665 if (dirty & /*$$scope, eraser, brush, crop_constraint, transforms, i18n, root, sources, value, proxy_url, bg*/ 2102719) { 34666 tools_changes.$$scope = { dirty, ctx }; 34667 } 34668 34669 tools.$set(tools_changes); 34670 const layers_changes = {}; 34671 if (dirty & /*value, root, proxy_url*/ 176) layers_changes.layer_files = normalise_file(/*value*/ ctx[7]?.layers || null, /*root*/ ctx[4], /*proxy_url*/ ctx[5]); 34672 layers.$set(layers_changes); 34673 34674 if (!/*bg*/ ctx[10] && !/*history*/ ctx[11]) { 34675 if (if_block) { 34676 if_block.p(ctx, dirty); 34677 } else { 34678 if_block = create_if_block$1(ctx); 34679 if_block.c(); 34680 if_block.m(if_block_anchor.parentNode, if_block_anchor); 34681 } 34682 } else if (if_block) { 34683 if_block.d(1); 34684 if_block = null; 34685 } 34686 }, 34687 i(local) { 34688 if (current) return; 34689 transition_in$1(tools.$$.fragment, local); 34690 transition_in$1(layers.$$.fragment, local); 34691 current = true; 34692 }, 34693 o(local) { 34694 transition_out$1(tools.$$.fragment, local); 34695 transition_out$1(layers.$$.fragment, local); 34696 current = false; 34697 }, 34698 d(detaching) { 34699 if (detaching) { 34700 detach$1(t0); 34701 detach$1(t1); 34702 detach$1(if_block_anchor); 34703 } 34704 34705 destroy_component$1(tools, detaching); 34706 destroy_component$1(layers, detaching); 34707 if (if_block) if_block.d(detaching); 34708 } 34709 }; 34710} 34711 34712function create_fragment$1(ctx) { 34713 let imageeditor; 34714 let updating_history; 34715 let updating_bg; 34716 let current; 34717 34718 function imageeditor_history_binding(value) { 34719 /*imageeditor_history_binding*/ ctx[17](value); 34720 } 34721 34722 function imageeditor_bg_binding(value) { 34723 /*imageeditor_bg_binding*/ ctx[18](value); 34724 } 34725 34726 let imageeditor_props = { 34727 changeable: /*changeable*/ ctx[6], 34728 sources: /*sources*/ ctx[2], 34729 crop_constraint: !!/*crop_constraint*/ ctx[12], 34730 $$slots: { default: [create_default_slot$1] }, 34731 $$scope: { ctx } 34732 }; 34733 34734 if (/*history*/ ctx[11] !== void 0) { 34735 imageeditor_props.history = /*history*/ ctx[11]; 34736 } 34737 34738 if (/*bg*/ ctx[10] !== void 0) { 34739 imageeditor_props.bg = /*bg*/ ctx[10]; 34740 } 34741 34742 imageeditor = new ImageEditor({ props: imageeditor_props }); 34743 /*imageeditor_binding*/ ctx[16](imageeditor); 34744 binding_callbacks$1.push(() => bind(imageeditor, 'history', imageeditor_history_binding)); 34745 binding_callbacks$1.push(() => bind(imageeditor, 'bg', imageeditor_bg_binding)); 34746 imageeditor.$on("save", /*save_handler*/ ctx[19]); 34747 34748 return { 34749 c() { 34750 create_component$1(imageeditor.$$.fragment); 34751 }, 34752 m(target, anchor) { 34753 mount_component$1(imageeditor, target, anchor); 34754 current = true; 34755 }, 34756 p(ctx, [dirty]) { 34757 const imageeditor_changes = {}; 34758 if (dirty & /*changeable*/ 64) imageeditor_changes.changeable = /*changeable*/ ctx[6]; 34759 if (dirty & /*sources*/ 4) imageeditor_changes.sources = /*sources*/ ctx[2]; 34760 if (dirty & /*crop_constraint*/ 4096) imageeditor_changes.crop_constraint = !!/*crop_constraint*/ ctx[12]; 34761 34762 if (dirty & /*$$scope, brush, sources, bg, history, value, root, proxy_url, i18n, eraser, crop_constraint, transforms*/ 2104767) { 34763 imageeditor_changes.$$scope = { dirty, ctx }; 34764 } 34765 34766 if (!updating_history && dirty & /*history*/ 2048) { 34767 updating_history = true; 34768 imageeditor_changes.history = /*history*/ ctx[11]; 34769 add_flush_callback(() => updating_history = false); 34770 } 34771 34772 if (!updating_bg && dirty & /*bg*/ 1024) { 34773 updating_bg = true; 34774 imageeditor_changes.bg = /*bg*/ ctx[10]; 34775 add_flush_callback(() => updating_bg = false); 34776 } 34777 34778 imageeditor.$set(imageeditor_changes); 34779 }, 34780 i(local) { 34781 if (current) return; 34782 transition_in$1(imageeditor.$$.fragment, local); 34783 current = true; 34784 }, 34785 o(local) { 34786 transition_out$1(imageeditor.$$.fragment, local); 34787 current = false;
34788 }, 34789 d(detaching) { 34790 /*imageeditor_binding*/ ctx[16](null); 34791 destroy_component$1(imageeditor, detaching); 34792 } 34793 }; 34794} 34795 34796function is_not_null(o) { 34797 return !!o; 34798} 34799 34800function is_file_data(o) { 34801 return !!o; 34802} 34803 34804function instance$1($$self, $$props, $$invalidate) { 34805 let crop_constraint; 34806 let { brush } = $$props; 34807 let { eraser } = $$props; 34808 let { sources } = $$props; 34809 let { crop_size = null } = $$props; 34810 let { i18n } = $$props; 34811 let { root } = $$props; 34812 let { proxy_url } = $$props; 34813 let { changeable = false } = $$props; 34814 34815 let { value = { 34816 background: null, 34817 layers: [], 34818 composite: null 34819 } } = $$props; 34820 34821 let { transforms = ["crop"] } = $$props; 34822 let editor; 34823 34824 async function get_data() { 34825 const blobs = await editor.get_blobs(); 34826 34827 const bg = blobs.background 34828 ? upload(await prepare_files([new File([blobs.background], "background.png")]), root) 34829 : Promise.resolve(null); 34830 34831 const layers = blobs.layers.filter(is_not_null).map(async (blob, i) => upload(await prepare_files([new File([blob], `layer_${i}.png`)]), root)); 34832 34833 const composite = blobs.composite 34834 ? upload(await prepare_files([new File([blobs.composite], "composite.png")]), root) 34835 : Promise.resolve(null); 34836 34837 const [background, composite_, ...layers_] = await Promise.all([bg, composite, ...layers]); 34838 34839 return { 34840 background: Array.isArray(background) ? background[0] : background, 34841 layers: layers_.flatMap(layer => Array.isArray(layer) ? layer : [layer]).filter(is_file_data), 34842 composite: Array.isArray(composite_) ? composite_[0] : composite_ 34843 }; 34844 } 34845 34846 function handle_value(value) { 34847 if (!editor) return; 34848 34849 if (value == null) { 34850 editor.handle_remove(); 34851 } 34852 } 34853 34854 let bg = false; 34855 let history = false; 34856 34857 function sources_1_bg_binding(value) { 34858 bg = value; 34859 $$invalidate(10, bg); 34860 } 34861 34862 function imageeditor_binding($$value) { 34863 binding_callbacks$1[$$value ? 'unshift' : 'push'](() => { 34864 editor = $$value; 34865 $$invalidate(9, editor); 34866 }); 34867 } 34868 34869 function imageeditor_history_binding(value) { 34870 history = value; 34871 $$invalidate(11, history); 34872 } 34873 34874 function imageeditor_bg_binding(value) { 34875 bg = value; 34876 $$invalidate(10, bg); 34877 } 34878 34879 function save_handler(event) { 34880 bubble$1.call(this, $$self, event); 34881 } 34882 34883 $$self.$$set = $$props => {
34884 if ('brush' in $$props) $$invalidate(0, brush = $$props.brush); 34885 if ('eraser' in $$props) $$invalidate(1, eraser = $$props.eraser); 34886 if ('sources' in $$props) $$invalidate(2, sources = $$props.sources); 34887 if ('crop_size' in $$props) $$invalidate(13, crop_size = $$props.crop_size); 34888 if ('i18n' in $$props) $$invalidate(3, i18n = $$props.i18n); 34889 if ('root' in $$props) $$invalidate(4, root = $$props.root); 34890 if ('proxy_url' in $$props) $$invalidate(5, proxy_url = $$props.proxy_url); 34891 if ('changeable' in $$props) $$invalidate(6, changeable = $$props.changeable); 34892 if ('value' in $$props) $$invalidate(7, value = $$props.value); 34893 if ('transforms' in $$props) $$invalidate(8, transforms = $$props.transforms); 34894 }; 34895 34896 $$self.$$.update = () => { 34897 if ($$self.$$.dirty & /*value*/ 128) { 34898 handle_value(value); 34899 } 34900 34901 if ($$self.$$.dirty & /*crop_size*/ 8192) { 34902 $$invalidate(12, crop_constraint = crop_size); 34903 } 34904 34905 if ($$self.$$.dirty & /*editor, sources*/ 516) { 34906 editor && editor.set_tool && (sources && sources.length 34907 ? editor.set_tool("bg") 34908 : editor.set_tool("draw")); 34909 } 34910 }; 34911 34912 return [ 34913 brush, 34914 eraser, 34915 sources, 34916 i18n, 34917 root, 34918 proxy_url, 34919 changeable, 34920 value, 34921 transforms, 34922 editor, 34923 bg, 34924 history, 34925 crop_constraint, 34926 crop_size, 34927 get_data, 34928 sources_1_bg_binding, 34929 imageeditor_binding, 34930 imageeditor_history_binding, 34931 imageeditor_bg_binding, 34932 save_handler 34933 ]; 34934} 34935 34936class InteractiveImageEditor extends SvelteComponent$1 { 34937 constructor(options) { 34938 super(); 34939 34940 init$1(this, options, instance$1, create_fragment$1, safe_not_equal$1, { 34941 brush: 0, 34942 eraser: 1, 34943 sources: 2, 34944 crop_size: 13, 34945 i18n: 3, 34946 root: 4, 34947 proxy_url: 5, 34948 changeable: 6, 34949 value: 7, 34950 transforms: 8, 34951 get_data: 14 34952 }); 34953 } 34954 34955 get get_data() { 34956 return this.$$.ctx[14]; 34957 } 34958} 34959 34960/* home/runner/work/gradio/gradio/js/imageeditor/Index.svelte generated by Svelte v4.2.2 */ 34961const { 34962 SvelteComponent, 34963 assign, 34964 binding_callbacks, 34965 bubble, 34966 check_outros, 34967 create_component, 34968 destroy_component, 34969 detach, 34970 empty, 34971 flush, 34972 get_spread_object, 34973 get_spread_update, 34974 group_outros, 34975 init, 34976 insert, 34977 mount_component, 34978 safe_not_equal, 34979 space, 34980 transition_in, 34981 transition_out 34982} = window.__gradio__svelte__internal; 34983function create_else_block(ctx) { 34984 let block; 34985 let current; 34986 34987 block = new Block({ 34988 props: { 34989 visible: /*visible*/ ctx[3], 34990 variant: /*value*/ ctx[4] === null ? "dashed" : "solid", 34991 border_mode: /*dragging*/ ctx[26] ? "focus" : "base", 34992 padding: false, 34993 elem_id: /*elem_id*/ ctx[1], 34994 elem_classes: /*elem_classes*/ ctx[2], 34995 height: /*height*/ ctx[9] || undefined, 34996 width: /*width*/ ctx[10], 34997 allow_overflow: false, 34998 container: /*container*/ ctx[12], 34999 scale: /*scale*/ ctx[13], 35000 min_width: /*min_width*/ ctx[14], 35001 $$slots: { default: [create_default_slot_1] }, 35002 $$scope: { ctx } 35003 } 35004 }); 35005 35006 return { 35007 c() { 35008 create_component(block.$$.fragment); 35009 }, 35010 m(target, anchor) { 35011 mount_component(block, target, anchor); 35012 current = true; 35013 }, 35014 p(ctx, dirty) { 35015 const block_changes = {}; 35016 if (dirty[0] & /*visible*/ 8) block_changes.visible = /*visible*/ ctx[3]; 35017 if (dirty[0] & /*value*/ 16) block_changes.variant = /*value*/ ctx[4] === null ? "dashed" : "solid"; 35018 if (dirty[0] & /*dragging*/ 67108864) block_changes.border_mode = /*dragging*/ ctx[26] ? "focus" : "base"; 35019 if (dirty[0] & /*elem_id*/ 2) block_changes.elem_id = /*elem_id*/ ctx[1]; 35020 if (dirty[0] & /*elem_classes*/ 4) block_changes.elem_classes = /*elem_classes*/ ctx[2]; 35021 if (dirty[0] & /*height*/ 512) block_changes.height = /*height*/ ctx[9] || undefined; 35022 if (dirty[0] & /*width*/ 1024) block_changes.width = /*width*/ ctx[10]; 35023 if (dirty[0] & /*container*/ 4096) block_changes.container = /*container*/ ctx[12]; 35024 if (dirty[0] & /*scale*/ 8192) block_changes.scale = /*scale*/ ctx[13]; 35025 if (dirty[0] & /*min_width*/ 16384) block_changes.min_width = /*min_width*/ ctx[14]; 35026 35027 if (dirty[0] & /*crop_size, value, root, sources, brush, eraser, proxy_url, attached_events, gradio, transforms, editor_instance, dragging, loading_status*/ 133890321 | dirty[1] & /*$$scope*/ 8192) { 35028 block_changes.$$scope = { dirty, ctx }; 35029 } 35030 35031 block.$set(block_changes); 35032 }, 35033 i(local) { 35034 if (current) return; 35035 transition_in(block.$$.fragment, local); 35036 current = true; 35037 }, 35038 o(local) { 35039 transition_out(block.$$.fragment, local); 35040 current = false;
35041 }, 35042 d(detaching) { 35043 destroy_component(block, detaching); 35044 } 35045 }; 35046} 35047 35048// (64:0) {#if !interactive} 35049function create_if_block(ctx) { 35050 let block; 35051 let current; 35052 35053 block = new Block({ 35054 props: { 35055 visible: /*visible*/ ctx[3], 35056 variant: "solid", 35057 border_mode: /*dragging*/ ctx[26] ? "focus" : "base", 35058 padding: false, 35059 elem_id: /*elem_id*/ ctx[1], 35060 elem_classes: /*elem_classes*/ ctx[2], 35061 height: /*height*/ ctx[9] || undefined, 35062 width: /*width*/ ctx[10], 35063 allow_overflow: false, 35064 container: /*container*/ ctx[12], 35065 scale: /*scale*/ ctx[13], 35066 min_width: /*min_width*/ ctx[14], 35067 $$slots: { default: [create_default_slot] }, 35068 $$scope: { ctx } 35069 } 35070 }); 35071 35072 return { 35073 c() { 35074 create_component(block.$$.fragment); 35075 }, 35076 m(target, anchor) { 35077 mount_component(block, target, anchor); 35078 current = true; 35079 }, 35080 p(ctx, dirty) { 35081 const block_changes = {}; 35082 if (dirty[0] & /*visible*/ 8) block_changes.visible = /*visible*/ ctx[3]; 35083 if (dirty[0] & /*dragging*/ 67108864) block_changes.border_mode = /*dragging*/ ctx[26] ? "focus" : "base"; 35084 if (dirty[0] & /*elem_id*/ 2) block_changes.elem_id = /*elem_id*/ ctx[1]; 35085 if (dirty[0] & /*elem_classes*/ 4) block_changes.elem_classes = /*elem_classes*/ ctx[2]; 35086 if (dirty[0] & /*height*/ 512) block_changes.height = /*height*/ ctx[9] || undefined; 35087 if (dirty[0] & /*width*/ 1024) block_changes.width = /*width*/ ctx[10]; 35088 if (dirty[0] & /*container*/ 4096) block_changes.container = /*container*/ ctx[12]; 35089 if (dirty[0] & /*scale*/ 8192) block_changes.scale = /*scale*/ ctx[13]; 35090 if (dirty[0] & /*min_width*/ 16384) block_changes.min_width = /*min_width*/ ctx[14]; 35091 35092 if (dirty[0] & /*value, root, proxy_url, label, show_label, show_download_button, _selectable, show_share_button, gradio, loading_status*/ 16943601 | dirty[1] & /*$$scope*/ 8192) { 35093 block_changes.$$scope = { dirty, ctx }; 35094 } 35095 35096 block.$set(block_changes); 35097 }, 35098 i(local) { 35099 if (current) return; 35100 transition_in(block.$$.fragment, local); 35101 current = true; 35102 }, 35103 o(local) { 35104 transition_out(block.$$.fragment, local); 35105 current = false; 35106 }, 35107 d(detaching) { 35108 destroy_component(block, detaching); 35109 } 35110 }; 35111} 35112 35113// (98:1) <Block {visible} variant={value === null ? "dashed" : "solid"} border_mode={dragging ? "focus" : "base"} padding={false} {elem_id} {elem_classes} height={height || undefined} {width} allow_overflow={false} {container} {scale} {min_width} > 35114function create_default_slot_1(ctx) { 35115 let statustracker; 35116 let t; 35117 let interactiveimageeditor; 35118 let current; 35119 35120 const statustracker_spread_levels = [ 35121 { 35122 autoscroll: /*gradio*/ ctx[24].autoscroll 35123 }, 35124 { i18n: /*gradio*/ ctx[24].i18n }, 35125 /*loading_status*/ ctx[0] 35126 ]; 35127 35128 let statustracker_props = {}; 35129 35130 for (let i = 0; i < statustracker_spread_levels.length; i += 1) { 35131 statustracker_props = assign(statustracker_props, statustracker_spread_levels[i]); 35132 } 35133 35134 statustracker = new Static({ props: statustracker_props }); 35135 35136 let interactiveimageeditor_props = { 35137 crop_size: /*crop_size*/ ctx[21], 35138 value: /*value*/ ctx[4], 35139 root: /*root*/ ctx[8], 35140 sources: /*sources*/ ctx[16], 35141 brush: /*brush*/ ctx[19], 35142 eraser: /*eraser*/ ctx[20], 35143 proxy_url: /*proxy_url*/ ctx[17], 35144 changeable: /*attached_events*/ ctx[23].includes("change"), 35145 i18n: /*gradio*/ ctx[24].i18n, 35146 transforms: /*transforms*/ ctx[22] 35147 }; 35148 35149 interactiveimageeditor = new InteractiveImageEditor({ props: interactiveimageeditor_props }); 35150 /*interactiveimageeditor_binding*/ ctx[32](interactiveimageeditor); 35151 interactiveimageeditor.$on("save", /*save_handler*/ ctx[33]); 35152 interactiveimageeditor.$on("edit", /*edit_handler*/ ctx[34]); 35153 interactiveimageeditor.$on("clear", /*clear_handler*/ ctx[35]); 35154 interactiveimageeditor.$on("stream", /*stream_handler*/ ctx[36]); 35155 interactiveimageeditor.$on("drag", /*drag_handler*/ ctx[37]); 35156 interactiveimageeditor.$on("upload", /*upload_handler*/ ctx[38]); 35157 interactiveimageeditor.$on("select", /*select_handler_1*/ ctx[39]); 35158 interactiveimageeditor.$on("share", /*share_handler_1*/ ctx[40]); 35159 interactiveimageeditor.$on("error", /*error_handler_2*/ ctx[41]); 35160 interactiveimageeditor.$on("error", /*error_handler*/ ctx[42]); 35161 35162 return { 35163 c() { 35164 create_component(statustracker.$$.fragment); 35165 t = space(); 35166 create_component(interactiveimageeditor.$$.fragment); 35167 }, 35168 m(target, anchor) { 35169 mount_component(statustracker, target, anchor); 35170 insert(target, t, anchor);
35171 mount_component(interactiveimageeditor, target, anchor); 35172 current = true; 35173 }, 35174 p(ctx, dirty) { 35175 const statustracker_changes = (dirty[0] & /*gradio, loading_status*/ 16777217) 35176 ? get_spread_update(statustracker_spread_levels, [ 35177 dirty[0] & /*gradio*/ 16777216 && { 35178 autoscroll: /*gradio*/ ctx[24].autoscroll 35179 }, 35180 dirty[0] & /*gradio*/ 16777216 && { i18n: /*gradio*/ ctx[24].i18n }, 35181 dirty[0] & /*loading_status*/ 1 && get_spread_object(/*loading_status*/ ctx[0]) 35182 ]) 35183 : {}; 35184 35185 statustracker.$set(statustracker_changes); 35186 const interactiveimageeditor_changes = {}; 35187 if (dirty[0] & /*crop_size*/ 2097152) interactiveimageeditor_changes.crop_size = /*crop_size*/ ctx[21]; 35188 if (dirty[0] & /*value*/ 16) interactiveimageeditor_changes.value = /*value*/ ctx[4]; 35189 if (dirty[0] & /*root*/ 256) interactiveimageeditor_changes.root = /*root*/ ctx[8]; 35190 if (dirty[0] & /*sources*/ 65536) interactiveimageeditor_changes.sources = /*sources*/ ctx[16]; 35191 if (dirty[0] & /*brush*/ 524288) interactiveimageeditor_changes.brush = /*brush*/ ctx[19]; 35192 if (dirty[0] & /*eraser*/ 1048576) interactiveimageeditor_changes.eraser = /*eraser*/ ctx[20]; 35193 if (dirty[0] & /*proxy_url*/ 131072) interactiveimageeditor_changes.proxy_url = /*proxy_url*/ ctx[17]; 35194 if (dirty[0] & /*attached_events*/ 8388608) interactiveimageeditor_changes.changeable = /*attached_events*/ ctx[23].includes("change"); 35195 if (dirty[0] & /*gradio*/ 16777216) interactiveimageeditor_changes.i18n = /*gradio*/ ctx[24].i18n; 35196 if (dirty[0] & /*transforms*/ 4194304) interactiveimageeditor_changes.transforms = /*transforms*/ ctx[22]; 35197 interactiveimageeditor.$set(interactiveimageeditor_changes); 35198 }, 35199 i(local) { 35200 if (current) return; 35201 transition_in(statustracker.$$.fragment, local); 35202 transition_in(interactiveimageeditor.$$.fragment, local); 35203 current = true; 35204 }, 35205 o(local) { 35206 transition_out(statustracker.$$.fragment, local); 35207 transition_out(interactiveimageeditor.$$.fragment, local); 35208 current = false; 35209 }, 35210 d(detaching) { 35211 if (detaching) { 35212 detach(t); 35213 } 35214 35215 destroy_component(statustracker, detaching); 35216 /*interactiveimageeditor_binding*/ ctx[32](null); 35217 destroy_component(interactiveimageeditor, detaching); 35218 } 35219 }; 35220} 35221 35222// (65:1) <Block {visible} variant={"solid"} border_mode={dragging ? "focus" : "base"} padding={false} {elem_id} {elem_classes} height={height || undefined} {width} allow_overflow={false} {container} {scale} {min_width} > 35223function create_default_slot(ctx) { 35224 let statustracker; 35225 let t; 35226 let staticimage; 35227 let current; 35228 35229 const statustracker_spread_levels = [ 35230 { 35231 autoscroll: /*gradio*/ ctx[24].autoscroll 35232 }, 35233 { i18n: /*gradio*/ ctx[24].i18n }, 35234 /*loading_status*/ ctx[0] 35235 ]; 35236 35237 let statustracker_props = {}; 35238 35239 for (let i = 0; i < statustracker_spread_levels.length; i += 1) { 35240 statustracker_props = assign(statustracker_props, statustracker_spread_levels[i]); 35241 } 35242 35243 statustracker = new Static({ props: statustracker_props }); 35244 35245 staticimage = new StaticImage({ 35246 props: { 35247 value: normalise_file(/*value*/ ctx[4]?.composite || null, /*root*/ ctx[8], /*proxy_url*/ ctx[17]), 35248 label: /*label*/ ctx[5], 35249 show_label: /*show_label*/ ctx[6], 35250 show_download_button: /*show_download_button*/ ctx[7], 35251 selectable: /*_selectable*/ ctx[11], 35252 show_share_button: /*show_share_button*/ ctx[15], 35253 i18n: /*gradio*/ ctx[24].i18n 35254 } 35255 }); 35256 35257 staticimage.$on("select", /*select_handler*/ ctx[29]); 35258 staticimage.$on("share", /*share_handler*/ ctx[30]); 35259 staticimage.$on("error", /*error_handler_1*/ ctx[31]); 35260 35261 return { 35262 c() { 35263 create_component(statustracker.$$.fragment); 35264 t = space(); 35265 create_component(staticimage.$$.fragment); 35266 }, 35267 m(target, anchor) { 35268 mount_component(statustracker, target, anchor); 35269 insert(target, t, anchor); 35270 mount_component(staticimage, target, anchor); 35271 current = true; 35272 }, 35273 p(ctx, dirty) { 35274 const statustracker_changes = (dirty[0] & /*gradio, loading_status*/ 16777217) 35275 ? get_spread_update(statustracker_spread_levels, [ 35276 dirty[0] & /*gradio*/ 16777216 && { 35277 autoscroll: /*gradio*/ ctx[24].autoscroll 35278 }, 35279 dirty[0] & /*gradio*/ 16777216 && { i18n: /*gradio*/ ctx[24].i18n }, 35280 dirty[0] & /*loading_status*/ 1 && get_spread_object(/*loading_status*/ ctx[0]) 35281 ]) 35282 : {}; 35283 35284 statustracker.$set(statustracker_changes); 35285 const staticimage_changes = {};
35286 if (dirty[0] & /*value, root, proxy_url*/ 131344) staticimage_changes.value = normalise_file(/*value*/ ctx[4]?.composite || null, /*root*/ ctx[8], /*proxy_url*/ ctx[17]); 35287 if (dirty[0] & /*label*/ 32) staticimage_changes.label = /*label*/ ctx[5]; 35288 if (dirty[0] & /*show_label*/ 64) staticimage_changes.show_label = /*show_label*/ ctx[6]; 35289 if (dirty[0] & /*show_download_button*/ 128) staticimage_changes.show_download_button = /*show_download_button*/ ctx[7]; 35290 if (dirty[0] & /*_selectable*/ 2048) staticimage_changes.selectable = /*_selectable*/ ctx[11]; 35291 if (dirty[0] & /*show_share_button*/ 32768) staticimage_changes.show_share_button = /*show_share_button*/ ctx[15]; 35292 if (dirty[0] & /*gradio*/ 16777216) staticimage_changes.i18n = /*gradio*/ ctx[24].i18n; 35293 staticimage.$set(staticimage_changes); 35294 }, 35295 i(local) { 35296 if (current) return; 35297 transition_in(statustracker.$$.fragment, local); 35298 transition_in(staticimage.$$.fragment, local); 35299 current = true; 35300 }, 35301 o(local) { 35302 transition_out(statustracker.$$.fragment, local); 35303 transition_out(staticimage.$$.fragment, local); 35304 current = false; 35305 }, 35306 d(detaching) { 35307 if (detaching) { 35308 detach(t); 35309 } 35310 35311 destroy_component(statustracker, detaching); 35312 destroy_component(staticimage, detaching); 35313 } 35314 }; 35315} 35316 35317function create_fragment(ctx) { 35318 let current_block_type_index; 35319 let if_block; 35320 let if_block_anchor; 35321 let current; 35322 const if_block_creators = [create_if_block, create_else_block]; 35323 const if_blocks = []; 35324 35325 function select_block_type(ctx, dirty) { 35326 if (!/*interactive*/ ctx[18]) return 0; 35327 return 1; 35328 } 35329 35330 current_block_type_index = select_block_type(ctx); 35331 if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); 35332 35333 return { 35334 c() { 35335 if_block.c(); 35336 if_block_anchor = empty(); 35337 }, 35338 m(target, anchor) { 35339 if_blocks[current_block_type_index].m(target, anchor); 35340 insert(target, if_block_anchor, anchor); 35341 current = true; 35342 }, 35343 p(ctx, dirty) { 35344 let previous_block_index = current_block_type_index; 35345 current_block_type_index = select_block_type(ctx); 35346 35347 if (current_block_type_index === previous_block_index) { 35348 if_blocks[current_block_type_index].p(ctx, dirty); 35349 } else { 35350 group_outros(); 35351 35352 transition_out(if_blocks[previous_block_index], 1, 1, () => { 35353 if_blocks[previous_block_index] = null; 35354 }); 35355 35356 check_outros(); 35357 if_block = if_blocks[current_block_type_index]; 35358 35359 if (!if_block) { 35360 if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); 35361 if_block.c(); 35362 } else { 35363 if_block.p(ctx, dirty); 35364 } 35365 35366 transition_in(if_block, 1); 35367 if_block.m(if_block_anchor.parentNode, if_block_anchor); 35368 } 35369 }, 35370 i(local) { 35371 if (current) return; 35372 transition_in(if_block); 35373 current = true; 35374 }, 35375 o(local) { 35376 transition_out(if_block); 35377 current = false; 35378 }, 35379 d(detaching) { 35380 if (detaching) { 35381 detach(if_block_anchor); 35382 } 35383 35384 if_blocks[current_block_type_index].d(detaching); 35385 } 35386 }; 35387} 35388 35389function instance($$self, $$props, $$invalidate) { 35390 let { elem_id = "" } = $$props; 35391 let { elem_classes = [] } = $$props; 35392 let { visible = true } = $$props; 35393 35394 let { value = { 35395 background: null, 35396 layers: [], 35397 composite: null 35398 } } = $$props; 35399 35400 let { label } = $$props; 35401 let { show_label } = $$props; 35402 let { show_download_button } = $$props; 35403 let { root } = $$props; 35404 let { height } = $$props; 35405 let { width } = $$props; 35406 let { _selectable = false } = $$props; 35407 let { container = true } = $$props; 35408 let { scale = null } = $$props; 35409 let { min_width = undefined } = $$props; 35410 let { loading_status } = $$props; 35411 let { show_share_button = false } = $$props; 35412 let { sources = ["upload", "clipboard", "webcam"] } = $$props; 35413 let { proxy_url } = $$props; 35414 let { interactive } = $$props; 35415 let { brush } = $$props; 35416 let { eraser } = $$props; 35417 let { crop_size = null } = $$props; 35418 let { transforms = ["crop"] } = $$props; 35419 let { attached_events = [] } = $$props; 35420 let { gradio } = $$props; 35421 let editor_instance; 35422 35423 async function get_value() { 35424 // @ts-ignore 35425 $$invalidate(0, loading_status = { status: "pending" }); 35426 35427 const blobs = await editor_instance.get_data(); 35428 35429 // @ts-ignore
35430 $$invalidate(0, loading_status = { status: "complete" }); 35431 35432 return blobs; 35433 } 35434 35435 let dragging; 35436 35437 function handle_change() { 35438 if (value && (value.background || value.layers?.length || value.composite)) { 35439 gradio.dispatch("change"); 35440 } 35441 } 35442 35443 function handle_save() { 35444 gradio.dispatch("change"); 35445 gradio.dispatch("input"); 35446 } 35447 35448 const select_handler = ({ detail }) => gradio.dispatch("select", detail); 35449 const share_handler = ({ detail }) => gradio.dispatch("share", detail); 35450 const error_handler_1 = ({ detail }) => gradio.dispatch("error", detail); 35451 35452 function interactiveimageeditor_binding($$value) { 35453 binding_callbacks[$$value ? 'unshift' : 'push'](() => { 35454 editor_instance = $$value; 35455 $$invalidate(25, editor_instance); 35456 }); 35457 } 35458 35459 const save_handler = e => handle_save(); 35460 const edit_handler = () => gradio.dispatch("edit"); 35461 const clear_handler = () => gradio.dispatch("clear"); 35462 const stream_handler = () => gradio.dispatch("stream"); 35463 const drag_handler = ({ detail }) => $$invalidate(26, dragging = detail); 35464 const upload_handler = () => gradio.dispatch("upload"); 35465 const select_handler_1 = ({ detail }) => gradio.dispatch("select", detail); 35466 const share_handler_1 = ({ detail }) => gradio.dispatch("share", detail); 35467 35468 const error_handler_2 = ({ detail }) => { 35469 $$invalidate(0, loading_status = loading_status || {}); 35470 $$invalidate(0, loading_status.status = "error", loading_status); 35471 gradio.dispatch("error", detail); 35472 }; 35473 35474 function error_handler(event) { 35475 bubble.call(this, $$self, event); 35476 } 35477 35478 $$self.$$set = $$props => {
35479 if ('elem_id' in $$props) $$invalidate(1, elem_id = $$props.elem_id); 35480 if ('elem_classes' in $$props) $$invalidate(2, elem_classes = $$props.elem_classes); 35481 if ('visible' in $$props) $$invalidate(3, visible = $$props.visible); 35482 if ('value' in $$props) $$invalidate(4, value = $$props.value); 35483 if ('label' in $$props) $$invalidate(5, label = $$props.label); 35484 if ('show_label' in $$props) $$invalidate(6, show_label = $$props.show_label); 35485 if ('show_download_button' in $$props) $$invalidate(7, show_download_button = $$props.show_download_button); 35486 if ('root' in $$props) $$invalidate(8, root = $$props.root); 35487 if ('height' in $$props) $$invalidate(9, height = $$props.height); 35488 if ('width' in $$props) $$invalidate(10, width = $$props.width); 35489 if ('_selectable' in $$props) $$invalidate(11, _selectable = $$props._selectable); 35490 if ('container' in $$props) $$invalidate(12, container = $$props.container); 35491 if ('scale' in $$props) $$invalidate(13, scale = $$props.scale); 35492 if ('min_width' in $$props) $$invalidate(14, min_width = $$props.min_width);
35493 if ('loading_status' in $$props) $$invalidate(0, loading_status = $$props.loading_status); 35494 if ('show_share_button' in $$props) $$invalidate(15, show_share_button = $$props.show_share_button); 35495 if ('sources' in $$props) $$invalidate(16, sources = $$props.sources); 35496 if ('proxy_url' in $$props) $$invalidate(17, proxy_url = $$props.proxy_url); 35497 if ('interactive' in $$props) $$invalidate(18, interactive = $$props.interactive); 35498 if ('brush' in $$props) $$invalidate(19, brush = $$props.brush); 35499 if ('eraser' in $$props) $$invalidate(20, eraser = $$props.eraser); 35500 if ('crop_size' in $$props) $$invalidate(21, crop_size = $$props.crop_size); 35501 if ('transforms' in $$props) $$invalidate(22, transforms = $$props.transforms); 35502 if ('attached_events' in $$props) $$invalidate(23, attached_events = $$props.attached_events); 35503 if ('gradio' in $$props) $$invalidate(24, gradio = $$props.gradio); 35504 }; 35505 35506 $$self.$$.update = () => { 35507 if ($$self.$$.dirty[0] & /*value*/ 16) { 35508 value && handle_change(); 35509 } 35510 }; 35511 35512 return [ 35513 loading_status, 35514 elem_id, 35515 elem_classes, 35516 visible, 35517 value, 35518 label, 35519 show_label, 35520 show_download_button, 35521 root, 35522 height, 35523 width, 35524 _selectable, 35525 container, 35526 scale, 35527 min_width, 35528 show_share_button, 35529 sources, 35530 proxy_url, 35531 interactive, 35532 brush, 35533 eraser, 35534 crop_size, 35535 transforms, 35536 attached_events, 35537 gradio, 35538 editor_instance, 35539 dragging, 35540 handle_save, 35541 get_value, 35542 select_handler, 35543 share_handler, 35544 error_handler_1, 35545 interactiveimageeditor_binding, 35546 save_handler, 35547 edit_handler, 35548 clear_handler, 35549 stream_handler, 35550 drag_handler, 35551 upload_handler, 35552 select_handler_1, 35553 share_handler_1, 35554 error_handler_2, 35555 error_handler 35556 ]; 35557} 35558 35559class Index extends SvelteComponent { 35560 constructor(options) { 35561 super(); 35562 35563 init( 35564 this, 35565 options, 35566 instance, 35567 create_fragment, 35568 safe_not_equal, 35569 { 35570 elem_id: 1, 35571 elem_classes: 2, 35572 visible: 3, 35573 value: 4, 35574 label: 5, 35575 show_label: 6, 35576 show_download_button: 7, 35577 root: 8, 35578 height: 9, 35579 width: 10, 35580 _selectable: 11, 35581 container: 12, 35582 scale: 13, 35583 min_width: 14, 35584 loading_status: 0, 35585 show_share_button: 15, 35586 sources: 16, 35587 proxy_url: 17, 35588 interactive: 18, 35589 brush: 19, 35590 eraser: 20, 35591 crop_size: 21, 35592 transforms: 22, 35593 attached_events: 23, 35594 gradio: 24, 35595 get_value: 28 35596 }, 35597 null, 35598 [-1, -1] 35599 ); 35600 } 35601 35602 get elem_id() { 35603 return this.$$.ctx[1]; 35604 } 35605 35606 set elem_id(elem_id) { 35607 this.$$set({ elem_id }); 35608 flush(); 35609 } 35610 35611 get elem_classes() { 35612 return this.$$.ctx[2]; 35613 } 35614 35615 set elem_classes(elem_classes) { 35616 this.$$set({ elem_classes }); 35617 flush(); 35618 } 35619 35620 get visible() { 35621 return this.$$.ctx[3]; 35622 } 35623 35624 set visible(visible) { 35625 this.$$set({ visible }); 35626 flush(); 35627 } 35628 35629 get value() { 35630 return this.$$.ctx[4]; 35631 } 35632 35633 set value(value) { 35634 this.$$set({ value }); 35635 flush(); 35636 } 35637 35638 get label() { 35639 return this.$$.ctx[5]; 35640 } 35641 35642 set label(label) { 35643 this.$$set({ label }); 35644 flush(); 35645 } 35646 35647 get show_label() { 35648 return this.$$.ctx[6]; 35649 } 35650 35651 set show_label(show_label) { 35652 this.$$set({ show_label }); 35653 flush(); 35654 } 35655 35656 get show_download_button() { 35657 return this.$$.ctx[7]; 35658 } 35659 35660 set show_download_button(show_download_button) { 35661 this.$$set({ show_download_button }); 35662 flush(); 35663 } 35664 35665 get root() { 35666 return this.$$.ctx[8]; 35667 } 35668 35669 set root(root) { 35670 this.$$set({ root }); 35671 flush(); 35672 } 35673 35674 get height() { 35675 return this.$$.ctx[9]; 35676 } 35677 35678 set height(height) { 35679 this.$$set({ height }); 35680 flush(); 35681 } 35682 35683 get width() { 35684 return this.$$.ctx[10]; 35685 } 35686 35687 set width(width) { 35688 this.$$set({ width }); 35689 flush(); 35690 } 35691 35692 get _selectable() { 35693 return this.$$.ctx[11]; 35694 } 35695 35696 set _selectable(_selectable) { 35697 this.$$set({ _selectable }); 35698 flush(); 35699 } 35700 35701 get container() { 35702 return this.$$.ctx[12]; 35703 } 35704 35705 set container(container) { 35706 this.$$set({ container }); 35707 flush(); 35708 } 35709 35710 get scale() { 35711 return this.$$.ctx[13]; 35712 } 35713 35714 set scale(scale) { 35715 this.$$set({ scale }); 35716 flush(); 35717 } 35718 35719 get min_width() { 35720 return this.$$.ctx[14]; 35721 } 35722 35723 set min_width(min_width) { 35724 this.$$set({ min_width }); 35725 flush(); 35726 } 35727 35728 get loading_status() { 35729 return this.$$.ctx[0]; 35730 } 35731 35732 set loading_status(loading_status) { 35733 this.$$set({ loading_status }); 35734 flush(); 35735 } 35736 35737 get show_share_button() { 35738 return this.$$.ctx[15]; 35739 } 35740 35741 set show_share_button(show_share_button) { 35742 this.$$set({ show_share_button }); 35743 flush(); 35744 } 35745 35746 get sources() { 35747 return this.$$.ctx[16]; 35748 } 35749 35750 set sources(sources) { 35751 this.$$set({ sources }); 35752 flush(); 35753 } 35754 35755 get proxy_url() { 35756 return this.$$.ctx[17]; 35757 } 35758 35759 set proxy_url(proxy_url) { 35760 this.$$set({ proxy_url }); 35761 flush(); 35762 } 35763 35764 get interactive() { 35765 return this.$$.ctx[18]; 35766 } 35767 35768 set interactive(interactive) { 35769 this.$$set({ interactive }); 35770 flush(); 35771 } 35772 35773 get brush() { 35774 return this.$$.ctx[19]; 35775 } 35776 35777 set brush(brush) { 35778 this.$$set({ brush }); 35779 flush(); 35780 } 35781 35782 get eraser() { 35783 return this.$$.ctx[20]; 35784 } 35785 35786 set eraser(eraser) { 35787 this.$$set({ eraser }); 35788 flush(); 35789 } 35790 35791 get crop_size() { 35792 return this.$$.ctx[21]; 35793 } 35794 35795 set crop_size(crop_size) { 35796 this.$$set({ crop_size }); 35797 flush(); 35798 } 35799 35800 get transforms() { 35801 return this.$$.ctx[22]; 35802 } 35803 35804 set transforms(transforms) { 35805 this.$$set({ transforms }); 35806 flush(); 35807 } 35808 35809 get attached_events() { 35810 return this.$$.ctx[23]; 35811 } 35812 35813 set attached_events(attached_events) { 35814 this.$$set({ attached_events }); 35815 flush(); 35816 } 35817 35818 get gradio() { 35819 return this.$$.ctx[24]; 35820 } 35821 35822 set gradio(gradio) { 35823 this.$$set({ gradio }); 35824 flush(); 35825 } 35826 35827 get get_value() { 35828 return this.$$.ctx[28]; 35829 } 35830} 35831 35832export { Index as default }; 35833//# sourceMappingURL=Index-c1c3d5b0.js.map
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.