agmon 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/.next/BUILD_ID +1 -0
  2. package/.next/app-path-routes-manifest.json +7 -0
  3. package/.next/build/chunks/[root-of-the-server]__05i36w1t4lzaf._.js +502 -0
  4. package/.next/build/chunks/[root-of-the-server]__05i36w1t4lzaf._.js.map +11 -0
  5. package/.next/build/chunks/[root-of-the-server]__1kki86fknkq7y._.js +190 -0
  6. package/.next/build/chunks/[root-of-the-server]__1kki86fknkq7y._.js.map +8 -0
  7. package/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_1gfkiq9iz8yb8._.js +13 -0
  8. package/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_1gfkiq9iz8yb8._.js.map +5 -0
  9. package/.next/build/chunks/[turbopack]_runtime.js +1056 -0
  10. package/.next/build/chunks/[turbopack]_runtime.js.map +11 -0
  11. package/.next/build/chunks/node_modules_20v-8wlfss9m1._.js +7314 -0
  12. package/.next/build/chunks/node_modules_20v-8wlfss9m1._.js.map +47 -0
  13. package/.next/build/chunks/pool_entry-[turbopack-node]_transforms_postcss_ts_0tp-k2vy8nj6i._.js +6 -0
  14. package/.next/build/chunks/pool_entry-[turbopack-node]_transforms_postcss_ts_0tp-k2vy8nj6i._.js.map +5 -0
  15. package/.next/build/package.json +1 -0
  16. package/.next/build-manifest.json +54 -0
  17. package/.next/export-marker.json +6 -0
  18. package/.next/fallback-build-manifest.json +15 -0
  19. package/.next/images-manifest.json +68 -0
  20. package/.next/next-minimal-server.js.nft.json +1 -0
  21. package/.next/next-server.js.nft.json +1 -0
  22. package/.next/package.json +1 -0
  23. package/.next/prerender-manifest.json +97 -0
  24. package/.next/required-server-files.js +366 -0
  25. package/.next/required-server-files.json +366 -0
  26. package/.next/routes-manifest.json +75 -0
  27. package/.next/server/app/_global-error/page/app-paths-manifest.json +3 -0
  28. package/.next/server/app/_global-error/page/build-manifest.json +21 -0
  29. package/.next/server/app/_global-error/page/next-font-manifest.json +6 -0
  30. package/.next/server/app/_global-error/page/react-loadable-manifest.json +1 -0
  31. package/.next/server/app/_global-error/page/server-reference-manifest.json +4 -0
  32. package/.next/server/app/_global-error/page.js +10 -0
  33. package/.next/server/app/_global-error/page.js.map +5 -0
  34. package/.next/server/app/_global-error/page.js.nft.json +1 -0
  35. package/.next/server/app/_global-error/page_client-reference-manifest.js +3 -0
  36. package/.next/server/app/_global-error.html +1 -0
  37. package/.next/server/app/_global-error.meta +30 -0
  38. package/.next/server/app/_global-error.rsc +18 -0
  39. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +23 -0
  40. package/.next/server/app/_global-error.segments/_full.segment.rsc +18 -0
  41. package/.next/server/app/_global-error.segments/_tree.segment.rsc +2 -0
  42. package/.next/server/app/_not-found/page/app-paths-manifest.json +3 -0
  43. package/.next/server/app/_not-found/page/build-manifest.json +21 -0
  44. package/.next/server/app/_not-found/page/next-font-manifest.json +6 -0
  45. package/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -0
  46. package/.next/server/app/_not-found/page/server-reference-manifest.json +4 -0
  47. package/.next/server/app/_not-found/page.js +12 -0
  48. package/.next/server/app/_not-found/page.js.map +5 -0
  49. package/.next/server/app/_not-found/page.js.nft.json +1 -0
  50. package/.next/server/app/_not-found/page_client-reference-manifest.js +3 -0
  51. package/.next/server/app/_not-found.html +1 -0
  52. package/.next/server/app/_not-found.meta +35 -0
  53. package/.next/server/app/_not-found.rsc +22 -0
  54. package/.next/server/app/_not-found.segments/_full.segment.rsc +22 -0
  55. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +28 -0
  56. package/.next/server/app/_not-found.segments/_tree.segment.rsc +4 -0
  57. package/.next/server/app/api/traces/stream/route/app-paths-manifest.json +3 -0
  58. package/.next/server/app/api/traces/stream/route/build-manifest.json +12 -0
  59. package/.next/server/app/api/traces/stream/route/server-reference-manifest.json +4 -0
  60. package/.next/server/app/api/traces/stream/route.js +7 -0
  61. package/.next/server/app/api/traces/stream/route.js.map +5 -0
  62. package/.next/server/app/api/traces/stream/route.js.nft.json +1 -0
  63. package/.next/server/app/api/traces/stream/route_client-reference-manifest.js +3 -0
  64. package/.next/server/app/api/version/route/app-paths-manifest.json +3 -0
  65. package/.next/server/app/api/version/route/build-manifest.json +12 -0
  66. package/.next/server/app/api/version/route/server-reference-manifest.json +4 -0
  67. package/.next/server/app/api/version/route.js +7 -0
  68. package/.next/server/app/api/version/route.js.map +5 -0
  69. package/.next/server/app/api/version/route.js.nft.json +1 -0
  70. package/.next/server/app/api/version/route_client-reference-manifest.js +3 -0
  71. package/.next/server/app/index.html +1 -0
  72. package/.next/server/app/index.meta +29 -0
  73. package/.next/server/app/index.rsc +29 -0
  74. package/.next/server/app/index.segments/__PAGE__.segment.rsc +34 -0
  75. package/.next/server/app/index.segments/_full.segment.rsc +29 -0
  76. package/.next/server/app/index.segments/_tree.segment.rsc +3 -0
  77. package/.next/server/app/page/app-paths-manifest.json +3 -0
  78. package/.next/server/app/page/build-manifest.json +21 -0
  79. package/.next/server/app/page/next-font-manifest.json +6 -0
  80. package/.next/server/app/page/react-loadable-manifest.json +1 -0
  81. package/.next/server/app/page/server-reference-manifest.json +4 -0
  82. package/.next/server/app/page.js +13 -0
  83. package/.next/server/app/page.js.map +5 -0
  84. package/.next/server/app/page.js.nft.json +1 -0
  85. package/.next/server/app/page_client-reference-manifest.js +3 -0
  86. package/.next/server/app-paths-manifest.json +7 -0
  87. package/.next/server/chunks/[externals]__0bwf06g0pqv3h._.js +3 -0
  88. package/.next/server/chunks/[externals]__0bwf06g0pqv3h._.js.map +1 -0
  89. package/.next/server/chunks/[externals]__1p2j9_5g429uh._.js +3 -0
  90. package/.next/server/chunks/[externals]__1p2j9_5g429uh._.js.map +1 -0
  91. package/.next/server/chunks/[root-of-the-server]__04an4kw4xcc5l._.js +5 -0
  92. package/.next/server/chunks/[root-of-the-server]__04an4kw4xcc5l._.js.map +1 -0
  93. package/.next/server/chunks/[root-of-the-server]__1s6v8mz-nanm-._.js +5 -0
  94. package/.next/server/chunks/[root-of-the-server]__1s6v8mz-nanm-._.js.map +1 -0
  95. package/.next/server/chunks/[root-of-the-server]__20xfs4y2ipcvv._.js +320 -0
  96. package/.next/server/chunks/[root-of-the-server]__20xfs4y2ipcvv._.js.map +1 -0
  97. package/.next/server/chunks/[turbopack]_runtime.js +937 -0
  98. package/.next/server/chunks/[turbopack]_runtime.js.map +10 -0
  99. package/.next/server/chunks/_next-internal_server_app_api_traces_stream_route_actions_07rmicxgds803.js +3 -0
  100. package/.next/server/chunks/_next-internal_server_app_api_traces_stream_route_actions_07rmicxgds803.js.map +1 -0
  101. package/.next/server/chunks/_next-internal_server_app_api_version_route_actions_0kbx30hro8e93.js +3 -0
  102. package/.next/server/chunks/_next-internal_server_app_api_version_route_actions_0kbx30hro8e93.js.map +1 -0
  103. package/.next/server/chunks/ssr/1q96_modules_pixi_js_lib_rendering_renderers_canvas_CanvasRenderer_mjs_1xntzghggpb51._.js +3 -0
  104. package/.next/server/chunks/ssr/1q96_modules_pixi_js_lib_rendering_renderers_canvas_CanvasRenderer_mjs_1xntzghggpb51._.js.map +1 -0
  105. package/.next/server/chunks/ssr/1q96_modules_pixi_js_lib_rendering_renderers_gpu_WebGPURenderer_mjs_00tc9jrf-ft1_._.js +76 -0
  106. package/.next/server/chunks/ssr/1q96_modules_pixi_js_lib_rendering_renderers_gpu_WebGPURenderer_mjs_00tc9jrf-ft1_._.js.map +1 -0
  107. package/.next/server/chunks/ssr/[root-of-the-server]__08zgqq_38tv57._.js +3 -0
  108. package/.next/server/chunks/ssr/[root-of-the-server]__08zgqq_38tv57._.js.map +1 -0
  109. package/.next/server/chunks/ssr/[root-of-the-server]__0aa2929udndo-._.js +3 -0
  110. package/.next/server/chunks/ssr/[root-of-the-server]__0aa2929udndo-._.js.map +1 -0
  111. package/.next/server/chunks/ssr/[root-of-the-server]__0ayw3c9e93kvf._.js +3 -0
  112. package/.next/server/chunks/ssr/[root-of-the-server]__0ayw3c9e93kvf._.js.map +1 -0
  113. package/.next/server/chunks/ssr/[root-of-the-server]__0ojpb-dtuk3-q._.js +3 -0
  114. package/.next/server/chunks/ssr/[root-of-the-server]__0ojpb-dtuk3-q._.js.map +1 -0
  115. package/.next/server/chunks/ssr/[root-of-the-server]__0py1t7q9ntzgc._.js +3 -0
  116. package/.next/server/chunks/ssr/[root-of-the-server]__0py1t7q9ntzgc._.js.map +1 -0
  117. package/.next/server/chunks/ssr/[root-of-the-server]__1cf6qt9agg_9-._.js +14 -0
  118. package/.next/server/chunks/ssr/[root-of-the-server]__1cf6qt9agg_9-._.js.map +1 -0
  119. package/.next/server/chunks/ssr/[root-of-the-server]__1e1_fmeab1ca7._.js +3 -0
  120. package/.next/server/chunks/ssr/[root-of-the-server]__1e1_fmeab1ca7._.js.map +1 -0
  121. package/.next/server/chunks/ssr/[root-of-the-server]__1w2vu9hh0h02y._.js +3 -0
  122. package/.next/server/chunks/ssr/[root-of-the-server]__1w2vu9hh0h02y._.js.map +1 -0
  123. package/.next/server/chunks/ssr/[turbopack]_runtime.js +937 -0
  124. package/.next/server/chunks/ssr/[turbopack]_runtime.js.map +10 -0
  125. package/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-psc_d2.js +3 -0
  126. package/.next/server/chunks/ssr/_next-internal_server_app__global-error_page_actions_0zi5s8-psc_d2.js.map +1 -0
  127. package/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yrisjoev.js +3 -0
  128. package/.next/server/chunks/ssr/_next-internal_server_app__not-found_page_actions_0pt47yrisjoev.js.map +1 -0
  129. package/.next/server/chunks/ssr/_next-internal_server_app_page_actions_0hhsz1jew5ls7.js +3 -0
  130. package/.next/server/chunks/ssr/_next-internal_server_app_page_actions_0hhsz1jew5ls7.js.map +1 -0
  131. package/.next/server/chunks/ssr/node_modules_01xbj_9zg44kw._.js +33 -0
  132. package/.next/server/chunks/ssr/node_modules_01xbj_9zg44kw._.js.map +1 -0
  133. package/.next/server/chunks/ssr/node_modules_0a548_llmwce7._.js +23 -0
  134. package/.next/server/chunks/ssr/node_modules_0a548_llmwce7._.js.map +1 -0
  135. package/.next/server/chunks/ssr/node_modules_0gxlxpuufujz9._.js +33 -0
  136. package/.next/server/chunks/ssr/node_modules_0gxlxpuufujz9._.js.map +1 -0
  137. package/.next/server/chunks/ssr/node_modules_next_dist_0janj0i6dqko7._.js +6 -0
  138. package/.next/server/chunks/ssr/node_modules_next_dist_0janj0i6dqko7._.js.map +1 -0
  139. package/.next/server/chunks/ssr/node_modules_next_dist_1hgv5i-pr1hza._.js +3 -0
  140. package/.next/server/chunks/ssr/node_modules_next_dist_1hgv5i-pr1hza._.js.map +1 -0
  141. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j32_ibz4._.js +3 -0
  142. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j32_ibz4._.js.map +1 -0
  143. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9mbf-fh.js +3 -0
  144. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9mbf-fh.js.map +1 -0
  145. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0q-w892nagajq.js +3 -0
  146. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0q-w892nagajq.js.map +1 -0
  147. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0xky89qu.js +3 -0
  148. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0xky89qu.js.map +1 -0
  149. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0aymk_x8-bu4q.js +3 -0
  150. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0aymk_x8-bu4q.js.map +1 -0
  151. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z4y02i7.js +3 -0
  152. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z4y02i7.js.map +1 -0
  153. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1qjycfedgh109.js +3 -0
  154. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1qjycfedgh109.js.map +1 -0
  155. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0hcyh9uzlz7ci._.js +3 -0
  156. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0hcyh9uzlz7ci._.js.map +1 -0
  157. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0k3f3soanqdoq._.js +3 -0
  158. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0k3f3soanqdoq._.js.map +1 -0
  159. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0ovgsftn-uvbz._.js +3 -0
  160. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0ovgsftn-uvbz._.js.map +1 -0
  161. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0xa24fqr5c5qi._.js +5 -0
  162. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0xa24fqr5c5qi._.js.map +1 -0
  163. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0zrftay3kjup7._.js +5 -0
  164. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_0zrftay3kjup7._.js.map +1 -0
  165. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_1z4lgkg_w-7fr._.js +208 -0
  166. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_1z4lgkg_w-7fr._.js.map +1 -0
  167. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_1zjkoj2kc4hm-._.js +3 -0
  168. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_1zjkoj2kc4hm-._.js.map +1 -0
  169. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_environment-browser_browserAll_mjs_0xb_t3dj4ad1f._.js +16 -0
  170. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_environment-browser_browserAll_mjs_0xb_t3dj4ad1f._.js.map +1 -0
  171. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_filters_Filter_mjs_0luksfw8ekifi._.js +3 -0
  172. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_filters_Filter_mjs_0luksfw8ekifi._.js.map +1 -0
  173. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_filters_init_mjs_1o5fmm_m60v_s._.js +3 -0
  174. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_filters_init_mjs_1o5fmm_m60v_s._.js.map +1 -0
  175. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_rendering_1fkio2phhfvow._.js +196 -0
  176. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_rendering_1fkio2phhfvow._.js.map +1 -0
  177. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_rendering_1n1q7aum4i7zo._.js +196 -0
  178. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_rendering_1n1q7aum4i7zo._.js.map +1 -0
  179. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_rendering_renderers_10vpvx1o7svnk._.js +3 -0
  180. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_rendering_renderers_10vpvx1o7svnk._.js.map +1 -0
  181. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_rendering_renderers_gl_WebGLRenderer_mjs_1hlux44jh7dk-._.js +153 -0
  182. package/.next/server/chunks/ssr/node_modules_pixi_js_lib_rendering_renderers_gl_WebGLRenderer_mjs_1hlux44jh7dk-._.js.map +1 -0
  183. package/.next/server/chunks/ssr/src_app_page_1vqfk0-j72fp6.js +3 -0
  184. package/.next/server/chunks/ssr/src_app_page_1vqfk0-j72fp6.js.map +1 -0
  185. package/.next/server/functions-config-manifest.json +4 -0
  186. package/.next/server/interception-route-rewrite-manifest.js +1 -0
  187. package/.next/server/middleware-build-manifest.js +54 -0
  188. package/.next/server/middleware-manifest.json +6 -0
  189. package/.next/server/next-font-manifest.js +1 -0
  190. package/.next/server/next-font-manifest.json +6 -0
  191. package/.next/server/pages/404.html +1 -0
  192. package/.next/server/pages/500.html +1 -0
  193. package/.next/server/pages-manifest.json +4 -0
  194. package/.next/server/prefetch-hints.json +34 -0
  195. package/.next/server/preview-props.json +5 -0
  196. package/.next/server/server-reference-manifest.js +1 -0
  197. package/.next/server/server-reference-manifest.json +5 -0
  198. package/.next/static/chunks/0_9x2udu0iodw.js +1 -0
  199. package/.next/static/chunks/0cz1d0mv5g_q7.js +1 -0
  200. package/.next/static/chunks/0umf92h1sb77c.js +1 -0
  201. package/.next/static/chunks/10om7oix6wjze.js +1 -0
  202. package/.next/static/chunks/1780fh11o7pze.js +1 -0
  203. package/.next/static/chunks/1cldmiyw3ya18.js +21 -0
  204. package/.next/static/chunks/1unuqfq-vfqtp.js +1 -0
  205. package/.next/static/chunks/2-vsu_pt58kse.js +3 -0
  206. package/.next/static/chunks/2drjv1ti9t4pg.js +1 -0
  207. package/.next/static/chunks/2hgsvrrwu57--.css +1 -0
  208. package/.next/static/chunks/2ogvir8krwwhf.js +1 -0
  209. package/.next/static/chunks/2tc54fmsk8v8q.js +1 -0
  210. package/.next/static/chunks/304ue7hvto0o0.js +206 -0
  211. package/.next/static/chunks/31gve42sn75--.js +1 -0
  212. package/.next/static/chunks/32kizm_7q94vd.js +194 -0
  213. package/.next/static/chunks/33bap0u4zwgab.js +74 -0
  214. package/.next/static/chunks/3c4xol65z2da2.js +22 -0
  215. package/.next/static/chunks/3cfn99dbrcvvp.js +31 -0
  216. package/.next/static/chunks/3d6xc1eemxy82.js +1 -0
  217. package/.next/static/chunks/3ycr8gfnsg-xv.js +151 -0
  218. package/.next/static/chunks/3ytt3vrdhke9u.js +14 -0
  219. package/.next/static/chunks/turbopack-3-ry682tkyiqk.js +1 -0
  220. package/.next/static/cy2F4S28h_-YWqCOuE_ul/_buildManifest.js +11 -0
  221. package/.next/static/cy2F4S28h_-YWqCOuE_ul/_clientMiddlewareManifest.js +1 -0
  222. package/.next/static/cy2F4S28h_-YWqCOuE_ul/_ssgManifest.js +1 -0
  223. package/.next/trace +1 -0
  224. package/.next/trace-build +1 -0
  225. package/.next/types/cache-life.d.ts +114 -0
  226. package/.next/types/root-params.d.ts +3 -0
  227. package/.next/types/routes.d.ts +74 -0
  228. package/.next/types/validator.ts +17 -0
  229. package/bin/cli.js +24 -6
  230. package/package.json +6 -6
  231. package/src/app/api/traces/stream/route.js +2 -2
  232. package/src/app/layout.js +1 -1
  233. package/src/app/page.js +6 -19
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/app/page.js","../../../../src/components/factory/office-scene.js","../../../../node_modules/tiny-lru/dist/tiny-lru.js","../../../../src/components/factory/office-canvas.js","../../../../src/lib/useFactoryTraces.js","../../../../src/components/factory/AgentPanel.js","../../../../src/components/UpdateNotification.js","../../../../src/lib/mockTraces.js","../../../../node_modules/pixi.js/src/scene/text/canvas/utils/fontStringFromTextStyle.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/utils/parseTaggedText.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/utils/textTokenization.ts","../../../../src/components/factory/scene/tool-icons.js","../../../../src/components/factory/scene/token-streams.js","../../../../src/components/factory/scene/characters.js","../../../../node_modules/pixi.js/src/environment-browser/browserExt.ts","../../../../node_modules/pixi.js/src/utils/browser/isWebGPUSupported.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/utils/wordWrap.ts","../../../../node_modules/pixi.js/src/scene/text/utils/updateTextBounds.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/BatchableText.ts","../../../../node_modules/pixi.js/src/scene/text/shared/GpuTextSystem.ts","../../../../node_modules/pixi.js/src/scene/text/utils/warnIgnoredTextureStyle.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/utils/measureTaggedText.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/CanvasTextSystem.ts","../../../../node_modules/pixi.js/src/app/TickerPlugin.ts","../../../../node_modules/pixi.js/src/utils/canvas/getCanvasBoundingBox.ts","../../../../src/components/factory/scene/office-layout.js","../../../../node_modules/pixi.js/src/rendering/renderers/autoDetectRenderer.ts","../../../../node_modules/pixi.js/src/utils/browser/isWebGLSupported.ts","../../../../node_modules/pixi.js/src/scene/text/AbstractText.ts","../../../../node_modules/pixi.js/src/scene/text/init.ts","../../../../node_modules/pixi.js/src/environment-webworker/webworkerExt.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/CanvasTextPipe.ts","../../../../node_modules/pixi.js/src/app/Application.ts","../../../../node_modules/pixi.js/src/scene/text/shared/AbstractTextSystem.ts","../../../../node_modules/pixi.js/src/scene/text/Text.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/utils/getCanvasFillStyle.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/CanvasTextGenerator.ts","../../../../node_modules/pixi.js/src/scene/text/TextStyle.ts","../../../../node_modules/pixi.js/src/app/ResizePlugin.ts","../../../../node_modules/pixi.js/src/scene/text/canvas/CanvasTextMetrics.ts","../../../../node_modules/pixi.js/src/index.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport OfficeCanvas from \"../components/factory/office-canvas\";\nimport { useFactoryTraces } from \"../lib/useFactoryTraces\";\nimport { buildOffice } from \"../components/factory/scene/office-layout\";\nimport AgentPanel from \"../components/factory/AgentPanel\";\nimport UpdateNotification from \"../components/UpdateNotification\";\n\nconst PRESETS = [\n { id: \"cases\", label: \"Edge Cases\" },\n { id: \"storm\", label: \"Storm (30 Agents)\" },\n { id: \"busy\", label: \"Busy (8 Agents)\" },\n { id: \"idle\", label: \"Idle (2 Agents)\" },\n { id: \"errors\", label: \"Error States\" },\n];\n\nexport default function FactoryPage() {\n const [mode, setMode] = useState(\"live\");\n const [mockPreset, setMockPreset] = useState(\"cases\");\n const [selectedId, setSelectedId] = useState(null);\n\n const { traces, connected, live, isRefreshing, refresh } = useFactoryTraces({ mode, preset: mockPreset });\n\n const office = useMemo(() => buildOffice(traces), [traces]);\n const selected = useMemo(\n () => office.workstations.find((w) => w.connectionId === selectedId) || null,\n [office, selectedId]\n );\n\n return (\n <main className=\"flex h-screen w-screen flex-col overflow-hidden bg-[#070b12] text-slate-100\">\n <UpdateNotification />\n\n {/* Top Header / Nav */}\n <header className=\"flex h-14 shrink-0 items-center justify-between border-b border-slate-800/80 bg-slate-950/70 px-5 backdrop-blur-md\">\n {/* Brand */}\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-emerald-500 to-cyan-600 shadow-lg shadow-emerald-500/20\">\n <span className=\"text-lg\">🤖</span>\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-extrabold tracking-wider text-sm bg-gradient-to-r from-emerald-400 via-cyan-300 to-blue-400 bg-clip-text text-transparent\">\n AGMON\n </span>\n <span className=\"rounded-full bg-slate-800 px-2 py-0.5 text-[10px] font-semibold text-slate-400 uppercase tracking-wider\">\n v0.1.3\n </span>\n </div>\n <p className=\"text-[11px] text-slate-400\">AI Agent Office & Activity Visualizer</p>\n </div>\n </div>\n\n {/* Live Counters */}\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-2 rounded-lg border border-slate-800 bg-slate-900/60 px-3 py-1 text-xs\">\n <span className=\"text-slate-400\">Desks:</span>\n <span className=\"font-bold text-slate-200\">{office.stats.agents}</span>\n </div>\n <div className=\"flex items-center gap-2 rounded-lg border border-slate-800 bg-slate-900/60 px-3 py-1 text-xs\">\n <span className=\"text-slate-400\">Working:</span>\n <span className=\"font-bold text-cyan-400\">{office.stats.busy}</span>\n </div>\n <div className=\"flex items-center gap-2 rounded-lg border border-slate-800 bg-slate-900/60 px-3 py-1 text-xs\">\n <span className=\"text-slate-400\">Tokens:</span>\n <span className=\"font-bold text-emerald-400\">{office.stats.tokensLabel}</span>\n </div>\n </div>\n\n {/* Mode & Preset Controls */}\n <div className=\"flex items-center gap-2\">\n {/* Force Refresh Button */}\n <button\n onClick={refresh}\n title=\"Làm mới kết nối & dữ liệu ngay lập tức\"\n className=\"flex h-8 w-8 items-center justify-center rounded-lg border border-slate-800 bg-slate-900/60 text-slate-400 hover:border-slate-700 hover:text-slate-200 transition-all\"\n >\n <svg\n className={`h-4 w-4 ${isRefreshing ? \"animate-spin text-emerald-400\" : \"\"}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n </button>\n\n {/* Live Button */}\n <button\n onClick={() => {\n setMode(\"live\");\n setSelectedId(null);\n }}\n className={`flex items-center gap-2 rounded-lg px-3 py-1.5 text-xs font-semibold transition-all ${\n mode === \"live\"\n ? \"border border-emerald-500 bg-emerald-500/15 text-emerald-300 shadow-sm shadow-emerald-500/20\"\n : \"border border-slate-800 bg-slate-900/40 text-slate-400 hover:border-slate-700 hover:text-slate-200\"\n }`}\n >\n <span\n className={`h-2 w-2 rounded-full ${\n connected && live ? \"bg-emerald-400 animate-pulse shadow-sm shadow-emerald-400\" : \"bg-slate-500\"\n }`}\n />\n Live Watchers\n </button>\n\n {/* Preset Selector */}\n <div className=\"flex items-center rounded-lg border border-slate-800 bg-slate-900/60 p-0.5 text-xs\">\n <button\n onClick={() => {\n setMode(\"mock\");\n setSelectedId(null);\n }}\n className={`rounded-md px-2.5 py-1 transition-all ${\n mode === \"mock\"\n ? \"bg-slate-800 font-medium text-slate-200\"\n : \"text-slate-400 hover:text-slate-300\"\n }`}\n >\n Demo Mock:\n </button>\n <select\n value={mockPreset}\n onChange={(e) => {\n setMode(\"mock\");\n setMockPreset(e.target.value);\n setSelectedId(null);\n }}\n className=\"bg-transparent px-2 py-1 text-xs text-slate-300 outline-none cursor-pointer\"\n >\n {PRESETS.map((p) => (\n <option key={p.id} value={p.id} className=\"bg-slate-900 text-slate-200\">\n {p.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n </header>\n\n {/* Main Canvas Area */}\n <section className=\"relative flex-1 p-3\">\n <OfficeCanvas\n traces={traces}\n selectedId={selectedId}\n onSelect={(id) => setSelectedId(id)}\n />\n\n {/* Selected Agent Inspector */}\n <AgentPanel ws={selected} onClose={() => setSelectedId(null)} />\n </section>\n </main>\n );\n}\n","import { Application, Container, FillGradient, Graphics, Text } from \"pixi.js\";\nimport { buildOffice, OFFICE, STATE_COLORS } from \"./scene/office-layout\";\nimport { createCharacter, createDesk, createBadge } from \"./scene/characters\";\nimport { createToolBadge, STATUS_KEYS, STATUS_TYPES, TOOL_KEYS } from \"./scene/tool-icons\";\nimport { createTokenStreams } from \"./scene/token-streams\";\n\nconst MAX_ZOOM = 1.6;\nconst MIN_ZOOM = 0.2;\n\n// World rectangle the camera frames (floor).\nconst FLOOR = { x: -60, y: 40, w: 2150, h: 980 };\n\nconst DESK_W = 150;\nconst clamp01 = (v) => Math.max(0, Math.min(1, v));\n\nconst MODE_INTENSITY = { streaming: 0.8, pending: 0.3, happy: 0.2, sleeping: 0, error: 1 };\n\n/**\n * Mount the office scene on `canvas`.\n *\n * Everything visible is a function of the trace records:\n * - robot pose <- account state (typing / waving / happy / asleep / error)\n * - badge over head <- queued, done, or the specific failure reason\n * - badge by monitor <- tool type currently running\n * - desk face <- latency bar, cost, cache share, request pile\n * - packets <- input (round), output (diamond), cached (square)\n * - pods <- load meter, siren when saturated, operator robot\n * - amber lanes <- fallback: courier drone carries the request to another provider\n */\nexport async function mountOfficeScene(canvas, traces, options = {}) {\n let selectedId = options.selectedId ?? null;\n let onSelect = options.onSelect;\n\n const app = new Application();\n await app.init({\n canvas,\n preference: \"webgl\",\n resizeTo: canvas.parentElement,\n background: 0x0b0f16,\n antialias: true,\n resolution: Math.min(globalThis.devicePixelRatio || 1, 2),\n autoDensity: true,\n });\n\n const world = new Container();\n const floorLayer = new Container();\n const laneLayer = new Container();\n const deskLayer = new Container();\n const actorLayer = new Container();\n const toolLayer = new Container();\n const hudLayer = new Container();\n const streams = createTokenStreams();\n world.addChild(floorLayer, laneLayer, streams.container, deskLayer, actorLayer, toolLayer, hudLayer);\n app.stage.addChild(world);\n\n // ---- floor -------------------------------------------------------------\n const floor = new Graphics();\n floor.roundRect(FLOOR.x, FLOOR.y, FLOOR.w, FLOOR.h, 28).fill(\n new FillGradient({\n type: \"linear\",\n start: { x: 0, y: 0 },\n end: { x: 0, y: 1 },\n colorStops: [{ offset: 0, color: 0x0b1018 }, { offset: 1, color: 0x161f2c }],\n textureSpace: \"local\",\n }),\n );\n for (let x = FLOOR.x + 100; x < FLOOR.x + FLOOR.w; x += 100) {\n floor.moveTo(x, FLOOR.y + 14).lineTo(x, FLOOR.y + FLOOR.h - 14).stroke({ width: 1, color: 0x1a2330, alpha: 0.7 });\n }\n for (let y = FLOOR.y + 100; y < FLOOR.y + FLOOR.h; y += 100) {\n floor.moveTo(FLOOR.x + 14, y).lineTo(FLOOR.x + FLOOR.w - 14, y).stroke({ width: 1, color: 0x1a2330, alpha: 0.7 });\n }\n floor.roundRect(FLOOR.x, FLOOR.y, FLOOR.w, FLOOR.h, 28).stroke({ width: 2, color: 0x263244, alpha: 0.9 });\n // Zone panels: agents | router | providers\n floor.roundRect(OFFICE.rackX - 130, FLOOR.y + 120, 260, FLOOR.h - 240, 22).fill({ color: 0xfde047, alpha: 0.035 });\n floor.roundRect(OFFICE.podX - 110, FLOOR.y + 40, 220, FLOOR.h - 150, 22).fill({ color: 0x22d3ee, alpha: 0.035 });\n floor.eventMode = \"static\";\n floor.on(\"pointertap\", () => select(null));\n floorLayer.addChild(floor);\n\n // ---- central rack (Core Hub) with a dispatcher robot behind it -----------\n const rack = new Container();\n const dispatcher = createCharacter({ color: 0xfde047, trimColor: 0xf59e0b, seed: 3, scale: 0.95, mode: \"sleeping\" });\n dispatcher.root.baseX = 0;\n dispatcher.root.baseY = -156;\n dispatcher.root.x = 0;\n dispatcher.root.y = -156;\n rack.addChild(dispatcher.root);\n\n const rackBody = new Graphics();\n rackBody.roundRect(-70, -170, 140, 230, 10).fill({ color: 0x1a222d });\n rackBody.roundRect(-62, -162, 124, 60, 6).fill({ color: 0x223040 });\n rackBody.roundRect(-58, 40, 116, 96, 6).fill({ color: 0x223040 });\n rack.addChild(rackBody);\n\n const rackGlow = new Graphics();\n rackGlow.roundRect(-80, -180, 160, 250, 14).fill({ color: 0xfde047, alpha: 0.12 });\n rack.addChildAt(rackGlow, 0);\n\n const leds = new Graphics();\n rack.addChild(leds);\n\n const rackLabel = new Text({\n text: \"CORE HUB\",\n style: { fontFamily: \"Inter, system-ui, sans-serif\", fontSize: 14, fill: 0x38bdf8, fontWeight: \"800\", letterSpacing: 2 },\n });\n rackLabel.anchor.set(0.5, 0);\n rackLabel.y = -92;\n rack.addChild(rackLabel);\n\n const rackCount = createBadge(\"0\", { color: 0xfde047, size: 13 });\n rackCount.anchor.set(0.5, 0);\n rackCount.y = 4;\n rack.addChild(rackCount);\n deskLayer.addChild(rack);\n\n // ---- build / rebuild on data change ----------------------------------\n // Everything created per data refresh is tracked here and destroyed together.\n let dyn = [];\n let deskEntries = [];\n let podEntries = [];\n let couriers = [];\n let rackActive = false;\n\n const track = (layer, obj) => {\n layer.addChild(obj);\n dyn.push(obj);\n return obj;\n };\n\n function refreshSelection() {\n for (const e of deskEntries) e.desk.setSelected(e.ws.connectionId === selectedId);\n }\n\n function select(id) {\n selectedId = id;\n refreshSelection();\n onSelect?.(id);\n }\n\n function dashedLine(g, x, y1, y2, color) {\n const dir = Math.sign(y2 - y1) || 1;\n for (let y = y1; dir > 0 ? y < y2 - 8 : y > y2 + 8; y += dir * 14) {\n g.moveTo(x, y).lineTo(x, y + dir * 8).stroke({ width: 2, color, alpha: 0.8 });\n }\n }\n\n function rebuild(nextTraces) {\n for (const o of dyn) o.destroy({ children: true });\n dyn = [];\n deskEntries = [];\n podEntries = [];\n couriers = [];\n\n const office = buildOffice(nextTraces);\n const podByProvider = new Map(office.pods.map((p) => [p.provider, p]));\n const routes = [];\n\n // Back-to-front so nearer desks overlap further ones.\n const ordered = [...office.workstations].sort((a, b) => a.y - b.y || a.x - b.x);\n\n for (const [i, ws] of ordered.entries()) {\n const desk = createDesk({\n color: ws.color,\n label: ws.account,\n meta: `${ws.model || \"\"} · ${ws.totalLabel}`,\n elapsedMs: ws.elapsedMs,\n cost: ws.cost,\n cachedPct: ws.cachedPct,\n queued: ws.queued,\n depth: ws.depth,\n });\n desk.root.x = ws.x;\n desk.root.y = ws.y;\n desk.root.on(\"pointertap\", (e) => {\n e.stopPropagation();\n select(ws.connectionId === selectedId ? null : ws.connectionId);\n });\n\n // Agent first: it sits behind the desk so the desk hides its torso.\n const character = createCharacter({ color: ws.color, depth: ws.depth, seed: i, mode: ws.mode });\n character.root.x = ws.x + 108;\n character.root.baseX = ws.x + 108;\n character.root.baseY = ws.y + 34;\n character.root.y = character.root.baseY;\n track(deskLayer, character.root);\n track(deskLayer, desk.root);\n\n // Tool-call badges cycle by the monitor, one glyph per tool type.\n const toolBadges = [];\n if (ws.busy > 0 || ws.tools.length > 0) {\n for (const tool of ws.tools) {\n const badge = createToolBadge(tool, { size: 1.05 });\n badge.root.x = ws.x + 28;\n badge.root.y = ws.y - 50;\n badge.root.visible = false;\n track(toolLayer, badge.root);\n toolBadges.push(badge);\n }\n }\n\n // Status badge over the head: queued / done / the exact failure reason.\n let statusBadge = null;\n const statusKey =\n ws.mode === \"pending\" ? \"pending\"\n : ws.mode === \"happy\" ? \"done\"\n : ws.mode === \"error\" ? (STATUS_TYPES[ws.errorReason] ? ws.errorReason : \"rate_limited\")\n : null;\n if (statusKey) {\n statusBadge = createToolBadge(statusKey, { size: 1.05 });\n statusBadge.root.x = ws.x + DESK_W + 14;\n statusBadge.root.y = ws.y - 34;\n track(toolLayer, statusBadge.root);\n }\n\n // Fallback marker: this request already failed over from another provider.\n if (ws.fallbackFrom) {\n const fb = createToolBadge(\"fallback\", { size: 0.85, label: `from ${ws.fallbackFrom}` });\n fb.root.x = ws.x + DESK_W + 14;\n fb.root.y = ws.y + 40;\n track(toolLayer, fb.root);\n }\n\n // Cost: a coin pops off the desk of a finished account.\n let coin = null;\n if (ws.mode === \"happy\" && ws.cost > 0) {\n coin = new Container();\n const disc = new Graphics();\n disc.circle(0, 0, 6).fill({ color: 0xfacc15 });\n disc.circle(0, 0, 6).stroke({ width: 1.2, color: 0xa16207 });\n const amount = new Text({\n text: `+$${ws.cost.toFixed(2)}`,\n style: { fontFamily: \"Inter, system-ui, sans-serif\", fontSize: 11, fill: 0xfacc15, fontWeight: \"800\" },\n });\n amount.x = 10;\n amount.anchor.set(0, 0.5);\n coin.addChild(disc, amount);\n coin.x = ws.x + 16;\n coin.visible = false;\n track(toolLayer, coin);\n }\n\n deskEntries.push({ desk, character, ws, toolBadges, statusBadge, coin });\n\n const pod = podByProvider.get(ws.provider);\n if (ws.busy > 0) {\n const cap = (v) => Math.max(0.15, clamp01(v));\n const wIn = cap(ws.tokens.input / 16000);\n const wOut = cap(ws.tokens.output / 3200);\n const wCache = ws.tokens.cached > 0 ? cap(ws.tokens.cached / 6500) : 0;\n const deskPt = { x: ws.x + 75, y: ws.y - 10 };\n const rackIn = { x: OFFICE.rackX, y: OFFICE.rackY - 90 };\n // input: desk -> rack -> provider\n routes.push({ from: deskPt, to: rackIn, color: ws.color, weight: wIn });\n if (pod) {\n routes.push({ from: { x: OFFICE.rackX, y: OFFICE.rackY - 40 }, to: { x: pod.x - 46, y: pod.y }, color: pod.color, weight: wIn });\n // output: provider -> rack -> desk, arcing underneath\n routes.push({ from: { x: pod.x - 46, y: pod.y + 14 }, to: { x: OFFICE.rackX + 20, y: OFFICE.rackY - 10 }, color: 0x86efac, weight: wOut, shape: \"diamond\", arc: -22 });\n }\n routes.push({ from: { x: OFFICE.rackX - 20, y: OFFICE.rackY + 10 }, to: { x: ws.x + 100, y: ws.y + 6 }, color: 0x86efac, weight: wOut, shape: \"diamond\", arc: -22 });\n // cached: served at the rack, never reaches a provider\n if (wCache) {\n routes.push({ from: { x: ws.x + 90, y: ws.y - 20 }, to: { x: OFFICE.rackX - 30, y: OFFICE.rackY - 120 }, color: 0xcbd5e1, weight: wCache, shape: \"square\", arc: 44 });\n }\n }\n }\n\n // Provider pods: load meter, siren when saturated, operator robot behind.\n for (const pod of office.pods) {\n const operator = createCharacter({\n color: pod.color,\n trimColor: pod.color,\n scale: 0.55,\n seed: pod.provider.length,\n mode: pod.overloaded ? \"pending\" : pod.busy > 0 ? \"streaming\" : \"sleeping\",\n });\n operator.root.x = pod.x + 2;\n operator.root.baseX = pod.x + 2;\n operator.root.baseY = pod.y + 10;\n operator.root.y = pod.y + 10;\n track(deskLayer, operator.root);\n\n const g = new Graphics();\n g.ellipse(0, 34, 52, 10).fill({ color: 0x000000, alpha: 0.35 });\n g.roundRect(-46, -30, 92, 62, 12).fill({ color: 0x1c2531 });\n g.roundRect(-46, -30, 92, 6, 5).fill({ color: 0xffffff, alpha: 0.06 });\n // Load meter: three rows fill in turn as the provider saturates.\n const meterColor = pod.overloaded ? STATE_COLORS.error : pod.load > 0.5 ? 0xfbbf24 : 0x34d399;\n for (let r = 0; r < 3; r += 1) {\n const fill = clamp01(pod.load * 3 - r);\n g.roundRect(-38, -18 + r * 14, 76, 9, 3).fill({ color: 0x0f141c });\n if (fill > 0) g.roundRect(-38, -18 + r * 14, 76 * fill, 9, 3).fill({ color: meterColor, alpha: 0.9 });\n }\n g.x = pod.x;\n g.y = pod.y;\n track(deskLayer, g);\n\n const siren = new Graphics();\n siren.x = pod.x + 34;\n siren.y = pod.y - 35;\n track(deskLayer, siren);\n\n const label = new Text({\n text: pod.provider.toUpperCase(),\n style: { fontFamily: \"Inter, system-ui, sans-serif\", fontSize: 12, fill: 0xdce6f2, fontWeight: \"800\", letterSpacing: 1 },\n });\n label.anchor.set(0.5, 0);\n label.x = pod.x;\n label.y = pod.y + 38;\n track(deskLayer, label);\n\n const sub = createBadge(`${pod.busy} in flight${pod.overloaded ? \" · FULL\" : \"\"}`, {\n color: pod.overloaded ? STATE_COLORS.error : pod.color,\n size: 10,\n });\n sub.anchor.set(0.5, 0);\n sub.x = pod.x;\n sub.y = pod.y + 53;\n track(deskLayer, sub);\n\n podEntries.push({ pod, operator, siren });\n }\n\n // Fallback lanes + courier drones: from the failed provider to the one that served it.\n office.fallbacks.forEach((lane, k) => {\n const from = podByProvider.get(lane.from);\n const to = podByProvider.get(lane.to);\n if (!from || !to) return;\n const laneX = OFFICE.podX - 82 - (k % 4) * 14;\n\n const g = new Graphics();\n g.moveTo(from.x - 46, from.y).lineTo(laneX, from.y).stroke({ width: 2, color: 0xfbbf24, alpha: 0.5 });\n g.moveTo(to.x - 46, to.y).lineTo(laneX, to.y).stroke({ width: 2, color: 0xfbbf24, alpha: 0.5 });\n dashedLine(g, laneX, from.y, to.y, 0xfbbf24);\n const dir = Math.sign(to.y - from.y) || 1;\n g.poly([laneX - 6, to.y - dir * 10, laneX + 6, to.y - dir * 10, laneX, to.y]).fill({ color: 0xfbbf24 });\n track(laneLayer, g);\n\n const tag = new Text({\n text: `FALLBACK ×${lane.count}`,\n style: { fontFamily: \"Inter, system-ui, sans-serif\", fontSize: 9, fill: 0xfbbf24, fontWeight: \"800\", letterSpacing: 1 },\n });\n tag.anchor.set(1, 0.5);\n tag.x = laneX - 9;\n tag.y = (from.y + to.y) / 2;\n track(laneLayer, tag);\n\n const drone = createCharacter({ color: 0xfbbf24, trimColor: 0xf59e0b, scale: 0.5, seed: k + 5, mode: \"streaming\" });\n const parcel = new Graphics();\n parcel.roundRect(-30, -22, 14, 12, 2).fill({ color: 0xd6a15c });\n parcel.moveTo(-30, -16).lineTo(-16, -16).stroke({ width: 1.2, color: 0x7c4a1d });\n const flame = new Graphics();\n drone.root.addChild(parcel, flame);\n track(actorLayer, drone.root);\n couriers.push({ drone, flame, laneX, y1: from.y, y2: to.y, offset: k * 900 });\n });\n\n rack.x = OFFICE.rackX;\n rack.y = OFFICE.rackY;\n rackCount.text = String(office.rack.active);\n rackActive = office.rack.active > 0;\n dispatcher.setMode(rackActive ? \"streaming\" : \"sleeping\");\n streams.setRoutes(routes);\n refreshSelection();\n }\n\n // ---- camera -----------------------------------------------------------\n function fit() {\n if (app.screen.width <= 0 || app.screen.height <= 0) return;\n const scale = Math.min(\n app.screen.width / (FLOOR.w + 40),\n app.screen.height / (FLOOR.h + 40),\n MAX_ZOOM,\n );\n world.scale.set(Math.max(MIN_ZOOM, scale));\n world.x = (app.screen.width - FLOOR.w * world.scale.x) / 2 - FLOOR.x * world.scale.x;\n world.y = (app.screen.height - FLOOR.h * world.scale.y) / 2 - FLOOR.y * world.scale.y;\n }\n\n app.renderer.on(\"resize\", fit);\n\n // ---- animation --------------------------------------------------------\n let t = 0;\n app.ticker.add((ticker) => {\n const dt = ticker.deltaMS;\n t += dt;\n\n streams.animate(dt);\n\n for (const entry of deskEntries) {\n const { ws } = entry;\n const intensity = ws.mode === \"streaming\" ? Math.min(1, ws.busy / 2) : MODE_INTENSITY[ws.mode] ?? 0;\n entry.desk.animate(t, intensity);\n entry.character.animate(t, intensity);\n\n // Tool badges: pop in, float, shrink out; one tool at a time.\n const n = entry.toolBadges.length;\n if (n > 0) {\n const slot = 2200;\n const cycle = Math.floor((t + ws.x * 3) / slot) % n;\n const local = ((t + ws.x * 3) % slot) / slot;\n entry.toolBadges.forEach((b, idx) => {\n const active = idx === cycle;\n b.root.visible = active;\n if (!active) return;\n const k = Math.min(Math.min(1, local * 6), Math.min(1, (1 - local) * 6));\n b.root.scale.set(1.05 * (0.35 + 0.65 * k));\n b.root.alpha = k;\n b.root.y = ws.y - 50 + Math.sin(t * 0.005 + idx) * 2.5;\n b.halo.scale.set(1 + Math.sin(t * 0.01) * 0.12);\n });\n }\n\n if (entry.statusBadge) {\n const err = ws.mode === \"error\";\n entry.statusBadge.root.y = ws.y - 34 + Math.sin(t * (err ? 0.02 : 0.004) + ws.x) * (err ? 3 : 2);\n entry.statusBadge.halo.scale.set(1 + Math.sin(t * (err ? 0.016 : 0.008)) * (err ? 0.3 : 0.12));\n }\n\n if (entry.coin) {\n const p = ((t + ws.x * 5) % 3400) / 3400;\n entry.coin.visible = p < 0.8;\n entry.coin.y = ws.y - 24 - p * 30;\n entry.coin.alpha = Math.sin(Math.min(1, p / 0.8) * Math.PI);\n }\n }\n\n for (const { pod, operator, siren } of podEntries) {\n operator.animate(t, pod.overloaded ? 1 : Math.min(1, pod.load));\n siren.clear();\n if (pod.overloaded) {\n const on = Math.sin(t * 0.014) > 0;\n siren.circle(0, 0, 5).fill({ color: 0xef4444, alpha: on ? 1 : 0.35 });\n siren.circle(0, 0, 13).fill({ color: 0xef4444, alpha: on ? 0.28 : 0.05 });\n } else {\n siren.circle(0, 0, 3).fill({ color: pod.busy > 0 ? 0x34d399 : 0x475569, alpha: 0.9 });\n }\n }\n\n for (const c of couriers) {\n const p = ((t + c.offset) % 4500) / 4500;\n const eased = p * p * (3 - 2 * p);\n c.drone.root.baseX = c.laneX;\n c.drone.root.baseY = c.y1 + (c.y2 - c.y1) * eased + 6;\n c.drone.animate(t, 1);\n c.flame.clear();\n c.flame.ellipse(0, 16, 7 + Math.sin(t * 0.04) * 1.5, 10 + Math.sin(t * 0.05) * 3).fill({ color: 0xfbbf24, alpha: 0.55 });\n c.flame.ellipse(0, 14, 4, 6).fill({ color: 0xfff1b8, alpha: 0.85 });\n c.drone.root.alpha = Math.min(1, p * 8) * Math.min(1, (1 - p) * 8);\n }\n\n dispatcher.animate(t, rackActive ? 1 : 0);\n\n // Rack activity LEDs\n leds.clear();\n for (let row = 0; row < 5; row += 1) {\n for (let col = 0; col < 6; col += 1) {\n const on = Math.sin(t * 0.006 + row * 1.7 + col * 0.9) > (rackActive ? -0.2 : 0.6);\n if (!on) continue;\n leds.circle(-40 + col * 16, 56 + row * 14, 2.4).fill({\n color: row % 3 === 0 ? 0x34d399 : 0x22d3ee,\n alpha: 0.9,\n });\n }\n }\n rackGlow.alpha = rackActive ? 0.5 + Math.sin(t * 0.005) * 0.3 : 0.15;\n });\n\n // ---- legend ------------------------------------------------------------\n const legendTitle = (text, x) => {\n const title = new Text({\n text,\n style: { fontFamily: \"Inter, system-ui, sans-serif\", fontSize: 11, fill: 0x7d8aa0, fontWeight: \"800\", letterSpacing: 2 },\n });\n title.x = x;\n title.y = FLOOR.y + FLOOR.h - 52;\n hudLayer.addChild(title);\n };\n legendTitle(\"TOOL CALLS\", 35);\n TOOL_KEYS.forEach((tool, i) => {\n const chip = createToolBadge(tool, { size: 0.72 });\n chip.root.x = 160 + i * 65;\n chip.root.y = FLOOR.y + FLOOR.h - 40;\n hudLayer.addChild(chip.root);\n });\n legendTitle(\"STATUS\", 965);\n STATUS_KEYS.forEach((key, i) => {\n const chip = createToolBadge(key, { size: 0.72 });\n chip.root.x = 1050 + i * 68;\n chip.root.y = FLOOR.y + FLOOR.h - 40;\n hudLayer.addChild(chip.root);\n });\n const packetKey = new Text({\n text: \"● input ◆ output ■ cached\",\n style: { fontFamily: \"Inter, system-ui, sans-serif\", fontSize: 11, fill: 0x7d8aa0, fontWeight: \"700\" },\n });\n packetKey.x = 1560;\n packetKey.y = FLOOR.y + FLOOR.h - 50;\n hudLayer.addChild(packetKey);\n\n rebuild(traces);\n fit();\n\n return {\n app,\n rebuild,\n fit,\n setSelected(id) {\n selectedId = id;\n refreshSelection();\n },\n setOnSelect(fn) {\n onSelect = fn;\n },\n destroy: () => app.destroy(true, { children: true }),\n };\n}\n\nexport { STATE_COLORS };\n","/**\n * tiny-lru\n *\n * @copyright 2026 Jason Mulligan <jason.mulligan@avoidwork.com>\n * @license BSD-3-Clause\n * @version 11.4.7\n */\n/**\n * A high-performance Least Recently Used (LRU) cache implementation with optional TTL support.\n * Items are automatically evicted when the cache reaches its maximum size,\n * removing the least recently used items first. All core operations (get, set, delete) are O(1).\n *\n * @class LRU\n * @example\n * // Create a cache with max 100 items\n * const cache = new LRU(100);\n * cache.set('key1', 'value1');\n * console.log(cache.get('key1')); // 'value1'\n *\n * @example\n * // Create a cache with TTL\n * const cache = new LRU(100, 5000); // 5 second TTL\n * cache.set('key1', 'value1');\n * // After 5 seconds, key1 will be expired\n */\nclass LRU {\n\t/**\n\t * Creates a new LRU cache instance.\n\t * Note: Constructor does not validate parameters. Use lru() factory function for parameter validation.\n\t *\n\t * @constructor\n\t * @param {number} [max=0] - Maximum number of items to store. 0 means unlimited.\n\t * @param {number} [ttl=0] - Time to live in milliseconds. 0 means no expiration.\n\t * @param {boolean} [resetTtl=false] - Whether to reset TTL when accessing existing items via get().\n\t * @example\n\t * const cache = new LRU(1000, 60000, true); // 1000 items, 1 minute TTL, reset on access\n\t * @see {@link lru} For parameter validation\n\t * @since 1.0.0\n\t */\n\tconstructor (max = 0, ttl = 0, resetTtl = false) {\n\t\tthis.first = null;\n\t\tthis.items = Object.create(null);\n\t\tthis.last = null;\n\t\tthis.max = max;\n\t\tthis.resetTtl = resetTtl;\n\t\tthis.size = 0;\n\t\tthis.ttl = ttl;\n\t}\n\n\t/**\n\t * Removes all items from the cache.\n\t *\n\t * @method clear\n\t * @memberof LRU\n\t * @returns {LRU} The LRU instance for method chaining.\n\t * @example\n\t * cache.clear();\n\t * console.log(cache.size); // 0\n\t * @since 1.0.0\n\t */\n\tclear () {\n\t\tthis.first = null;\n\t\tthis.items = Object.create(null);\n\t\tthis.last = null;\n\t\tthis.size = 0;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes an item from the cache by key.\n\t *\n\t * @method delete\n\t * @memberof LRU\n\t * @param {string} key - The key of the item to delete.\n\t * @returns {LRU} The LRU instance for method chaining.\n\t * @example\n\t * cache.set('key1', 'value1');\n\t * cache.delete('key1');\n\t * console.log(cache.has('key1')); // false\n\t * @see {@link LRU#has}\n\t * @see {@link LRU#clear}\n\t * @since 1.0.0\n\t */\n\tdelete (key) {\n\t\tif (this.has(key)) {\n\t\t\tconst item = this.items[key];\n\n\t\t\tdelete this.items[key];\n\t\t\tthis.size--;\n\n\t\t\tif (item.prev !== null) {\n\t\t\t\titem.prev.next = item.next;\n\t\t\t}\n\n\t\t\tif (item.next !== null) {\n\t\t\t\titem.next.prev = item.prev;\n\t\t\t}\n\n\t\t\tif (this.first === item) {\n\t\t\t\tthis.first = item.next;\n\t\t\t}\n\n\t\t\tif (this.last === item) {\n\t\t\t\tthis.last = item.prev;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns an array of [key, value] pairs for the specified keys.\n\t * Order follows LRU order (least to most recently used).\n\t *\n\t * @method entries\n\t * @memberof LRU\n\t * @param {string[]} [keys=this.keys()] - Array of keys to get entries for. Defaults to all keys.\n\t * @returns {Array<Array<*>>} Array of [key, value] pairs in LRU order.\n\t * @example\n\t * cache.set('a', 1).set('b', 2);\n\t * console.log(cache.entries()); // [['a', 1], ['b', 2]]\n\t * console.log(cache.entries(['a'])); // [['a', 1]]\n\t * @see {@link LRU#keys}\n\t * @see {@link LRU#values}\n\t * @since 11.1.0\n\t */\n\tentries (keys = this.keys()) {\n\t\tconst result = new Array(keys.length);\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tconst key = keys[i];\n\t\t\tresult[i] = [key, this.get(key)];\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Removes the least recently used item from the cache.\n\t *\n\t * @method evict\n\t * @memberof LRU\n\t * @param {boolean} [bypass=false] - Whether to force eviction even when cache is empty.\n\t * @returns {LRU} The LRU instance for method chaining.\n\t * @example\n\t * cache.set('old', 'value').set('new', 'value');\n\t * cache.evict(); // Removes 'old' item\n\t * @see {@link LRU#setWithEvicted}\n\t * @since 1.0.0\n\t */\n\tevict (bypass = false) {\n\t\tif (bypass || this.size > 0) {\n\t\t\tconst item = this.first;\n\n\t\t\tdelete this.items[item.key];\n\n\t\t\tif (--this.size === 0) {\n\t\t\t\tthis.first = null;\n\t\t\t\tthis.last = null;\n\t\t\t} else {\n\t\t\t\tthis.first = item.next;\n\t\t\t\tthis.first.prev = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns the expiration timestamp for a given key.\n\t *\n\t * @method expiresAt\n\t * @memberof LRU\n\t * @param {string} key - The key to check expiration for.\n\t * @returns {number|undefined} The expiration timestamp in milliseconds, or undefined if key doesn't exist.\n\t * @example\n\t * const cache = new LRU(100, 5000); // 5 second TTL\n\t * cache.set('key1', 'value1');\n\t * console.log(cache.expiresAt('key1')); // timestamp 5 seconds from now\n\t * @see {@link LRU#get}\n\t * @see {@link LRU#has}\n\t * @since 1.0.0\n\t */\n\texpiresAt (key) {\n\t\tlet result;\n\n\t\tif (this.has(key)) {\n\t\t\tresult = this.items[key].expiry;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Retrieves a value from the cache by key. Updates the item's position to most recently used.\n\t *\n\t * @method get\n\t * @memberof LRU\n\t * @param {string} key - The key to retrieve.\n\t * @returns {*} The value associated with the key, or undefined if not found or expired.\n\t * @example\n\t * cache.set('key1', 'value1');\n\t * console.log(cache.get('key1')); // 'value1'\n\t * console.log(cache.get('nonexistent')); // undefined\n\t * @see {@link LRU#set}\n\t * @see {@link LRU#has}\n\t * @since 1.0.0\n\t */\n\tget (key) {\n\t\tconst item = this.items[key];\n\n\t\tif (item !== undefined) {\n\t\t\t// Check TTL only if enabled to avoid unnecessary Date.now() calls\n\t\t\tif (this.ttl > 0) {\n\t\t\t\tif (item.expiry <= Date.now()) {\n\t\t\t\t\tthis.delete(key);\n\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fast LRU update without full set() overhead\n\t\t\tthis.moveToEnd(item);\n\n\t\t\treturn item.value;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Checks if a key exists in the cache.\n\t *\n\t * @method has\n\t * @memberof LRU\n\t * @param {string} key - The key to check for.\n\t * @returns {boolean} True if the key exists, false otherwise.\n\t * @example\n\t * cache.set('key1', 'value1');\n\t * console.log(cache.has('key1')); // true\n\t * console.log(cache.has('nonexistent')); // false\n\t * @see {@link LRU#get}\n\t * @see {@link LRU#delete}\n\t * @since 9.0.0\n\t */\n\thas (key) {\n\t\treturn key in this.items;\n\t}\n\n\t/**\n\t * Efficiently moves an item to the end of the LRU list (most recently used position).\n\t * This is an internal optimization method that avoids the overhead of the full set() operation\n\t * when only LRU position needs to be updated.\n\t *\n\t * @method moveToEnd\n\t * @memberof LRU\n\t * @param {Object} item - The cache item with prev/next pointers to reposition.\n\t * @private\n\t * @since 11.3.5\n\t */\n\tmoveToEnd (item) {\n\t\t// If already at the end, nothing to do\n\t\tif (this.last === item) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove item from current position in the list\n\t\tif (item.prev !== null) {\n\t\t\titem.prev.next = item.next;\n\t\t}\n\n\t\tif (item.next !== null) {\n\t\t\titem.next.prev = item.prev;\n\t\t}\n\n\t\t// Update first pointer if this was the first item\n\t\tif (this.first === item) {\n\t\t\tthis.first = item.next;\n\t\t}\n\n\t\t// Add item to the end\n\t\titem.prev = this.last;\n\t\titem.next = null;\n\n\t\tif (this.last !== null) {\n\t\t\tthis.last.next = item;\n\t\t}\n\n\t\tthis.last = item;\n\n\t\t// Handle edge case: if this was the only item, it's also first\n\t\tif (this.first === null) {\n\t\t\tthis.first = item;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an array of all keys in the cache, ordered from least to most recently used.\n\t *\n\t * @method keys\n\t * @memberof LRU\n\t * @returns {string[]} Array of keys in LRU order.\n\t * @example\n\t * cache.set('a', 1).set('b', 2);\n\t * cache.get('a'); // Move 'a' to most recent\n\t * console.log(cache.keys()); // ['b', 'a']\n\t * @see {@link LRU#values}\n\t * @see {@link LRU#entries}\n\t * @since 9.0.0\n\t */\n\tkeys () {\n\t\tconst result = new Array(this.size);\n\t\tlet x = this.first;\n\t\tlet i = 0;\n\n\t\twhile (x !== null) {\n\t\t\tresult[i++] = x.key;\n\t\t\tx = x.next;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Sets a value in the cache and returns any evicted item.\n\t *\n\t * @method setWithEvicted\n\t * @memberof LRU\n\t * @param {string} key - The key to set.\n\t * @param {*} value - The value to store.\n\t * @param {boolean} [resetTtl=this.resetTtl] - Whether to reset the TTL for this operation.\n\t * @returns {Object|null} The evicted item (if any) with shape {key, value, expiry, prev, next}, or null.\n\t * @example\n\t * const cache = new LRU(2);\n\t * cache.set('a', 1).set('b', 2);\n\t * const evicted = cache.setWithEvicted('c', 3); // evicted = {key: 'a', value: 1, ...}\n\t * @see {@link LRU#set}\n\t * @see {@link LRU#evict}\n\t * @since 11.3.0\n\t */\n\tsetWithEvicted (key, value, resetTtl = this.resetTtl) {\n\t\tlet evicted = null;\n\n\t\tif (this.has(key)) {\n\t\t\tthis.set(key, value, true, resetTtl);\n\t\t} else {\n\t\t\tif (this.max > 0 && this.size === this.max) {\n\t\t\t\tevicted = {...this.first};\n\t\t\t\tthis.evict(true);\n\t\t\t}\n\n\t\t\tlet item = this.items[key] = {\n\t\t\t\texpiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,\n\t\t\t\tkey: key,\n\t\t\t\tprev: this.last,\n\t\t\t\tnext: null,\n\t\t\t\tvalue\n\t\t\t};\n\n\t\t\tif (++this.size === 1) {\n\t\t\t\tthis.first = item;\n\t\t\t} else {\n\t\t\t\tthis.last.next = item;\n\t\t\t}\n\n\t\t\tthis.last = item;\n\t\t}\n\n\t\treturn evicted;\n\t}\n\n\t/**\n\t * Sets a value in the cache. Updates the item's position to most recently used.\n\t *\n\t * @method set\n\t * @memberof LRU\n\t * @param {string} key - The key to set.\n\t * @param {*} value - The value to store.\n\t * @param {boolean} [bypass=false] - Internal parameter for setWithEvicted method.\n\t * @param {boolean} [resetTtl=this.resetTtl] - Whether to reset the TTL for this operation.\n\t * @returns {LRU} The LRU instance for method chaining.\n\t * @example\n\t * cache.set('key1', 'value1')\n\t * .set('key2', 'value2')\n\t * .set('key3', 'value3');\n\t * @see {@link LRU#get}\n\t * @see {@link LRU#setWithEvicted}\n\t * @since 1.0.0\n\t */\n\tset (key, value, bypass = false, resetTtl = this.resetTtl) {\n\t\tlet item = this.items[key];\n\n\t\tif (bypass || item !== undefined) {\n\t\t\t// Existing item: update value and position\n\t\t\titem.value = value;\n\n\t\t\tif (bypass === false && resetTtl) {\n\t\t\t\titem.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;\n\t\t\t}\n\n\t\t\t// Always move to end, but the bypass parameter affects TTL reset behavior\n\t\t\tthis.moveToEnd(item);\n\t\t} else {\n\t\t\t// New item: check for eviction and create\n\t\t\tif (this.max > 0 && this.size === this.max) {\n\t\t\t\tthis.evict(true);\n\t\t\t}\n\n\t\t\titem = this.items[key] = {\n\t\t\t\texpiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,\n\t\t\t\tkey: key,\n\t\t\t\tprev: this.last,\n\t\t\t\tnext: null,\n\t\t\t\tvalue\n\t\t\t};\n\n\t\t\tif (++this.size === 1) {\n\t\t\t\tthis.first = item;\n\t\t\t} else {\n\t\t\t\tthis.last.next = item;\n\t\t\t}\n\n\t\t\tthis.last = item;\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns an array of all values in the cache for the specified keys.\n\t * Order follows LRU order (least to most recently used).\n\t *\n\t * @method values\n\t * @memberof LRU\n\t * @param {string[]} [keys=this.keys()] - Array of keys to get values for. Defaults to all keys.\n\t * @returns {Array<*>} Array of values corresponding to the keys in LRU order.\n\t * @example\n\t * cache.set('a', 1).set('b', 2);\n\t * console.log(cache.values()); // [1, 2]\n\t * console.log(cache.values(['a'])); // [1]\n\t * @see {@link LRU#keys}\n\t * @see {@link LRU#entries}\n\t * @since 11.1.0\n\t */\n\tvalues (keys = this.keys()) {\n\t\tconst result = new Array(keys.length);\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tresult[i] = this.get(keys[i]);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n\n/**\n * Factory function to create a new LRU cache instance with parameter validation.\n *\n * @function lru\n * @param {number} [max=1000] - Maximum number of items to store. Must be >= 0. Use 0 for unlimited size.\n * @param {number} [ttl=0] - Time to live in milliseconds. Must be >= 0. Use 0 for no expiration.\n * @param {boolean} [resetTtl=false] - Whether to reset TTL when accessing existing items via get().\n * @returns {LRU} A new LRU cache instance.\n * @throws {TypeError} When parameters are invalid (negative numbers or wrong types).\n * @example\n * // Create cache with factory function\n * const cache = lru(100, 5000, true);\n * cache.set('key', 'value');\n *\n * @example\n * // Error handling\n * try {\n * const cache = lru(-1); // Invalid max\n * } catch (error) {\n * console.error(error.message); // \"Invalid max value\"\n * }\n * @see {@link LRU}\n * @since 1.0.0\n */\nfunction lru (max = 1000, ttl = 0, resetTtl = false) {\n\tif (isNaN(max) || max < 0) {\n\t\tthrow new TypeError(\"Invalid max value\");\n\t}\n\n\tif (isNaN(ttl) || ttl < 0) {\n\t\tthrow new TypeError(\"Invalid ttl value\");\n\t}\n\n\tif (typeof resetTtl !== \"boolean\") {\n\t\tthrow new TypeError(\"Invalid resetTtl value\");\n\t}\n\n\treturn new LRU(max, ttl, resetTtl);\n}export{LRU,lru};","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { mountOfficeScene } from \"./office-scene\";\n\nexport default function OfficeCanvas({ traces = [], onStats, onSelect, selectedId = null }) {\n const hostRef = useRef(null);\n const sceneRef = useRef(null);\n const latest = useRef({ onSelect, selectedId, traces });\n\n useEffect(() => {\n latest.current = { onSelect, selectedId, traces };\n });\n\n const [error, setError] = useState(null);\n\n useEffect(() => {\n let disposed = false;\n let handle = null;\n const host = hostRef.current;\n if (!host) return undefined;\n\n const canvas = document.createElement(\"canvas\");\n canvas.style.position = \"absolute\";\n canvas.style.inset = \"0\";\n canvas.style.width = \"100%\";\n canvas.style.height = \"100%\";\n canvas.style.display = \"block\";\n host.appendChild(canvas);\n\n (async () => {\n try {\n const mounted = await mountOfficeScene(canvas, latest.current.traces, {\n selectedId: latest.current.selectedId,\n onSelect: (id) => latest.current.onSelect?.(id),\n });\n\n if (disposed) {\n mounted.destroy?.();\n canvas.remove();\n return;\n }\n\n handle = mounted;\n sceneRef.current = handle;\n\n // Immediately reconcile in case traces arrived during async init\n if (latest.current.traces && latest.current.traces.length > 0) {\n handle.rebuild?.(latest.current.traces);\n }\n } catch (err) {\n console.error(\"[OfficeCanvas] mount failed:\", err);\n setError(err?.message || \"Failed to start the scene\");\n }\n })();\n\n return () => {\n disposed = true;\n handle?.destroy?.();\n sceneRef.current = null;\n host?.replaceChildren();\n };\n }, []);\n\n useEffect(() => {\n if (sceneRef.current) {\n sceneRef.current.rebuild?.(traces);\n }\n }, [traces]);\n\n useEffect(() => {\n if (sceneRef.current) {\n sceneRef.current.setSelected?.(selectedId);\n }\n }, [selectedId]);\n\n useEffect(() => {\n if (!onStats) return undefined;\n const id = setInterval(() => {\n onStats?.({ mounted: Boolean(sceneRef.current) });\n }, 2000);\n return () => clearInterval(id);\n }, [onStats]);\n\n return (\n <div className=\"relative h-full w-full overflow-hidden rounded-xl border border-slate-800 bg-[#080d14] shadow-2xl\">\n <div ref={hostRef} className=\"absolute inset-0\" />\n {error && (\n <div className=\"absolute inset-0 flex items-center justify-center p-6 text-center text-sm text-rose-400\">\n {error}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { generateMockTraces, mockProviderDescriptors, MOCK_PRESETS } from \"./mockTraces\";\n\nexport function useFactoryTraces({ mode = \"live\", preset = \"cases\" } = {}) {\n const [traces, setTraces] = useState([]);\n const [providers, setProviders] = useState([]);\n const [connected, setConnected] = useState(false);\n const [isRefreshing, setIsRefreshing] = useState(false);\n const [lastUpdated, setLastUpdated] = useState(null);\n\n const eventSourceRef = useRef(null);\n const watchdogTimerRef = useRef(null);\n\n // Reconnection trigger\n const [connectionEpoch, setConnectionEpoch] = useState(0);\n\n const refresh = useCallback(() => {\n setIsRefreshing(true);\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n eventSourceRef.current = null;\n }\n setConnectionEpoch((prev) => prev + 1);\n setTimeout(() => setIsRefreshing(false), 500);\n }, []);\n\n // 1. Mock Mode\n useEffect(() => {\n if (mode !== \"mock\") return undefined;\n\n const cfg = MOCK_PRESETS[preset] || MOCK_PRESETS.cases;\n const updateMock = () => {\n const next = generateMockTraces({ count: cfg.agents, cases: !!cfg.cases, errorRatio: cfg.errorRatio });\n setTraces(next);\n setProviders(mockProviderDescriptors(next));\n setConnected(true);\n setLastUpdated(Date.now());\n };\n\n updateMock();\n const interval = setInterval(updateMock, 3000);\n return () => clearInterval(interval);\n }, [mode, preset, connectionEpoch]);\n\n // 2. Live Mode (SSE + Wake-up Watchdog)\n useEffect(() => {\n if (mode !== \"live\") return undefined;\n\n let cancelled = false;\n\n const resetWatchdog = () => {\n if (watchdogTimerRef.current) clearTimeout(watchdogTimerRef.current);\n // If no packet arrives for 7s, force reconnect\n watchdogTimerRef.current = setTimeout(() => {\n if (!cancelled) {\n console.warn(\"[SSE] Watchdog timeout, reconnecting...\");\n setConnectionEpoch((prev) => prev + 1);\n }\n }, 7000);\n };\n\n try {\n const es = new EventSource(\"/api/traces/stream?source=live\");\n eventSourceRef.current = es;\n\n es.onopen = () => {\n if (!cancelled) {\n setConnected(true);\n resetWatchdog();\n }\n };\n\n es.onmessage = (event) => {\n if (cancelled || !event?.data) return;\n try {\n const payload = JSON.parse(event.data);\n if (Array.isArray(payload.traces)) {\n setTraces(payload.traces);\n }\n if (Array.isArray(payload.providers)) {\n setProviders(payload.providers);\n }\n setLastUpdated(Date.now());\n resetWatchdog();\n } catch {\n // ignore ping\n }\n };\n\n es.onerror = () => {\n if (!cancelled) {\n setConnected(false);\n }\n };\n } catch {\n setConnected(false);\n }\n\n return () => {\n cancelled = true;\n if (watchdogTimerRef.current) clearTimeout(watchdogTimerRef.current);\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n eventSourceRef.current = null;\n }\n };\n }, [mode, connectionEpoch]);\n\n // 3. Auto-reconnect when laptop wakes up or tab gains focus\n useEffect(() => {\n if (mode !== \"live\") return undefined;\n\n const handleWakeup = () => {\n if (document.visibilityState === \"visible\") {\n console.log(\"[AgentFactory] Tab active / wake up, refreshing telemetry...\");\n refresh();\n }\n };\n\n window.addEventListener(\"visibilitychange\", handleWakeup);\n window.addEventListener(\"online\", handleWakeup);\n window.addEventListener(\"focus\", handleWakeup);\n\n return () => {\n window.removeEventListener(\"visibilitychange\", handleWakeup);\n window.removeEventListener(\"online\", handleWakeup);\n window.removeEventListener(\"focus\", handleWakeup);\n };\n }, [mode, refresh]);\n\n return {\n traces,\n providers,\n connected,\n live: mode === \"live\",\n isRefreshing,\n refresh,\n lastUpdated,\n };\n}\n","\"use client\";\n\nconst MODE_LABELS = {\n streaming: \"Working\",\n pending: \"Queued\",\n done: \"Done\",\n happy: \"Done\",\n sleeping: \"Idle\",\n error: \"Failed\",\n};\n\nfunction fmtMs(ms) {\n if (!ms) return \"0ms\";\n return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction InspectorRow({ label, value, color, mono = false }) {\n return (\n <div className=\"flex items-center justify-between gap-3 py-1 text-[12px] border-b border-slate-800/40 last:border-b-0\">\n <span className=\"text-slate-400 font-normal\">{label}</span>\n <span\n className={`truncate font-medium ${mono ? \"font-mono\" : \"\"}`}\n style={color ? { color } : undefined}\n >\n {value}\n </span>\n </div>\n );\n}\n\nexport default function AgentPanel({ ws, onClose }) {\n if (!ws) return null;\n const hex = `#${ws.color ? ws.color.toString(16).padStart(6, \"0\") : \"38bdf8\"}`;\n\n return (\n <div className=\"absolute right-4 top-4 z-20 w-80 rounded-xl border border-slate-700/80 bg-slate-900/90 p-4 shadow-2xl backdrop-blur-md transition-all animate-in fade-in slide-in-from-right-2\">\n {/* Header */}\n <div className=\"mb-3 flex items-start justify-between gap-2 border-b border-slate-800 pb-2\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n <span\n className=\"inline-block h-2 w-2 rounded-full\"\n style={{ backgroundColor: hex }}\n />\n <div className=\"truncate text-sm font-bold text-slate-100\">{ws.account}</div>\n </div>\n <div className=\"text-[11px] font-semibold uppercase tracking-wider mt-0.5\" style={{ color: hex }}>\n {MODE_LABELS[ws.mode] || ws.mode}\n </div>\n </div>\n <button\n onClick={onClose}\n className=\"rounded-md p-1 text-slate-400 hover:bg-slate-800 hover:text-slate-100 transition-colors\"\n aria-label=\"Close\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Main Details */}\n <div className=\"space-y-0.5\">\n <InspectorRow label=\"Agent / Desk\" value={ws.connectionId} />\n <InspectorRow label=\"Provider\" value={ws.provider?.toUpperCase()} color=\"#38bdf8\" />\n <InspectorRow label=\"Model\" value={ws.model} />\n <InspectorRow label=\"Elapsed\" value={fmtMs(ws.elapsedMs)} />\n <InspectorRow label=\"Input Tokens\" value={ws.tokens?.input?.toLocaleString() || \"0\"} mono />\n <InspectorRow label=\"Output Tokens\" value={ws.tokens?.output?.toLocaleString() || \"0\"} mono />\n <InspectorRow\n label=\"Cached\"\n value={`${ws.tokens?.cached?.toLocaleString() || \"0\"} (${ws.cachedPct || 0}%)`}\n color=\"#34d399\"\n mono\n />\n <InspectorRow label=\"Active Tools\" value={ws.tools?.length ? ws.tools.join(\", \") : \"None\"} />\n {ws.currentCommand && (\n <div className=\"mt-2 rounded-md bg-slate-950/80 p-2 border border-slate-800/80\">\n <div className=\"text-[10px] text-slate-400 uppercase tracking-wider mb-1 font-semibold\">Active Command / File</div>\n <div className=\"font-mono text-[11px] text-emerald-400 truncate\">{ws.currentCommand}</div>\n </div>\n )}\n {ws.fallbackFrom && <InspectorRow label=\"Fallback From\" value={ws.fallbackFrom} color=\"#fbbf24\" />}\n {ws.errorReason && <InspectorRow label=\"Error Cause\" value={ws.errorReason} color=\"#ef4444\" />}\n </div>\n\n <div className=\"mt-3 pt-2 border-t border-slate-800 text-[10px] text-slate-500 text-center\">\n Live telemetry via Local CLI Log Watcher\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nexport default function UpdateNotification() {\n const [updateAvailable, setUpdateAvailable] = useState(false);\n const [newVersion, setNewVersion] = useState(null);\n\n useEffect(() => {\n // 1. Service Worker update listener (PWA)\n if (typeof window !== \"undefined\" && \"serviceWorker\" in navigator) {\n navigator.serviceWorker.ready.then((registration) => {\n registration.addEventListener(\"updatefound\", () => {\n const newWorker = registration.installing;\n if (newWorker) {\n newWorker.addEventListener(\"statechange\", () => {\n if (newWorker.state === \"installed\" && navigator.serviceWorker.controller) {\n setUpdateAvailable(true);\n }\n });\n }\n });\n });\n }\n\n // 2. Version polling from server API (/api/version)\n let initialVersion = null;\n const checkVersion = async () => {\n try {\n const res = await fetch(\"/api/version\");\n if (res.ok) {\n const data = await res.json();\n if (!initialVersion) {\n initialVersion = data.version;\n } else if (data.version && data.version !== initialVersion) {\n setNewVersion(data.version);\n setUpdateAvailable(true);\n }\n }\n } catch {\n // network error\n }\n };\n\n checkVersion();\n const interval = setInterval(checkVersion, 60 * 1000); // Check every 60s\n return () => clearInterval(interval);\n }, []);\n\n const handleApplyUpdate = () => {\n if (typeof window !== \"undefined\") {\n window.location.reload();\n }\n };\n\n if (!updateAvailable) return null;\n\n return (\n <div className=\"fixed bottom-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-3 rounded-full border border-emerald-500/40 bg-slate-900/95 px-4 py-2 shadow-2xl backdrop-blur-md animate-in slide-in-from-bottom-4 duration-300\">\n <span className=\"flex h-2 w-2 rounded-full bg-emerald-400 animate-ping\" />\n <span className=\"text-xs text-slate-200\">\n 🚀 Đã có phiên bản mới {newVersion ? `(${newVersion})` : \"\"}\n </span>\n <button\n onClick={handleApplyUpdate}\n className=\"rounded-full bg-emerald-500 hover:bg-emerald-400 px-3 py-1 text-xs font-semibold text-slate-950 transition-colors shadow-sm\"\n >\n Cập nhật ngay\n </button>\n <button\n onClick={() => setUpdateAvailable(false)}\n className=\"text-slate-400 hover:text-slate-200 text-xs ml-1\"\n aria-label=\"Dismiss\"\n >\n ✕\n </button>\n </div>\n );\n}\n","export const MOCK_PRESETS = {\n idle: { agents: 2, errorRatio: 0 },\n busy: { agents: 8, errorRatio: 0 },\n storm: { agents: 30, errorRatio: 0.15 },\n errors: { agents: 10, errorRatio: 0.6 },\n cases: { agents: 16, errorRatio: 0, cases: true },\n};\n\nconst CLIENTS = [\n { account: \"Claude Code · main\", icon: \"terminal\" },\n { account: \"Claude Code · review\", icon: \"rate_review\" },\n { account: \"Antigravity · agent\", icon: \"smart_toy\" },\n { account: \"Antigravity · dev\", icon: \"construction\" },\n { account: \"Cursor · workspace\", icon: \"edit_note\" },\n { account: \"OpenCode · build\", icon: \"science\" },\n { account: \"Aider\", icon: \"smart_toy\" },\n { account: \"Continue · dev\", icon: \"play_arrow\" },\n];\n\nconst PROVIDER_MODELS = [\n { provider: \"claude\", model: \"claude-3-7-sonnet\" },\n { provider: \"gemini\", model: \"gemini-2.5-pro\" },\n { provider: \"openai\", model: \"gpt-4o\" },\n { provider: \"minimax\", model: \"minimax-m2\" },\n { provider: \"deepseek\", model: \"deepseek-v3\" },\n];\n\nconst ERROR_REASONS = [\n \"rate_limited\",\n \"upstream_timeout\",\n \"quota_exhausted\",\n \"auth_refresh_failed\",\n];\n\nexport const MOCK_TOOL_TYPES = [\"bash\", \"read\", \"edit\", \"search\", \"web\", \"mcp\", \"agent\", \"gitnexus\", \"browser\", \"git\", \"docker\"];\n\nconst CASE_DECK = [\n { name: \"sleeping\", state: \"done\", ageMs: 38000 },\n { name: \"happy\", state: \"done\", ageMs: 9000, cost: 1.42 },\n { name: \"pending\", state: \"pending\", ageMs: 2500, tools: [\"todo\"] },\n { name: \"gitnexus\", state: \"streaming\", ageMs: 14000, tools: [\"gitnexus\", \"read\"] },\n { name: \"docker\", state: \"streaming\", ageMs: 15000, tools: [\"docker\", \"bash\"] },\n { name: \"browser\", state: \"streaming\", ageMs: 16000, tools: [\"browser\", \"web\"] },\n { name: \"git+agent\", state: \"streaming\", ageMs: 12000, tools: [\"git\", \"agent\"], concurrent: 4 },\n { name: \"rate_limited\", state: \"error\", ageMs: 6000, error: \"rate_limited\" },\n { name: \"upstream_timeout\", state: \"error\", ageMs: 30000, error: \"upstream_timeout\" },\n { name: \"quota_exhausted\", state: \"error\", ageMs: 8000, error: \"quota_exhausted\" },\n { name: \"auth_refresh_failed\", state: \"error\", ageMs: 5000, error: \"auth_refresh_failed\" },\n { name: \"fallback-1\", state: \"streaming\", ageMs: 13000, tools: [\"bash\"], fallbackShift: 3 },\n { name: \"fallback-2\", state: \"streaming\", ageMs: 14000, tools: [\"browser\", \"mcp\"], fallbackShift: 2 },\n { name: \"slow\", state: \"streaming\", ageMs: 36000, tools: [\"docker\"] },\n { name: \"queue+cached\", state: \"streaming\", ageMs: 10000, tools: [\"read\", \"search\"], concurrent: 5, cachedBoost: true },\n { name: \"expensive\", state: \"done\", ageMs: 20000, cost: 7.35 },\n];\n\nfunction createRandom(seed) {\n let s = seed >>> 0 || 1;\n return () => {\n s ^= s << 13;\n s ^= s >>> 17;\n s ^= s << 5;\n s >>>= 0;\n return s / 4294967296;\n };\n}\n\nfunction pick(rand, list) {\n return list[Math.floor(rand() * list.length) % list.length];\n}\n\nfunction accountTarget(index) {\n return PROVIDER_MODELS[index % PROVIDER_MODELS.length];\n}\n\nfunction randomTokens(rand) {\n return {\n input: Math.round(400 + rand() * 14000),\n output: Math.round(80 + rand() * 2900),\n cached: Math.round(rand() * 6000),\n };\n}\n\nexport function generateMockTraces({ count = 8, errorRatio = 0, seed = 42, now = Date.now(), cases = false } = {}) {\n const rand = createRandom(seed);\n const traces = [];\n\n for (let i = 0; i < count; i += 1) {\n const client = CLIENTS[i % CLIENTS.length];\n const cycle = Math.floor(i / CLIENTS.length) + 1;\n const account = cycle > 1 ? `${client.account} ${cycle}` : client.account;\n const connectionId = `mock-conn-${i}`;\n const target = accountTarget(i);\n const deck = cases ? CASE_DECK[i % CASE_DECK.length] : null;\n const randAge = Math.floor(rand() * 40000);\n const randErr = rand() < errorRatio;\n const ageMs = deck ? deck.ageMs : randAge;\n const startedAt = now - ageMs;\n const isError = deck ? deck.state === \"error\" : randErr;\n\n const ageRatio = ageMs / 40000;\n let state;\n if (deck) state = deck.state;\n else if (isError) state = \"error\";\n else if (ageRatio < 0.25) state = \"pending\";\n else if (ageRatio < 0.6) state = \"streaming\";\n else state = \"done\";\n\n const tokens = randomTokens(rand);\n const toolRand = createRandom(seed * 7919 + i * 104729 + 13);\n const toolCount = state === \"done\" ? 0 : 1 + Math.floor(toolRand() * 3);\n const toolPick = [];\n for (let k = 0; k < toolCount; k += 1) {\n toolPick.push(MOCK_TOOL_TYPES[Math.floor(toolRand() * MOCK_TOOL_TYPES.length)]);\n }\n const toolNames = deck?.tools ?? (state === \"error\" ? [] : toolPick);\n const toolCalls = [];\n for (const tool of toolNames) {\n if (!toolCalls.some((c) => c.tool === tool)) {\n toolCalls.push({ tool, state: toolCalls.length === 0 ? \"running\" : \"queued\" });\n }\n }\n\n const wantsFallback = deck ? !!deck.fallbackShift : toolRand() < 0.28;\n const fallbackProvider = PROVIDER_MODELS[(i + (deck?.fallbackShift ?? 3)) % PROVIDER_MODELS.length].provider;\n const fallback =\n wantsFallback && (state === \"pending\" || state === \"streaming\") && fallbackProvider !== target.provider\n ? { from: fallbackProvider }\n : null;\n\n const concurrent = deck?.concurrent ?? (state === \"done\" || state === \"error\" ? 1 : 1 + Math.floor(toolRand() * 3));\n if (deck?.cachedBoost) tokens.cached = 14000;\n\n traces.push({\n traceId: `mock-${i}-${Math.floor(rand() * 1e6).toString(36)}`,\n cli: \"mock\",\n connectionId,\n account,\n model: target.model,\n provider: target.provider,\n state,\n startedAt,\n elapsedMs: ageMs,\n tokens,\n cost: deck?.cost ?? Math.round((tokens.input * 0.000015 + tokens.output * 0.00006) * 100) / 100,\n status: isError ? \"error\" : \"200\",\n error: isError ? deck?.error ?? pick(rand, ERROR_REASONS) : null,\n clientIcon: client.icon,\n toolCalls,\n tools: toolNames,\n activeTool: toolNames[0] || null,\n currentCommand: toolNames[0] ? `${toolNames[0]} task running...` : null,\n fallback,\n concurrent,\n });\n }\n\n return traces;\n}\n\nexport function mockProviderDescriptors(traces) {\n const seen = new Map();\n for (const trace of traces) {\n if (trace.provider && !seen.has(trace.provider)) {\n seen.set(trace.provider, {\n provider: trace.provider,\n name: trace.provider.charAt(0).toUpperCase() + trace.provider.slice(1),\n });\n }\n }\n return [...seen.values()];\n}\n","import type { TextStyle } from '../../TextStyle';\n\nconst genericFontFamilies = [\n 'serif',\n 'sans-serif',\n 'monospace',\n 'cursive',\n 'fantasy',\n 'system-ui',\n];\n\n/**\n * Generates a font style string to use for `TextMetrics.measureFont()`.\n * @param style\n * @returns Font style string, for passing to `TextMetrics.measureFont()`\n * @internal\n */\nexport function fontStringFromTextStyle(style: TextStyle): string\n{\n // build canvas api font setting from individual components. Convert a numeric style.fontSize to px\n const fontSizeString = (typeof style.fontSize === 'number') ? `${style.fontSize}px` : style.fontSize;\n\n // Clean-up fontFamily property by quoting each font name\n // this will support font names with spaces\n let fontFamilies: string | string[] = style.fontFamily;\n\n if (!Array.isArray(style.fontFamily))\n {\n fontFamilies = style.fontFamily.split(',');\n }\n\n for (let i = fontFamilies.length - 1; i >= 0; i--)\n {\n // Trim any extra white-space\n let fontFamily = fontFamilies[i].trim();\n\n // Check if font already contains strings\n if (!(/([\\\"\\'])[^\\'\\\"]+\\1/).test(fontFamily) && !genericFontFamilies.includes(fontFamily))\n {\n fontFamily = `\"${fontFamily}\"`;\n }\n (fontFamilies as string[])[i] = fontFamily;\n }\n\n // eslint-disable-next-line max-len\n return `${style.fontStyle} ${style.fontVariant} ${style.fontWeight} ${fontSizeString} ${(fontFamilies as string[]).join(',')}`;\n}\n","import type { TextStyle, TextStyleOptions } from '../../TextStyle';\n\n/**\n * Represents a run of text with a specific style.\n * Used internally for tagged text rendering.\n * @internal\n */\nexport interface TextStyleRun\n{\n /** The text content of this run */\n text: string;\n /** The computed style for this run (base style merged with tag overrides) */\n style: TextStyle;\n}\n\n/**\n * Checks whether the given style has tagStyles defined with at least one entry.\n * @param style - The TextStyle to check\n * @returns True if tagStyles is defined and has entries\n * @internal\n */\nexport function hasTagStyles(style: TextStyle): boolean\n{\n return !!style.tagStyles && Object.keys(style.tagStyles).length > 0;\n}\n\n/**\n * Checks whether the text contains potential tag markup.\n * This is a quick check before attempting to parse.\n * @param text - The text to check\n * @returns True if text contains '<' character\n * @internal\n */\nexport function hasTagMarkup(text: string): boolean\n{\n return text.includes('<');\n}\n\n/**\n * Creates a merged TextStyle from a base style and tag style overrides.\n * @param baseStyle - The base TextStyle\n * @param overrides - Style overrides from the tag\n * @returns A new TextStyle with merged properties\n * @internal\n */\nfunction createMergedStyle(baseStyle: TextStyle, overrides: TextStyleOptions): TextStyle\n{\n return baseStyle.clone().assign(overrides);\n}\n\n/**\n * Parses text with tag markup into an array of styled runs.\n * Supports simple open/close tags like `<red>text</red>`.\n * Nested tags are supported via a stack - inner tags inherit from outer tags.\n * Unknown tags (not in tagStyles) are treated as literal text.\n * @param text - The text to parse\n * @param style - The base TextStyle containing tagStyles\n * @returns Array of TextStyleRun objects\n * @internal\n */\nexport function parseTaggedText(text: string, style: TextStyle): TextStyleRun[]\n{\n const runs: TextStyleRun[] = [];\n const tagStyles = style.tagStyles;\n\n // If no tagStyles or no potential tags, return single run with base style\n if (!hasTagStyles(style) || !hasTagMarkup(text))\n {\n runs.push({ text, style });\n\n return runs;\n }\n\n // Stack of active styles (for nested tags)\n const styleStack: TextStyle[] = [style];\n // Stack of active tag names (to match closing tags)\n const tagStack: string[] = [];\n\n let currentText = '';\n let i = 0;\n\n while (i < text.length)\n {\n const char = text[i];\n\n if (char === '<')\n {\n // Find the closing bracket\n const closeIndex = text.indexOf('>', i);\n\n if (closeIndex === -1)\n {\n // No closing bracket - treat as literal\n currentText += char;\n i++;\n continue;\n }\n\n const nextOpenIndex = text.indexOf('<', i + 1);\n\n if (nextOpenIndex !== -1 && nextOpenIndex < closeIndex)\n {\n // If there's another '<' before the closing '>', treat this as literal\n currentText += char;\n i++;\n continue;\n }\n\n const tagContent = text.slice(i + 1, closeIndex);\n\n // Check if it's a closing tag\n if (tagContent.startsWith('/'))\n {\n const closingTagName = tagContent.slice(1).trim();\n\n // Check if this closing tag matches the most recent opening tag\n if (tagStack.length > 0 && tagStack[tagStack.length - 1] === closingTagName)\n {\n // Flush current text with current style\n if (currentText.length > 0)\n {\n runs.push({\n text: currentText,\n style: styleStack[styleStack.length - 1]\n });\n currentText = '';\n }\n\n // Pop the style and tag stacks\n styleStack.pop();\n tagStack.pop();\n i = closeIndex + 1;\n continue;\n }\n else\n {\n // Mismatched closing tag - treat as literal\n currentText += text.slice(i, closeIndex + 1);\n i = closeIndex + 1;\n continue;\n }\n }\n else\n {\n // Opening tag\n const tagName = tagContent.trim();\n\n // Check if this tag is in tagStyles\n if (tagStyles[tagName])\n {\n // Flush current text with current style\n if (currentText.length > 0)\n {\n runs.push({\n text: currentText,\n style: styleStack[styleStack.length - 1]\n });\n currentText = '';\n }\n\n // Create merged style from current style and tag overrides\n const currentStyle = styleStack[styleStack.length - 1];\n const mergedStyle = createMergedStyle(currentStyle, tagStyles[tagName]);\n\n styleStack.push(mergedStyle);\n tagStack.push(tagName);\n i = closeIndex + 1;\n continue;\n }\n else\n {\n // Unknown tag - treat as literal\n currentText += text.slice(i, closeIndex + 1);\n i = closeIndex + 1;\n continue;\n }\n }\n }\n else\n {\n currentText += char;\n i++;\n }\n }\n\n // Flush any remaining text\n if (currentText.length > 0)\n {\n runs.push({\n text: currentText,\n style: styleStack[styleStack.length - 1]\n });\n }\n\n return runs;\n}\n\n/**\n * Extracts plain text from tagged text (strips all tags).\n * Useful for cache keys and debugging.\n * @param text - The tagged text\n * @param style - The TextStyle containing tagStyles\n * @returns Plain text with tags removed\n * @internal\n */\nexport function getPlainText(text: string, style: TextStyle): string\n{\n if (!hasTagStyles(style) || !hasTagMarkup(text))\n {\n return text;\n }\n\n const runs = parseTaggedText(text, style);\n\n return runs.map((run) => run.text).join('');\n}\n","import type { TextStyleWhiteSpace } from '../../TextStyle';\n\n/**\n * Cache of new line character codes.\n * @internal\n */\nexport const NEWLINES: number[] = [\n 0x000A, // line feed\n 0x000D, // carriage return\n];\n\n/**\n * Set of new line character codes for fast lookup.\n * @internal\n */\nexport const NEWLINES_SET = new Set(NEWLINES);\n\n/**\n * Cache of breaking space character codes.\n * @internal\n */\nexport const BREAKING_SPACES: number[] = [\n 0x0009, // character tabulation\n 0x0020, // space\n 0x2000, // en quad\n 0x2001, // em quad\n 0x2002, // en space\n 0x2003, // em space\n 0x2004, // three-per-em space\n 0x2005, // four-per-em space\n 0x2006, // six-per-em space\n 0x2008, // punctuation space\n 0x2009, // thin space\n 0x200A, // hair space\n 0x205F, // medium mathematical space\n 0x3000, // ideographic space\n];\n\n/**\n * Set of breaking space character codes for fast lookup.\n * @internal\n */\nexport const BREAKING_SPACES_SET = new Set(BREAKING_SPACES);\n\n/**\n * Cache of CSS-collapsible whitespace character codes.\n * Per CSS Text Module Level 3, only regular spaces and tabs are collapsible.\n * Unicode spaces (em space, en space, etc.) are NOT collapsible.\n * @internal\n */\nexport const COLLAPSIBLE_SPACES: number[] = [\n 0x0009, // character tabulation (tab)\n 0x0020, // space\n];\n\n/**\n * Set of collapsible space character codes for fast lookup.\n * @internal\n */\nexport const COLLAPSIBLE_SPACES_SET = new Set(COLLAPSIBLE_SPACES);\n\n/**\n * Characters that allow a line break AFTER them (they stay with the preceding word).\n * @internal\n */\nexport const BREAK_AFTER_CHARS: number[] = [\n 0x002D, // hyphen-minus\n 0x2010, // unicode hyphen\n 0x2013, // en-dash\n 0x2014, // em-dash\n 0x00AD, // soft hyphen\n];\n\n/**\n * Set of break-after character codes for fast lookup.\n * @internal\n */\nexport const BREAK_AFTER_CHARS_SET = new Set(BREAK_AFTER_CHARS);\n\n/**\n * Regex to split text while capturing newline sequences.\n * @internal\n */\nexport const NEWLINE_SPLIT_REGEX = /(\\r\\n|\\r|\\n)/;\n\n/**\n * Regex to split text on newlines without capturing.\n * @internal\n */\nexport const NEWLINE_MATCH_REGEX = /(?:\\r\\n|\\r|\\n)/;\n\n/**\n * Determines if char is a newline.\n * @param char - The character\n * @returns True if newline, False otherwise.\n * @internal\n */\nexport function isNewline(char: string): boolean\n{\n if (typeof char !== 'string')\n {\n return false;\n }\n\n return NEWLINES_SET.has(char.charCodeAt(0));\n}\n\n/**\n * Determines if char is a breaking whitespace.\n *\n * It allows one to determine whether char should be a breaking whitespace\n * For example certain characters in CJK langs or numbers.\n * It must return a boolean.\n * @param char - The character\n * @param _nextChar - The next character (unused, for override compatibility)\n * @returns True if whitespace, False otherwise.\n * @internal\n */\nexport function isBreakingSpace(char: string, _nextChar?: string): boolean\n{\n if (typeof char !== 'string')\n {\n return false;\n }\n\n return BREAKING_SPACES_SET.has(char.charCodeAt(0));\n}\n\n/**\n * Determines if char is a CSS-collapsible whitespace character.\n * Only regular space (U+0020) and tab (U+0009) are collapsible per CSS spec.\n * Unicode spaces like em space are NOT collapsible.\n * @param char - The character\n * @returns True if collapsible, False otherwise.\n * @internal\n */\nexport function isCollapsibleSpace(char: string): boolean\n{\n if (typeof char !== 'string')\n {\n return false;\n }\n\n return COLLAPSIBLE_SPACES_SET.has(char.charCodeAt(0));\n}\n\n/**\n * Determines if char is a break-after character (line can break after it, but\n * the character stays with the preceding word).\n * @param char - The character\n * @returns True if break-after, False otherwise.\n * @internal\n */\nexport function isBreakAfterChar(char: string): boolean\n{\n if (typeof char !== 'string')\n {\n return false;\n }\n\n return BREAK_AFTER_CHARS_SET.has(char.charCodeAt(0));\n}\n\n/**\n * Determines whether we should collapse breaking spaces.\n * @param whiteSpace - The TextStyle property whiteSpace\n * @returns Should collapse\n * @internal\n */\nexport function collapseSpaces(whiteSpace: TextStyleWhiteSpace): boolean\n{\n return (whiteSpace === 'normal' || whiteSpace === 'pre-line');\n}\n\n/**\n * Determines whether we should collapse newLine chars.\n * @param whiteSpace - The white space\n * @returns should collapse\n * @internal\n */\nexport function collapseNewlines(whiteSpace: TextStyleWhiteSpace): boolean\n{\n return (whiteSpace === 'normal');\n}\n\n/**\n * Trims breaking whitespaces from the right side of a string.\n * @param text - The text\n * @returns Trimmed string\n * @internal\n */\nexport function trimRight(text: string): string\n{\n if (typeof text !== 'string')\n {\n return '';\n }\n\n let i = text.length - 1;\n\n while (i >= 0 && isBreakingSpace(text[i]))\n {\n i--;\n }\n\n // Only slice if we found trailing spaces\n return i < text.length - 1 ? text.slice(0, i + 1) : text;\n}\n\n/**\n * Splits a string into words, breaking-spaces and newLine characters\n * @param text - The text\n * @returns A tokenized array\n * @internal\n */\nexport function tokenize(text: string): string[]\n{\n const tokens: string[] = [];\n const tokenChars: string[] = [];\n\n if (typeof text !== 'string')\n {\n return tokens;\n }\n\n for (let i = 0; i < text.length; i++)\n {\n const char = text[i];\n const nextChar = text[i + 1];\n\n if (isBreakingSpace(char, nextChar) || isNewline(char))\n {\n if (tokenChars.length > 0)\n {\n tokens.push(tokenChars.join(''));\n tokenChars.length = 0;\n }\n\n // treat \\r\\n as a single new line token\n if (char === '\\r' && nextChar === '\\n')\n {\n tokens.push('\\r\\n');\n i++;\n }\n else\n {\n tokens.push(char);\n }\n\n continue;\n }\n\n tokenChars.push(char);\n\n // Break-after chars stay with the word, then emit the token\n if (isBreakAfterChar(char) && nextChar && !isBreakingSpace(nextChar) && !isNewline(nextChar))\n {\n tokens.push(tokenChars.join(''));\n tokenChars.length = 0;\n }\n }\n\n if (tokenChars.length > 0)\n {\n tokens.push(tokenChars.join(''));\n }\n\n return tokens;\n}\n\n/**\n * Splits a token into character groups that should not be broken apart.\n * Adjacent characters that can't be broken are combined into single groups.\n * @param token - The token to split\n * @param breakWords - Whether word breaking is enabled\n * @param splitFn - Function to split token into characters (default: grapheme segmenter)\n * @param canBreakCharsFn - Function to check if chars can be broken\n * @returns Array of character groups\n * @internal\n */\nexport function getCharacterGroups(\n token: string,\n breakWords: boolean,\n splitFn: (s: string) => string[],\n canBreakCharsFn: (char: string, nextChar: string, token: string, index: number, breakWords: boolean) => boolean,\n): string[]\n{\n const characters = splitFn(token);\n const groups: string[] = [];\n\n for (let j = 0; j < characters.length; j++)\n {\n let char = characters[j];\n let lastChar = char;\n\n // Combine chars that shouldn't be split\n let k = 1;\n\n while (characters[j + k])\n {\n const nextChar = characters[j + k];\n\n if (!canBreakCharsFn(lastChar, nextChar, token, j, breakWords))\n {\n char += nextChar;\n lastChar = nextChar;\n k++;\n }\n else\n {\n break;\n }\n }\n j += k - 1;\n groups.push(char);\n }\n\n return groups;\n}\n","import { Container, Graphics, Text } from \"pixi.js\";\n\n// One glyph per tool type. Each is drawn inside a ±10 box so a badge can swap\n// icons without relayout. Only the tool *type* is shown — never arguments.\n\nconst S = { cap: \"round\", join: \"round\" };\n\nexport const TOOL_TYPES = {\n bash: {\n label: \"Bash\",\n color: 0x34d399,\n draw(g, c) {\n g.moveTo(-8, -6).lineTo(-2, 0).lineTo(-8, 6).stroke({ width: 2.4, color: c, ...S });\n g.moveTo(1, 7).lineTo(8, 7).stroke({ width: 2.4, color: c, ...S });\n },\n },\n read: {\n label: \"Read\",\n color: 0x60a5fa,\n draw(g, c) {\n g.moveTo(-6, -9).lineTo(3, -9).lineTo(7, -5).lineTo(7, 9).lineTo(-6, 9).closePath()\n .stroke({ width: 2, color: c, ...S });\n g.moveTo(-3, -1).lineTo(4, -1).stroke({ width: 1.8, color: c, ...S });\n g.moveTo(-3, 3).lineTo(4, 3).stroke({ width: 1.8, color: c, ...S });\n g.moveTo(-3, 6.5).lineTo(1, 6.5).stroke({ width: 1.8, color: c, ...S });\n },\n },\n edit: {\n label: \"Edit\",\n color: 0xfbbf24,\n draw(g, c) {\n g.moveTo(-7, 8).lineTo(-6, 3).lineTo(4, -7).lineTo(8, -3).lineTo(-2, 7).closePath()\n .stroke({ width: 2, color: c, ...S });\n g.moveTo(1, -4).lineTo(5, 0).stroke({ width: 1.8, color: c, ...S });\n g.moveTo(-8, 9.5).lineTo(-1, 9.5).stroke({ width: 1.8, color: c, ...S });\n },\n },\n search: {\n label: \"Search\",\n color: 0xf472b6,\n draw(g, c) {\n g.circle(-2, -2, 6).stroke({ width: 2.2, color: c, ...S });\n g.moveTo(2.5, 2.5).lineTo(8, 8).stroke({ width: 2.6, color: c, ...S });\n },\n },\n web: {\n label: \"Web\",\n color: 0x22d3ee,\n draw(g, c) {\n g.circle(0, 0, 8.5).stroke({ width: 2, color: c, ...S });\n g.ellipse(0, 0, 3.6, 8.5).stroke({ width: 1.6, color: c, ...S });\n g.moveTo(-8.5, 0).lineTo(8.5, 0).stroke({ width: 1.6, color: c, ...S });\n },\n },\n mcp: {\n label: \"MCP\",\n color: 0xa78bfa,\n draw(g, c) {\n g.moveTo(-4, -9).lineTo(-4, -3).stroke({ width: 2.4, color: c, ...S });\n g.moveTo(4, -9).lineTo(4, -3).stroke({ width: 2.4, color: c, ...S });\n g.roundRect(-8, -3, 16, 9, 3).stroke({ width: 2, color: c, ...S });\n g.moveTo(0, 6).lineTo(0, 10).stroke({ width: 2.4, color: c, ...S });\n },\n },\n agent: {\n label: \"Subagent\",\n color: 0xfb923c,\n draw(g, c) {\n g.moveTo(0, -4).lineTo(-6, 6).stroke({ width: 1.8, color: c, ...S });\n g.moveTo(0, -4).lineTo(6, 6).stroke({ width: 1.8, color: c, ...S });\n g.circle(0, -5, 3.6).fill({ color: c });\n g.circle(-6.5, 7, 3).fill({ color: c });\n g.circle(6.5, 7, 3).fill({ color: c });\n },\n },\n todo: {\n label: \"Todo\",\n color: 0x94a3b8,\n draw(g, c) {\n g.moveTo(-8, -5).lineTo(-6, -3).lineTo(-3, -7).stroke({ width: 1.8, color: c, ...S });\n g.moveTo(1, -5).lineTo(8, -5).stroke({ width: 1.8, color: c, ...S });\n g.moveTo(-8, 5).lineTo(-6, 7).lineTo(-3, 3).stroke({ width: 1.8, color: c, ...S });\n g.moveTo(1, 5).lineTo(8, 5).stroke({ width: 1.8, color: c, ...S });\n },\n },\n gitnexus: {\n label: \"GitNexus\",\n color: 0xc084fc, // purple-400\n draw(g, c) {\n // Knowledge graph: central hub connected to 3 orbiting nodes\n g.moveTo(0, 0).lineTo(-6, -6).stroke({ width: 1.5, color: c, ...S });\n g.moveTo(0, 0).lineTo(6, -5).stroke({ width: 1.5, color: c, ...S });\n g.moveTo(0, 0).lineTo(0, 7).stroke({ width: 1.5, color: c, ...S });\n g.circle(0, 0, 3.2).fill({ color: c });\n g.circle(-6, -6, 2.2).fill({ color: c });\n g.circle(6, -5, 2.2).fill({ color: c });\n g.circle(0, 7, 2.2).fill({ color: c });\n },\n },\n browser: {\n label: \"Browser\",\n color: 0x06b6d4, // cyan-500\n draw(g, c) {\n // Browser window with top tab bar\n g.roundRect(-8, -7, 16, 14, 2.5).stroke({ width: 1.8, color: c, ...S });\n g.moveTo(-8, -2).lineTo(8, -2).stroke({ width: 1.4, color: c, ...S });\n g.circle(-5, -4.5, 1).fill({ color: c });\n g.circle(-2, -4.5, 1).fill({ color: c });\n },\n },\n git: {\n label: \"Git\",\n color: 0xf97316, // orange-500\n draw(g, c) {\n // Git branching tree\n g.moveTo(-4, -7).lineTo(-4, 7).stroke({ width: 2, color: c, ...S });\n g.moveTo(-4, 2).arc(0, 2, 4, Math.PI, 0).lineTo(4, -3).stroke({ width: 1.8, color: c, ...S });\n g.circle(-4, -6, 2.4).fill({ color: c });\n g.circle(-4, 6, 2.4).fill({ color: c });\n g.circle(4, -3, 2.4).fill({ color: c });\n },\n },\n docker: {\n label: \"Docker\",\n color: 0x38bdf8, // light blue\n draw(g, c) {\n // Container blocks stacked\n g.roundRect(-7, 1, 6, 5, 1).fill({ color: c, alpha: 0.8 }).stroke({ width: 1.2, color: c, ...S });\n g.roundRect(1, 1, 6, 5, 1).fill({ color: c, alpha: 0.8 }).stroke({ width: 1.2, color: c, ...S });\n g.roundRect(-3, -6, 6, 5, 1).fill({ color: c, alpha: 0.8 }).stroke({ width: 1.2, color: c, ...S });\n },\n },\n};\n\n// Request-status glyphs share the badge machinery with tools: lifecycle states,\n// the four failure reasons, and fallback.\nexport const STATUS_TYPES = {\n pending: {\n label: \"Queued\",\n color: 0xf59e0b,\n draw(g, c) {\n for (const x of [-7, 0, 7]) g.circle(x, 1, 2.6).fill({ color: c });\n },\n },\n done: {\n label: \"Done\",\n color: 0x34d399,\n draw(g, c) {\n g.moveTo(-7, 0).lineTo(-2, 6).lineTo(8, -7).stroke({ width: 3, color: c, ...S });\n },\n },\n rate_limited: {\n label: \"Rate limit\",\n color: 0xef4444,\n draw(g, c) {\n g.moveTo(-6, -9).lineTo(6, -9).lineTo(-6, 9).lineTo(6, 9).closePath()\n .stroke({ width: 2, color: c, ...S });\n g.moveTo(-3, 6.5).lineTo(3, 6.5).stroke({ width: 2.2, color: c, ...S });\n },\n },\n upstream_timeout: {\n label: \"Timeout\",\n color: 0xef4444,\n draw(g, c) {\n g.circle(0, 0, 8.5).stroke({ width: 2, color: c, ...S });\n g.moveTo(0, -5).lineTo(0, 0).lineTo(4.5, 3).stroke({ width: 2, color: c, ...S });\n },\n },\n quota_exhausted: {\n label: \"Quota\",\n color: 0xef4444,\n draw(g, c) {\n g.roundRect(-8, -5, 14, 10, 2).stroke({ width: 2, color: c, ...S });\n g.rect(6, -2, 3, 4).fill({ color: c });\n g.rect(-6, -3, 2.6, 6).fill({ color: c });\n },\n },\n auth_refresh_failed: {\n label: \"Auth\",\n color: 0xef4444,\n draw(g, c) {\n g.circle(-4, 0, 4.2).stroke({ width: 2, color: c, ...S });\n g.moveTo(0, 0).lineTo(8, 0).stroke({ width: 2, color: c, ...S });\n g.moveTo(5, 0).lineTo(5, 4).stroke({ width: 2, color: c, ...S });\n g.moveTo(-9, -8).lineTo(9, 8).stroke({ width: 2.2, color: 0xfbbf24, ...S });\n },\n },\n fallback: {\n label: \"Fallback\",\n color: 0xfbbf24,\n draw(g, c) {\n g.moveTo(-8, -4).lineTo(7, -4).stroke({ width: 2.2, color: c, ...S });\n g.moveTo(3, -8).lineTo(8, -4).lineTo(3, 0).stroke({ width: 2.2, color: c, ...S });\n g.moveTo(8, 5).lineTo(-7, 5).stroke({ width: 2.2, color: c, ...S });\n g.moveTo(-3, 1).lineTo(-8, 5).lineTo(-3, 9).stroke({ width: 2.2, color: c, ...S });\n },\n },\n};\n\nexport const TOOL_KEYS = Object.keys(TOOL_TYPES);\nexport const STATUS_KEYS = [\"pending\", \"done\", \"rate_limited\", \"upstream_timeout\", \"quota_exhausted\", \"auth_refresh_failed\", \"fallback\"];\n\n/** A round badge: dark disc, coloured ring, the tool's glyph, optional name. */\nexport function createToolBadge(tool, { size = 1, showLabel = true, label: labelOverride } = {}) {\n const def = TOOL_TYPES[tool] || STATUS_TYPES[tool] || TOOL_TYPES.bash;\n const root = new Container();\n\n const halo = new Graphics();\n halo.circle(0, 0, 21).fill({ color: def.color, alpha: 0.18 });\n\n const disc = new Graphics();\n disc.circle(0, 0, 15).fill({ color: 0x0f141c });\n disc.circle(0, 0, 15).stroke({ width: 2, color: def.color, alpha: 0.95 });\n\n const glyph = new Graphics();\n def.draw(glyph, def.color);\n glyph.scale.set(0.95);\n\n root.addChild(halo, disc, glyph);\n\n if (showLabel) {\n const label = new Text({\n text: labelOverride ?? def.label,\n style: { fontFamily: \"Inter, system-ui, sans-serif\", fontSize: 9, fill: def.color, fontWeight: \"800\" },\n });\n label.anchor.set(0.5, 0);\n label.y = 18;\n root.addChild(label);\n }\n\n root.scale.set(size);\n return { root, halo, tool };\n}\n","import { Container, Graphics } from \"pixi.js\";\n\n// Token packets travelling between desks, the rack, and provider pods.\n//\n// Three kinds, so the picture says which way tokens flow:\n// input round, desk -> rack -> provider (arcs over the room)\n// output diamond, provider -> rack -> desk (arcs underneath)\n// cached square, desk -> rack only: served from cache, never reaches a provider\n//\n// One Graphics object is shared by every particle and rebuilt each frame: at a\n// few hundred dots that is far cheaper than a Sprite per packet.\n\nfunction lerpPoint(from, to, t, arc) {\n const lift = Math.sin(t * Math.PI) * arc;\n return {\n x: from.x + (to.x - from.x) * t,\n y: from.y + (to.y - from.y) * t - lift,\n };\n}\n\nconst MAX_PACKETS = 700;\n\nexport function createTokenStreams() {\n const container = new Container();\n const layer = new Graphics();\n const glowLayer = new Graphics();\n container.addChild(glowLayer, layer);\n\n const packets = [];\n\n return {\n container,\n\n /**\n * Replace the set of active routes; called when the graph changes.\n * route: { from, to, color, weight, shape?: \"circle\"|\"diamond\"|\"square\", arc?: number }\n */\n setRoutes(routes) {\n packets.length = 0;\n for (const route of routes) {\n const spawn = Math.max(1, Math.min(6, Math.round(route.weight * 6)));\n for (let i = 0; i < spawn; i += 1) {\n packets.push({\n from: route.from,\n to: route.to,\n t: (i / spawn + Math.random() * 0.1) % 1,\n speed: 0.00035 + Math.random() * 0.0006 + route.weight * 0.0004,\n color: route.color,\n size: 1.6 + route.weight * 2.2,\n shape: route.shape || \"circle\",\n arc: route.arc ?? 26,\n });\n }\n }\n while (packets.length > MAX_PACKETS) packets.pop();\n },\n\n animate(deltaMS) {\n layer.clear();\n glowLayer.clear();\n\n for (const p of packets) {\n p.t += p.speed * deltaMS;\n if (p.t > 1) {\n p.t -= 1;\n p.speed = 0.00035 + Math.random() * 0.0006;\n }\n const pt = lerpPoint(p.from, p.to, p.t, p.arc);\n // Fade in/out at the ends so packets do not pop.\n const alpha = Math.min(1, p.t * 6) * Math.min(1, (1 - p.t) * 6);\n const s = p.size;\n\n if (p.shape === \"diamond\") {\n layer.poly([pt.x, pt.y - s * 1.5, pt.x + s * 1.2, pt.y, pt.x, pt.y + s * 1.5, pt.x - s * 1.2, pt.y]).fill({ color: p.color, alpha });\n } else if (p.shape === \"square\") {\n const q = s * 0.7;\n layer.rect(pt.x - q, pt.y - q, q * 2, q * 2).fill({ color: p.color, alpha: alpha * 0.9 });\n } else {\n layer.circle(pt.x, pt.y, s).fill({ color: p.color, alpha });\n }\n glowLayer.circle(pt.x, pt.y, s * 3).fill({ color: p.color, alpha: alpha * 0.14 });\n }\n },\n };\n}\n","import { Container, FillGradient, Graphics, Rectangle, Text } from \"pixi.js\";\nimport { STATE_COLORS, STATE_LABELS } from \"./office-layout\";\n\nfunction clip(text, max) {\n const str = String(text || \"\");\n return str.length > max ? `${str.slice(0, max - 1)}…` : str;\n}\n\nconst MONO = \"ui-monospace, Menlo, monospace\";\nconst SANS = \"Inter, system-ui, sans-serif\";\n\n// Vertical two/three-stop gradient in the shape's own space — the cheap trick\n// that turns flat 2D primitives into lit, rounded-looking \"3D\" volumes.\nfunction vgrad(...stops) {\n return new FillGradient({\n type: \"linear\",\n start: { x: 0, y: 0 },\n end: { x: 0, y: 1 },\n colorStops: stops.map((color, i) => ({ offset: i / (stops.length - 1), color })),\n textureSpace: \"local\",\n });\n}\n\n// A chibi robot (big round helmet, oval visor with scanline eyes, coloured ear\n// pods, tiny body) drawn from primitives — no sprite sheet, so every colour and\n// pose is controllable from live data. Origin = base of the torso (hidden\n// behind the desk/console), so the helmet and shoulders peek over the edge.\n//\n// Poses (`mode`):\n// streaming typing, scanline eyes pending one arm waving, waiting\n// happy ^ ^ eyes, smile, bounce sleeping closed eyes, drifting z's\n// error X eyes, shaking, smoke, arms up\nexport function createCharacter({ color, depth = 1, scale = 1, seed = 0, trimColor, mode = \"streaming\" }) {\n const root = new Container();\n const trims = [0xb5528f, 0x3fb6a8, 0xe08a3c, 0x7c63d8, 0x4a8ee0];\n const trim = trimColor ?? trims[seed % trims.length];\n const SHELL = 0xf3f5f9;\n const SHADE = 0xc9d0dc;\n\n // Torso: two stacked shells with a coloured band between them.\n const body = new Graphics();\n body.roundRect(-17, -30, 34, 22, 11).fill(vgrad(0xffffff, SHELL, SHADE));\n body.roundRect(-17, -30, 34, 8, 8).fill({ color: 0xffffff, alpha: 0.6 });\n body.roundRect(-14, -12, 28, 8, 4).fill({ color: trim });\n body.roundRect(-16, -8, 32, 16, 8).fill(vgrad(SHELL, SHADE, 0x8c97a9));\n body.roundRect(-16, 2, 32, 6, 4).fill({ color: SHADE, alpha: 0.6 });\n\n const neck = new Graphics();\n neck.roundRect(-10, -36, 20, 8, 4).fill({ color: trim });\n const status = new Graphics();\n status.roundRect(-6, -34, 12, 3, 1.5).fill({ color });\n\n // Arms pivot at the shoulder so raising one does not swing it around the hip.\n const armL = new Graphics();\n const armR = new Graphics();\n for (const [arm, x, dir] of [[armL, -26, -1], [armR, 18, 1]]) {\n arm.roundRect(x, -28, 8, 24, 4).fill({ color: SHELL });\n arm.roundRect(x, -28, 8, 8, 4).fill({ color: 0xffffff, alpha: 0.6 });\n arm.circle(x + 4 + dir * 1.5, -2, 4.5).stroke({ width: 2.4, color: SHELL });\n arm.pivot.set(x + 4, -26);\n arm.position.set(x + 4, -26);\n }\n\n const head = new Graphics();\n head.circle(-27, -56, 8).fill({ color: trim });\n head.circle(27, -56, 8).fill({ color: trim });\n head.circle(-29, -58, 3).fill({ color: 0xffffff, alpha: 0.35 });\n head.circle(25, -58, 3).fill({ color: 0xffffff, alpha: 0.35 });\n head.ellipse(0, -56, 26, 24).fill(vgrad(0xffffff, SHELL, 0x9aa6b8));\n head.ellipse(4, -50, 24, 21).stroke({ width: 3, color: 0x6b7a90, alpha: 0.25 }); // bottom-right rim shade\n head.ellipse(-8, -68, 12, 5.5).fill({ color: 0xffffff, alpha: 0.8 }); // specular\n head.circle(-14, -64, 2).fill({ color: 0xffffff, alpha: 0.9 });\n head.ellipse(0, -53, 22, 17).fill({ color: SHADE });\n head.ellipse(0, -53, 20, 15.5).fill({ color: 0x0f141c });\n head.ellipse(-5, -58, 11, 5).fill({ color: 0xffffff, alpha: 0.06 });\n\n const face = new Graphics();\n const fx = new Graphics(); // smoke / z's, drawn in front of everything\n\n root.addChild(body, neck, status, armL, armR, head, face, fx);\n root.scale.set(scale * depth);\n\n let currentMode = mode;\n let faceColor = color;\n\n const stroke = (w, c, a = 1) => ({ width: w, color: c, alpha: a, cap: \"round\", join: \"round\" });\n\n const eye = (cx, cy, w, h, a, kind) => {\n if (kind === \"happy\") {\n face.moveTo(cx - 4.6, cy + 2).arc(cx, cy + 2, 4.6, Math.PI, 0).stroke(stroke(2.6, faceColor, a));\n } else if (kind === \"sleep\") {\n face.moveTo(cx - 4.6, cy).arc(cx, cy, 4.6, 0, Math.PI).stroke(stroke(2.2, faceColor, 0.7));\n } else if (kind === \"x\") {\n face.moveTo(cx - 4, cy - 4).lineTo(cx + 4, cy + 4).stroke(stroke(2.6, faceColor, a));\n face.moveTo(cx + 4, cy - 4).lineTo(cx - 4, cy + 4).stroke(stroke(2.6, faceColor, a));\n } else {\n face.ellipse(cx, cy, w, h).fill({ color: faceColor, alpha: 0.9 * a });\n for (let y = cy - h + 1; y < cy + h; y += 2.4) {\n face.rect(cx - w - 1, y, w * 2 + 2, 1).fill({ color: 0x0f141c, alpha: 0.55 });\n }\n }\n };\n\n return {\n root,\n statusDot: status,\n setMode(next) {\n currentMode = next;\n },\n /** `intensity` 0..1 scales how hard the agent is working. */\n animate(t, intensity = 0) {\n const bx = root.baseX ?? root.x;\n const m = currentMode;\n const phase = t * 0.012 + bx;\n\n // Body motion per mode.\n let bob = Math.sin(t * 0.004 + bx * 0.05) * (0.8 + intensity * 1.4);\n let shake = 0;\n let tilt = 0;\n if (m === \"happy\") bob = -Math.abs(Math.sin(t * 0.005 + bx)) * 3.2;\n if (m === \"sleeping\") {\n bob = Math.sin(t * 0.0016 + bx) * 1.1 + 2.2;\n tilt = 0.12 + Math.sin(t * 0.0016 + bx) * 0.02;\n }\n if (m === \"error\") shake = Math.sin(t * 0.09) * 1.8;\n root.x = bx + shake;\n root.y = (root.baseY || 0) + bob;\n root.rotation = tilt;\n\n // Arms.\n armL.rotation = 0;\n armR.rotation = 0;\n if (m === \"streaming\") {\n armL.rotation = Math.sin(phase) * 0.14 * (0.3 + intensity);\n armR.rotation = -Math.sin(phase + 1.3) * 0.14 * (0.3 + intensity);\n } else if (m === \"pending\") {\n armL.rotation = 2.5 + Math.sin(t * 0.012) * 0.35; // waving for attention\n armR.rotation = -Math.sin(phase + 1.3) * 0.06;\n } else if (m === \"happy\") {\n armL.rotation = 2.2 + Math.sin(t * 0.01) * 0.2;\n armR.rotation = -2.2 - Math.sin(t * 0.01 + 1) * 0.2;\n } else if (m === \"error\") {\n armL.rotation = 2.7 + Math.sin(t * 0.08) * 0.1; // hands on head\n armR.rotation = -2.7 - Math.sin(t * 0.08) * 0.1;\n } else if (m === \"sleeping\") {\n armL.rotation = 0.05;\n armR.rotation = -0.05;\n }\n\n // Face.\n const blinking = Math.sin(t * 0.0013 + seed * 2.1) > 0.985;\n const flicker = 0.85 + Math.sin(t * 0.01 + seed) * 0.15;\n face.clear();\n const kind = m === \"happy\" ? \"happy\" : m === \"sleeping\" ? \"sleep\" : m === \"error\" ? \"x\" : \"scan\";\n eye(-8, -57, 4.8, blinking ? 0.8 : 4.4, flicker, kind);\n eye(8, -57, 4.8, blinking ? 0.8 : 4.4, flicker, kind);\n if (m === \"happy\") {\n face.moveTo(-6, -48).arc(0, -48, 6, 0, Math.PI).stroke(stroke(2.2, faceColor, 0.9));\n } else if (m === \"sleeping\") {\n face.circle(0, -45, 1.8).stroke(stroke(1.6, faceColor, 0.6));\n } else if (m === \"error\") {\n face.moveTo(-7, -45).lineTo(-3.5, -48).lineTo(0, -45).lineTo(3.5, -48).lineTo(7, -45)\n .stroke(stroke(2, faceColor, flicker));\n } else {\n const mw = 5 + intensity * 3;\n face.ellipse(0, -46, mw, 2.4 + intensity * 1.2).fill({ color: faceColor, alpha: 0.75 * flicker });\n }\n\n // Effects: drifting z's while asleep, smoke while failing.\n fx.clear();\n if (m === \"sleeping\") {\n for (let k = 0; k < 3; k += 1) {\n const p = ((t * 0.0004 + k / 3 + seed * 0.13) % 1);\n const zx = 20 + p * 16;\n const zy = -78 - p * 30;\n const s = 3 + p * 4;\n fx.moveTo(zx, zy).lineTo(zx + s, zy).lineTo(zx, zy + s).lineTo(zx + s, zy + s)\n .stroke(stroke(1.6, 0xa5b4cc, 1 - p));\n }\n } else if (m === \"error\") {\n for (let k = 0; k < 4; k += 1) {\n const p = ((t * 0.0007 + k / 4 + seed * 0.1) % 1);\n fx.circle(Math.sin(p * 9 + k) * 6 + (k - 1.5) * 4, -80 - p * 34, 3 + p * 6)\n .fill({ color: 0x6b7280, alpha: 0.55 * (1 - p) });\n }\n }\n\n status.alpha = 0.6 + Math.sin(t * 0.007 + seed) * 0.4 * (0.3 + intensity);\n },\n setState(nextColor) {\n status.tint = nextColor;\n },\n };\n}\n\n// Desk + monitor + nameplate. Origin = top-left of the desk surface. All the\n// numbers sit on the desk's front face so neighbouring rows never collide:\n// row 1 account · row 2 model + tokens · row 3 latency, cost, cache share\n// bottom bar = elapsed time (green → amber → red), left pile = queued requests\nexport function createDesk({\n color,\n label = \"\",\n meta = \"\",\n elapsedMs = 0,\n cost = 0,\n cachedPct = 0,\n queued = 1,\n depth = 1,\n}) {\n const root = new Container();\n const W = 150;\n const H = 96;\n\n const desk = new Graphics();\n // Soft layered ground shadow (offset down-right, as if lit from top-left).\n desk.ellipse(W / 2 + 8, H + 6, W * 0.62, 11).fill({ color: 0x000000, alpha: 0.18 });\n desk.ellipse(W / 2 + 6, H + 4, W * 0.56, 8).fill({ color: 0x000000, alpha: 0.28 });\n // Front face (gradient, darker toward the floor) + right side face for depth.\n desk.roundRect(0, 34, W, H - 34, 7).fill(vgrad(0x2b3443, 0x181d26));\n desk.poly([W, 40, W + 9, 32, W + 9, H - 8, W, H - 2]).fill({ color: 0x10141b });\n // Desk top: lighter slab seen from slightly above, with a bright front lip.\n desk.poly([-5, 28, 8, 20, W - 2, 20, W + 9, 28]).fill({ color: 0x5d6b7d });\n desk.roundRect(-5, 26, W + 14, 14, 6).fill(vgrad(0x65738a, 0x3a4554));\n desk.roundRect(-5, 26, W + 14, 2.5, 2).fill({ color: 0xffffff, alpha: 0.3 });\n desk.roundRect(0, 40, W, 2, 1).fill({ color: 0x000000, alpha: 0.35 });\n root.addChild(desk);\n\n // Elapsed-time bar: fill grows with latency, colour warns when it drags.\n const ratio = Math.min(1, elapsedMs / 40000);\n const barColor = elapsedMs < 12000 ? 0x34d399 : elapsedMs < 26000 ? 0xfbbf24 : 0xef4444;\n const bar = new Graphics();\n bar.roundRect(10, H - 9, W - 20, 4, 2).fill({ color: 0x0f141c });\n bar.roundRect(10, H - 9, Math.max(4, (W - 20) * ratio), 4, 2).fill({ color: barColor });\n root.addChild(bar);\n\n const glow = new Graphics();\n glow.roundRect(W / 2 - 62, -30, 76, 62, 12).fill({ color, alpha: 0.12 });\n root.addChild(glow);\n\n const screen = new Graphics();\n screen.roundRect(W / 2 - 50, -16, 58, 38, 5).fill({ color: 0x000000, alpha: 0.35 }); // drop shadow\n screen.roundRect(W / 2 - 52, -18, 58, 38, 5).fill(vgrad(0x2a313c, 0x0b0e13));\n screen.roundRect(W / 2 - 48, -14, 50, 30, 3).fill({ color, alpha: 0.6 });\n for (let i = 0; i < 4; i += 1) {\n screen.roundRect(W / 2 - 44, -9 + i * 6, 18 + ((i * 11) % 22), 2.4, 1).fill({ color: 0xffffff, alpha: 0.5 });\n }\n screen.poly([W / 2 - 48, -14, W / 2 - 22, -14, W / 2 - 34, 16, W / 2 - 48, 16]).fill({ color: 0xffffff, alpha: 0.07 }); // glass glare\n screen.roundRect(W / 2 - 29, 20, 8, 6, 2).fill({ color: 0x2d3541 });\n root.addChild(screen);\n\n const keys = new Graphics();\n keys.roundRect(W / 2 + 14, 29, 34, 8, 3).fill({ color: 0x0b0e13 });\n keys.roundRect(W / 2 + 14, 27, 34, 8, 3).fill(vgrad(0x3b4554, 0x232a35));\n root.addChild(keys);\n\n // Request pile: one sheet per queued request (max 5) + ×N when stacked.\n const pile = new Graphics();\n const sheets = Math.min(5, Math.max(1, queued));\n for (let i = 0; i < sheets; i += 1) {\n pile.roundRect(-2 + (i % 2), 22 - i * 3.4, 22, 5, 1.5)\n .fill({ color: i % 2 ? 0xe6edf6 : 0xcfd8e6 })\n .stroke({ width: 0.6, color: 0x0f141c, alpha: 0.5 });\n }\n root.addChild(pile);\n if (queued > 1) {\n const q = new Text({ text: `×${queued}`, style: { fontFamily: SANS, fontSize: 10, fill: 0xfbbf24, fontWeight: \"800\" } });\n q.anchor.set(0.5, 1);\n q.x = 9;\n q.y = 22 - sheets * 3.4 - 1;\n root.addChild(q);\n }\n\n const name = new Text({\n text: clip(label, 20),\n style: { fontFamily: SANS, fontSize: 12, fill: 0xe6edf6, fontWeight: \"700\" },\n });\n name.anchor.set(0.5, 0);\n name.x = W / 2;\n name.y = 43;\n\n const sub = new Text({\n text: clip(meta, 28),\n style: { fontFamily: MONO, fontSize: 9, fill: 0x93a1b5 },\n });\n sub.anchor.set(0.5, 0);\n sub.x = W / 2;\n sub.y = 58;\n\n const secs = elapsedMs >= 1000 ? `${(elapsedMs / 1000).toFixed(1)}s` : `${elapsedMs}ms`;\n const stats = new Text({\n text: `${secs} · $${cost.toFixed(2)} · ${cachedPct}% cached`,\n style: { fontFamily: MONO, fontSize: 8.5, fill: barColor },\n });\n stats.anchor.set(0.5, 0);\n stats.x = W / 2;\n stats.y = 71;\n\n root.addChild(name, sub, stats);\n\n // Selection ring (toggled from outside) + click target.\n const ring = new Graphics();\n ring.roundRect(-12, -76, W + 24, H + 84, 14).stroke({ width: 2.5, color: 0xfde047, alpha: 0.9 });\n ring.roundRect(-12, -76, W + 24, H + 84, 14).fill({ color: 0xfde047, alpha: 0.05 });\n ring.visible = false;\n root.addChildAt(ring, 0);\n\n root.eventMode = \"static\";\n root.cursor = \"pointer\";\n root.hitArea = new Rectangle(-12, -76, W + 24, H + 84);\n root.scale.set(depth);\n\n return {\n root,\n screen,\n glow,\n setSelected(on) {\n ring.visible = !!on;\n },\n /** Flicker on the monitor while work is in flight. */\n animate(t, intensity = 0) {\n screen.alpha = 0.7 + Math.sin(t * 0.008 + root.x) * 0.12 * (0.4 + intensity);\n glow.alpha = 0.3 + intensity * 0.5 + Math.sin(t * 0.004 + root.x) * 0.08;\n },\n };\n}\n\nexport function createBadge(text, { color = 0x22d3ee, size = 10 } = {}) {\n const label = new Text({\n text,\n style: { fontFamily: SANS, fontSize: size, fill: color, fontWeight: \"700\" },\n });\n return label;\n}\n\nexport { STATE_COLORS, STATE_LABELS };\n","import { ExtensionType } from '../extensions/Extensions';\n\n/**\n * Extension for the browser environment.\n * @category environment\n * @internal\n */\nexport const browserExt = {\n extension: {\n type: ExtensionType.Environment,\n name: 'browser',\n priority: -1,\n },\n test: () => true,\n load: async () =>\n {\n await import('./browserAll');\n },\n};\n","import { DOMAdapter } from '../../environment/adapter';\n\nlet _isWebGPUSupported: boolean | undefined;\n\n/**\n * Helper for checking for WebGPU support in the current environment.\n * Results are cached after first call for better performance.\n * @example\n * ```ts\n * // Basic WebGPU support check\n * const hasWebGPU = await isWebGPUSupported();\n * console.log('WebGPU available:', hasWebGPU);\n * ```\n * @param options - The options for requesting a GPU adapter\n * @returns Promise that resolves to true if WebGPU is supported\n * @category utils\n * @standard\n */\nexport async function isWebGPUSupported(options: GPURequestAdapterOptions = {}): Promise<boolean>\n{\n if (_isWebGPUSupported !== undefined) return _isWebGPUSupported;\n\n _isWebGPUSupported = await (async (): Promise<boolean> =>\n {\n const gpu = DOMAdapter.get().getNavigator().gpu;\n\n if (!gpu)\n {\n return false;\n }\n\n try\n {\n const adapter = await gpu.requestAdapter(options) as GPUAdapter;\n\n // TODO and one of these!\n await adapter.requestDevice();\n\n return true;\n }\n catch (_e)\n {\n return false;\n }\n })();\n\n return _isWebGPUSupported;\n}\n","import {\n collapseNewlines,\n collapseSpaces,\n getCharacterGroups,\n isBreakingSpace,\n isNewline,\n tokenize,\n trimRight,\n} from './textTokenization';\n\nimport type { ICanvas, ICanvasRenderingContext2DSettings } from '../../../../environment/canvas/ICanvas';\nimport type { ICanvasRenderingContext2D } from '../../../../environment/canvas/ICanvasRenderingContext2D';\nimport type { TextStyle } from '../../TextStyle';\nimport type { CanBreakCharsFn, MeasureTextFn, WordWrapSplitFn } from './types';\n\ntype CharacterWidthCache = Record<string, number>;\n/**\n * Function type for checking if words can be broken.\n * @internal\n */\ntype CanBreakWordsFn = (token: string, breakWords: boolean) => boolean;\n\n// Default settings used for all getContext calls\nconst contextSettings: ICanvasRenderingContext2DSettings = {\n // TextMetrics requires getImageData readback for measuring fonts.\n willReadFrequently: true,\n};\n\n/**\n * Gets & sets the widths of calculated characters in a cache object\n * @param key - The key\n * @param letterSpacing - The letter spacing\n * @param cache - The cache\n * @param context - The canvas context\n * @param measureTextFn - Function to measure text\n * @returns The cached or measured width.\n * @internal\n */\nfunction getFromCache(\n key: string,\n letterSpacing: number,\n cache: CharacterWidthCache,\n context: ICanvasRenderingContext2D,\n measureTextFn: MeasureTextFn,\n): number\n{\n let width = cache[key];\n\n if (typeof width !== 'number')\n {\n width = measureTextFn(key, letterSpacing, context) + letterSpacing;\n cache[key] = width;\n }\n\n return width;\n}\n\n/**\n * Applies newlines to a string to have it optimally fit into the horizontal\n * bounds set by the Text object's wordWrapWidth property.\n * @param text - String to apply word wrapping to\n * @param style - the style to use when wrapping\n * @param canvas - specification of the canvas to use for measuring.\n * @param measureTextFn - Function to measure text width\n * @param canBreakWordsFn - Function to check if words can be broken\n * @param canBreakCharsFn - Function to check if characters can be broken\n * @param wordWrapSplitFn - Function to split words into characters\n * @returns New string with new lines applied where required\n * @internal\n */\nexport function wordWrap(\n text: string,\n style: TextStyle,\n canvas: ICanvas,\n measureTextFn: MeasureTextFn,\n canBreakWordsFn: CanBreakWordsFn,\n canBreakCharsFn: CanBreakCharsFn,\n wordWrapSplitFn: WordWrapSplitFn,\n): string\n{\n const context = canvas.getContext('2d', contextSettings);\n\n context.font = style._fontString;\n\n let width = 0;\n let line = '';\n const linesArray: string[] = [];\n\n const cache: CharacterWidthCache = Object.create(null);\n const { letterSpacing, whiteSpace } = style;\n\n // How to handle whitespaces\n const shouldCollapseSpaces = collapseSpaces(whiteSpace);\n const shouldCollapseNewlines = collapseNewlines(whiteSpace);\n\n // whether or not spaces may be added to the beginning of lines\n let canPrependSpaces = !shouldCollapseSpaces;\n\n // There is letterSpacing after every char except the last one\n // t_h_i_s_' '_i_s_' '_a_n_' '_e_x_a_m_p_l_e_' '_!\n // so for convenience the above needs to be compared to width + 1 extra letterSpace\n // t_h_i_s_' '_i_s_' '_a_n_' '_e_x_a_m_p_l_e_' '_!_\n // ________________________________________________\n // And then the final space is simply no appended to each line\n const wordWrapWidth = style.wordWrapWidth + letterSpacing;\n\n // break text into words, spaces and newline chars\n const tokens = tokenize(text);\n\n for (let i = 0; i < tokens.length; i++)\n {\n // get the word, space or newlineChar\n let token = tokens[i];\n\n // if word is a new line\n if (isNewline(token))\n {\n // keep the new line\n if (!shouldCollapseNewlines)\n {\n linesArray.push(trimRight(line));\n canPrependSpaces = !shouldCollapseSpaces;\n line = '';\n width = 0;\n continue;\n }\n\n // if we should collapse new lines\n // we simply convert it into a space\n token = ' ';\n }\n\n // if we should collapse repeated whitespaces\n if (shouldCollapseSpaces)\n {\n // check both this and the last tokens for spaces\n const currIsBreakingSpace = isBreakingSpace(token);\n const lastIsBreakingSpace = isBreakingSpace(line[line.length - 1]);\n\n if (currIsBreakingSpace && lastIsBreakingSpace)\n {\n continue;\n }\n }\n\n // get word width from cache if possible\n const tokenWidth = getFromCache(token, letterSpacing, cache, context, measureTextFn);\n\n // word is longer than desired bounds\n if (tokenWidth > wordWrapWidth)\n {\n // if we are not already at the beginning of a line\n if (line !== '')\n {\n // start newlines for overflow words\n linesArray.push(trimRight(line));\n line = '';\n width = 0;\n }\n\n // break large word over multiple lines\n if (canBreakWordsFn(token, style.breakWords))\n {\n // break word into character groups that shouldn't be split\n const charGroups = getCharacterGroups(token, style.breakWords, wordWrapSplitFn, canBreakCharsFn);\n\n // loop the character groups\n for (const char of charGroups)\n {\n const characterWidth = getFromCache(char, letterSpacing, cache, context, measureTextFn);\n\n if (characterWidth + width > wordWrapWidth)\n {\n linesArray.push(trimRight(line));\n canPrependSpaces = false;\n line = '';\n width = 0;\n }\n\n line += char;\n width += characterWidth;\n }\n }\n\n // run word out of the bounds\n else\n {\n // if there are words in this line already\n // finish that line and start a new one\n if (line.length > 0)\n {\n linesArray.push(trimRight(line));\n line = '';\n width = 0;\n }\n\n // give it its own line\n linesArray.push(trimRight(token));\n canPrependSpaces = false;\n line = '';\n width = 0;\n }\n }\n\n // word could fit\n else\n {\n // word won't fit because of existing words\n // start a new line\n if (tokenWidth + width > wordWrapWidth)\n {\n // if its a space we don't want it\n canPrependSpaces = false;\n\n // add a new line\n linesArray.push(trimRight(line));\n\n // start a new line\n line = '';\n width = 0;\n }\n\n // don't add spaces to the beginning of lines\n if (line.length > 0 || !isBreakingSpace(token) || canPrependSpaces)\n {\n // add the word to the current line\n line += token;\n\n // update width counter\n width += tokenWidth;\n }\n }\n }\n\n const trimmedLine = trimRight(line);\n\n if (trimmedLine.length > 0)\n {\n linesArray.push(trimmedLine);\n }\n\n return linesArray.join('\\n');\n}\n","import { updateQuadBounds } from '../../../utils/data/updateQuadBounds';\nimport { type BatchableSprite } from '../../sprite/BatchableSprite';\nimport { type AbstractText } from '../AbstractText';\nimport { type TextStyle, type TextStyleOptions } from '../TextStyle';\n\n/**\n * Updates the bounds of the given batchable sprite based on the provided text object.\n *\n * This function adjusts the bounds of the batchable sprite to match the dimensions\n * and anchor point of the text's texture. Additionally, it compensates for any padding\n * specified in the text's style to ensure the text is rendered correctly on screen.\n * @param {BatchableSprite} batchableSprite - The sprite whose bounds need to be updated.\n * @param {AbstractText} text - The text object containing the texture and style information.\n * @internal\n */\nexport function updateTextBounds(batchableSprite: BatchableSprite, text: AbstractText<TextStyle, TextStyleOptions>)\n{\n const { texture, bounds } = batchableSprite;\n const padding = text._style._getFinalPadding();\n\n // When HTML text textures are created, they include the padding around the text content\n // to prevent text clipping and provide a buffer zone. This padding is built into\n // the texture itself. However, we don't want this padding to affect the text's\n // actual position on screen.\n\n // First, calculate bounds using the full padded texture\n updateQuadBounds(bounds, text._anchor, texture);\n\n // Then adjust by the padding amount to compensate for the buffer zone\n // This shifts the render position back by the padding amount, ensuring the text\n // appears exactly where intended while maintaining the buffer zone around it.\n const paddingOffset = text._anchor._x * padding * 2;\n const paddingOffsetY = text._anchor._y * padding * 2;\n\n bounds.minX -= padding - paddingOffset;\n bounds.minY -= padding - paddingOffsetY;\n bounds.maxX -= padding - paddingOffset;\n bounds.maxY -= padding - paddingOffsetY;\n}\n","import { BatchableSprite } from '../../sprite/BatchableSprite';\n\n/** @internal */\nexport class BatchableText extends BatchableSprite\n{\n public currentKey: string;\n}\n","import { ExtensionType } from '../../../extensions/Extensions';\nimport { AbstractTextSystem } from './AbstractTextSystem';\n\nimport type { Renderer } from '../../../rendering/renderers/types';\n\n/**\n * System plugin to the renderer to manage canvas text for GPU renderers.\n * @category rendering\n * @advanced\n */\nexport class CanvasTextSystem extends AbstractTextSystem\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLSystem,\n ExtensionType.WebGPUSystem,\n ],\n name: 'canvasText',\n } as const;\n\n constructor(renderer: Renderer)\n {\n super(renderer, false);\n }\n}\n","import { TextureStyle } from '../../../rendering/renderers/shared/texture/TextureStyle';\nimport { warn } from '../../../utils/logging/warn';\n\nlet warned = false;\n\n/**\n * Warns once when a text texture style carries anything beyond scaleMode, which is the only\n * field a pooled text texture honours.\n * @param textureStyle - the style given to a Text or HTMLText\n * @internal\n */\nexport function warnIgnoredTextureStyle(textureStyle: TextureStyle): void\n{\n // #if _DEBUG\n if (warned) return;\n\n // styles with the same sampler parameters share a resource id, so a style that only sets\n // scaleMode matches a fresh style built from that scaleMode alone\n const scaleModeOnly = new TextureStyle({ scaleMode: textureStyle.scaleMode });\n\n if (textureStyle._resourceId === scaleModeOnly._resourceId) return;\n\n warned = true;\n warn('Text textureStyle: only scaleMode is applied to a text texture, the other fields are ignored');\n // #endif\n}\n","import { parseTaggedText, type TextStyleRun } from './parseTaggedText';\nimport {\n collapseNewlines,\n collapseSpaces,\n getCharacterGroups,\n isBreakingSpace,\n isNewline,\n NEWLINE_SPLIT_REGEX,\n tokenize,\n trimRight,\n} from './textTokenization';\n\nimport type { ICanvasRenderingContext2D } from '../../../../environment/canvas/ICanvasRenderingContext2D';\nimport type { TextStyle } from '../../TextStyle';\nimport type {\n CanBreakCharsFn,\n FontMetrics,\n MeasureTextFn,\n WordWrapSplitFn,\n} from './types';\n\n/**\n * Function type for measuring font metrics.\n * @internal\n */\ntype MeasureFontFn = (font: string) => FontMetrics;\n\n/**\n * Result of measuring tagged text.\n * @internal\n */\ninterface TaggedMeasurementResult\n{\n /** Total width including stroke and shadow */\n width: number;\n /** Total height including shadow */\n height: number;\n /** Array of line text (for compatibility) */\n lines: string[];\n /** Per-line widths */\n lineWidths: number[];\n /** Base line height from style */\n lineHeight: number;\n /** Maximum line width */\n maxLineWidth: number;\n /** Font properties from base style */\n fontProperties: FontMetrics;\n /** Per-line style runs */\n runsByLine: TextStyleRun[][];\n /** Per-line ascent values */\n lineAscents: number[];\n /** Per-line descent values */\n lineDescents: number[];\n /** Per-line heights */\n lineHeights: number[];\n /** Whether any run has drop shadow */\n hasDropShadow: boolean;\n}\n\n/**\n * Styled token with continuation flag for word wrapping.\n * @internal\n */\ninterface StyledToken\n{\n token: string;\n style: TextStyle;\n continuesFromPrevious: boolean;\n}\n\n/**\n * Regex to replace newlines with spaces.\n * @internal\n */\nconst NEWLINE_TO_SPACE_REGEX = /\\r\\n|\\r|\\n/g;\n\n/**\n * Measures tagged text with multiple styles.\n * Handles per-run font measurement and per-line metrics.\n * @param text - The tagged text to measure\n * @param style - The base text style containing tagStyles\n * @param wordWrap - Whether to apply word wrapping\n * @param context - The canvas 2D context\n * @param measureTextFn - Function to measure text width (includes bounding box)\n * @param wrapMeasureTextFn - Function to measure advance width only (for word wrap line-fitting)\n * @param measureFontFn - Function to measure font metrics\n * @param canBreakCharsFn - Function to check if characters can be broken\n * @param wordWrapSplitFn - Function to split words into characters\n * @returns TaggedMeasurementResult with all measurement data\n * @internal\n */\nexport function measureTaggedText(\n text: string,\n style: TextStyle,\n wordWrap: boolean,\n context: ICanvasRenderingContext2D,\n measureTextFn: MeasureTextFn,\n wrapMeasureTextFn: MeasureTextFn,\n measureFontFn: MeasureFontFn,\n canBreakCharsFn: CanBreakCharsFn,\n wordWrapSplitFn: WordWrapSplitFn,\n): TaggedMeasurementResult\n{\n // Parse text into runs\n const runs = parseTaggedText(text, style);\n\n // Collapse newlines to spaces in 'normal' mode (matching regular text behavior)\n const shouldCollapseNewlines = collapseNewlines(style.whiteSpace);\n\n if (shouldCollapseNewlines)\n {\n for (let i = 0; i < runs.length; i++)\n {\n const run = runs[i];\n\n runs[i] = { text: run.text.replace(NEWLINE_TO_SPACE_REGEX, ' '), style: run.style };\n }\n }\n\n // First, we need to handle newlines and word wrap\n // Split runs by newlines first\n const runsByLine: TextStyleRun[][] = [];\n let currentLineRuns: TextStyleRun[] = [];\n\n for (const run of runs)\n {\n // Split run text by newlines\n const parts = run.text.split(NEWLINE_SPLIT_REGEX);\n\n for (let i = 0; i < parts.length; i++)\n {\n const part = parts[i];\n\n if (part === '\\r\\n' || part === '\\r' || part === '\\n')\n {\n // Push current line and start a new one\n runsByLine.push(currentLineRuns);\n currentLineRuns = [];\n }\n else if (part.length > 0)\n {\n currentLineRuns.push({ text: part, style: run.style });\n }\n }\n }\n // Don't forget the last line\n if (currentLineRuns.length > 0 || runsByLine.length === 0)\n {\n runsByLine.push(currentLineRuns);\n }\n\n // Apply word wrap if enabled (uses advance-only measurement for additive line-fitting)\n const wrappedRunsByLine = wordWrap\n ? wordWrapTaggedLines(\n runsByLine,\n style,\n context,\n wrapMeasureTextFn,\n canBreakCharsFn,\n wordWrapSplitFn,\n )\n : runsByLine;\n\n // Measure each line\n const lineWidths: number[] = [];\n const lineAscents: number[] = [];\n const lineDescents: number[] = [];\n const lineHeightsArr: number[] = [];\n const lines: string[] = [];\n let maxLineWidth = 0;\n\n // Get base font properties for fallback\n const baseFont = style._fontString;\n const baseFontProps = measureFontFn(baseFont);\n\n // Fallback in case UA disallows canvas data extraction\n if (baseFontProps.fontSize === 0)\n {\n baseFontProps.fontSize = style.fontSize as number;\n baseFontProps.ascent = style.fontSize as number;\n }\n\n let lastFont = '';\n let hasDropShadow = !!style.dropShadow;\n let maxRunStrokeWidth = style._stroke?.width || 0;\n\n for (const lineRuns of wrappedRunsByLine)\n {\n let lineWidth = 0;\n let lineAscent = baseFontProps.ascent;\n let lineDescent = baseFontProps.descent;\n let lineText = '';\n\n for (const run of lineRuns)\n {\n const runFont = run.style._fontString;\n const runFontProps = measureFontFn(runFont);\n\n if (runFont !== lastFont)\n {\n context.font = runFont;\n lastFont = runFont;\n }\n\n const runWidth = measureTextFn(run.text, run.style.letterSpacing, context);\n\n lineWidth += runWidth;\n lineAscent = Math.max(lineAscent, runFontProps.ascent);\n lineDescent = Math.max(lineDescent, runFontProps.descent);\n lineText += run.text;\n\n const runStrokeWidth = run.style._stroke?.width || 0;\n\n if (runStrokeWidth > maxRunStrokeWidth) maxRunStrokeWidth = runStrokeWidth;\n\n if (!hasDropShadow && run.style.dropShadow)\n {\n hasDropShadow = true;\n }\n }\n\n // Handle empty lines\n if (lineRuns.length === 0)\n {\n lineAscent = baseFontProps.ascent;\n lineDescent = baseFontProps.descent;\n }\n\n lineWidths.push(lineWidth);\n lineAscents.push(lineAscent);\n lineDescents.push(lineDescent);\n lines.push(lineText);\n\n // Calculate line height - use style.lineHeight if set, otherwise use measured metrics\n const computedLineHeight = style.lineHeight || (lineAscent + lineDescent);\n\n lineHeightsArr.push(computedLineHeight + style.leading);\n maxLineWidth = Math.max(maxLineWidth, lineWidth);\n }\n\n // Calculate total dimensions\n const strokeWidth = maxRunStrokeWidth;\n\n const width = maxLineWidth + strokeWidth + (style.dropShadow ? style.dropShadow.distance : 0);\n\n // Calculate total height from per-line heights\n let baseHeight = 0;\n\n for (let i = 0; i < lineHeightsArr.length; i++)\n {\n baseHeight += lineHeightsArr[i];\n }\n\n // Add stroke width to height for first line (to match non-tagged behavior)\n baseHeight = Math.max(baseHeight, lineHeightsArr[0] + strokeWidth);\n const height = baseHeight + (style.dropShadow ? style.dropShadow.distance : 0);\n\n // Use the base style's line height for the lineHeight property (for backwards compat)\n const baseLineHeight = style.lineHeight || baseFontProps.fontSize;\n\n return {\n width,\n height,\n lines,\n lineWidths,\n lineHeight: baseLineHeight + style.leading,\n maxLineWidth,\n fontProperties: baseFontProps,\n runsByLine: wrappedRunsByLine,\n lineAscents,\n lineDescents,\n lineHeights: lineHeightsArr,\n hasDropShadow,\n };\n}\n\n/**\n * Applies word wrapping to tagged text lines.\n * Breaks runs at word boundaries while maintaining style information.\n * @param runsByLine - Array of run arrays, one per line\n * @param style - The base text style\n * @param context - The canvas 2D context\n * @param measureTextFn - Function to measure text width\n * @param canBreakCharsFn - Function to check if characters can be broken\n * @param wordWrapSplitFn - Function to split words into characters\n * @returns New runsByLine array with word wrap applied\n * @internal\n */\nexport function wordWrapTaggedLines(\n runsByLine: TextStyleRun[][],\n style: TextStyle,\n context: ICanvasRenderingContext2D,\n measureTextFn: MeasureTextFn,\n canBreakCharsFn: CanBreakCharsFn,\n wordWrapSplitFn: WordWrapSplitFn,\n): TextStyleRun[][]\n{\n const { letterSpacing, whiteSpace, wordWrapWidth, breakWords } = style;\n\n // How to handle whitespaces\n const shouldCollapseSpaces = collapseSpaces(whiteSpace);\n\n // Adjust for letterSpacing (see _wordWrap for explanation)\n const adjustedWrapWidth = wordWrapWidth + letterSpacing;\n\n // Cache for token width measurements and font tracking to avoid redundant work\n const tokenWidthCache: Record<string, number> = {};\n let lastFont = '';\n\n const measureTokenWidth = (token: string, tokenStyle: TextStyle): number =>\n {\n const cacheKey = `${token}|${tokenStyle.styleKey}`;\n let width = tokenWidthCache[cacheKey];\n\n if (width === undefined)\n {\n const font = tokenStyle._fontString;\n\n if (font !== lastFont)\n {\n context.font = font;\n lastFont = font;\n }\n width = measureTextFn(token, tokenStyle.letterSpacing, context)\n + tokenStyle.letterSpacing;\n tokenWidthCache[cacheKey] = width;\n }\n\n return width;\n };\n\n const result: TextStyleRun[][] = [];\n\n // Process each line from the input\n for (const lineRuns of runsByLine)\n {\n // Tokenize all runs on this line into styled tokens\n const styledTokens = tokenizeTaggedRuns(lineRuns);\n\n // Track if we pushed content directly to result (for word groups)\n const resultStartLength = result.length;\n\n // Helper to calculate the total width of a word group starting at index\n // A word group is a sequence of tokens where each subsequent token has continuesFromPrevious: true\n const getWordGroupWidth = (startIndex: number): number =>\n {\n let totalWidth = 0;\n let j = startIndex;\n\n do\n {\n const { token: groupToken, style: groupStyle } = styledTokens[j];\n\n totalWidth += measureTokenWidth(groupToken, groupStyle);\n j++;\n }\n while (j < styledTokens.length && styledTokens[j].continuesFromPrevious);\n\n return totalWidth;\n };\n\n // Helper to get all tokens in a word group\n const getWordGroupTokens = (startIndex: number): Array<{ token: string; style: TextStyle }> =>\n {\n const tokens: Array<{ token: string; style: TextStyle }> = [];\n let j = startIndex;\n\n do\n {\n tokens.push({ token: styledTokens[j].token, style: styledTokens[j].style });\n j++;\n }\n while (j < styledTokens.length && styledTokens[j].continuesFromPrevious);\n\n return tokens;\n };\n\n // Now apply word wrap logic to these tokens\n let currentLineRuns: TextStyleRun[] = [];\n let currentWidth = 0;\n let canPrependSpaces = !shouldCollapseSpaces;\n\n // Track the current \"building\" run (to merge adjacent tokens with same style)\n let buildingRun: TextStyleRun | null = null;\n\n const flushBuildingRun = (): void =>\n {\n if (buildingRun && buildingRun.text.length > 0)\n {\n currentLineRuns.push(buildingRun);\n }\n buildingRun = null;\n };\n\n const startNewLine = (): void =>\n {\n flushBuildingRun();\n // Trim trailing spaces from last run on line\n if (currentLineRuns.length > 0)\n {\n const lastRun = currentLineRuns[currentLineRuns.length - 1];\n\n lastRun.text = trimRight(lastRun.text);\n if (lastRun.text.length === 0)\n {\n currentLineRuns.pop();\n }\n }\n result.push(currentLineRuns);\n currentLineRuns = [];\n currentWidth = 0;\n canPrependSpaces = false;\n };\n\n for (let i = 0; i < styledTokens.length; i++)\n {\n const { token, style: tokenStyle, continuesFromPrevious } = styledTokens[i];\n\n const tokenWidth = measureTokenWidth(token, tokenStyle);\n\n // Handle collapsing spaces\n if (shouldCollapseSpaces)\n {\n const currIsSpace = isBreakingSpace(token);\n const lastChar = buildingRun?.text[buildingRun.text.length - 1]\n ?? currentLineRuns[currentLineRuns.length - 1]?.text.slice(-1)\n ?? '';\n const lastIsSpace = lastChar ? isBreakingSpace(lastChar) : false;\n\n if (currIsSpace && lastIsSpace)\n {\n continue;\n }\n }\n\n // Check if this token starts a word group (not a continuation)\n const startsWordGroup = !continuesFromPrevious;\n\n // Calculate word group width if this starts a new word group\n const wordGroupWidth = startsWordGroup ? getWordGroupWidth(i) : tokenWidth;\n\n // Word group is longer than the wrap width\n if (wordGroupWidth > adjustedWrapWidth && startsWordGroup)\n {\n // Flush any existing content to a new line\n if (currentWidth > 0)\n {\n startNewLine();\n }\n\n // Break the long word group if allowed\n if (breakWords)\n {\n // Get all tokens in this word group\n const wordGroupTokens = getWordGroupTokens(i);\n\n // Process each token in the word group\n for (let g = 0; g < wordGroupTokens.length; g++)\n {\n const groupToken = wordGroupTokens[g].token;\n const groupStyle = wordGroupTokens[g].style;\n const charGroups = getCharacterGroups(\n groupToken,\n breakWords,\n wordWrapSplitFn,\n canBreakCharsFn,\n );\n\n for (const char of charGroups)\n {\n const charWidth = measureTokenWidth(char, groupStyle);\n\n // eslint-disable-next-line max-depth\n if (charWidth + currentWidth > adjustedWrapWidth)\n {\n startNewLine();\n }\n\n // Add char to building run\n // eslint-disable-next-line max-depth\n if (!buildingRun || buildingRun.style !== groupStyle)\n {\n flushBuildingRun();\n buildingRun = { text: char, style: groupStyle };\n }\n else\n {\n buildingRun.text += char;\n }\n currentWidth += charWidth;\n }\n }\n\n // Skip all the tokens we just processed\n i += wordGroupTokens.length - 1;\n }\n else\n {\n // Can't break - put whole word group on its own line\n const wordGroupTokens = getWordGroupTokens(i);\n\n flushBuildingRun();\n result.push(wordGroupTokens.map((t) => ({ text: t.token, style: t.style })));\n canPrependSpaces = false;\n\n // Skip all the tokens we just processed\n i += wordGroupTokens.length - 1;\n }\n }\n // Word group would exceed line width (but fits on its own line)\n else if (wordGroupWidth + currentWidth > adjustedWrapWidth && startsWordGroup)\n {\n // Don't start new line with just a space\n if (isBreakingSpace(token))\n {\n canPrependSpaces = false;\n continue;\n }\n\n startNewLine();\n\n // Start new building run with this token\n buildingRun = { text: token, style: tokenStyle };\n currentWidth = tokenWidth;\n }\n // Token is a continuation of a word group - always add it (don't wrap mid-word when breakWords: false)\n else if (continuesFromPrevious && !breakWords)\n {\n // Add to building run or start new one\n if (!buildingRun || buildingRun.style !== tokenStyle)\n {\n flushBuildingRun();\n buildingRun = { text: token, style: tokenStyle };\n }\n else\n {\n buildingRun.text += token;\n }\n currentWidth += tokenWidth;\n }\n // Token fits on current line (or is a continuation with breakWords: true)\n else\n {\n const isSpace = isBreakingSpace(token);\n\n // Don't prepend spaces to line start unless allowed\n if (currentWidth === 0 && isSpace && !canPrependSpaces)\n {\n continue;\n }\n\n // Add to building run or start new one\n if (!buildingRun || buildingRun.style !== tokenStyle)\n {\n flushBuildingRun();\n buildingRun = { text: token, style: tokenStyle };\n }\n else\n {\n buildingRun.text += token;\n }\n currentWidth += tokenWidth;\n }\n }\n\n // Flush final content\n flushBuildingRun();\n if (currentLineRuns.length > 0)\n {\n // Trim trailing spaces\n const lastRun = currentLineRuns[currentLineRuns.length - 1];\n\n lastRun.text = trimRight(lastRun.text);\n if (lastRun.text.length === 0)\n {\n currentLineRuns.pop();\n }\n }\n\n // Push final line if it has content, or if we haven't pushed anything yet.\n // The second condition (result.length === resultStartLength) ensures we preserve\n // explicit blank lines from the input text. Without this, a line containing only\n // whitespace would be trimmed away entirely, collapsing consecutive newlines.\n if (currentLineRuns.length > 0 || result.length === resultStartLength)\n {\n result.push(currentLineRuns);\n }\n }\n\n return result;\n}\n\n/**\n * Tokenizes an array of TextStyleRuns into individual styled tokens.\n * Each token is a word, space, or newline with its associated style.\n * Tracks whether adjacent tokens across run boundaries form a continuous word.\n * @param runs - The runs to tokenize\n * @returns Array of styled tokens with continuation flags\n * @internal\n */\nexport function tokenizeTaggedRuns(\n runs: TextStyleRun[]\n): StyledToken[]\n{\n const styledTokens: StyledToken[] = [];\n let lastTokenWasWord = false;\n\n for (const run of runs)\n {\n const tokens = tokenize(run.text);\n let isFirstTokenInRun = true;\n\n for (const token of tokens)\n {\n const isSpace = isBreakingSpace(token) || isNewline(token);\n\n // Token continues from previous word if:\n // 1. It's the first token in this run\n // 2. The previous run's last token was a word (not space)\n // 3. This token is also a word (not space)\n const continuesFromPrevious = isFirstTokenInRun && lastTokenWasWord && !isSpace;\n\n styledTokens.push({ token, style: run.style, continuesFromPrevious });\n\n lastTokenWasWord = !isSpace;\n isFirstTokenInRun = false;\n }\n }\n\n return styledTokens;\n}\n","import { ExtensionType } from '../../../extensions/Extensions';\nimport { AbstractTextSystem } from '../shared/AbstractTextSystem';\n\nimport type { Renderer } from '../../../rendering/renderers/types';\n\n/**\n * System plugin to the renderer to manage canvas text for Canvas2D.\n * @category rendering\n * @advanced\n */\nexport class CanvasRendererTextSystem extends AbstractTextSystem\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.CanvasSystem,\n ],\n name: 'canvasText',\n } as const;\n\n constructor(renderer: Renderer)\n {\n super(renderer, true);\n }\n}\n","import { ExtensionType } from '../extensions/Extensions';\nimport { UPDATE_PRIORITY } from '../ticker/const';\nimport { Ticker } from '../ticker/Ticker';\n\nimport type { ExtensionMetadata } from '../extensions/Extensions';\n\n/**\n * Application options for the {@link TickerPlugin}.\n * These options control the animation loop and update cycle of your PixiJS application.\n * @example\n * ```ts\n * import { Application } from 'pixi.js';\n *\n * // Basic setup with default options\n * const app = new Application();\n * await app.init({\n * autoStart: true, // Start animation loop automatically\n * sharedTicker: false // Use dedicated ticker instance\n * });\n *\n * // Advanced setup with shared ticker\n * const app2 = new Application();\n * await app2.init({\n * autoStart: false, // Don't start automatically\n * sharedTicker: true // Use global shared ticker\n * });\n *\n * // Start animation when ready\n * app2.start();\n * ```\n * @remarks\n * The ticker is the heart of your application's animation system. It:\n * - Manages the render loop\n * - Provides accurate timing information\n * - Handles frame-based updates\n * - Supports priority-based execution order\n * @see {@link Ticker} For detailed ticker functionality\n * @see {@link UPDATE_PRIORITY} For update priority constants\n * @category app\n * @standard\n */\nexport interface TickerPluginOptions\n{\n /**\n * Controls whether the animation loop starts automatically after initialization.\n * > [!IMPORTANT]\n * > Setting this to `false` does NOT stop the shared ticker even if `sharedTicker` is `true`.\n * > You must stop the shared ticker manually if needed.\n * @example\n * ```ts\n * // Auto-start (default behavior)\n * await app.init({ autoStart: true });\n *\n * // Manual start\n * await app.init({ autoStart: false });\n * app.start(); // Start when ready\n * ```\n * @default true\n */\n autoStart?: boolean;\n\n /**\n * Controls whether to use the shared global ticker or create a new instance.\n *\n * The shared ticker is useful when you have multiple instances that should sync their updates.\n * However, it has some limitations regarding update order control.\n *\n * Update Order:\n * 1. System ticker (always runs first)\n * 2. Shared ticker (if enabled)\n * 3. App ticker (if using own ticker)\n * @example\n * ```ts\n * // Use shared ticker (global instance)\n * await app.init({ sharedTicker: true });\n *\n * // Use dedicated ticker (default)\n * await app.init({ sharedTicker: false });\n *\n * // Access ticker properties\n * console.log(app.ticker.FPS); // Current FPS\n * console.log(app.ticker.deltaMS); // MS since last update\n * ```\n * @default false\n */\n sharedTicker?: boolean;\n}\n\n/**\n * Middleware for Application's {@link Ticker} functionality. This plugin manages the\n * animation loop and update cycle of your PixiJS application.\n *\n * Adds the following features to {@link Application}:\n * - `ticker`: Access to the application's ticker\n * - `start`: Start the animation loop\n * - `stop`: Stop the animation loop\n * @example\n * ```ts\n * import { Application, TickerPlugin, extensions } from 'pixi.js';\n *\n * // Create application\n * const app = new Application();\n *\n * // Example 1: Basic ticker usage (default autoStart)\n * await app.init({ autoStart: true }); // Starts ticker automatically\n *\n * // Example 2: Manual ticker control\n * await app.init({ autoStart: false }); // Don't start automatically\n * app.start(); // Start manually\n * app.stop(); // Stop manually\n *\n * // Example 3: Add custom update logic\n * app.ticker.add((ticker) => {\n * // Run every frame, delta is the time since last update\n * sprite.rotation += 0.1 * ticker.deltaTime;\n * });\n *\n * // Example 4: Control update priority\n * import { UPDATE_PRIORITY } from 'pixi.js';\n *\n * app.ticker.add(\n * (ticker) => {\n * // Run before normal priority updates\n * },\n * null,\n * UPDATE_PRIORITY.HIGH\n * );\n *\n * // Example 5: One-time update\n * app.ticker.addOnce(() => {\n * console.log('Runs next frame only');\n * });\n * ```\n * @see {@link Ticker} For detailed ticker functionality\n * @see {@link UPDATE_PRIORITY} For priority constants\n * @category app\n * @standard\n */\nexport class TickerPlugin\n{\n /** @ignore */\n public static extension: ExtensionMetadata = ExtensionType.Application;\n\n /** @internal */\n public static start: () => void;\n /** @internal */\n public static stop: () => void;\n /** @internal */\n private static _ticker: Ticker;\n /** @internal */\n public static ticker: Ticker;\n\n /**\n * Initialize the plugin with scope of application instance\n * @private\n * @param {object} [options] - See application options\n */\n public static init(options?: PixiMixins.ApplicationOptions): void\n {\n // Set default\n options = Object.assign({\n autoStart: true,\n sharedTicker: false,\n }, options);\n\n // Create ticker setter\n Object.defineProperty(this, 'ticker',\n {\n configurable: true,\n set(ticker)\n {\n if (this._ticker)\n {\n this._ticker.remove(this.render, this);\n }\n this._ticker = ticker;\n if (ticker)\n {\n ticker.add(this.render, this, UPDATE_PRIORITY.LOW);\n }\n },\n get()\n {\n return this._ticker;\n },\n });\n\n this.stop = (): void =>\n {\n this._ticker.stop();\n };\n\n this.start = (): void =>\n {\n this._ticker.start();\n };\n\n this._ticker = null;\n this.ticker = options.sharedTicker ? Ticker.shared : new Ticker();\n\n // Start the rendering\n if (options.autoStart)\n {\n this.start();\n }\n }\n\n /**\n * Clean up the ticker, scoped to application.\n * @private\n */\n public static destroy(): void\n {\n if (this._ticker)\n {\n const oldTicker = this._ticker;\n\n this.ticker = null;\n oldTicker.destroy();\n }\n }\n}\n","import { DOMAdapter } from '../../environment/adapter';\nimport { nextPow2 } from '../../maths/misc/pow2';\nimport { Rectangle } from '../../maths/shapes/Rectangle';\n\nimport type { ICanvas } from '../../environment/canvas/ICanvas';\nimport type { ICanvasRenderingContext2D } from '../../environment/canvas/ICanvasRenderingContext2D';\n\n// Internal canvas for measuring bounds\nlet _internalCanvas: ICanvas | null = null;\nlet _internalContext: ICanvasRenderingContext2D | null = null;\n\nfunction ensureInternalCanvas(width: number, height: number): void\n{\n if (!_internalCanvas)\n {\n _internalCanvas = DOMAdapter.get().createCanvas(256, 128);\n _internalContext = _internalCanvas.getContext('2d', { willReadFrequently: true });\n _internalContext.globalCompositeOperation = 'copy';\n _internalContext.globalAlpha = 1;\n }\n\n if (_internalCanvas.width < width || _internalCanvas.height < height)\n {\n // Use power-of-two dimensions for better performance\n _internalCanvas.width = nextPow2(width);\n _internalCanvas.height = nextPow2(height);\n }\n}\n\nfunction checkRow(data: Uint8ClampedArray, width: number, y: number)\n{\n for (let x = 0, index = 4 * y * width; x < width; ++x, index += 4)\n {\n if (data[index + 3] !== 0) return false;\n }\n\n return true;\n}\n\nfunction checkColumn(data: Uint8ClampedArray, width: number, x: number, top: number, bottom: number)\n{\n const stride = 4 * width;\n\n for (let y = top, index = (top * stride) + (4 * x); y <= bottom; ++y, index += stride)\n {\n if (data[index + 3] !== 0) return false;\n }\n\n return true;\n}\n\n/** @internal */\nexport interface GetCanvasBoundingBoxOptions\n{\n /** The canvas to measure */\n canvas: ICanvas;\n /** Optional. The width to analyze (defaults to canvas.width) */\n width?: number;\n /** Optional. The height to analyze (defaults to canvas.height) */\n height?: number;\n /**\n * Optional. The resolution at which to analyze the canvas, between 0-1.\n * Lower values improve performance for large canvases but may be less precise.\n * Default is 1 (full resolution).\n */\n resolution?: number;\n /** Optional. The rectangle to store the result in. */\n output?: Rectangle;\n}\n\n/**\n * Measures the bounding box of a canvas's visible (non-transparent) pixels.\n *\n * This function analyzes the alpha channel of the canvas pixels to find the smallest\n * rectangle containing all non-transparent pixels. It's useful for optimizing sprite\n * rendering by trimming transparent borders.\n *\n * Uses an internal canvas with `willReadFrequently: true` for efficient pixel data access.\n * This internal canvas is reused between calls for better performance.\n * @example\n * ```typescript\n * // Basic usage - get trim bounds at full resolution\n * const bounds = getCanvasBoundingBox({ canvas: myCanvas });\n * console.log(bounds); // Rectangle{x: 10, y: 5, width: 100, height: 200}\n * // Optimized for performance with lower resolution scanning\n * const fastBounds = getCanvasBoundingBox({\n * canvas: largeCanvas,\n * width: largeCanvas.width,\n * height: largeCanvas.height,\n * resolution: 0.5\n * });\n * // Resolution of 0.5 means scanning at half size, much faster for large canvases\n *\n * // Using custom dimensions - only analyze part of the canvas\n * const partialBounds = getCanvasBoundingBox({ canvas: myCanvas, width: 100, height: 100 });\n * // Only analyzes a 100x100 region starting from top-left\n * ```\n * @param options - The options for measuring the bounding box, including the canvas to measure.\n * @returns The bounding box as a Rectangle containing the visible content.\n * Returns Rectangle.EMPTY if the canvas is completely transparent.\n * @internal\n */\nexport function getCanvasBoundingBox(\n options: GetCanvasBoundingBoxOptions,\n): Rectangle;\n/**\n * @param canvas\n * @param resolution\n * @internal\n * @deprecated since 8.10.0\n */\nexport function getCanvasBoundingBox(canvas: ICanvas, resolution?: number): Rectangle;\n/**\n * @param {...any} args\n * @internal\n */\nexport function getCanvasBoundingBox(...args: [GetCanvasBoundingBoxOptions] | [ICanvas, number?]): Rectangle\n{\n let options = args[0] as GetCanvasBoundingBoxOptions;\n\n if (!options.canvas)\n {\n options = { canvas: args[0] as ICanvas, resolution: args[1] };\n }\n\n const { canvas } = options; // canvas is correctly extracted from options\n\n // Cap resolution at 1\n const resolution = Math.min(options.resolution ?? 1, 1);\n const width = options.width ?? canvas.width;\n const height = options.height ?? canvas.height;\n let output = options.output;\n\n // Ensure internal canvas is large enough\n ensureInternalCanvas(width, height);\n\n if (!_internalContext)\n {\n throw new TypeError('Failed to get canvas 2D context');\n }\n\n // Set up for pixel replacement (no blending)\n _internalContext.drawImage(\n canvas as unknown as CanvasImageSource,\n 0, 0,\n width, height,\n 0, 0,\n width * resolution, height * resolution\n );\n\n // Get the image data at full resolution\n const imageData = _internalContext.getImageData(0, 0, width, height);\n const data = imageData.data;\n\n let left = 0;\n let top = 0;\n let right = width - 1;\n let bottom = height - 1;\n\n while (top < height && checkRow(data, width, top)) ++top;\n if (top === height) return Rectangle.EMPTY;\n while (checkRow(data, width, bottom)) --bottom;\n while (checkColumn(data, width, left, top, bottom)) ++left;\n while (checkColumn(data, width, right, top, bottom)) --right;\n\n ++right;\n ++bottom;\n\n _internalContext.globalCompositeOperation = 'source-over';\n // draw the rect on the canvas\n _internalContext.strokeRect(left, top, right - left, bottom - top);\n _internalContext.globalCompositeOperation = 'copy';\n\n output ??= new Rectangle();\n\n output.set(left / resolution, top / resolution, (right - left) / resolution, (bottom - top) / resolution);\n\n return output;\n}\n\n","// Maps the frozen trace contract onto positions in a virtual office.\n//\n// Everything here derives from build-factory-graph's grouping so the scene and\n// the topology view agree on what an \"account\" is. No new data model.\n\nexport const STATE_COLORS = {\n pending: 0xf59e0b,\n streaming: 0x22d3ee,\n done: 0x34d399,\n error: 0xef4444,\n};\n\n// A finished account that has been quiet this long is shown asleep.\nexport const SLEEP_AFTER_MS = 32000;\n\nexport const STATE_LABELS = {\n pending: \"Queued\",\n streaming: \"Working\",\n done: \"Done\",\n error: \"Failed\",\n};\n\n// Office geometry, in world units (the camera scales these to the viewport).\nexport const OFFICE = {\n floorY: 820,\n agentCols: 6,\n agentRows: 5,\n deskW: 150,\n deskH: 84,\n colGap: 200,\n rowGap: 170,\n originX: 60,\n rackX: 1500,\n rackY: 480,\n podX: 1860,\n podGap: 104,\n podCapacity: 4,\n};\n\nfunction humanSize(n) {\n if (!n) return \"0\";\n if (n >= 1000000) return `${(n / 1000000).toFixed(1)}M`;\n if (n >= 1000) return `${(n / 1000).toFixed(1)}k`;\n return String(n);\n}\n\n/**\n * Build the scene graph: one workstation per account, one rack, one pod per\n * provider.\n *\n * @param {Array} traces Records in the frozen contract shape.\n * @returns {{ workstations: Array, rack: object, pods: Array, stats: object }}\n */\nexport function buildOffice(traces = []) {\n const byAccount = new Map();\n\n for (const trace of traces) {\n if (!trace?.connectionId) continue;\n let entry = byAccount.get(trace.connectionId);\n if (!entry) {\n entry = {\n connectionId: trace.connectionId,\n account: trace.account || trace.connectionId,\n model: trace.model,\n provider: trace.provider,\n clientIcon: trace.clientIcon,\n traces: [],\n tokens: { input: 0, output: 0, cached: 0 },\n activeCount: 0,\n errorCount: 0,\n tools: [],\n errorReason: null,\n fallbackFrom: null,\n queued: 0,\n elapsedMs: 0,\n cost: 0,\n pendingCount: 0,\n };\n byAccount.set(trace.connectionId, entry);\n }\n entry.traces.push(trace);\n for (const call of trace.toolCalls || []) {\n const toolName = call.tool || call.type;\n if (toolName && !entry.tools.includes(toolName)) entry.tools.push(toolName);\n }\n entry.tokens.input += trace.tokens?.input || 0;\n entry.tokens.output += trace.tokens?.output || 0;\n entry.tokens.cached += trace.tokens?.cached || 0;\n entry.queued += Math.max(1, trace.concurrent || 1);\n entry.elapsedMs = Math.max(entry.elapsedMs, trace.elapsedMs || 0);\n entry.cost += trace.cost || 0;\n if (trace.fallback?.from && !entry.fallbackFrom) entry.fallbackFrom = trace.fallback.from;\n if (trace.state === \"error\") {\n entry.errorCount += 1;\n entry.errorReason = entry.errorReason || trace.error || \"error\";\n } else if (trace.state !== \"done\") {\n entry.activeCount += 1;\n if (trace.state === \"pending\") entry.pendingCount += 1;\n }\n }\n\n const workstations = [...byAccount.values()].map((entry, i) => {\n const col = i % OFFICE.agentCols;\n const row = Math.floor(i / OFFICE.agentCols);\n // Only even rows get a character: half the desks are empty, which reads as a\n // real office rather than a fully packed grid.\n // Every account has an agent at its desk; what they are doing is `mode`.\n const occupied = true;\n const state = entry.errorCount > 0 ? \"error\" : entry.activeCount > 0 ? \"streaming\" : \"done\";\n const mode =\n state === \"error\"\n ? \"error\"\n : state === \"streaming\"\n ? entry.pendingCount === entry.activeCount\n ? \"pending\"\n : \"streaming\"\n : entry.elapsedMs >= SLEEP_AFTER_MS\n ? \"sleeping\"\n : \"happy\";\n const totalTokens = entry.tokens.input + entry.tokens.output + entry.tokens.cached;\n const cachedPct = totalTokens ? Math.round((entry.tokens.cached / totalTokens) * 100) : 0;\n return {\n ...entry,\n occupied,\n state,\n mode,\n cachedPct,\n cost: Math.round(entry.cost * 100) / 100,\n color: STATE_COLORS[state],\n totalTokens: entry.tokens.input + entry.tokens.output + entry.tokens.cached,\n totalLabel: humanSize(entry.tokens.input + entry.tokens.output + entry.tokens.cached),\n count: entry.traces.length,\n x: OFFICE.originX + col * OFFICE.colGap,\n y: OFFICE.floorY - row * OFFICE.rowGap,\n // Desks further back are drawn first and slightly smaller.\n depth: 1,\n busy: entry.activeCount,\n };\n });\n\n const providers = [...new Set(workstations.map((w) => w.provider).filter(Boolean))];\n\n const pods = providers.map((provider, i) => {\n const clients = workstations.filter((w) => w.provider === provider);\n const busy = clients.reduce((s, w) => s + w.busy, 0);\n const tokens = clients.reduce((s, w) => s + w.totalTokens, 0);\n const anyError = clients.some((w) => w.state === \"error\");\n return {\n provider,\n x: OFFICE.podX,\n y: OFFICE.rackY - ((providers.length - 1) * OFFICE.podGap) / 2 + i * OFFICE.podGap,\n busy,\n load: Math.min(1, busy / OFFICE.podCapacity),\n overloaded: busy >= OFFICE.podCapacity,\n totalTokens: tokens,\n totalLabel: humanSize(tokens),\n color: anyError ? STATE_COLORS.error : busy > 0 ? STATE_COLORS.streaming : STATE_COLORS.done,\n };\n });\n\n // Fallback lanes: failed provider -> provider that actually served it.\n const podNames = new Set(providers);\n const laneMap = new Map();\n for (const w of workstations) {\n if (!w.fallbackFrom || !podNames.has(w.fallbackFrom) || w.fallbackFrom === w.provider) continue;\n const key = `${w.fallbackFrom}>${w.provider}`;\n const lane = laneMap.get(key) || { from: w.fallbackFrom, to: w.provider, count: 0 };\n lane.count += 1;\n laneMap.set(key, lane);\n }\n\n return {\n workstations,\n pods,\n fallbacks: [...laneMap.values()],\n rack: {\n x: OFFICE.rackX,\n y: OFFICE.rackY,\n active: workstations.reduce((s, w) => s + w.busy, 0),\n },\n stats: {\n agents: workstations.length,\n busy: workstations.filter((w) => w.busy > 0).length,\n tokens: workstations.reduce((s, w) => s + w.totalTokens, 0),\n tokensLabel: humanSize(workstations.reduce((s, w) => s + w.totalTokens, 0)),\n },\n };\n}\n","import { isWebGLSupported } from '../../utils/browser/isWebGLSupported';\nimport { isWebGPUSupported } from '../../utils/browser/isWebGPUSupported';\nimport { AbstractRenderer } from './shared/system/AbstractRenderer';\n\nimport type { CanvasOptions } from './canvas/CanvasRenderer';\nimport type { WebGLOptions } from './gl/WebGLRenderer';\nimport type { WebGPUOptions } from './gpu/WebGPURenderer';\nimport type { Renderer, RendererOptions } from './types';\n\n/**\n * A renderer type string for specifying renderer preference.\n * @category rendering\n * @standard\n */\nexport type RendererPreference = 'webgl' | 'webgpu' | 'canvas';\n\n/**\n * Options for {@link autoDetectRenderer}.\n * @category rendering\n * @advanced\n */\nexport interface AutoDetectOptions extends RendererOptions\n{\n /**\n * The preferred renderer type(s).\n *\n * - When a **string** is provided (e.g. `'webgpu'`), that renderer is tried first and\n * the remaining renderers are used as fallbacks in the default priority order.\n * - When an **array** is provided (e.g. `['webgpu', 'webgl']`), only the listed\n * renderers are tried, in the given order. Any renderer type **not** in the array\n * is excluded entirely — this can be used as a blocklist.\n */\n preference?: RendererPreference | RendererPreference[];\n /** Optional WebGPUOptions to pass only to WebGPU renderer. */\n webgpu?: Partial<WebGPUOptions>;\n /** Optional WebGLOptions to pass only to the WebGL renderer */\n webgl?: Partial<WebGLOptions>;\n /** Optional CanvasOptions to pass only to the Canvas renderer */\n canvasOptions?: Partial<CanvasOptions>;\n}\n\nconst renderPriority = ['webgl', 'webgpu', 'canvas'];\n\n/**\n * Automatically determines the most appropriate renderer for the current environment.\n *\n * The function will prioritize the WebGL renderer as it is the most tested safe API to use.\n * In the near future as WebGPU becomes more stable and ubiquitous, it will be prioritized over WebGL.\n *\n * The selected renderer's code is then dynamically imported to optimize\n * performance and minimize the initial bundle size.\n *\n * To maximize the benefits of dynamic imports, it's recommended to use a modern bundler\n * that supports code splitting. This will place the renderer code in a separate chunk,\n * which is loaded only when needed.\n * @example\n *\n * // create a renderer\n * const renderer = await autoDetectRenderer({\n * width: 800,\n * height: 600,\n * antialias: true,\n * });\n *\n * // custom for each renderer\n * const renderer = await autoDetectRenderer({\n * width: 800,\n * height: 600,\n * webgpu:{\n * antialias: true,\n * backgroundColor: 'red'\n * },\n * webgl:{\n * antialias: true,\n * backgroundColor: 'green'\n * }\n * });\n *\n * // only allow webgl and canvas (exclude webgpu entirely)\n * const renderer = await autoDetectRenderer({\n * preference: ['webgl', 'canvas'],\n * });\n * @param options - A partial configuration object based on the `AutoDetectOptions` type.\n * @returns A Promise that resolves to an instance of the selected renderer.\n * @category rendering\n * @standard\n */\nexport async function autoDetectRenderer(options: Partial<AutoDetectOptions>): Promise<Renderer>\n{\n let preferredOrder: string[] = [];\n\n if (options.preference)\n {\n if (Array.isArray(options.preference))\n {\n // When an array is provided, use only those renderers in that order.\n preferredOrder = options.preference.slice();\n }\n else\n {\n // When a single string is provided, try it first then fall back to the rest.\n preferredOrder.push(options.preference);\n\n renderPriority.forEach((item) =>\n {\n if (item !== options.preference)\n {\n preferredOrder.push(item);\n }\n });\n }\n }\n else\n {\n preferredOrder = renderPriority.slice();\n }\n\n let RendererClass: new () => Renderer;\n let finalOptions: Partial<AutoDetectOptions> = {};\n\n for (let i = 0; i < preferredOrder.length; i++)\n {\n const rendererType = preferredOrder[i];\n\n if (rendererType === 'webgpu' && (await isWebGPUSupported()))\n {\n const { WebGPURenderer } = await import('./gpu/WebGPURenderer');\n\n RendererClass = WebGPURenderer;\n\n finalOptions = { ...options, ...options.webgpu };\n\n break;\n }\n else if (\n rendererType === 'webgl'\n && isWebGLSupported(\n options.failIfMajorPerformanceCaveat\n ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat\n )\n )\n {\n const { WebGLRenderer } = await import('./gl/WebGLRenderer');\n\n RendererClass = WebGLRenderer;\n\n finalOptions = { ...options, ...options.webgl };\n\n break;\n }\n else if (rendererType === 'canvas')\n {\n const { CanvasRenderer } = await import('./canvas/CanvasRenderer');\n\n RendererClass = CanvasRenderer;\n\n finalOptions = { ...options, ...options.canvasOptions };\n\n break;\n }\n }\n\n delete finalOptions.webgpu;\n delete finalOptions.webgl;\n delete finalOptions.canvasOptions;\n\n if (!RendererClass)\n {\n throw new Error('No available renderer for the current environment');\n }\n\n const renderer = new RendererClass();\n\n await renderer.init(finalOptions);\n\n return renderer;\n}\n","import { DOMAdapter } from '../../environment/adapter';\nimport { AbstractRenderer } from '../../rendering/renderers/shared/system/AbstractRenderer';\n\nlet _isWebGLSupported: boolean | undefined;\n\n/**\n * Helper for checking for WebGL support in the current environment.\n *\n * Results are cached after first call for better performance.\n * @example\n * ```ts\n * // Basic WebGL support check\n * if (isWebGLSupported()) {\n * console.log('WebGL is available');\n * }\n * ```\n * @param failIfMajorPerformanceCaveat - Whether to fail if there is a major performance caveat\n * @returns True if WebGL is supported\n * @category utils\n * @standard\n */\nexport function isWebGLSupported(\n failIfMajorPerformanceCaveat?: boolean\n): boolean\n{\n if (_isWebGLSupported !== undefined) return _isWebGLSupported;\n\n _isWebGLSupported = ((): boolean =>\n {\n const contextOptions = {\n stencil: true,\n failIfMajorPerformanceCaveat:\n failIfMajorPerformanceCaveat\n ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat,\n };\n\n try\n {\n if (!DOMAdapter.get().getWebGLRenderingContext())\n {\n return false;\n }\n\n const canvas = DOMAdapter.get().createCanvas();\n let gl = canvas.getContext('webgl', contextOptions);\n\n const success = !!gl?.getContextAttributes()?.stencil;\n\n if (gl)\n {\n const loseContext = gl.getExtension('WEBGL_lose_context');\n\n if (loseContext)\n {\n loseContext.loseContext();\n }\n }\n\n gl = null;\n\n return success;\n }\n catch (_e)\n {\n return false;\n }\n })();\n\n return _isWebGLSupported;\n}\n","import { ObservablePoint } from '../../maths/point/ObservablePoint';\nimport { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\nimport { ViewContainer, type ViewContainerOptions } from '../view/ViewContainer';\n\nimport type { Size } from '../../maths/misc/Size';\nimport type { PointData } from '../../maths/point/PointData';\nimport type { View } from '../../rendering/renderers/shared/view/View';\nimport type { Optional } from '../container/container-mixins/measureMixin';\nimport type { DestroyOptions } from '../container/destroyTypes';\nimport type { HTMLTextStyle, HTMLTextStyleOptions } from '../text-html/HTMLTextStyle';\nimport type { TextStyle, TextStyleOptions } from './TextStyle';\n\n/**\n * A string or number that can be used as text.\n * @example\n * ```ts\n * const text: TextString = 'Hello Pixi!';\n * const text2: TextString = 12345;\n * const text3: TextString = { toString: () => 'Hello Pixi!' };\n * ```\n * @category text\n * @standard\n */\nexport type TextString = string | number | { toString: () => string };\n/**\n * A union of all text styles, including HTML, Bitmap and Canvas text styles.\n * This is used to allow for any text style to be passed to a text object.\n * @example\n * ```ts\n * import { TextStyle, HTMLTextStyle } from 'pixi.js';\n * const style: AnyTextStyle = new TextStyle({ fontSize: 24 });\n * const htmlStyle: AnyTextStyle = new HTMLTextStyle({ fontSize: '24px' });\n * ```\n * @category text\n * @standard\n * @see TextStyle\n * @see HTMLTextStyle\n */\nexport type AnyTextStyle = TextStyle | HTMLTextStyle;\n/**\n * A union of all text style options, including HTML, Bitmap and Canvas text style options.\n * This is used to allow for any text style options to be passed to a text object.\n * @example\n * ```ts\n * import { TextStyleOptions, HTMLTextStyleOptions } from 'pixi.js';\n * const styleOptions: AnyTextStyleOptions = { fontSize: 24 } as TextStyleOptions;\n * const htmlStyleOptions: AnyTextStyleOptions = { fontSize: '24px' } as HTMLTextStyleOptions;\n * ```\n * @category text\n * @standard\n * @see TextStyleOptions\n * @see HTMLTextStyleOptions\n */\nexport type AnyTextStyleOptions = TextStyleOptions | HTMLTextStyleOptions;\n\n/**\n * Options for creating text objects in PixiJS. This interface defines the common properties\n * used across different text rendering implementations (Canvas, HTML, and Bitmap).\n * @example\n * ```ts\n * // Create basic text with minimal options\n * const basicText = new Text({\n * text: 'Hello Pixi!',\n * style: {\n * fontSize: 24,\n * fill: 0xff1010\n * }\n * });\n *\n * // Create text with advanced styling\n * const styledText = new Text({\n * text: 'Styled Text',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 32,\n * fill: new FillGradient({\n * end: { x: 1, y: 1 },\n * stops: [\n * { color: 0xff0000, offset: 0 }, // Red at start\n * { color: 0x0000ff, offset: 1 }, // Blue at end\n * ]\n * }),\n * stroke: { color: '#4a1850', width: 5 },\n * dropShadow: {\n * color: '#000000',\n * blur: 4,\n * distance: 6\n * },\n * align: 'center'\n * },\n * anchor: 0.5,\n * resolution: window.devicePixelRatio\n * });\n *\n * // Create multiline text with word wrap\n * const wrappedText = new Text({\n * text: 'This is a long piece of text that will wrap onto multiple lines',\n * style: {\n * fontSize: 20,\n * wordWrap: true,\n * wordWrapWidth: 200,\n * lineHeight: 30\n * },\n * resolution: 2,\n * roundPixels: true\n * });\n * ```\n * @category text\n * @standard\n * @noInheritDoc\n */\nexport interface TextOptions<\n TEXT_STYLE extends TextStyle = TextStyle,\n TEXT_STYLE_OPTIONS extends TextStyleOptions = TextStyleOptions,\n> extends PixiMixins.TextOptions, ViewContainerOptions\n{\n /**\n * The anchor point of the text that controls the origin point for positioning and rotation.\n * Can be a number (same value for x/y) or a PointData object.\n * - (0,0) is top-left\n * - (0.5,0.5) is center\n * - (1,1) is bottom-right\n * ```ts\n * // Set anchor to center\n * const text = new Text({\n * text: 'Hello Pixi!',\n * anchor: 0.5 // Same as { x: 0.5, y: 0.5 }\n * });\n * // Set anchor to top-left\n * const text2 = new Text({\n * text: 'Hello Pixi!',\n * anchor: { x: 0, y: 0 } // Top-left corner\n * });\n * // Set anchor to bottom-right\n * const text3 = new Text({\n * text: 'Hello Pixi!',\n * anchor: { x: 1, y: 1 } // Bottom-right corner\n * });\n * ```\n * @default { x: 0, y: 0 }\n */\n anchor?: PointData | number;\n /**\n * The text content to display. Use '\\n' for line breaks.\n * Accepts strings, numbers, or objects with toString() method.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Hello Pixi!',\n * });\n * const multilineText = new Text({\n * text: 'Line 1\\nLine 2\\nLine 3',\n * });\n * const numberText = new Text({\n * text: 12345, // Will be converted to '12345'\n * });\n * const objectText = new Text({\n * text: { toString: () => 'Object Text' }, // Custom toString\n * });\n * ```\n * @default ''\n */\n text?: TextString;\n /**\n * The resolution/device pixel ratio for rendering.\n * Higher values result in sharper text at the cost of performance.\n * Set to null for auto-resolution based on device.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Hello Pixi!',\n * resolution: 2 // High DPI for sharper text\n * });\n * const autoResText = new Text({\n * text: 'Auto Resolution',\n * resolution: null // Use device's pixel ratio\n * });\n * ```\n * @default null\n */\n resolution?: number;\n /**\n * The style configuration for the text.\n * Can be a TextStyle instance or a configuration object.\n * Supports canvas text styles, HTML text styles, and bitmap text styles.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Styled Text',\n * style: {\n * fontSize: 24,\n * fill: 0xff1010, // Red color\n * fontFamily: 'Arial',\n * align: 'center', // Center alignment\n * stroke: { color: '#4a1850', width: 5 }, // Purple stroke\n * dropShadow: {\n * color: '#000000', // Black shadow\n * blur: 4, // Shadow blur\n * distance: 6 // Shadow distance\n * }\n * }\n * });\n * const htmlText = new HTMLText({\n * text: 'HTML Styled Text',\n * style: {\n * fontSize: '20px',\n * fill: 'blue',\n * fontFamily: 'Verdana',\n * }\n * });\n * const bitmapText = new BitmapText({\n * text: 'Bitmap Styled Text',\n * style: {\n * fontName: 'Arial',\n * fontSize: 32,\n * }\n * })\n */\n style?: TEXT_STYLE | TEXT_STYLE_OPTIONS;\n /**\n * Whether to round the x/y position to whole pixels.\n * Enabling can prevent anti-aliasing of text edges but may cause slight position shifting.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Rounded Text',\n * roundPixels: true // Rounds position to whole pixels\n * });\n * @default false\n */\n roundPixels?: boolean;\n}\n\n/**\n * An abstract Text class, used by all text type in Pixi. This includes Canvas, HTML, and Bitmap Text.\n * @see Text\n * @see BitmapText\n * @see HTMLText\n * @category text\n * @advanced\n */\nexport abstract class AbstractText<\n TEXT_STYLE extends TextStyle = TextStyle,\n TEXT_STYLE_OPTIONS extends TextStyleOptions = TextStyleOptions,\n TEXT_OPTIONS extends TextOptions<TEXT_STYLE, TEXT_STYLE_OPTIONS> = TextOptions<TEXT_STYLE, TEXT_STYLE_OPTIONS>,\n GPU_DATA extends { destroy: () => void } = any\n> extends ViewContainer<GPU_DATA> implements View\n{\n /** @internal */\n public batched = true;\n /** @internal */\n public _anchor: ObservablePoint;\n\n /** @internal */\n public _resolution: number = null;\n /** @internal */\n public _autoResolution: boolean = true;\n\n /** @internal */\n public _style: TEXT_STYLE;\n /** @internal */\n public _didTextUpdate = true;\n\n protected _text: string;\n private readonly _styleClass: new (options: TEXT_STYLE_OPTIONS) => TEXT_STYLE;\n\n constructor(\n options: TEXT_OPTIONS,\n styleClass: new (options: TEXT_STYLE_OPTIONS) => TEXT_STYLE\n )\n {\n const { text, resolution, style, anchor, width, height, roundPixels, ...rest } = options;\n\n super({\n ...rest\n });\n\n this._styleClass = styleClass;\n\n this.text = text ?? '';\n\n this.style = style;\n\n this.resolution = resolution ?? null;\n\n this.allowChildren = false;\n\n this._anchor = new ObservablePoint(\n {\n _onUpdate: () =>\n {\n this.onViewUpdate();\n },\n },\n );\n\n if (anchor) this.anchor = anchor;\n this.roundPixels = roundPixels ?? false;\n\n // needs to be set after the container has initiated\n if (width !== undefined) this.width = width;\n if (height !== undefined) this.height = height;\n }\n\n /**\n * The anchor point of the text that controls the origin point for positioning and rotation.\n * Can be a number (same value for x/y) or a PointData object.\n * - (0,0) is top-left\n * - (0.5,0.5) is center\n * - (1,1) is bottom-right\n * ```ts\n * // Set anchor to center\n * const text = new Text({\n * text: 'Hello Pixi!',\n * anchor: 0.5 // Same as { x: 0.5, y: 0.5 }\n * });\n * // Set anchor to top-left\n * const text2 = new Text({\n * text: 'Hello Pixi!',\n * anchor: { x: 0, y: 0 } // Top-left corner\n * });\n * // Set anchor to bottom-right\n * const text3 = new Text({\n * text: 'Hello Pixi!',\n * anchor: { x: 1, y: 1 } // Bottom-right corner\n * });\n * ```\n * @default { x: 0, y: 0 }\n */\n get anchor(): ObservablePoint\n {\n return this._anchor;\n }\n\n set anchor(value: PointData | number)\n {\n typeof value === 'number' ? this._anchor.set(value) : this._anchor.copyFrom(value);\n }\n\n /**\n * The text content to display. Use '\\n' for line breaks.\n * Accepts strings, numbers, or objects with toString() method.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Hello Pixi!',\n * });\n * const multilineText = new Text({\n * text: 'Line 1\\nLine 2\\nLine 3',\n * });\n * const numberText = new Text({\n * text: 12345, // Will be converted to '12345'\n * });\n * const objectText = new Text({\n * text: { toString: () => 'Object Text' }, // Custom toString\n * });\n *\n * // Update text dynamically\n * text.text = 'Updated Text'; // Re-renders with new text\n * text.text = 67890; // Updates to '67890'\n * text.text = { toString: () => 'Dynamic Text' }; // Uses custom toString method\n * // Clear text\n * text.text = ''; // Clears the text\n * ```\n * @default ''\n */\n set text(value: TextString)\n {\n // check its a string\n value = value.toString();\n\n if (this._text === value) return;\n\n this._text = value as string;\n this.onViewUpdate();\n }\n\n get text(): string\n {\n return this._text;\n }\n\n /**\n * The resolution/device pixel ratio for rendering.\n * Higher values result in sharper text at the cost of performance.\n * Set to null for auto-resolution based on device.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Hello Pixi!',\n * resolution: 2 // High DPI for sharper text\n * });\n * const autoResText = new Text({\n * text: 'Auto Resolution',\n * resolution: null // Use device's pixel ratio\n * });\n * ```\n * @default null\n */\n set resolution(value: number)\n {\n this._autoResolution = value === null;\n this._resolution = value;\n this.onViewUpdate();\n }\n\n get resolution(): number\n {\n return this._resolution;\n }\n\n get style(): TEXT_STYLE\n {\n return this._style;\n }\n\n /**\n * The style configuration for the text.\n * Can be a TextStyle instance or a configuration object.\n * Supports canvas text styles, HTML text styles, and bitmap text styles.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Styled Text',\n * style: {\n * fontSize: 24,\n * fill: 0xff1010, // Red color\n * fontFamily: 'Arial',\n * align: 'center', // Center alignment\n * stroke: { color: '#4a1850', width: 5 }, // Purple stroke\n * dropShadow: {\n * color: '#000000', // Black shadow\n * blur: 4, // Shadow blur\n * distance: 6 // Shadow distance\n * }\n * }\n * });\n * const htmlText = new HTMLText({\n * text: 'HTML Styled Text',\n * style: {\n * fontSize: '20px',\n * fill: 'blue',\n * fontFamily: 'Verdana',\n * }\n * });\n * const bitmapText = new BitmapText({\n * text: 'Bitmap Styled Text',\n * style: {\n * fontName: 'Arial',\n * fontSize: 32,\n * }\n * })\n *\n * // Update style dynamically\n * text.style = {\n * fontSize: 30, // Change font size\n * fill: 0x00ff00, // Change color to green\n * align: 'right', // Change alignment to right\n * stroke: { color: '#000000', width: 2 }, // Add black stroke\n * }\n */\n set style(style: TEXT_STYLE | Partial<TEXT_STYLE> | TEXT_STYLE_OPTIONS)\n {\n style ||= {};\n\n this._style?.off('update', this.onViewUpdate, this);\n\n if (style instanceof this._styleClass)\n {\n this._style = style as TEXT_STYLE;\n }\n else\n {\n this._style = new this._styleClass(style as TEXT_STYLE_OPTIONS);\n }\n\n this._style.on('update', this.onViewUpdate, this);\n this.onViewUpdate();\n }\n\n /**\n * The width of the sprite, setting this will actually modify the scale to achieve the value set.\n * @example\n * ```ts\n * // Set width directly\n * texture.width = 200;\n * console.log(texture.scale.x); // Scale adjusted to match width\n *\n * // For better performance when setting both width and height\n * texture.setSize(300, 400); // Avoids recalculating bounds twice\n * ```\n */\n override get width(): number\n {\n return Math.abs(this.scale.x) * this.bounds.width;\n }\n\n override set width(value: number)\n {\n this._setWidth(value, this.bounds.width);\n }\n\n /**\n * The height of the sprite, setting this will actually modify the scale to achieve the value set.\n * @example\n * ```ts\n * // Set height directly\n * texture.height = 200;\n * console.log(texture.scale.y); // Scale adjusted to match height\n *\n * // For better performance when setting both width and height\n * texture.setSize(300, 400); // Avoids recalculating bounds twice\n * ```\n */\n override get height(): number\n {\n return Math.abs(this.scale.y) * this.bounds.height;\n }\n\n override set height(value: number)\n {\n this._setHeight(value, this.bounds.height);\n }\n\n /**\n * Retrieves the size of the Text as a [Size]{@link Size} object based on the texture dimensions and scale.\n * This is faster than getting width and height separately as it only calculates the bounds once.\n * @example\n * ```ts\n * // Basic size retrieval\n * const text = new Text({\n * text: 'Hello Pixi!',\n * style: { fontSize: 24 }\n * });\n * const size = text.getSize();\n * console.log(`Size: ${size.width}x${size.height}`);\n *\n * // Reuse existing size object\n * const reuseSize = { width: 0, height: 0 };\n * text.getSize(reuseSize);\n * ```\n * @param out - Optional object to store the size in, to avoid allocating a new object\n * @returns The size of the Sprite\n * @see {@link Text#width} For getting just the width\n * @see {@link Text#height} For getting just the height\n * @see {@link Text#setSize} For setting both width and height\n */\n public override getSize(out?: Size): Size\n {\n out ||= {} as Size;\n out.width = Math.abs(this.scale.x) * this.bounds.width;\n out.height = Math.abs(this.scale.y) * this.bounds.height;\n\n return out;\n }\n\n /**\n * Sets the size of the Text to the specified width and height.\n * This is faster than setting width and height separately as it only recalculates bounds once.\n * @example\n * ```ts\n * // Basic size setting\n * const text = new Text({\n * text: 'Hello Pixi!',\n * style: { fontSize: 24 }\n * });\n * text.setSize(100, 200); // Width: 100, Height: 200\n *\n * // Set uniform size\n * text.setSize(100); // Sets both width and height to 100\n *\n * // Set size with object\n * text.setSize({\n * width: 200,\n * height: 300\n * });\n * ```\n * @param value - This can be either a number or a {@link Size} object\n * @param height - The height to set. Defaults to the value of `width` if not provided\n * @see {@link Text#width} For setting width only\n * @see {@link Text#height} For setting height only\n */\n public override setSize(value: number | Optional<Size, 'height'>, height?: number)\n {\n if (typeof value === 'object')\n {\n height = value.height ?? value.width;\n value = value.width;\n }\n else\n {\n height ??= value;\n }\n\n value !== undefined && this._setWidth(value, this.bounds.width);\n height !== undefined && this._setHeight(height, this.bounds.height);\n }\n\n /**\n * Checks if the object contains the given point in local coordinates.\n * Uses the text's bounds for hit testing.\n * @example\n * ```ts\n * // Basic point check\n * const localPoint = { x: 50, y: 25 };\n * const contains = text.containsPoint(localPoint);\n * console.log('Point is inside:', contains);\n * ```\n * @param point - The point to check in local coordinates\n * @returns True if the point is within the text's bounds\n * @see {@link Container#toLocal} For converting global coordinates to local\n */\n public override containsPoint(point: PointData)\n {\n const width = this.bounds.width;\n const height = this.bounds.height;\n\n const x1 = -width * this.anchor.x;\n let y1 = 0;\n\n if (point.x >= x1 && point.x <= x1 + width)\n {\n y1 = -height * this.anchor.y;\n\n if (point.y >= y1 && point.y <= y1 + height) return true;\n }\n\n return false;\n }\n\n /** @internal */\n public override onViewUpdate()\n {\n if (!this.didViewUpdate) this._didTextUpdate = true;\n super.onViewUpdate();\n }\n\n /**\n * Destroys this text renderable and optionally its style texture.\n * @param options - Options parameter. A boolean will act as if all options\n * have been set to that value\n * @example\n * // Destroys the text and its style\n * text.destroy({ style: true, texture: true, textureSource: true });\n * text.destroy(true);\n * text.destroy() // Destroys the text, but not its style\n */\n public override destroy(options: DestroyOptions = false): void\n {\n // detach from the style so a shared style does not keep a reference\n // to this destroyed instance (issue #12049)\n this._style?.off('update', this.onViewUpdate, this);\n\n super.destroy(options);\n\n (this as any).owner = null;\n this._bounds = null;\n this._anchor = null;\n\n if (typeof options === 'boolean' ? options : options?.style)\n {\n this._style.destroy(options);\n }\n\n this._style = null;\n this._text = null;\n }\n\n /**\n * Returns a unique key for this instance.\n * This key is used for caching.\n * @returns {string} Unique key for the instance\n */\n public get styleKey(): string\n {\n return `${this._text}:${this._style.styleKey}:${this._resolution}`;\n }\n}\n\n/**\n * Helper function to ensure consistent handling of text options across different text classes.\n * This function handles both the new options object format and the deprecated parameter format.\n * @example\n * // New recommended way:\n * const options = ensureTextOptions([{\n * text: \"Hello\",\n * style: { fontSize: 20 }\n * }], \"Text\");\n *\n * // Deprecated way (will show warning in debug):\n * const options = ensureTextOptions([\"Hello\", { fontSize: 20 }], \"Text\");\n * @param args - Arguments passed to text constructor\n * @param name - Name of the text class (used in deprecation warning)\n * @returns Normalized text options object\n * @template TEXT_OPTIONS - The type of the text options\n * @internal\n */\nexport function ensureTextOptions<\n TEXT_OPTIONS extends TextOptions\n>(\n args: any[],\n name: string\n): TEXT_OPTIONS\n{\n let options = (args[0] ?? {}) as TEXT_OPTIONS;\n\n // @deprecated\n if (typeof options === 'string' || args[1])\n {\n // #if _DEBUG\n deprecation(v8_0_0, `use new ${name}({ text: \"hi!\", style }) instead`);\n // #endif\n\n options = {\n text: options,\n style: args[1],\n } as unknown as TEXT_OPTIONS;\n }\n\n return options;\n}\n","import { extensions } from '../../extensions/Extensions';\nimport { CanvasTextPipe } from './canvas/CanvasTextPipe';\nimport { CanvasRendererTextSystem } from './canvas/CanvasTextSystem';\nimport { CanvasTextSystem } from './shared/GpuTextSystem';\n\nextensions.add(CanvasRendererTextSystem);\nextensions.add(CanvasTextSystem);\nextensions.add(CanvasTextPipe);\n","import { ExtensionType } from '../extensions/Extensions';\n\n/**\n * Extension for the webworker environment.\n * @category environment\n * @internal\n */\nexport const webworkerExt = {\n extension: {\n type: ExtensionType.Environment,\n name: 'webworker',\n priority: 0,\n },\n test: () => typeof self !== 'undefined' && self.WorkerGlobalScope !== undefined,\n load: async () =>\n {\n await import('./webworkerAll');\n },\n};\n","import { ExtensionType } from '../../../extensions/Extensions';\nimport { GCManagedHash } from '../../../utils/data/GCManagedHash';\nimport { updateTextBounds } from '../utils/updateTextBounds';\nimport { BatchableText } from './BatchableText';\n\nimport type { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { Text } from '../Text';\n\n/** @internal */\nexport class CanvasTextPipe implements RenderPipe<Text>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'text',\n } as const;\n\n private _renderer: Renderer;\n private readonly _managedTexts: GCManagedHash<Text>;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n renderer.runners.resolutionChange.add(this);\n renderer.runners.contextChange.add(this);\n this._managedTexts = new GCManagedHash({\n renderer,\n type: 'renderable',\n onUnload: this.onTextUnload.bind(this),\n name: 'canvasText'\n });\n }\n\n protected resolutionChange()\n {\n for (const key in this._managedTexts.items)\n {\n const text = this._managedTexts.items[key];\n\n if (text?._autoResolution) text.onViewUpdate();\n }\n }\n\n /**\n * Text textures are uploaded from pooled canvases that are cleared and reused straight after upload,\n * so they cannot be re-uploaded after a context loss. Unload them and regenerate on the next render.\n */\n protected contextChange()\n {\n for (const key in this._managedTexts.items)\n {\n this._managedTexts.items[key]?.unload();\n }\n }\n\n public validateRenderable(text: Text): boolean\n {\n const gpuText = this._getGpuText(text);\n\n const newKey = text.styleKey;\n\n if (gpuText.currentKey !== newKey) return true;\n\n return text._didTextUpdate;\n }\n\n public addRenderable(text: Text, instructionSet: InstructionSet)\n {\n const batchableText = this._getGpuText(text);\n\n // also update when this renderer has no texture for the text yet, e.g. the text was first rendered elsewhere\n if (text._didTextUpdate || batchableText.currentKey !== text.styleKey)\n {\n const resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n\n if (batchableText.currentKey !== text.styleKey || text._resolution !== resolution)\n {\n // If the text has changed, we need to update the GPU text\n this._updateGpuText(text);\n }\n\n text._didTextUpdate = false;\n\n updateTextBounds(batchableText, text);\n }\n\n this._renderer.renderPipes.batch.addToBatch(batchableText, instructionSet);\n }\n\n public updateRenderable(text: Text)\n {\n const batchableText = this._getGpuText(text);\n\n batchableText._batcher.updateElement(batchableText);\n }\n\n private _updateGpuText(text: Text)\n {\n const batchableText = this._getGpuText(text);\n\n if (batchableText.texture)\n {\n this._renderer.canvasText.decreaseReferenceCount(batchableText.currentKey);\n }\n\n text._resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n\n batchableText.texture = this._renderer.canvasText.getManagedTexture(text);\n batchableText.currentKey = text.styleKey;\n }\n\n private _getGpuText(text: Text)\n {\n return text._gpuData[this._renderer.uid] || this.initGpuText(text);\n }\n\n public initGpuText(text: Text)\n {\n const batchableText = new BatchableText();\n\n batchableText.currentKey = '--';\n batchableText.renderable = text;\n batchableText.transform = text.groupTransform;\n batchableText.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 };\n batchableText.roundPixels = (this._renderer._roundPixels | text._roundPixels) as 0 | 1;\n\n text._gpuData[this._renderer.uid] = batchableText;\n this._managedTexts.add(text);\n\n return batchableText;\n }\n\n protected onTextUnload(text: Text)\n {\n const gpuData = text._gpuData[this._renderer.uid];\n\n if (!gpuData) return;\n\n const { canvasText } = this._renderer;\n const refCount = canvasText.getReferenceCount(gpuData.currentKey);\n\n if (refCount > 0)\n {\n canvasText.decreaseReferenceCount(gpuData.currentKey);\n }\n else if (gpuData.texture)\n {\n canvasText.returnTexture(gpuData.texture);\n }\n }\n\n public destroy()\n {\n this._managedTexts.destroy();\n this._renderer = null;\n }\n}\n","import { extensions, ExtensionType } from '../extensions/Extensions';\nimport { autoDetectRenderer } from '../rendering/renderers/autoDetectRenderer';\nimport { Container } from '../scene/container/Container';\nimport { ApplicationInitHook } from '../utils/global/globalHooks';\nimport { deprecation, v8_0_0 } from '../utils/logging/deprecation';\nimport '../app/init';\n\nimport type { Rectangle } from '../maths/shapes/Rectangle';\nimport type { AutoDetectOptions } from '../rendering/renderers/autoDetectRenderer';\nimport type { RendererDestroyOptions } from '../rendering/renderers/shared/system/AbstractRenderer';\nimport type { Renderer } from '../rendering/renderers/types';\nimport type { DestroyOptions } from '../scene/container/destroyTypes';\n\n/**\n * Interface for creating Application plugins. Any plugin that's usable for Application must implement these methods.\n *\n * To create a plugin:\n * 1. Create a class that implements this interface\n * 2. Add the required static extension property\n * 3. Register the plugin using extensions.add()\n * @example\n * ```ts\n * import { ApplicationPlugin, ExtensionType, extensions } from 'pixi.js';\n *\n * class MyPlugin {\n * // Required: Declare the extension type\n * public static extension = ExtensionType.Application;\n *\n * // Required: Implement init method\n * public static init(options: Partial<ApplicationOptions>): void {\n * // Add properties/methods to the Application instance (this)\n * Object.defineProperty(this, 'myFeature', {\n * value: () => console.log('My feature!'),\n * });\n *\n * // Use options if needed\n * console.log('Plugin initialized with:', options);\n * }\n *\n * // Required: Implement destroy method\n * public static destroy(): void {\n * // Clean up any resources\n * console.log('Plugin destroyed');\n * }\n * }\n *\n * // Register the plugin\n * extensions.add(MyPlugin);\n *\n * // Usage in application\n * const app = new Application();\n * await app.init();\n * app.myFeature(); // Output: \"My feature!\"\n * ```\n * > [!IMPORTANT]\n * > - Plugins are initialized in the order they are added\n * > - Plugins are destroyed in reverse order\n * > - The `this` context in both methods refers to the Application instance\n * @see {@link ExtensionType} For different types of extensions\n * @see {@link extensions} For the extension registration system\n * @see {@link ApplicationOptions} For available application options\n * @category app\n * @advanced\n */\nexport interface ApplicationPlugin\n{\n /**\n * Called when Application is constructed, scoped to Application instance.\n * Passes in `options` as the only argument, which are Application `init()` options.\n * @param {object} options - Application options.\n */\n init(options: Partial<ApplicationOptions>): void;\n /** Called when destroying Application, scoped to Application instance. */\n destroy(): void;\n}\n\n/**\n * Application options supplied to the {@link Application#init} method.\n * These options configure how your PixiJS application behaves.\n * @category app\n * @standard\n * @example\n * ```js\n * import { Application } from 'pixi.js';\n *\n * const app = new Application();\n *\n * // Initialize with common options\n * await app.init({\n * // Rendering options\n * width: 800, // Canvas width\n * height: 600, // Canvas height\n * backgroundColor: 0x1099bb, // Background color\n * antialias: true, // Enable antialiasing\n * resolution: window.devicePixelRatio, // Screen resolution\n *\n * // Performance options\n * autoStart: true, // Auto-starts the render loop\n * sharedTicker: true, // Use shared ticker for better performance\n *\n * // Automatic resize options\n * resizeTo: window, // Auto-resize to window\n * autoDensity: true, // Adjust for device pixel ratio\n *\n * // Advanced options\n * preference: 'webgl', // Renderer preference ('webgl', 'webgpu', 'canvas', or an array)\n * powerPreference: 'high-performance' // GPU power preference\n * });\n * ```\n * @see {@link WebGLOptions} For resize-related options\n * @see {@link WebGPUOptions} For resize-related options\n * @see {@link TickerPlugin} For ticker-related options\n * @see {@link ResizePlugin} For resize-related options\n */\nexport interface ApplicationOptions extends AutoDetectOptions, PixiMixins.ApplicationOptions { }\n\n// eslint-disable-next-line max-len\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type, requireExport/require-export-jsdoc, requireMemberAPI/require-member-api-doc\nexport interface Application extends PixiMixins.Application { }\n\n/**\n * Convenience class to create a new PixiJS application.\n *\n * The Application class is the main entry point for creating a PixiJS application. It handles the setup of all core\n * components needed to start rendering and managing your game or interactive experience.\n *\n * Key features:\n * - Automatically creates and manages the renderer\n * - Provides a stage (root container) for your display objects\n * - Handles canvas creation and management\n * - Supports plugins for extending functionality\n * - {@link ResizePlugin} for automatic resizing\n * - {@link TickerPlugin} for managing frame updates\n * - {@link CullerPlugin} for culling off-screen objects\n * @example\n * ```js\n * import { Assets, Application, Sprite } from 'pixi.js';\n *\n * // Create a new application\n * const app = new Application();\n *\n * // Initialize with options\n * await app.init({\n * width: 800, // Canvas width\n * height: 600, // Canvas height\n * backgroundColor: 0x1099bb, // Background color\n * antialias: true, // Enable antialiasing\n * resolution: 1, // Resolution / device pixel ratio\n * preference: 'webgl', // or 'webgpu' // Renderer preference\n * });\n *\n * // Add the canvas to your webpage\n * document.body.appendChild(app.canvas);\n *\n * // Start adding content to your application\n * const texture = await Assets.load('your-image.png');\n * const sprite = new Sprite(texture);\n * app.stage.addChild(sprite);\n * ```\n * > [!IMPORTANT] From PixiJS v8.0.0, the application must be initialized using the async `init()` method\n * > rather than passing options to the constructor.\n * @category app\n * @standard\n * @see {@link ApplicationOptions} For all available initialization options\n * @see {@link Container} For information about the stage container\n * @see {@link Renderer} For details about the rendering system\n */\nexport class Application<R extends Renderer = Renderer>\n{\n /**\n * Collection of installed plugins.\n * @internal\n */\n public static _plugins: ApplicationPlugin[] = [];\n\n /**\n * The root display container for your application.\n * All visual elements should be added to this container or its children.\n * @example\n * ```js\n * // Create a sprite and add it to the stage\n * const sprite = Sprite.from('image.png');\n * app.stage.addChild(sprite);\n *\n * // Create a container for grouping objects\n * const container = new Container();\n * app.stage.addChild(container);\n * ```\n */\n public stage: Container = new Container();\n\n /**\n * The renderer instance that handles all drawing operations.\n *\n * Unless specified, it will automatically create a WebGL renderer if available.\n * If WebGPU is available and the `preference` is set to `webgpu`, it will create a WebGPU renderer.\n * @example\n * ```js\n * // Create a new application\n * const app = new Application();\n * await app.init({\n * width: 800,\n * height: 600,\n * preference: 'webgl', // or 'webgpu'\n * });\n *\n * // Access renderer properties\n * console.log(app.renderer.width, app.renderer.height);\n * ```\n */\n public renderer: R;\n\n /** Create new Application instance */\n constructor();\n\n /** @deprecated since 8.0.0 */\n constructor(options?: Partial<ApplicationOptions>);\n\n constructor(...args: [Partial<ApplicationOptions>] | [])\n {\n // #if _DEBUG\n if (args[0] !== undefined)\n {\n deprecation(v8_0_0, 'Application constructor options are deprecated, please use Application.init() instead.');\n }\n // #endif\n }\n\n /**\n * Initializes the PixiJS application with the specified options.\n *\n * This method must be called after creating a new Application instance.\n * @param options - Configuration options for the application and renderer\n * @returns A promise that resolves when initialization is complete\n * @example\n * ```js\n * const app = new Application();\n *\n * // Initialize with custom options\n * await app.init({\n * width: 800,\n * height: 600,\n * backgroundColor: 0x1099bb,\n * preference: 'webgl', // or 'webgpu'\n * });\n * ```\n */\n public async init(options?: Partial<ApplicationOptions>)\n {\n // The default options\n options = { ...options };\n\n this.stage ||= new Container();\n this.renderer = await autoDetectRenderer(options as ApplicationOptions) as R;\n\n // install plugins here\n Application._plugins.forEach((plugin) =>\n {\n plugin.init.call(this, options);\n });\n }\n\n /**\n * Renders the current stage to the screen.\n *\n * When using the default setup with {@link TickerPlugin} (enabled by default), you typically don't need to call\n * this method directly as rendering is handled automatically.\n *\n * Only use this method if you've disabled the {@link TickerPlugin} or need custom\n * render timing control.\n * @example\n * ```js\n * // Example 1: Default setup (TickerPlugin handles rendering)\n * const app = new Application();\n * await app.init();\n * // No need to call render() - TickerPlugin handles it\n *\n * // Example 2: Custom rendering loop (if TickerPlugin is disabled)\n * const app = new Application();\n * await app.init({ autoStart: false }); // Disable automatic rendering\n *\n * function animate() {\n * app.render();\n * requestAnimationFrame(animate);\n * }\n * animate();\n * ```\n */\n public render(): void\n {\n this.renderer.render({ container: this.stage });\n }\n\n /**\n * Reference to the renderer's canvas element. This is the HTML element\n * that displays your application's graphics.\n * @readonly\n * @type {HTMLCanvasElement}\n * @example\n * ```js\n * // Create a new application\n * const app = new Application();\n * // Initialize the application\n * await app.init({...});\n * // Add canvas to the page\n * document.body.appendChild(app.canvas);\n *\n * // Access the canvas directly\n * console.log(app.canvas); // HTMLCanvasElement\n * ```\n */\n get canvas(): R['canvas']\n {\n return this.renderer.canvas as R['canvas'];\n }\n\n /**\n * Reference to the renderer's canvas element.\n * @type {HTMLCanvasElement}\n * @deprecated since 8.0.0\n * @see {@link Application#canvas}\n */\n get view(): R['canvas']\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'Application.view is deprecated, please use Application.canvas instead.');\n // #endif\n\n return this.renderer.canvas as R['canvas'];\n }\n\n /**\n * Reference to the renderer's screen rectangle. This represents the visible area of your application.\n *\n * It's commonly used for:\n * - Setting filter areas for full-screen effects\n * - Defining hit areas for screen-wide interaction\n * - Determining the visible bounds of your application\n * @readonly\n * @example\n * ```js\n * // Use as filter area for a full-screen effect\n * const blurFilter = new BlurFilter();\n * sprite.filterArea = app.screen;\n *\n * // Use as hit area for screen-wide interaction\n * const screenSprite = new Sprite();\n * screenSprite.hitArea = app.screen;\n *\n * // Get screen dimensions\n * console.log(app.screen.width, app.screen.height);\n * ```\n * @see {@link Rectangle} For all available properties and methods\n */\n get screen(): Rectangle\n {\n return this.renderer.screen;\n }\n\n /**\n * Get the html div element that holds all DOM Container elements.\n * @readonly\n * @type {HTMLDivElement}\n */\n get domContainerRoot()\n {\n return this.renderer.renderPipes.dom?._domElement;\n }\n\n /**\n * Destroys the application and all of its resources.\n *\n * This method should be called when you want to completely\n * clean up the application and free all associated memory.\n * @param rendererDestroyOptions - Options for destroying the renderer:\n * - `false` or `undefined`: Preserves the canvas element (default)\n * - `true`: Removes the canvas element\n * - `{ removeView: boolean }`: Object with removeView property to control canvas removal\n * @param options - Options for destroying the application:\n * - `false` or `undefined`: Basic cleanup (default)\n * - `true`: Complete cleanup including children\n * - Detailed options object:\n * - `children`: Remove children\n * - `texture`: Destroy textures\n * - `textureSource`: Destroy texture sources\n * - `context`: Destroy WebGL context\n * @example\n * ```js\n * // Basic cleanup\n * app.destroy();\n *\n * // Remove canvas and do complete cleanup\n * app.destroy(true, true);\n *\n * // Remove canvas with explicit options\n * app.destroy({ removeView: true }, true);\n *\n * // Detailed cleanup with specific options\n * app.destroy(\n * { removeView: true },\n * {\n * children: true,\n * texture: true,\n * textureSource: true,\n * context: true\n * }\n * );\n * ```\n * > [!WARNING] After calling destroy, the application instance should no longer be used.\n * > All properties will be null and further operations will throw errors.\n */\n public destroy(rendererDestroyOptions: RendererDestroyOptions = false, options: DestroyOptions = false): void\n {\n // Destroy plugins in the opposite order\n // which they were constructed\n const plugins = Application._plugins.slice(0);\n\n plugins.reverse();\n plugins.forEach((plugin) =>\n {\n plugin.destroy.call(this);\n });\n\n this.stage.destroy(options);\n this.stage = null;\n\n this.renderer.destroy(rendererDestroyOptions);\n this.renderer = null;\n }\n}\n\nextensions.handleByList(ExtensionType.Application, Application._plugins);\nextensions.add(ApplicationInitHook);\n","import { type ICanvas } from '../../../environment/canvas/ICanvas';\nimport { type Filter } from '../../../filters/Filter';\nimport { TexturePool } from '../../../rendering/renderers/shared/texture/TexturePool';\nimport { deprecation } from '../../../utils/logging/deprecation';\nimport { CanvasTextGenerator } from '../canvas/CanvasTextGenerator';\nimport { type CanvasTextOptions, type Text } from '../Text';\nimport { TextStyle } from '../TextStyle';\nimport { getPo2TextureFromSource } from '../utils/getPo2TextureFromSource';\n\nimport type { System } from '../../../rendering/renderers/shared/system/System';\nimport type { Texture } from '../../../rendering/renderers/shared/texture/Texture';\nimport type { Renderer } from '../../../rendering/renderers/types';\n\n/**\n * Base system plugin to the renderer to manage canvas text.\n * @category rendering\n * @advanced\n */\nexport abstract class AbstractTextSystem implements System\n{\n protected readonly _renderer: Renderer;\n private readonly _retainCanvasContext: boolean;\n\n private readonly _activeTextures: Record<string, {\n texture: Texture,\n usageCount: number,\n }> = {};\n\n constructor(renderer: Renderer, retainCanvasContext: boolean)\n {\n this._renderer = renderer;\n this._retainCanvasContext = retainCanvasContext;\n }\n\n /** @deprecated since 8.0.0 */\n public getTexture(text: string, resolution: number, style: TextStyle, textKey: string): Texture;\n /**\n * This is a function that will create a texture from a text string, style and resolution.\n * Useful if you want to make a texture of your text and use if for various pixi things!\n * @param options - The options of the text that will be used to generate the texture.\n * @param options.text - the text to render\n * @param options.style - the style of the text\n * @param options.resolution - the resolution of the texture\n * @returns the newly created texture\n */\n public getTexture(options: CanvasTextOptions): Texture;\n public getTexture(\n options: CanvasTextOptions | string,\n _resolution?: number,\n _style?: TextStyle,\n _textKey?: string\n ): Texture\n {\n if (typeof options === 'string')\n {\n // #if _DEBUG\n deprecation('8.0.0', 'CanvasTextSystem.getTexture: Use object TextOptions instead of separate arguments');\n // #endif\n\n options = {\n text: options,\n style: _style,\n resolution: _resolution,\n };\n }\n\n if (!(options.style instanceof TextStyle))\n {\n options.style = new TextStyle(options.style);\n }\n\n if (typeof options.text !== 'string')\n {\n options.text = options.text.toString();\n }\n\n const { text, style, textureStyle, autoGenerateMipmaps } = options;\n\n const resolution = options.resolution ?? this._renderer.resolution;\n\n const { frame, canvasAndContext } = CanvasTextGenerator.getCanvasAndContext({\n text: text as string,\n style: style as TextStyle,\n resolution,\n });\n\n const texture = getPo2TextureFromSource(\n canvasAndContext.canvas,\n frame.width,\n frame.height,\n resolution,\n autoGenerateMipmaps,\n textureStyle?.scaleMode\n );\n\n if (style.trim)\n {\n // reapply the padding to the frame\n frame.pad(style.padding);\n texture.frame.copyFrom(frame);\n\n // We initially increased the frame size by a resolution factor to achieve a crisper display.\n // Now we need to scale down the already trimmed frame to render the texture in the expected size.\n texture.frame.scale(1 / resolution);\n texture.updateUvs();\n }\n\n if (style.filters)\n {\n // apply the filters to the texture if required..\n // this returns a new texture with the filters applied\n const filteredTexture = this._applyFilters(texture, style.filters as Filter[]);\n\n // return the original texture to the pool so we can reuse the next frame\n this.returnTexture(texture);\n\n CanvasTextGenerator.returnCanvasAndContext(canvasAndContext);\n\n // return the new texture with the filters applied\n return filteredTexture;\n }\n\n this._renderer.texture.initSource(texture._source);\n\n if (!this._retainCanvasContext)\n {\n CanvasTextGenerator.returnCanvasAndContext(canvasAndContext);\n }\n\n return texture;\n }\n\n /**\n * Returns a texture that was created wit the above `getTexture` function.\n * Handy if you are done with a texture and want to return it to the pool.\n * @param texture - The texture to be returned.\n */\n public returnTexture(texture: Texture)\n {\n const source = texture.source;\n const resource = source.resource as ICanvas | null;\n\n if (this._retainCanvasContext && resource?.getContext)\n {\n const context = resource.getContext('2d');\n\n if (context)\n {\n CanvasTextGenerator.returnCanvasAndContext({ canvas: resource, context });\n }\n }\n\n source.resource = null;\n source.uploadMethodId = 'unknown';\n source.alphaMode = 'no-premultiply-alpha';\n\n TexturePool.returnTexture(texture);\n }\n\n /**\n * Renders text to its canvas, and updates its texture.\n * @deprecated since 8.10.0\n */\n public renderTextToCanvas(): void\n {\n // #if _DEBUG\n deprecation(\n '8.10.0',\n 'CanvasTextSystem.renderTextToCanvas: no longer supported, use CanvasTextSystem.getTexture instead'\n );\n // #endif\n }\n\n /**\n * Gets or creates a managed texture for a Text object. This method handles texture reuse and reference counting.\n * @param text - The Text object that needs a texture\n * @returns A Texture instance that represents the rendered text\n * @remarks\n * This method performs the following:\n * 1. Sets the appropriate resolution based on auto-resolution settings\n * 2. Checks if a texture already exists for the text's style\n * 3. Creates a new texture if needed or returns an existing one\n * 4. Manages reference counting for texture reuse\n */\n public getManagedTexture(text: Text)\n {\n text._resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n const textKey = text.styleKey;\n\n if (this._activeTextures[textKey])\n {\n this._increaseReferenceCount(textKey);\n\n return this._activeTextures[textKey].texture;\n }\n\n const texture = this.getTexture({\n text: text.text,\n style: text.style,\n resolution: text._resolution,\n textureStyle: text.textureStyle,\n autoGenerateMipmaps: text.autoGenerateMipmaps,\n });\n\n this._activeTextures[textKey] = {\n texture,\n usageCount: 1,\n };\n\n return texture;\n }\n\n /**\n * Decreases the reference count for a texture associated with a text key.\n * When the reference count reaches zero, the texture is returned to the pool.\n * @param textKey - The unique key identifying the text style configuration\n * @remarks\n * This method is crucial for memory management, ensuring textures are properly\n * cleaned up when they are no longer needed by any Text instances.\n */\n public decreaseReferenceCount(textKey: string)\n {\n const activeTexture = this._activeTextures[textKey];\n\n if (!activeTexture) return;\n\n activeTexture.usageCount--;\n\n if (activeTexture.usageCount === 0)\n {\n this.returnTexture(activeTexture.texture);\n this._activeTextures[textKey] = null;\n }\n }\n\n /**\n * Gets the current reference count for a texture associated with a text key.\n * @param textKey - The unique key identifying the text style configuration\n * @returns The number of Text instances currently using this texture\n */\n public getReferenceCount(textKey: string)\n {\n return this._activeTextures[textKey]?.usageCount ?? 0;\n }\n\n private _increaseReferenceCount(textKey: string)\n {\n this._activeTextures[textKey].usageCount++;\n }\n\n /**\n * Applies the specified filters to the given texture.\n *\n * This method takes a texture and a list of filters, applies the filters to the texture,\n * and returns the resulting texture. It also ensures that the alpha mode of the resulting\n * texture is set to 'premultiplied-alpha'.\n * @param {Texture} texture - The texture to which the filters will be applied.\n * @param {Filter[]} filters - The filters to apply to the texture.\n * @returns {Texture} The resulting texture after all filters have been applied.\n */\n private _applyFilters(texture: Texture, filters: Filter[]): Texture\n {\n // Save the current render target so it can be restored later\n const currentRenderTarget = this._renderer.renderTarget.renderTarget;\n\n // Apply the filters to the texture and get the resulting texture\n const resultTexture = this._renderer.filter.generateFilteredTexture({\n texture,\n filters,\n });\n\n // Restore the previous render target\n this._renderer.renderTarget.bind({ target: currentRenderTarget, clear: false });\n\n // Return the resulting texture with the filters applied\n return resultTexture;\n }\n\n public destroy(): void\n {\n (this._renderer as null) = null;\n // Clean up active textures\n for (const key in this._activeTextures)\n {\n if (this._activeTextures[key]) this.returnTexture(this._activeTextures[key].texture);\n }\n (this._activeTextures as null) = null;\n }\n}\n","import { TextureSource } from '../../rendering/renderers/shared/texture/sources/TextureSource';\nimport { TextureStyle, type TextureStyleOptions } from '../../rendering/renderers/shared/texture/TextureStyle';\nimport { AbstractText, ensureTextOptions } from './AbstractText';\nimport { type BatchableText } from './canvas/BatchableText';\nimport { CanvasTextGenerator } from './canvas/CanvasTextGenerator';\nimport { CanvasTextMetrics } from './canvas/CanvasTextMetrics';\nimport { TextStyle } from './TextStyle';\nimport { warnIgnoredTextureStyle } from './utils/warnIgnoredTextureStyle';\nimport './init';\n\nimport type { View } from '../../rendering/renderers/shared/view/View';\nimport type { TextOptions, TextString } from './AbstractText';\nimport type { TextStyleOptions } from './TextStyle';\n\n// eslint-disable-next-line requireExport/require-export-jsdoc, requireMemberAPI/require-member-api-doc\nexport interface Text extends PixiMixins.Text, AbstractText<\n TextStyle,\n TextStyleOptions,\n CanvasTextOptions,\n BatchableText\n> {}\n\n/**\n * Constructor options used for `Text` instances. These options extend TextOptions with\n * canvas-specific features like texture styling.\n * @example\n * ```ts\n * // Create basic canvas text\n * const text = new Text({\n * text: 'Hello Pixi!',\n * style: {\n * fontSize: 24,\n * fill: 0xff1010,\n * }\n * });\n *\n * // Create text with custom texture style\n * const customText = new Text({\n * text: 'Custom Text',\n * style: {\n * fontSize: 32,\n * fill: 0x4a4a4a\n * },\n * textureStyle: {\n * scaleMode: 'nearest',\n * }\n * });\n * ```\n * @extends TextOptions\n * @category text\n * @standard\n */\nexport interface CanvasTextOptions extends TextOptions\n{\n /**\n * Optional texture style for the text texture. Only `scaleMode` is read (`nearest` or `linear`):\n * the text gets a pooled texture with that scale mode. Every other field is ignored.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Crisp Text',\n * textureStyle: {\n * scaleMode: 'nearest', // Pixel-perfect scaling\n * }\n * });\n * ```\n * @advanced\n */\n textureStyle?: TextureStyle | TextureStyleOptions;\n /**\n * Whether to generate mipmaps for the text texture.\n * Improves rendering quality when the text is scaled down.\n * @default undefined - Falls back to TextureSource.defaultOptions.autoGenerateMipmaps\n */\n autoGenerateMipmaps?: boolean;\n}\n\n/**\n * A powerful text rendering class that creates one or multiple lines of text using the Canvas API.\n * Provides rich text styling capabilities with runtime modifications.\n *\n * Key features:\n * - Dynamic text content and styling\n * - Multi-line text support\n * - Word wrapping\n * - Custom texture styling\n * - High-quality text rendering\n * @example\n * ```ts\n * import { Text } from 'pixi.js';\n *\n * // Basic text creation\n * const basicText = new Text({\n * text: 'Hello Pixi!',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * }\n * });\n *\n * // Rich text with multiple styles\n * const richText = new Text({\n * text: 'Styled\\nMultiline\\nText',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 36,\n * fill: 'red',\n * stroke: { color: '#4a1850', width: 5 },\n * align: 'center',\n * lineHeight: 45,\n * dropShadow: {\n * color: '#000000',\n * blur: 4,\n * distance: 6,\n * }\n * },\n * anchor: 0.5,\n * });\n *\n * // Text with custom texture settings\n * const crispText = new Text({\n * text: 'High Quality Text',\n * style: {\n * fontSize: 24,\n * fill: 0x4a4a4a,\n * },\n * textureStyle: {\n * scaleMode: 'nearest',\n * }\n * });\n *\n * // Word-wrapped text\n * const wrappedText = new Text({\n * text: 'This is a long piece of text that will automatically wrap to multiple lines',\n * style: {\n * fontSize: 20,\n * wordWrap: true,\n * wordWrapWidth: 200,\n * lineHeight: 30,\n * }\n * });\n * ```\n *\n * Performance Considerations:\n * - Each text instance creates its own texture\n * - Texture is regenerated when text or style changes\n * - Use BitmapText for better performance with static text\n * - Consider texture style options for quality vs performance tradeoffs\n * @category text\n * @standard\n * @see {@link TextStyle} For detailed style options\n * @see {@link BitmapText} For better performance with static text\n * @see {@link HTMLText} For HTML/CSS-based text rendering\n */\nexport class Text\n extends AbstractText<TextStyle, TextStyleOptions, CanvasTextOptions, BatchableText>\n implements View\n{\n /** @internal */\n public override readonly renderPipeId: string = 'text';\n\n /**\n * Optional texture style to use for the text. Only `scaleMode` is read, when a new texture is\n * generated for the text (a text, style or resolution change).\n * @advanced\n */\n public textureStyle?: TextureStyle;\n\n /**\n * Whether to generate mipmaps for the text texture.\n * Improves rendering quality when the text is scaled down.\n * > [!NOTE] Text is not updated when this property is updated,\n * > you must update the text manually by calling `text.onViewUpdate()`\n * @default undefined - Falls back to TextureSource.defaultOptions.autoGenerateMipmaps\n */\n public autoGenerateMipmaps?: boolean;\n\n /**\n * @param {CanvasTextOptions} options - The options of the text.\n */\n constructor(options?: CanvasTextOptions);\n /** @deprecated since 8.0.0 */\n constructor(text?: TextString, options?: Partial<TextStyle>);\n constructor(...args: [CanvasTextOptions?] | [TextString, Partial<TextStyle>])\n {\n const options = ensureTextOptions<CanvasTextOptions>(args, 'Text');\n\n super(options, TextStyle);\n\n if (options.textureStyle)\n {\n this.textureStyle = options.textureStyle instanceof TextureStyle\n ? options.textureStyle\n : new TextureStyle(options.textureStyle);\n\n warnIgnoredTextureStyle(this.textureStyle);\n }\n\n this.autoGenerateMipmaps = options.autoGenerateMipmaps ?? TextureSource.defaultOptions.autoGenerateMipmaps;\n }\n\n /** @private */\n protected updateBounds()\n {\n const bounds = this._bounds;\n const anchor = this._anchor;\n\n let width = 0;\n let height = 0;\n\n if (this._style.trim)\n {\n const { frame, canvasAndContext } = CanvasTextGenerator.getCanvasAndContext({\n text: this.text,\n style: this._style,\n resolution: 1,\n });\n\n CanvasTextGenerator.returnCanvasAndContext(canvasAndContext);\n\n width = frame.width;\n height = frame.height;\n }\n else\n {\n const canvasMeasurement = CanvasTextMetrics.measureText(\n this._text,\n this._style\n );\n\n width = canvasMeasurement.width;\n height = canvasMeasurement.height;\n }\n\n bounds.minX = (-anchor._x * width);\n bounds.maxX = bounds.minX + width;\n bounds.minY = (-anchor._y * height);\n bounds.maxY = bounds.minY + height;\n }\n}\n","import { Color } from '../../../../color/Color';\nimport { Matrix } from '../../../../maths/matrix/Matrix';\nimport { canvasUtils } from '../../../../rendering/renderers/canvas/utils/canvasUtils';\nimport { Texture } from '../../../../rendering/renderers/shared/texture/Texture';\nimport { warn } from '../../../../utils/logging/warn';\nimport { FillGradient } from '../../../graphics/shared/fill/FillGradient';\nimport { FillPattern } from '../../../graphics/shared/fill/FillPattern';\n\nimport type { ICanvasRenderingContext2D } from '../../../../environment/canvas/ICanvasRenderingContext2D';\nimport type { ConvertedFillStyle } from '../../../graphics/shared/FillTypes';\nimport type { CanvasTextMetrics } from '../CanvasTextMetrics';\n\n// 5 decimal places\nconst PRECISION = 100000;\n\n/**\n * Converts a PixiJS fill style into a Canvas-compatible fill style.\n * Handles solid colors, textures, patterns, and gradients.\n * @param fillStyle - The PixiJS fill style to convert\n * @param context - The canvas rendering context\n * @param textMetrics - Metrics about the text being rendered\n * @param padding - Padding to add to the text metrics (used to ensure that the gradient accommodates the stroke width)\n * @param offsetX - X offset for gradient positioning (used for tagged text runs)\n * @param offsetY - Y offset for gradient positioning (used for tagged text runs)\n * @returns Canvas-compatible fill style (string, CanvasGradient, or CanvasPattern)\n * @internal\n */\nexport function getCanvasFillStyle(\n fillStyle: ConvertedFillStyle,\n context: ICanvasRenderingContext2D,\n textMetrics?: CanvasTextMetrics,\n padding = 0,\n offsetX = 0,\n offsetY = 0\n): string | CanvasGradient | CanvasPattern\n{\n // Solid color fill\n if (fillStyle.texture === Texture.WHITE && !fillStyle.fill)\n {\n return Color.shared.setValue(fillStyle.color).setAlpha(fillStyle.alpha ?? 1).toHexa();\n }\n // Basic texture fill\n else if (!fillStyle.fill)\n {\n const pattern = context.createPattern(fillStyle.texture.source.resource, 'repeat');\n const tempMatrix = fillStyle.matrix.copyTo(Matrix.shared);\n\n tempMatrix.scale(fillStyle.texture.source.pixelWidth, fillStyle.texture.source.pixelHeight);\n pattern.setTransform(tempMatrix);\n\n return pattern;\n }\n // Pattern fill\n else if (fillStyle.fill instanceof FillPattern)\n {\n const fillPattern = fillStyle.fill;\n const pattern = context.createPattern(fillPattern.texture.source.resource, 'repeat');\n\n canvasUtils.applyPatternTransform(pattern, fillPattern.transform, false);\n\n return pattern;\n }\n // Gradient fill\n else if (fillStyle.fill instanceof FillGradient)\n {\n const fillGradient = fillStyle.fill;\n\n const isLinear = fillGradient.type === 'linear';\n const isLocal = fillGradient.textureSpace === 'local';\n\n let width = 1;\n let height = 1;\n\n // Use text dimensions if in local space\n if (isLocal && textMetrics)\n {\n width = textMetrics.width + padding;\n height = textMetrics.height + padding;\n }\n\n let gradient: CanvasGradient;\n let isNearlyVertical = false;\n\n if (isLinear)\n {\n const { start, end } = fillGradient;\n\n gradient = context.createLinearGradient(\n (start.x * width) + offsetX,\n (start.y * height) + offsetY,\n (end.x * width) + offsetX,\n (end.y * height) + offsetY\n );\n\n // Check if gradient is nearly vertical (10% threshold)\n isNearlyVertical = Math.abs(end.x - start.x) < Math.abs((end.y - start.y) * 0.1);\n }\n else\n {\n const { center, innerRadius, outerCenter, outerRadius } = fillGradient;\n\n gradient = context.createRadialGradient(\n (center.x * width) + offsetX,\n (center.y * height) + offsetY,\n innerRadius * width,\n (outerCenter.x * width) + offsetX,\n (outerCenter.y * height) + offsetY,\n outerRadius * width\n );\n }\n\n // For vertical gradients in local space, repeat gradient per text line\n if (isNearlyVertical && isLocal && textMetrics)\n {\n const ratio = (textMetrics.lineHeight) / height;\n\n for (let i = 0; i < textMetrics.lines.length; i++)\n {\n const start = ((i * textMetrics.lineHeight) + (padding / 2)) / height;\n\n fillGradient.colorStops.forEach((stop) =>\n {\n // Convert to global space\n let globalStop = start + (stop.offset * ratio);\n\n globalStop = Math.max(0, Math.min(1, globalStop));\n\n gradient.addColorStop(\n // fix to 5 decimal places to avoid floating point precision issues\n Math.floor(globalStop * PRECISION) / PRECISION,\n Color.shared.setValue(stop.color).toHex()\n );\n });\n }\n }\n else\n {\n // Standard global space gradient handling\n fillGradient.colorStops.forEach((stop) =>\n {\n gradient.addColorStop(stop.offset, Color.shared.setValue(stop.color).toHex());\n });\n }\n\n return gradient;\n }\n\n // #if _DEBUG\n warn('FillStyle not recognised', fillStyle);\n // #endif\n\n return 'red';\n}\n","import { Color } from '../../../color/Color';\nimport { Rectangle } from '../../../maths/shapes/Rectangle';\nimport { type CanvasAndContext, CanvasPool } from '../../../rendering/renderers/shared/texture/CanvasPool';\nimport { getCanvasBoundingBox } from '../../../utils/canvas/getCanvasBoundingBox';\nimport { type TextStyle } from '../TextStyle';\nimport { CanvasTextMetrics } from './CanvasTextMetrics';\nimport { fontStringFromTextStyle } from './utils/fontStringFromTextStyle';\nimport { getCanvasFillStyle } from './utils/getCanvasFillStyle';\n\n/**\n * Temporary rectangle for getting the bounding box of the text.\n * @internal\n */\nconst tempRect = new Rectangle();\n\nfunction countSpaces(text: string): number\n{\n let count = 0;\n\n for (let i = 0; i < text.length; i++)\n {\n if (text.charCodeAt(i) === 32) count++;\n }\n\n return count;\n}\n\n/**\n * Utility for generating and managing canvas-based text rendering.\n *\n * This class is responsible for rendering text to canvas elements based on provided styles,\n * measuring the resulting text dimensions, and managing the lifecycle of canvas resources.\n *\n * CanvasTextGenerator supports:\n * - Text rendering with various styles (fill, stroke, gradient, etc.)\n * - Drop shadows and letter spacing\n * - Automatic trimming of transparent pixels\n * - Canvas resource pooling\n *\n * As a singleton, it's accessed via the exported `CanvasTextGenerator` constant.\n * @example\n * ```typescript\n * // Basic usage - render text to a canvas\n * import { CanvasTextGenerator } from 'pixi.js';\n * import { TextStyle } from 'pixi.js';\n *\n * // Create a text style\n * const style = new TextStyle({\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * });\n *\n * // Get a canvas with the text rendered to it\n * const { canvasAndContext, frame } = CanvasTextGenerator.getCanvasAndContext({\n * text: 'Hello Pixi!',\n * style,\n * resolution: 1\n * });\n *\n * @internal\n */\nclass CanvasTextGeneratorClass\n{\n /**\n * Creates a canvas with the specified text rendered to it.\n *\n * Generates a canvas of appropriate size, renders the text with the provided style,\n * and returns both the canvas/context and a Rectangle representing the text bounds.\n *\n * When trim is enabled in the style, the frame will represent the bounds of the\n * non-transparent pixels, which can be smaller than the full canvas.\n * @param options - The options for generating the text canvas\n * @param options.text - The text to render\n * @param options.style - The style to apply to the text\n * @param options.resolution - The resolution of the canvas (defaults to 1)\n * @param options.padding\n * @returns An object containing the canvas/context and the frame (bounds) of the text\n */\n public getCanvasAndContext(options: {text: string, style: TextStyle, resolution?: number, padding?: number})\n {\n const { text, style, resolution = 1 } = options;\n\n const padding = (style as TextStyle)._getFinalPadding();\n\n // create a canvas with the word hello on it\n const measured = CanvasTextMetrics.measureText(text || ' ', style);\n\n const width = Math.ceil(Math.ceil((Math.max(1, measured.width) + (padding * 2))) * resolution);\n const height = Math.ceil(Math.ceil((Math.max(1, measured.height) + (padding * 2))) * resolution);\n\n const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(width, height);\n\n this._renderTextToCanvas(style, padding, resolution, canvasAndContext, measured);\n\n const frame = style.trim\n ? getCanvasBoundingBox({ canvas: canvasAndContext.canvas, width, height, resolution: 1, output: tempRect })\n : tempRect.set(0, 0, width, height);\n\n return {\n canvasAndContext,\n frame\n };\n }\n\n /**\n * Returns a canvas and context to the pool.\n *\n * This should be called when you're done with the canvas to allow reuse\n * and prevent memory leaks.\n * @param canvasAndContext - The canvas and context to return to the pool\n */\n public returnCanvasAndContext(canvasAndContext: CanvasAndContext): void\n {\n CanvasPool.returnCanvasAndContext(canvasAndContext);\n }\n\n /**\n * Renders text to its canvas, and updates its texture.\n * @param style - The style of the text\n * @param padding - The padding of the text\n * @param resolution - The resolution of the text\n * @param canvasAndContext - The canvas and context to render the text to\n * @param measured - Pre-measured text metrics to avoid duplicate measurement\n */\n private _renderTextToCanvas(\n style: TextStyle,\n padding: number,\n resolution: number,\n canvasAndContext: CanvasAndContext,\n measured: CanvasTextMetrics\n ): void\n {\n // Check if we have tagged text data\n if (measured.runsByLine && measured.runsByLine.length > 0)\n {\n this._renderTaggedTextToCanvas(measured, style, padding, resolution, canvasAndContext);\n\n return;\n }\n\n const { canvas, context } = canvasAndContext as { canvas: HTMLCanvasElement, context: CanvasRenderingContext2D };\n\n const font = fontStringFromTextStyle(style);\n\n const lines = measured.lines;\n const lineHeight = measured.lineHeight;\n const lineWidths = measured.lineWidths;\n const maxLineWidth = measured.maxLineWidth;\n const fontProperties = measured.fontProperties;\n\n const height = canvas.height;\n\n context.resetTransform();\n context.scale(resolution, resolution);\n context.textBaseline = style.textBaseline;\n\n // set stroke styles..\n\n if (style._stroke?.width)\n {\n const strokeStyle = style._stroke;\n\n context.lineWidth = strokeStyle.width;\n\n context.miterLimit = strokeStyle.miterLimit;\n context.lineJoin = strokeStyle.join;\n context.lineCap = strokeStyle.cap;\n }\n\n // return;\n context.font = font;\n\n let linePositionX: number;\n let linePositionY: number;\n\n // require 2 passes if a shadow; the first to draw the drop shadow, the second to draw the text\n const passesCount = style.dropShadow ? 2 : 1;\n\n // For v4, we drew text at the colours of the drop shadow underneath the normal text. This gave the correct zIndex,\n // but features such as alpha and shadowblur did not look right at all, since we were using actual text as a shadow.\n //\n // For v5.0.0, we moved over to just use the canvas API for drop shadows, which made them look much nicer and more\n // visually please, but now because the stroke is drawn and then the fill, drop shadows would appear on both the fill\n // and the stroke; and fill drop shadows would appear over the top of the stroke.\n //\n // For v5.1.1, the new route is to revert to v4 style of drawing text first to get the drop shadows underneath normal\n // text, but instead drawing text in the correct location, we'll draw it off screen (-paddingY), and then adjust the\n // drop shadow so only that appears on screen (+paddingY). Now we'll have the correct draw order of the shadow\n // beneath the text, whilst also having the proper text shadow styling.\n const strokeWidth = style._stroke?.width ?? 0;\n const halfStroke = strokeWidth / 2;\n\n let linePositionYShift = (lineHeight - fontProperties.fontSize) / 2;\n\n if (lineHeight - fontProperties.fontSize < 0)\n {\n linePositionYShift = 0;\n }\n\n for (let i = 0; i < passesCount; ++i)\n {\n const isShadowPass = style.dropShadow && i === 0;\n // we only want the drop shadow, so put text way off-screen\n const dsOffsetText = isShadowPass ? Math.ceil(Math.max(1, height) + (padding * 2)) : 0;\n const dsOffsetShadow = dsOffsetText * resolution;\n\n if (isShadowPass)\n {\n this._setupDropShadow(context, style, resolution, dsOffsetShadow);\n }\n else\n {\n // When gradient bounds are set (e.g., from SplitText), use them for gradient calculation\n const gradientBounds = style._gradientBounds;\n const gradientOffset = style._gradientOffset;\n\n if (gradientBounds)\n {\n const gradientMetrics = {\n width: gradientBounds.width,\n height: gradientBounds.height,\n lineHeight: gradientBounds.height,\n lines: measured.lines,\n } as CanvasTextMetrics;\n\n this._setFillAndStrokeStyles(\n context, style, gradientMetrics, padding, halfStroke,\n gradientOffset?.x ?? 0, gradientOffset?.y ?? 0\n );\n }\n else if (gradientOffset)\n {\n this._setFillAndStrokeStyles(\n context, style, measured, padding, halfStroke,\n gradientOffset.x, gradientOffset.y\n );\n }\n else\n {\n this._setFillAndStrokeStyles(context, style, measured, padding, halfStroke);\n }\n\n context.shadowColor = 'rgba(0,0,0,0)';\n }\n\n // draw lines line by line\n for (let j = 0; j < lines.length; j++)\n {\n linePositionX = halfStroke;\n linePositionY = (halfStroke + (j * lineHeight)) + fontProperties.ascent + linePositionYShift;\n\n linePositionX += this._getAlignmentOffset(lineWidths[j], maxLineWidth, style.align);\n\n let wordSpacing = 0;\n\n if (style.align === 'justify' && style.wordWrap && j < lines.length - 1)\n {\n const spaces = countSpaces(lines[j]);\n\n if (spaces > 0)\n {\n wordSpacing = (maxLineWidth - lineWidths[j]) / spaces;\n }\n }\n\n if (style._stroke?.width)\n {\n this._drawLetterSpacing(\n lines[j],\n style,\n canvasAndContext,\n linePositionX + padding,\n linePositionY + padding - dsOffsetText,\n true,\n wordSpacing\n );\n }\n\n if (style._fill !== undefined)\n {\n this._drawLetterSpacing(\n lines[j],\n style,\n canvasAndContext,\n linePositionX + padding,\n linePositionY + padding - dsOffsetText,\n false,\n wordSpacing\n );\n }\n }\n }\n }\n\n /**\n * Renders tagged text (with per-run styles) to canvas.\n * @param measured - The measured text metrics containing runsByLine\n * @param style - The base text style\n * @param padding - The padding of the text\n * @param resolution - The resolution of the text\n * @param canvasAndContext - The canvas and context to render to\n */\n private _renderTaggedTextToCanvas(\n measured: CanvasTextMetrics,\n style: TextStyle,\n padding: number,\n resolution: number,\n canvasAndContext: CanvasAndContext\n ): void\n {\n const { canvas, context } = canvasAndContext;\n const { runsByLine, lineWidths, maxLineWidth, lineAscents, lineHeights, hasDropShadow } = measured;\n\n const height = canvas.height;\n\n context.resetTransform();\n context.scale(resolution, resolution);\n context.textBaseline = style.textBaseline;\n\n // require 2 passes if a shadow; the first to draw the drop shadow, the second to draw the text\n const passesCount = hasDropShadow ? 2 : 1;\n\n let maxStrokeWidth = style._stroke?.width ?? 0;\n\n for (const lineRuns of runsByLine)\n {\n for (const run of lineRuns)\n {\n const w = run.style._stroke?.width ?? 0;\n\n if (w > maxStrokeWidth) maxStrokeWidth = w;\n }\n }\n const halfStroke = maxStrokeWidth / 2;\n\n // Pre-calculate run widths and font strings to avoid redundant computation per pass\n const runDataByLine: Array<Array<{ width: number; font: string }>> = [];\n\n for (let lineIndex = 0; lineIndex < runsByLine.length; lineIndex++)\n {\n const lineRuns = runsByLine[lineIndex];\n const runData: Array<{ width: number; font: string }> = [];\n\n for (const run of lineRuns)\n {\n const font = fontStringFromTextStyle(run.style);\n\n context.font = font;\n runData.push({\n width: CanvasTextMetrics._measureText(run.text, run.style.letterSpacing, context),\n font,\n });\n }\n runDataByLine.push(runData);\n }\n\n for (let pass = 0; pass < passesCount; ++pass)\n {\n const isShadowPass = hasDropShadow && pass === 0;\n const dsOffsetText = isShadowPass ? Math.ceil(Math.max(1, height) + (padding * 2)) : 0;\n const dsOffsetShadow = dsOffsetText * resolution;\n\n if (!isShadowPass)\n {\n context.shadowColor = 'rgba(0,0,0,0)';\n }\n\n let currentY = halfStroke;\n\n // Draw lines\n for (let lineIndex = 0; lineIndex < runsByLine.length; lineIndex++)\n {\n const lineRuns = runsByLine[lineIndex];\n const lineWidth = lineWidths[lineIndex];\n const lineAscent = lineAscents[lineIndex];\n const currentLineHeight = lineHeights[lineIndex];\n const lineRunData = runDataByLine[lineIndex];\n\n // Calculate line X position based on alignment\n let linePositionX = halfStroke;\n\n linePositionX += this._getAlignmentOffset(lineWidth, maxLineWidth, style.align);\n\n let wordSpacing = 0;\n\n if (style.align === 'justify' && style.wordWrap && lineIndex < runsByLine.length - 1)\n {\n let totalSpaces = 0;\n\n for (const run of lineRuns)\n {\n totalSpaces += countSpaces(run.text);\n }\n\n if (totalSpaces > 0)\n {\n wordSpacing = (maxLineWidth - lineWidth) / totalSpaces;\n }\n }\n\n // Calculate Y position - use line ascent for proper baseline\n const linePositionY = currentY + lineAscent;\n\n // Track X position for runs\n let runX = linePositionX + padding;\n\n // First pass: draw strokes for all runs\n for (let runIndex = 0; runIndex < lineRuns.length; runIndex++)\n {\n const run = lineRuns[runIndex];\n const { width: runWidth, font: runFont } = lineRunData[runIndex];\n\n context.font = runFont;\n context.textBaseline = run.style.textBaseline;\n\n // Set stroke style for this run\n if (run.style._stroke?.width)\n {\n const runStroke = run.style._stroke;\n\n // Always set stroke properties (both passes need correct lineWidth)\n context.lineWidth = runStroke.width;\n context.miterLimit = runStroke.miterLimit;\n context.lineJoin = runStroke.join;\n context.lineCap = runStroke.cap;\n\n if (isShadowPass)\n {\n // Set up drop shadow for this specific run\n if (run.style.dropShadow)\n {\n this._setupDropShadow(\n context as CanvasRenderingContext2D,\n run.style,\n resolution,\n dsOffsetShadow\n );\n }\n else\n {\n // No shadow for this run, skip drawing\n const spacesSkipped = countSpaces(run.text);\n\n runX += runWidth + (spacesSkipped * wordSpacing);\n continue;\n }\n }\n else\n {\n // Create per-run metrics for gradient calculation\n // Use run's font metrics for height to match non-tagged text behavior\n const runFontProps = CanvasTextMetrics.measureFont(runFont);\n const runHeight = run.style.lineHeight || runFontProps.fontSize;\n\n const runMetrics = {\n width: runWidth,\n height: runHeight,\n lineHeight: runHeight,\n lines: [run.text],\n } as CanvasTextMetrics;\n\n // Pass position offsets so gradient aligns with where the run is drawn\n // Subtract padding from runX because runX already includes padding,\n // but regular text rendering has gradient at origin with text at +padding\n context.strokeStyle = getCanvasFillStyle(\n runStroke, context, runMetrics, padding * 2, runX - padding, currentY\n );\n }\n\n this._drawLetterSpacing(\n run.text,\n run.style,\n canvasAndContext,\n runX,\n linePositionY + padding - dsOffsetText,\n true,\n wordSpacing\n );\n }\n\n const spacesInRun = countSpaces(run.text);\n\n runX += runWidth + (spacesInRun * wordSpacing);\n }\n\n // Reset X position for fill pass\n runX = linePositionX + padding;\n\n // Second pass: draw fills for all runs\n for (let runIndex = 0; runIndex < lineRuns.length; runIndex++)\n {\n const run = lineRuns[runIndex];\n const { width: runWidth, font: runFont } = lineRunData[runIndex];\n\n context.font = runFont;\n context.textBaseline = run.style.textBaseline;\n\n // Set fill style for this run if not shadow pass\n if (run.style._fill !== undefined)\n {\n if (isShadowPass)\n {\n // Set up drop shadow for this specific run\n if (run.style.dropShadow)\n {\n this._setupDropShadow(\n context as CanvasRenderingContext2D,\n run.style,\n resolution,\n dsOffsetShadow\n );\n }\n else\n {\n // No shadow for this run, skip drawing\n const spacesSkipped = countSpaces(run.text);\n\n runX += runWidth + (spacesSkipped * wordSpacing);\n continue;\n }\n }\n else\n {\n // Create per-run metrics for gradient calculation\n // Use run's font metrics for height to match non-tagged text behavior\n const runFontProps = CanvasTextMetrics.measureFont(runFont);\n const runHeight = run.style.lineHeight || runFontProps.fontSize;\n\n const runMetrics = {\n width: runWidth,\n height: runHeight,\n lineHeight: runHeight,\n lines: [run.text],\n } as CanvasTextMetrics;\n\n // Pass position offsets so gradient aligns with where the run is drawn\n // Subtract padding from runX because runX already includes padding,\n // but regular text rendering has gradient at origin with text at +padding\n context.fillStyle = getCanvasFillStyle(\n run.style._fill, context, runMetrics, padding * 2, runX - padding, currentY\n );\n }\n\n this._drawLetterSpacing(\n run.text,\n run.style,\n canvasAndContext,\n runX,\n linePositionY + padding - dsOffsetText,\n false,\n wordSpacing\n );\n }\n\n const spacesInFillRun = countSpaces(run.text);\n\n runX += runWidth + (spacesInFillRun * wordSpacing);\n }\n\n currentY += currentLineHeight;\n }\n }\n }\n\n /**\n * Sets fill and stroke styles on the canvas context for text rendering.\n * @param context - The canvas context\n * @param style - The text style\n * @param metrics - The text metrics for gradient calculation\n * @param padding - The padding value\n * @param halfStroke - Half the stroke width\n * @param offsetX - X offset for gradient positioning\n * @param offsetY - Y offset for gradient positioning\n */\n private _setFillAndStrokeStyles(\n context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n style: TextStyle,\n metrics: CanvasTextMetrics,\n padding: number,\n halfStroke: number,\n offsetX: number = 0,\n offsetY: number = 0\n ): void\n {\n context.fillStyle = style._fill\n ? getCanvasFillStyle(style._fill, context, metrics, padding * 2, offsetX, offsetY)\n : null;\n\n if (style._stroke?.width)\n {\n const strokePadding = halfStroke + (padding * 2);\n\n context.strokeStyle = getCanvasFillStyle(\n style._stroke, context, metrics, strokePadding, offsetX, offsetY\n );\n }\n }\n\n /**\n * Sets up the canvas context for drop shadow rendering.\n * @param context - The canvas context\n * @param style - The text style containing drop shadow options\n * @param resolution - The resolution multiplier\n * @param dsOffsetShadow - The shadow Y offset\n */\n private _setupDropShadow(\n context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n style: TextStyle,\n resolution: number,\n dsOffsetShadow: number\n ): void\n {\n // On Safari, text with gradient and drop shadows together do not position correctly\n // if the scale of the canvas is not 1: https://bugs.webkit.org/show_bug.cgi?id=197689\n // Therefore we'll set the styles to be a plain black whilst generating this drop shadow\n context.fillStyle = 'black';\n context.strokeStyle = 'black';\n\n const shadowOptions = style.dropShadow;\n const dropShadowColor = shadowOptions.color;\n const dropShadowAlpha = shadowOptions.alpha;\n\n context.shadowColor = Color.shared\n .setValue(dropShadowColor)\n .setAlpha(dropShadowAlpha)\n .toRgbaString();\n\n const dropShadowBlur = shadowOptions.blur * resolution;\n const dropShadowDistance = shadowOptions.distance * resolution;\n\n context.shadowBlur = dropShadowBlur;\n context.shadowOffsetX = Math.cos(shadowOptions.angle) * dropShadowDistance;\n context.shadowOffsetY = (Math.sin(shadowOptions.angle) * dropShadowDistance) + dsOffsetShadow;\n }\n\n /**\n * Calculates the X offset for text alignment.\n * @param lineWidth - The width of the current line\n * @param alignWidth - The width to align against\n * @param align - The text alignment\n * @returns The X offset for this line\n */\n private _getAlignmentOffset(lineWidth: number, alignWidth: number, align: string): number\n {\n if (align === 'right')\n {\n return alignWidth - lineWidth;\n }\n else if (align === 'center')\n {\n return (alignWidth - lineWidth) / 2;\n }\n\n return 0;\n }\n\n /**\n * Render the text with letter-spacing.\n *\n * This method handles rendering text with the correct letter spacing, using either:\n * 1. Native letter spacing if supported by the browser\n * 2. Manual letter spacing calculation if not natively supported\n *\n * For manual letter spacing, it calculates the position of each character\n * based on its width and the desired spacing.\n * @param text - The text to draw\n * @param style - The text style to apply\n * @param canvasAndContext - The canvas and context to draw to\n * @param x - Horizontal position to draw the text\n * @param y - Vertical position to draw the text\n * @param isStroke - Whether to render the stroke (true) or fill (false)\n * @param wordSpacing - Extra spacing to add between words (for justify alignment)\n * @private\n */\n private _drawLetterSpacing(\n text: string,\n style: TextStyle,\n canvasAndContext: CanvasAndContext,\n x: number, y: number,\n isStroke = false,\n wordSpacing = 0\n ): void\n {\n const { context } = canvasAndContext;\n\n // letterSpacing of 0 means normal\n const letterSpacing = style.letterSpacing;\n\n let useExperimentalLetterSpacing = false;\n\n if (CanvasTextMetrics.experimentalLetterSpacingSupported)\n {\n if (CanvasTextMetrics.experimentalLetterSpacing)\n {\n context.letterSpacing = `${letterSpacing}px`;\n context.textLetterSpacing = `${letterSpacing}px`;\n useExperimentalLetterSpacing = true;\n }\n else\n {\n context.letterSpacing = '0px';\n context.textLetterSpacing = '0px';\n }\n }\n\n if ((letterSpacing === 0 || useExperimentalLetterSpacing) && wordSpacing === 0)\n {\n if (isStroke)\n {\n context.strokeText(text, x, y);\n }\n else\n {\n context.fillText(text, x, y);\n }\n\n return;\n }\n\n if (wordSpacing !== 0 && (letterSpacing === 0 || useExperimentalLetterSpacing))\n {\n const words = text.split(' ');\n let currentPosition = x;\n const spaceWidth = context.measureText(' ').width;\n\n for (let i = 0; i < words.length; i++)\n {\n if (isStroke)\n {\n context.strokeText(words[i], currentPosition, y);\n }\n else\n {\n context.fillText(words[i], currentPosition, y);\n }\n\n currentPosition += context.measureText(words[i]).width + spaceWidth + wordSpacing;\n }\n\n return;\n }\n\n let currentPosition = x;\n\n const stringArray = CanvasTextMetrics.graphemeSegmenter(text);\n let previousWidth = context.measureText(text).width;\n let currentWidth = 0;\n\n for (let i = 0; i < stringArray.length; ++i)\n {\n const currentChar = stringArray[i];\n\n if (isStroke)\n {\n context.strokeText(currentChar, currentPosition, y);\n }\n else\n {\n context.fillText(currentChar, currentPosition, y);\n }\n let textStr = '';\n\n for (let j = i + 1; j < stringArray.length; ++j)\n {\n textStr += stringArray[j];\n }\n currentWidth = context.measureText(textStr).width;\n currentPosition += previousWidth - currentWidth + letterSpacing;\n if (currentChar === ' ') currentPosition += wordSpacing;\n previousWidth = currentWidth;\n }\n }\n}\n\n/** @internal */\nexport const CanvasTextGenerator = new CanvasTextGeneratorClass();\n","import EventEmitter from 'eventemitter3';\nimport { Color, type ColorSource } from '../../color/Color';\nimport { type Filter } from '../../filters/Filter';\nimport { uid } from '../../utils/data/uid';\nimport { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\nimport { warn } from '../../utils/logging/warn';\nimport { FillGradient } from '../graphics/shared/fill/FillGradient';\nimport { FillPattern } from '../graphics/shared/fill/FillPattern';\nimport { GraphicsContext } from '../graphics/shared/GraphicsContext';\nimport { toFillStyle, toStrokeStyle } from '../graphics/shared/utils/convertFillInputToFillStyle';\nimport { fontStringFromTextStyle } from './canvas/utils/fontStringFromTextStyle';\n\nimport type { TextureDestroyOptions, TypeOrBool } from '../container/destroyTypes';\nimport type {\n ConvertedFillStyle,\n ConvertedStrokeStyle,\n FillInput,\n FillStyle,\n StrokeInput,\n StrokeStyle\n} from '../graphics/shared/FillTypes';\n\n/**\n * The alignment of the text.\n *\n * - 'left': Aligns text to the left edge.\n * - 'center': Centers text horizontally.\n * - 'right': Aligns text to the right edge.\n * - 'justify': Justifies text, aligning both left and right edges.\n * @example\n * ```ts\n * import { TextStyle } from 'pixi.js';\n * const style = new TextStyle({\n * align: 'center', // or 'left', 'right', 'justify'\n * });\n * ```\n * @category text\n * @standard\n */\nexport type TextStyleAlign = 'left' | 'center' | 'right' | 'justify';\n/**\n * The fill style input for text styles.\n *\n * This can be:\n * - A color string like 'red', '#00FF00', or 'rgba(255,0,0,0.5)'\n * - A hex number like 0xff0000 for red\n * - A FillStyle object with properties like { color: 0xff0000, alpha: 0.5 }\n * - A FillGradient for gradient fills\n * - A FillPattern for pattern/texture fills\n * @example\n * ```ts\n * // Simple Fills\n * new TextStyle({ fill: 'red' }); // Color string\n * new TextStyle({ fill: 0x00ff00 }); // Hex color\n * new TextStyle({ fill: 'rgb(255,0,0)' }); // RGB string\n * // Gradients\n * new TextStyle({\n * fill: new FillGradient({\n * end: { x: 1, y: 1 },\n * stops: [\n * { color: 0xff0000, offset: 0 }, // Red at start\n * { color: 0x0000ff, offset: 1 }, // Blue at end\n * ]\n * }),\n * });\n * // Patterns\n * new TextStyle({\n * fill: new FillPattern(Assets.get('pattern.png'))\n * });\n * ```\n * @category text\n * @standard\n */\nexport type TextStyleFill = string | string[] | number | number[] | CanvasGradient | CanvasPattern;\n/**\n * The font style input for text styles. Controls the slant or italicization of the text.\n * @example\n * ```ts\n * // Create text with normal font style\n * const normalText = new Text({\n * text: 'Normal Style Text',\n * style: {\n * fontStyle: 'normal',\n * fontSize: 24\n * }\n * });\n *\n * // Create italic text\n * const italicText = new Text({\n * text: 'Italic Style Text',\n * style: {\n * fontStyle: 'italic',\n * fontSize: 24,\n * fontFamily: 'Arial'\n * }\n * });\n *\n * // Create oblique text\n * const obliqueText = new Text({\n * text: 'Oblique Style Text',\n * style: {\n * fontStyle: 'oblique',\n * fontSize: 24,\n * fontFamily: 'Times New Roman'\n * }\n * });\n *\n * // Dynamic style changes\n * let isItalic = false;\n * text.style = {\n * ...text.style,\n * fontStyle: isItalic ? 'italic' : 'normal'\n * };\n * ```\n *\n * Supported values:\n * - 'normal': Regular upright text with no slant\n * - 'italic': True italics using specifically designed italic glyphs\n * - 'oblique': Slanted version of the regular glyphs\n * @remarks\n * - 'italic' uses specially designed glyphs with cursive characteristics\n * - 'oblique' is a mechanical slant of the normal glyphs\n * - Not all fonts include true italic designs; some may fall back to oblique\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-style | MDN font-style}\n * @category text\n * @standard\n */\nexport type TextStyleFontStyle = 'normal' | 'italic' | 'oblique';\n/**\n * The font variant input for text styles. Controls the capitalization and presentation of letters.\n * Used to enable special rendering like small caps.\n * @example\n * ```ts\n * // Create text with normal font variant\n * const normalText = new Text({\n * text: 'Normal Text',\n * style: {\n * fontVariant: 'normal',\n * fontSize: 24\n * }\n * });\n *\n * // Create text with small-caps variant\n * const smallCapsText = new Text({\n * text: 'Small Caps Text',\n * style: {\n * fontVariant: 'small-caps',\n * fontSize: 24,\n * fontFamily: 'Arial'\n * }\n * });\n *\n * // Use in a TextStyle instance\n * const style = new TextStyle({\n * fontVariant: 'small-caps',\n * fontSize: 32,\n * fill: 0x4a4a4a\n * });\n *\n * // Update variant dynamically\n * text.style = {\n * ...text.style,\n * fontVariant: text.style.fontVariant === 'normal' ? 'small-caps' : 'normal'\n * };\n * ```\n *\n * Supported values:\n * - 'normal': Regular text rendering with standard capitalization\n * - 'small-caps': Renders lowercase letters as smaller versions of capital letters\n * @remarks\n * Small caps are only available if the font supports them.\n * Not all fonts include true small caps glyphs.\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant | MDN font-variant}\n * @category text\n * @standard\n */\nexport type TextStyleFontVariant = 'normal' | 'small-caps';\n/**\n * The font weight input for text styles. Controls the thickness or boldness of the text.\n * @example\n * ```ts\n * // Create text with different font weights\n * const normalText = new Text({\n * text: 'Normal Weight',\n * style: { fontWeight: 'normal' }\n * });\n *\n * const boldText = new Text({\n * text: 'Bold Weight',\n * style: { fontWeight: 'bold' }\n * });\n *\n * // Using numeric weights\n * const lightText = new Text({\n * text: 'Light Weight',\n * style: { fontWeight: '300' }\n * });\n *\n * const mediumText = new Text({\n * text: 'Medium Weight',\n * style: { fontWeight: '500' }\n * });\n *\n * const heavyText = new Text({\n * text: 'Heavy Weight',\n * style: { fontWeight: '900' }\n * });\n *\n * // Responsive weight changes\n * const adaptiveText = new Text({\n * text: 'Adaptive Weight',\n * style: { fontWeight: window.innerWidth > 600 ? 'bold' : 'normal' }\n * });\n * ```\n *\n * Supported values:\n * - 'normal': Standard weight (equivalent to 400)\n * - 'bold': Bold weight (equivalent to 700)\n * - 'bolder': One weight darker than the parent element\n * - 'lighter': One weight lighter than the parent element\n * - '100': Thin (Hairline)\n * - '200': Extra Light (Ultra Light)\n * - '300': Light\n * - '400': Normal\n * - '500': Medium\n * - '600': Semi Bold (Demi Bold)\n * - '700': Bold\n * - '800': Extra Bold (Ultra Bold)\n * - '900': Heavy (Black)\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight | MDN font-weight}\n * @category text\n * @standard\n */\nexport type TextStyleFontWeight =\n | 'normal' // Standard weight (400)\n | 'bold' // Bold weight (700)\n | 'bolder' // Relative weight increase\n | 'lighter' // Relative weight decrease\n | '100' // Thin\n | '200' // Extra Light\n | '300' // Light\n | '400' // Normal\n | '500' // Medium\n | '600' // Semi Bold\n | '700' // Bold\n | '800' // Extra Bold\n | '900'; // Heavy\n/**\n * The line join style for text strokes. Determines how lines connect at corners.\n * @example\n * ```ts\n * // Create text with miter joins (sharp corners)\n * const sharpText = new Text({\n * text: 'Sharp Corners',\n * style: {\n * fontSize: 36,\n * stroke: {\n * color: '#4a1850',\n * width: 4,\n * lineJoin: 'miter' // Sharp corners\n * }\n * }\n * });\n *\n * // Create text with round joins\n * const roundText = new Text({\n * text: 'Rounded Corners',\n * style: {\n * fontSize: 36,\n * stroke: {\n * color: '#4a1850',\n * width: 4,\n * lineJoin: 'round' // Smooth rounded corners\n * }\n * }\n * });\n *\n * // Create text with beveled joins\n * const bevelText = new Text({\n * text: 'Beveled Corners',\n * style: {\n * fontSize: 36,\n * stroke: {\n * color: '#4a1850',\n * width: 4,\n * lineJoin: 'bevel' // Flattened corners\n * }\n * }\n * });\n * ```\n * Available values:\n * - 'miter': Creates sharp corners by extending the outer edges until they meet\n * - 'round': Creates smooth, rounded corners using a circular arc\n * - 'bevel': Creates flattened corners by filling an additional triangle between the outer edges\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin | MDN lineJoin}\n * @category text\n * @standard\n */\nexport type TextStyleLineJoin = 'miter' | 'round' | 'bevel';\n/**\n * The text baseline for text styles.\n *\n * This can be:\n * - 'alphabetic': The alphabetic baseline\n * - 'top': The top of the text\n * - 'hanging': The hanging baseline\n * - 'middle': The middle of the text\n * - 'ideographic': The ideographic baseline\n * - 'bottom': The bottom of the text\n * @category text\n * @standard\n */\nexport type TextStyleTextBaseline = 'alphabetic' | 'top' | 'hanging' | 'middle' | 'ideographic' | 'bottom';\n/**\n * Controls how whitespace (spaces, tabs, and line breaks) is handled within the text.\n * This affects text wrapping and spacing behavior.\n * @example\n * ```ts\n * // Normal mode (collapse spaces and newlines)\n * const normalText = new Text({\n * text: 'Hello World\\n\\nNew Line',\n * style: {\n * whiteSpace: 'normal',\n * fontSize: 24\n * }\n * }); // Renders as: \"Hello World New Line\"\n *\n * // Pre mode (preserve all whitespace)\n * const preText = new Text({\n * text: 'Hello World\\n\\nNew Line',\n * style: {\n * whiteSpace: 'pre',\n * fontSize: 24\n * }\n * }); // Preserves spaces and line breaks exactly\n *\n * // Pre-line mode (preserve newlines, collapse spaces)\n * const preLineText = new Text({\n * text: 'Hello World\\n\\nNew Line',\n * style: {\n * whiteSpace: 'pre-line',\n * fontSize: 24\n * }\n * }); // Preserves line breaks, collapses multiple spaces\n *\n * // With word wrap enabled\n * const wrappedText = new Text({\n * text: 'A long text with multiple spaces\\nand line breaks',\n * style: {\n * whiteSpace: 'pre-line',\n * wordWrap: true,\n * wordWrapWidth: 200,\n * fontSize: 24\n * }\n * });\n * ```\n *\n * Supported values:\n * - 'normal': Collapses all whitespace (spaces, tabs, line breaks) into a single space\n * - 'pre': Preserves all whitespace characters exactly as written\n * - 'pre-line': Preserves line breaks but collapses multiple spaces into a single space\n * @remarks\n * - 'normal' is best for single-line text or when you want to ignore formatting\n * - 'pre' is useful for code blocks or when exact spacing is important\n * - 'pre-line' is good for formatted text where you want to keep line breaks but clean up spaces\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/white-space | MDN white-space}\n * @see {@link TextStyle#wordWrap} For controlling text wrapping\n * @category text\n * @standard\n */\nexport type TextStyleWhiteSpace = 'normal' | 'pre' | 'pre-line';\n\n/**\n * Defines a drop shadow effect for text rendering.\n * Drop shadows add depth and emphasis to text by creating a shadow offset from the text.\n * @example\n * ```ts\n * // Create text with basic drop shadow\n * const text = new Text({\n * text: 'Shadow Text',\n * style: {\n * fontSize: 48,\n * dropShadow: {\n * alpha: 0.5, // 50% opacity shadow\n * angle: Math.PI / 6, // 30 degrees\n * blur: 4, // Soft shadow edge\n * color: '#000000', // Black shadow\n * distance: 6 // Shadow offset\n * }\n * }\n * });\n *\n * // Dynamic shadow updates\n * text.style.dropShadow = {\n * alpha: Math.sin(Date.now() / 1000) * 0.5 + 0.5, // Pulsing opacity\n * angle: Date.now() / 1000, // Rotating angle\n * blur: 4,\n * color: '#000000',\n * distance: 6\n * };\n * ```\n * @category text\n * @standard\n */\nexport type TextDropShadow = {\n /**\n * The opacity of the drop shadow.\n * - Range: 0 to 1\n * - 0 = fully transparent\n * - 1 = fully opaque\n * @example\n * ```ts\n * // Set drop shadow opacity to 50%\n * dropShadow: {\n * alpha: 0.5\n * }\n * ```\n * @default 1\n */\n alpha: number;\n\n /**\n * The angle of the drop shadow in radians.\n * - 0 = right\n * - Math.PI/2 = down\n * - Math.PI = left\n * - Math.PI*1.5 = up\n * @example\n * ```ts\n * // Set drop shadow angle to 30 degrees\n * dropShadow: {\n * angle: Math.PI / 6 // 30 degrees\n * }\n * ```\n * @default Math.PI/6 (30 degrees)\n */\n angle: number;\n\n /**\n * The blur radius of the shadow.\n * - 0 = sharp shadow\n * - Higher values = softer shadow\n * @example\n * ```ts\n * // Set drop shadow blur radius to 10 pixels\n * dropShadow: {\n * blur: 10\n * }\n * ```\n * @default 0\n */\n blur: number;\n\n /**\n * The color of the drop shadow.\n * Accepts any valid CSS color string, hex number, or RGB/RGBA values.\n * @example '#000000', 'rgba(0,0,0,0.5)', 0x000000\n * @default 'black'\n */\n color: ColorSource;\n\n /**\n * The distance of the drop shadow from the text.\n * Measured in pixels.\n * @example\n * ```ts\n * // Set drop shadow distance to 5 pixels\n * dropShadow: {\n * distance: 5\n * }\n * ```\n * @default 5\n */\n distance: number;\n};\n\n/**\n * Constructor options used for `TextStyle` instances. Defines the visual appearance and layout of text.\n * @example\n * ```ts\n * // Basic text style\n * const basicStyle = new TextStyle({\n * fontSize: 24,\n * fill: 'black',\n * fontFamily: 'Arial'\n * });\n *\n * // Rich text style with multiple features\n * const richStyle = new TextStyle({\n * fontFamily: ['Arial', 'Helvetica', 'sans-serif'],\n * fontSize: 36,\n * fontWeight: 'bold',\n * fill: 'red',\n * stroke: { color: '#4a1850', width: 5 },\n * align: 'center',\n * dropShadow: {\n * color: '#000000',\n * blur: 4,\n * distance: 6,\n * angle: Math.PI / 6\n * },\n * wordWrap: true,\n * wordWrapWidth: 440,\n * lineHeight: 40,\n * textBaseline: 'middle'\n * });\n * ```\n * @see {@link TextStyle} For the main style class\n * @category text\n * @standard\n */\nexport interface TextStyleOptions\n{\n /**\n * Alignment for multiline text, does not affect single line text\n * @default 'left'\n */\n align?: TextStyleAlign;\n /**\n * Whether to allow line breaks within words.\n * Requires wordWrap to be true.\n * @example\n * ```ts\n * // Enable word breaking\n * const style = new TextStyle({\n * breakWords: true,\n * wordWrap: true,\n * wordWrapWidth: 200\n * });\n * ```\n * @default false\n */\n breakWords?: boolean;\n /**\n * Drop shadow configuration for the text.\n * Can be boolean or a TextDropShadow object.\n * @default null\n */\n dropShadow?: boolean | Partial<TextDropShadow>;\n /**\n * Fill style for the text.\n * Can be a color, gradient, or pattern.\n * @default 'black'\n */\n fill?: FillInput;\n /**\n * Font family or families to use.\n * Can be single name or array of fallbacks.\n * @example\n * ```ts\n * // Single font family\n * fontFamily: 'Arial'\n * // Multiple font families\n * fontFamily: ['Helvetica', 'Arial', 'sans-serif']\n * ```\n * @default 'Arial'\n */\n fontFamily?: string | string[];\n /**\n * Font size in pixels or as string.\n *\n * Equivalents are '26px','20pt','160%' or '1.6em')\n * @example\n * ```ts\n * // Numeric size\n * fontSize: 26\n * // String size\n * fontSize: '26px'\n * // Percentage size\n * fontSize: '160%' // 1.6 times the parent element's font size\n * // Em size\n * fontSize: '1.6em' // 1.6 times the parent element's font size\n * @default 26\n */\n fontSize?: number | string;\n /**\n * Font style (normal, italic, oblique).\n * @default 'normal'\n */\n fontStyle?: TextStyleFontStyle;\n /**\n * Font variant (normal, small-caps).\n * @default 'normal'\n */\n fontVariant?: TextStyleFontVariant;\n /**\n * Font weight (normal, bold, bolder, lighter, 100-900).\n * @default 'normal'\n */\n fontWeight?: TextStyleFontWeight;\n /** The height of the line, a number that represents the vertical space that a letter uses. */\n leading?: number;\n /** The amount of spacing between letters, default is 0 */\n letterSpacing?: number;\n /** The line height, a number that represents the vertical space that a letter uses */\n lineHeight?: number;\n /**\n * Padding around the text.\n *\n * Occasionally some fonts are cropped. Adding some padding will prevent this from\n * happening by adding padding to all sides of the text.\n */\n padding?: number;\n /**\n * Stroke style for text outline.\n * @default null\n */\n stroke?: StrokeInput;\n /**\n * Vertical alignment baseline.\n * @default 'alphabetic'\n */\n textBaseline?: TextStyleTextBaseline;\n /**\n * Whether to trim transparent edges.\n * > [!NOTE] This is an expensive operation and should only be used when necessary.\n * @default false\n */\n trim?: boolean;\n /**\n * How to handle whitespace.\n *\n * It needs wordWrap to be set to true for this to have an effect.\n * @default 'pre'\n */\n whiteSpace?: TextStyleWhiteSpace;\n /** Indicates if word wrap should be used */\n wordWrap?: boolean;\n /** The width at which text will wrap, it needs wordWrap to be set to true */\n wordWrapWidth?: number;\n /**\n * Array of filters to apply to the text.\n *\n * These filters will be applied to the text as it is created, resulting in faster rendering for static text\n * compared to applying the filter directly to the text object (which would be applied at run time).\n * @default undefined\n */\n filters?: Filter[] | readonly Filter[];\n /**\n * Custom styles to apply to specific tags within the text.\n * Allows for rich text formatting using simple tag markup like `<red>text</red>`.\n *\n * Tags are only parsed when this property has entries. If `tagStyles` is empty or undefined,\n * `<` characters in text are treated as literal.\n *\n * Nested tags are supported via a style stack - inner tags inherit from outer tags\n * but can override specific properties.\n * @example\n * ```ts\n * const text = new Text({\n * text: '<red>Red</red>, <blue>Blue</blue>, <big>Big</big>',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 'white',\n * tagStyles: {\n * red: { fill: 'red' },\n * blue: { fill: 'blue' },\n * big: { fontSize: 48 }\n * }\n * }\n * });\n * ```\n * @default undefined\n */\n tagStyles?: Record<string, TextStyleOptions>;\n}\n\n/**\n * A TextStyle Object contains information to decorate Text objects.\n * An instance can be shared between multiple Text objects; then changing the style will update all text objects using it.\n * @example\n * ```ts\n * // Create a basic text style\n * const style = new TextStyle({\n * fontFamily: ['Helvetica', 'Arial', 'sans-serif'],\n * fontSize: 36,\n * fill: 0xff1010,\n * align: 'center'\n * });\n *\n * // Create a rich text style with multiple features\n * const richStyle = new TextStyle({\n * fontFamily: 'Arial',\n * fontSize: 32,\n * fill: 'white',\n * stroke: {\n * color: '#4a1850',\n * width: 5\n * },\n * dropShadow: {\n * color: '#000000',\n * blur: 4,\n * distance: 6,\n * angle: Math.PI / 6\n * },\n * wordWrap: true,\n * wordWrapWidth: 440,\n * lineHeight: 40,\n * align: 'center'\n * });\n *\n * // Share style between multiple text objects\n * const text1 = new Text({\n * text: 'Hello',\n * style: richStyle\n * });\n *\n * const text2 = new Text({\n * text: 'World',\n * style: richStyle\n * });\n *\n * // Update style dynamically - affects all text objects\n * richStyle.fontSize = 48;\n * richStyle.fill = 0x00ff00;\n * ```\n *\n * Key Features:\n * - Shared styling between multiple text objects\n * - Rich text formatting options\n * - Gradient and pattern fills\n * - Drop shadows and strokes\n * - Word wrapping and alignment\n * - Dynamic updates\n * @category text\n * @standard\n */\nexport class TextStyle extends EventEmitter<{\n update: TextDropShadow\n}>\n{\n /**\n * Default drop shadow settings used when enabling drop shadows on text.\n * These values are used as the base configuration when drop shadows are enabled without specific settings.\n * @example\n * ```ts\n * // Customize default settings globally\n * TextStyle.defaultDropShadow.alpha = 0.5; // 50% opacity for all shadows\n * TextStyle.defaultDropShadow.blur = 2; // 2px blur for all shadows\n * TextStyle.defaultDropShadow.color = 'blue'; // Blue shadows by default\n * ```\n */\n public static defaultDropShadow: TextDropShadow = {\n alpha: 1,\n angle: Math.PI / 6,\n blur: 0,\n color: 'black',\n distance: 5\n };\n\n /**\n * Unique identifier for the TextStyle class.\n * This is used to track instances and ensure uniqueness.\n * @internal\n */\n public uid = uid('textStyle');\n /**\n * Internal tick counter used to track updates and changes.\n * This is incremented whenever the style is modified, allowing for efficient change detection.\n * @internal\n */\n public _tick = 0;\n\n /**\n * Default text style settings used when creating new text objects.\n * These values serve as the base configuration and can be customized globally.\n * @example\n * ```ts\n * // Customize default text style globally\n * TextStyle.defaultTextStyle.fontSize = 16;\n * TextStyle.defaultTextStyle.fill = 0x333333;\n * TextStyle.defaultTextStyle.fontFamily = ['Arial', 'Helvetica', 'sans-serif'];\n * ```\n */\n public static defaultTextStyle: TextStyleOptions = {\n align: 'left',\n breakWords: false,\n dropShadow: null,\n fill: 'black',\n fontFamily: 'Arial',\n fontSize: 26,\n fontStyle: 'normal',\n fontVariant: 'normal',\n fontWeight: 'normal',\n leading: 0,\n letterSpacing: 0,\n lineHeight: 0,\n padding: 0,\n stroke: null,\n textBaseline: 'alphabetic',\n trim: false,\n whiteSpace: 'pre',\n wordWrap: false,\n wordWrapWidth: 100\n };\n\n // colors!!\n /** @internal */\n public _fill: ConvertedFillStyle;\n private _originalFill: FillInput;\n\n /** @internal */\n public _stroke: ConvertedStrokeStyle;\n private _originalStroke: StrokeInput;\n\n private _dropShadow: TextDropShadow;\n\n private _fontFamily: string | string[];\n private _fontSize: number;\n private _fontStyle: TextStyleFontStyle;\n private _fontVariant: TextStyleFontVariant;\n private _fontWeight: TextStyleFontWeight;\n\n private _breakWords: boolean;\n private _align: TextStyleAlign;\n private _leading: number;\n private _letterSpacing: number;\n private _lineHeight: number;\n\n private _textBaseline: TextStyleTextBaseline;\n private _whiteSpace: TextStyleWhiteSpace;\n private _wordWrap: boolean;\n private _wordWrapWidth: number;\n private _filters: readonly Filter[];\n\n private _padding: number;\n\n private _trim: boolean;\n private _cachedFontString: string | null = null;\n /** @internal */\n public _tagStyles: Record<string, TextStyleOptions> | undefined;\n\n /**\n * When set, gradient fills use these bounds instead of the text's own measured dimensions.\n * Used by SplitText to make character gradients span the full text width.\n * @internal\n */\n public _gradientBounds?: { width: number; height: number };\n\n /**\n * When set, gradient fills are offset by this amount within the gradient bounds.\n * Used by SplitText to position each character's gradient correctly.\n * @internal\n */\n public _gradientOffset?: { x: number; y: number };\n\n constructor(style: Partial<TextStyleOptions> = {})\n {\n super();\n\n convertV7Tov8Style(style);\n\n // When style is a TextStyle instance, use its toObject() values instead of the spread\n // which copies proxy objects bound to the wrong instance.\n const isTextStyle = style instanceof TextStyle;\n const existingStyle = style as TextStyle;\n\n if (isTextStyle)\n {\n style = existingStyle._toObject();\n }\n\n const fullStyle = { ...TextStyle.defaultTextStyle, ...style };\n\n for (const key in fullStyle)\n {\n const thisKey = key as keyof typeof this;\n\n this[thisKey] = fullStyle[key as keyof TextStyleOptions] as any;\n }\n\n // Initialize tagStyles separately (not in defaultTextStyle to avoid shared reference)\n this._tagStyles = style.tagStyles ?? undefined;\n\n this.update();\n this._tick = 0;\n }\n\n /**\n * Alignment for multiline text, does not affect single line text.\n * @type {'left'|'center'|'right'|'justify'}\n */\n get align(): TextStyleAlign { return this._align; }\n\n set align(value: TextStyleAlign)\n {\n if (this._align === value) return;\n\n this._align = value;\n this.update();\n }\n\n /** Indicates if lines can be wrapped within words, it needs wordWrap to be set to true. */\n get breakWords(): boolean { return this._breakWords; }\n\n set breakWords(value: boolean)\n {\n if (this._breakWords === value) return;\n\n this._breakWords = value;\n this.update();\n }\n\n /** Set a drop shadow for the text. */\n get dropShadow(): TextDropShadow { return this._dropShadow; }\n\n set dropShadow(value: boolean | TextDropShadow)\n {\n if (this._dropShadow === value) return;\n\n if (value !== null && typeof value === 'object')\n {\n this._dropShadow = this._createProxy({ ...TextStyle.defaultDropShadow, ...value });\n }\n else\n {\n this._dropShadow = value ? this._createProxy({ ...TextStyle.defaultDropShadow }) : null;\n }\n\n this.update();\n }\n\n /** The font family, can be a single font name, or a list of names where the first is the preferred font. */\n get fontFamily(): string | string[] { return this._fontFamily; }\n\n set fontFamily(value: string | string[])\n {\n if (this._fontFamily === value) return;\n\n this._fontFamily = value;\n this.update();\n }\n\n /** The font size (as a number it converts to px, but as a string, equivalents are '26px','20pt','160%' or '1.6em') */\n get fontSize(): number { return this._fontSize; }\n\n set fontSize(value: string | number)\n {\n if (this._fontSize === value) return;\n\n if (typeof value === 'string')\n {\n // eg '34px' to number\n this._fontSize = parseInt(value as string, 10);\n }\n else\n {\n this._fontSize = value as number;\n }\n this.update();\n }\n\n /**\n * The font style.\n * @type {'normal'|'italic'|'oblique'}\n */\n get fontStyle(): TextStyleFontStyle { return this._fontStyle; }\n\n set fontStyle(value: TextStyleFontStyle)\n {\n if (this._fontStyle === value) return;\n\n this._fontStyle = value.toLowerCase() as TextStyleFontStyle;\n this.update();\n }\n\n /**\n * The font variant.\n * @type {'normal'|'small-caps'}\n */\n get fontVariant(): TextStyleFontVariant { return this._fontVariant; }\n\n set fontVariant(value: TextStyleFontVariant)\n {\n if (this._fontVariant === value) return;\n\n this._fontVariant = value;\n this.update();\n }\n\n /**\n * The font weight.\n * @type {'normal'|'bold'|'bolder'|'lighter'|'100'|'200'|'300'|'400'|'500'|'600'|'700'|'800'|'900'}\n */\n get fontWeight(): TextStyleFontWeight { return this._fontWeight; }\n\n set fontWeight(value: TextStyleFontWeight)\n {\n if (this._fontWeight === value) return;\n\n this._fontWeight = value;\n this.update();\n }\n\n /** The space between lines. */\n get leading(): number { return this._leading; }\n\n set leading(value: number)\n {\n if (this._leading === value) return;\n\n this._leading = value;\n this.update();\n }\n\n /** The amount of spacing between letters, default is 0. */\n get letterSpacing(): number { return this._letterSpacing; }\n\n set letterSpacing(value: number)\n {\n if (this._letterSpacing === value) return;\n\n this._letterSpacing = value;\n this.update();\n }\n\n /** The line height, a number that represents the vertical space that a letter uses. */\n get lineHeight(): number { return this._lineHeight; }\n\n set lineHeight(value: number)\n {\n if (this._lineHeight === value) return;\n\n this._lineHeight = value;\n this.update();\n }\n\n /**\n * Occasionally some fonts are cropped. Adding some padding will prevent this from happening\n * by adding padding to all sides of the text.\n * > [!NOTE] This will NOT affect the positioning or bounds of the text.\n */\n get padding(): number { return this._padding; }\n\n set padding(value: number)\n {\n if (this._padding === value) return;\n\n this._padding = value;\n this.update();\n }\n\n /**\n * An optional filter or array of filters to apply to the text, allowing for advanced visual effects.\n * These filters will be applied to the text as it is created, resulting in faster rendering for static text\n * compared to applying the filter directly to the text object (which would be applied at run time).\n * @default null\n */\n get filters(): readonly Filter[] { return this._filters; }\n\n set filters(value: Filter[])\n {\n if (this._filters === value) return;\n\n this._filters = Object.freeze(value);\n this.update();\n }\n\n /**\n * Trim transparent borders from the text texture.\n * > [!IMPORTANT] PERFORMANCE WARNING:\n * > This is a costly operation as it requires scanning pixel alpha values.\n * > Avoid using `trim: true` for dynamic text, as it could significantly impact performance.\n */\n get trim(): boolean { return this._trim; }\n\n set trim(value: boolean)\n {\n if (this._trim === value) return;\n\n this._trim = value;\n this.update();\n }\n\n /**\n * The baseline of the text that is rendered.\n * @type {'alphabetic'|'top'|'hanging'|'middle'|'ideographic'|'bottom'}\n */\n get textBaseline(): TextStyleTextBaseline { return this._textBaseline; }\n\n set textBaseline(value: TextStyleTextBaseline)\n {\n if (this._textBaseline === value) return;\n\n this._textBaseline = value;\n this.update();\n }\n\n /**\n * How newlines and spaces should be handled.\n * Default is 'pre' (preserve, preserve).\n *\n * value | New lines | Spaces\n * --- | --- | ---\n * 'normal' | Collapse | Collapse\n * 'pre' | Preserve | Preserve\n * 'pre-line' | Preserve | Collapse\n * @type {'normal'|'pre'|'pre-line'}\n */\n get whiteSpace(): TextStyleWhiteSpace { return this._whiteSpace; }\n\n set whiteSpace(value: TextStyleWhiteSpace)\n {\n if (this._whiteSpace === value) return;\n\n this._whiteSpace = value;\n this.update();\n }\n\n /** Indicates if word wrap should be used. */\n get wordWrap(): boolean { return this._wordWrap; }\n\n set wordWrap(value: boolean)\n {\n if (this._wordWrap === value) return;\n\n this._wordWrap = value;\n this.update();\n }\n\n /** The width at which text will wrap, it needs wordWrap to be set to true. */\n get wordWrapWidth(): number { return this._wordWrapWidth; }\n\n set wordWrapWidth(value: number)\n {\n if (this._wordWrapWidth === value) return;\n\n this._wordWrapWidth = value;\n this.update();\n }\n\n /**\n * The fill style that will be used to color the text.\n * This can be:\n * - A color string like 'red', '#00FF00', or 'rgba(255,0,0,0.5)'\n * - A hex number like 0xff0000 for red\n * - A FillStyle object with properties like { color: 0xff0000, alpha: 0.5 }\n * - A FillGradient for gradient fills\n * - A FillPattern for pattern/texture fills\n *\n * When using a FillGradient, vertical gradients (angle of 90 degrees) are applied per line of text,\n * while gradients at any other angle are spread across the entire text body as a whole.\n * @example\n * // Vertical gradient applied per line\n * const verticalGradient = new FillGradient(0, 0, 0, 1)\n * .addColorStop(0, 0xff0000)\n * .addColorStop(1, 0x0000ff);\n *\n * const text = new Text({\n * text: 'Line 1\\nLine 2',\n * style: { fill: verticalGradient }\n * });\n *\n * To manage the gradient in a global scope, set the textureSpace property of the FillGradient to 'global'.\n * @type {string|number|FillStyle|FillGradient|FillPattern}\n */\n get fill(): FillInput\n {\n return this._originalFill;\n }\n\n set fill(value: FillInput)\n {\n if (value === this._originalFill) return;\n\n this._originalFill = value;\n\n if (this._isFillStyle(value))\n {\n this._originalFill = this._createProxy({ ...GraphicsContext.defaultFillStyle, ...value }, () =>\n {\n this._fill = toFillStyle(\n { ...this._originalFill as FillStyle },\n GraphicsContext.defaultFillStyle\n );\n });\n }\n\n this._fill = toFillStyle(\n value === 0x0 ? 'black' : value,\n GraphicsContext.defaultFillStyle\n );\n this.update();\n }\n\n /** A fillstyle that will be used on the text stroke, e.g., 'blue', '#FCFF00'. */\n get stroke(): StrokeInput\n {\n return this._originalStroke;\n }\n\n set stroke(value: StrokeInput)\n {\n if (value === this._originalStroke) return;\n\n this._originalStroke = value;\n\n if (this._isFillStyle(value))\n {\n this._originalStroke = this._createProxy({ ...GraphicsContext.defaultStrokeStyle, ...value }, () =>\n {\n this._stroke = toStrokeStyle(\n { ...this._originalStroke as StrokeStyle },\n GraphicsContext.defaultStrokeStyle\n );\n });\n }\n\n this._stroke = toStrokeStyle(value, GraphicsContext.defaultStrokeStyle);\n this.update();\n }\n\n /**\n * Custom styles to apply to specific tags within the text.\n * Allows for rich text formatting using simple tag markup like `<red>text</red>`.\n *\n * Tags are only parsed when this property has entries. If `tagStyles` is undefined,\n * `<` characters in text are treated as literal.\n * @example\n * ```ts\n * const text = new Text({\n * text: '<red>Red</red>, <blue>Blue</blue>',\n * style: {\n * fill: 'white',\n * tagStyles: {\n * red: { fill: 'red' },\n * blue: { fill: 'blue' }\n * }\n * }\n * });\n * ```\n */\n public get tagStyles(): Record<string, TextStyleOptions> | undefined\n {\n return this._tagStyles;\n }\n\n public set tagStyles(value: Record<string, TextStyleOptions> | undefined)\n {\n if (this._tagStyles === value) return;\n\n this._tagStyles = value ?? undefined;\n this.update();\n }\n\n public update()\n {\n this._tick++;\n this._cachedFontString = null;\n this.emit('update', this);\n }\n\n /** Resets all properties to the default values */\n public reset()\n {\n const defaultStyle = TextStyle.defaultTextStyle;\n\n for (const key in defaultStyle)\n {\n this[key as keyof typeof this] = defaultStyle[key as keyof TextStyleOptions] as any;\n }\n }\n\n /**\n * Assigns partial style options to this TextStyle instance.\n * Uses public setters to ensure proper value transformation.\n * @param values - Partial style options to assign\n * @returns This TextStyle instance for chaining\n */\n public assign(values: Partial<TextStyleOptions>): this\n {\n for (const key in values)\n {\n const thisKey = key as keyof typeof this;\n\n this[thisKey] = values[key as keyof typeof values] as any;\n }\n\n return this;\n }\n\n /**\n * Returns a unique key for this instance.\n * This key is used for caching.\n * @returns {string} Unique key for the instance\n */\n public get styleKey(): string\n {\n return `${this.uid}-${this._tick}`;\n }\n\n /**\n * Returns the CSS font string for this style, cached for performance.\n * @internal\n * @returns CSS font string\n */\n public get _fontString(): string\n {\n if (this._cachedFontString === null)\n {\n this._cachedFontString = fontStringFromTextStyle(this);\n }\n\n return this._cachedFontString;\n }\n\n /**\n * Returns an object with the same values as this TextStyle instance.\n * @returns Object with the same values as this TextStyle instance\n * @example\n * ```ts\n * const style = new TextStyle({\n * fontSize: 24,\n * fill: 0xff0000,\n * stroke: { color: 0x0000ff, width: 2 }\n * });\n * const object = style.toObject();\n * console.log(object);\n * // { fontSize: 24, fill: 0xff0000, stroke: { color: 0x0000ff, width: 2 } }\n * ```\n */\n protected _toObject(): Required<TextStyleOptions>\n {\n return {\n align: this.align,\n breakWords: this.breakWords,\n dropShadow: this._dropShadow ? { ...this._dropShadow } : null,\n fill: this._fill ? { ...this._fill } : undefined,\n fontFamily: this.fontFamily,\n fontSize: this.fontSize,\n fontStyle: this.fontStyle,\n fontVariant: this.fontVariant,\n fontWeight: this.fontWeight,\n leading: this.leading,\n letterSpacing: this.letterSpacing,\n lineHeight: this.lineHeight,\n padding: this.padding,\n stroke: this._stroke ? { ...this._stroke } : undefined,\n textBaseline: this.textBaseline,\n trim: this.trim,\n whiteSpace: this.whiteSpace,\n wordWrap: this.wordWrap,\n wordWrapWidth: this.wordWrapWidth,\n filters: this._filters ? [...this._filters] : undefined,\n tagStyles: this._tagStyles ? { ...this._tagStyles } : undefined,\n };\n }\n\n /**\n * Creates a new TextStyle object with the same values as this one.\n * @returns New cloned TextStyle object\n */\n public clone(): TextStyle\n {\n return new TextStyle(this._toObject());\n }\n\n /**\n * Returns the final padding for the text style, taking into account any filters applied.\n * Used internally for correct measurements\n * @internal\n * @returns {number} The final padding for the text style.\n */\n public _getFinalPadding(): number\n {\n let filterPadding = 0;\n\n if (this._filters)\n {\n for (let i = 0; i < this._filters.length; i++)\n {\n filterPadding += this._filters[i].padding;\n }\n }\n\n return Math.max(this._padding, filterPadding);\n }\n\n /**\n * Destroys this text style.\n * @param options - Options parameter. A boolean will act as if all options\n * have been set to that value\n * @example\n * // Destroy the text style and its textures\n * textStyle.destroy({ texture: true, textureSource: true });\n * textStyle.destroy(true);\n */\n public destroy(options: TypeOrBool<TextureDestroyOptions> = false)\n {\n this.removeAllListeners();\n\n const destroyTexture = typeof options === 'boolean' ? options : options?.texture;\n\n if (destroyTexture)\n {\n const destroyTextureSource = typeof options === 'boolean' ? options : options?.textureSource;\n\n if (this._fill?.texture)\n {\n this._fill.texture.destroy(destroyTextureSource);\n }\n\n if ((this._originalFill as FillStyle)?.texture)\n {\n (this._originalFill as FillStyle).texture.destroy(destroyTextureSource);\n }\n\n if (this._stroke?.texture)\n {\n this._stroke.texture.destroy(destroyTextureSource);\n }\n\n if ((this._originalStroke as FillStyle)?.texture)\n {\n (this._originalStroke as FillStyle).texture.destroy(destroyTextureSource);\n }\n }\n\n this._fill = null;\n this._stroke = null;\n this.dropShadow = null;\n this._originalStroke = null;\n this._originalFill = null;\n }\n\n private _createProxy<T extends object>(value: T, cb?: (property: string, newValue: any) => void): T\n {\n return new Proxy<T>(value, {\n set: (target, property, newValue) =>\n {\n if (target[property as keyof T] === newValue) return true;\n\n target[property as keyof T] = newValue;\n cb?.(property as string, newValue);\n this.update();\n\n return true;\n }\n });\n }\n\n private _isFillStyle(value: FillInput): value is FillStyle\n {\n return ((value ?? null) !== null\n && !(Color.isColorLike(value) || value instanceof FillGradient || value instanceof FillPattern));\n }\n}\n\nfunction convertV7Tov8Style(style: TextStyleOptions)\n{\n const oldStyle = style as TextStyleOptions & {\n dropShadowAlpha?: number;\n dropShadowAngle?: number;\n dropShadowBlur?: number;\n dropShadowColor?: number;\n dropShadowDistance?: number;\n fillGradientStops?: number[];\n strokeThickness?: number;\n };\n\n if (typeof oldStyle.dropShadow === 'boolean' && oldStyle.dropShadow)\n {\n const defaults = TextStyle.defaultDropShadow;\n\n style.dropShadow = {\n alpha: oldStyle.dropShadowAlpha ?? defaults.alpha,\n angle: oldStyle.dropShadowAngle ?? defaults.angle,\n blur: oldStyle.dropShadowBlur ?? defaults.blur,\n color: oldStyle.dropShadowColor ?? defaults.color,\n distance: oldStyle.dropShadowDistance ?? defaults.distance\n };\n }\n\n if (oldStyle.strokeThickness !== undefined)\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'strokeThickness is now a part of stroke');\n // #endif\n\n const color = oldStyle.stroke;\n let obj: FillStyle = {};\n\n // handles stroke: 0x0, stroke: { r: 0, g: 0, b: 0, a: 0 } stroke: new Color(0x0)\n if (Color.isColorLike(color as ColorSource))\n {\n obj.color = color as ColorSource;\n }\n // handles stroke: new FillGradient()\n else if (color instanceof FillGradient || color instanceof FillPattern)\n {\n obj.fill = color as FillGradient | FillPattern;\n }\n // handles stroke: { color: 0x0 } or stroke: { fill: new FillGradient() }\n else if (Object.hasOwnProperty.call(color, 'color') || Object.hasOwnProperty.call(color, 'fill'))\n {\n obj = color as FillStyle;\n }\n else\n {\n throw new Error('Invalid stroke value.');\n }\n\n style.stroke = {\n ...obj,\n width: oldStyle.strokeThickness\n };\n }\n\n if (Array.isArray(oldStyle.fillGradientStops))\n {\n // #if _DEBUG\n deprecation(v8_0_0, 'gradient fill is now a fill pattern: `new FillGradient(...)`');\n // #endif\n\n if (!Array.isArray(oldStyle.fill) || oldStyle.fill.length === 0)\n {\n throw new Error('Invalid fill value. Expected an array of colors for gradient fill.');\n }\n\n if (oldStyle.fill.length !== oldStyle.fillGradientStops.length)\n {\n // #if _DEBUG\n warn('The number of fill colors must match the number of fill gradient stops.');\n // #endif\n }\n\n const gradientFill = new FillGradient({\n start: { x: 0, y: 0 },\n end: { x: 0, y: 1 },\n textureSpace: 'local'\n });\n\n const fillGradientStops = oldStyle.fillGradientStops.slice();\n const fills: number[] = oldStyle.fill\n .map((color: ColorSource) => Color.shared.setValue(color).toNumber());\n\n fillGradientStops.forEach((stop, index) =>\n {\n gradientFill.addColorStop(stop, fills[index]);\n });\n\n style.fill = {\n fill: gradientFill\n };\n }\n}\n\n","import { ExtensionType } from '../extensions/Extensions';\n\nimport type { ExtensionMetadata } from '../extensions/Extensions';\nimport type { Renderer } from '../rendering/renderers/types';\n\ntype ResizeableRenderer = Pick<Renderer, 'resize'>;\n\n/**\n * Application options for the {@link ResizePlugin}.\n * These options control how your application handles window and element resizing.\n * @example\n * ```ts\n * // Auto-resize to window\n * await app.init({ resizeTo: window });\n *\n * // Auto-resize to container element\n * await app.init({ resizeTo: document.querySelector('#game') });\n * ```\n * @category app\n * @standard\n */\nexport interface ResizePluginOptions\n{\n /**\n * Element to automatically resize the renderer to.\n * @example\n * ```ts\n * const app = new Application();\n * await app.init({\n * resizeTo: window, // Resize to the entire window\n * // or\n * resizeTo: document.querySelector('#game-container'), // Resize to a specific element\n * // or\n * resizeTo: null, // Disable auto-resize\n * });\n * ```\n * @default null\n */\n resizeTo?: Window | HTMLElement;\n}\n\n/**\n * Middleware for Application's resize functionality. This plugin handles automatic\n * and manual resizing of your PixiJS application.\n *\n * Adds the following features to {@link Application}:\n * - `resizeTo`: Set an element to automatically resize to\n * - `resize`: Manually trigger a resize\n * - `queueResize`: Queue a resize for the next animation frame\n * - `cancelResize`: Cancel a queued resize\n * @example\n * ```ts\n * import { Application, ResizePlugin } from 'pixi.js';\n *\n * // Create application\n * const app = new Application();\n *\n * // Example 1: Auto-resize to window\n * await app.init({ resizeTo: window });\n *\n * // Example 2: Auto-resize to specific element\n * const container = document.querySelector('#game-container');\n * await app.init({ resizeTo: container });\n *\n * // Example 3: Change resize target at runtime\n * app.resizeTo = window; // Enable auto-resize to window\n * app.resizeTo = null; // Disable auto-resize\n * ```\n * @category app\n * @standard\n */\nexport class ResizePlugin\n{\n /** @ignore */\n public static extension: ExtensionMetadata = ExtensionType.Application;\n /** @internal */\n public static resizeTo: Window | HTMLElement;\n /** @internal */\n public static resize: () => void;\n /** @internal */\n public static renderer: ResizeableRenderer;\n /** @internal */\n public static queueResize: () => void;\n /** @internal */\n public static render: () => void;\n /** @internal */\n private static _resizeId: number;\n /** @internal */\n private static _resizeTo: Window | HTMLElement;\n /** @internal */\n private static _cancelResize: () => void;\n\n /**\n * Initialize the plugin with scope of application instance\n * @private\n * @param {object} [options] - See application options\n */\n public static init(options: ResizePluginOptions): void\n {\n Object.defineProperty(this, 'resizeTo',\n {\n configurable: true,\n set(dom: Window | HTMLElement)\n {\n globalThis.removeEventListener('resize', this.queueResize);\n this._resizeTo = dom;\n if (dom)\n {\n globalThis.addEventListener('resize', this.queueResize);\n this.resize();\n }\n },\n get()\n {\n return this._resizeTo;\n },\n });\n\n this.queueResize = (): void =>\n {\n if (!this._resizeTo)\n {\n return;\n }\n\n this._cancelResize();\n\n // // Throttle resize events per raf\n this._resizeId = requestAnimationFrame(() => this.resize());\n };\n\n this._cancelResize = (): void =>\n {\n if (this._resizeId)\n {\n cancelAnimationFrame(this._resizeId);\n this._resizeId = null;\n }\n };\n\n this.resize = (): void =>\n {\n if (!this._resizeTo)\n {\n return;\n }\n\n // clear queue resize\n this._cancelResize();\n\n let width: number;\n let height: number;\n\n // Resize to the window\n if (this._resizeTo === globalThis.window)\n {\n width = globalThis.innerWidth;\n height = globalThis.innerHeight;\n }\n // Resize to other HTML entities\n else\n {\n const { clientWidth, clientHeight } = this._resizeTo as HTMLElement;\n\n width = clientWidth;\n height = clientHeight;\n }\n\n this.renderer.resize(width, height);\n this.render();\n };\n\n // On resize\n this._resizeId = null;\n this._resizeTo = null;\n this.resizeTo = options.resizeTo || null;\n }\n\n /**\n * Clean up the ticker, scoped to application\n * @private\n */\n public static destroy(): void\n {\n globalThis.removeEventListener('resize', this.queueResize);\n this._cancelResize();\n this._cancelResize = null;\n this.queueResize = null;\n this.resizeTo = null;\n this.resize = null;\n }\n}\n","import { lru } from 'tiny-lru';\nimport { DOMAdapter } from '../../../environment/adapter';\nimport { measureTaggedText } from './utils/measureTaggedText';\nimport { hasTagMarkup, hasTagStyles, type TextStyleRun } from './utils/parseTaggedText';\nimport { isBreakingSpace as isBreakingSpaceUtil, NEWLINE_MATCH_REGEX } from './utils/textTokenization';\nimport { wordWrap } from './utils/wordWrap';\n\nimport type { ICanvas, ICanvasRenderingContext2DSettings } from '../../../environment/canvas/ICanvas';\nimport type { ICanvasRenderingContext2D } from '../../../environment/canvas/ICanvasRenderingContext2D';\nimport type { TextStyle } from '../TextStyle';\nimport type { FontMetrics } from './utils/types';\n\n// The type for Intl.Segmenter is only available since TypeScript 4.7.2, so let's make a polyfill for it.\ninterface ISegmentData\n{\n segment: string;\n}\ninterface ISegments\n{\n [Symbol.iterator](): IterableIterator<ISegmentData>;\n}\ninterface ISegmenter\n{\n segment(input: string): ISegments;\n}\ninterface IIntl\n{\n Segmenter?: {\n prototype: ISegmenter;\n /**\n * Creates a new Intl.Segmenter object.\n * @returns A new Intl.Segmenter object.\n */\n new(): ISegmenter;\n };\n}\n\n// Default settings used for all getContext calls\nconst contextSettings: ICanvasRenderingContext2DSettings = {\n // TextMetrics requires getImageData readback for measuring fonts.\n willReadFrequently: true,\n};\n\n/**\n * The TextMetrics object represents the measurement of a block of text with a specified style.\n * @example\n * import { CanvasTextMetrics, TextStyle } from 'pixi.js';\n *\n * const style = new TextStyle({\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * });\n * const textMetrics = CanvasTextMetrics.measureText('Your text', style);\n * @category text\n * @advanced\n */\nexport class CanvasTextMetrics\n{\n /** The text that was measured. */\n public text: string;\n\n /** The style that was measured. */\n public style: TextStyle;\n\n /** The measured width of the text. */\n public width: number;\n\n /** The measured height of the text. */\n public height: number;\n\n /** An array of lines of the text broken by new lines and wrapping is specified in style. */\n public lines: string[];\n\n /** An array of the line widths for each line matched to `lines`. */\n public lineWidths: number[];\n\n /** The measured line height for this style. */\n public lineHeight: number;\n\n /** The maximum line width for all measured lines. */\n public maxLineWidth: number;\n\n /** The font properties object from TextMetrics.measureFont. */\n public fontProperties: FontMetrics;\n\n /**\n * Per-line style runs for tagged text rendering.\n * Each element is an array of runs for that line.\n * Only populated when text contains tag markup.\n * @internal\n */\n public runsByLine?: TextStyleRun[][];\n\n /**\n * Per-line ascent values for tagged text with mixed fonts.\n * Represents the max ascent across all runs on each line.\n * Only populated when text contains tag markup.\n * @internal\n */\n public lineAscents?: number[];\n\n /**\n * Per-line descent values for tagged text with mixed fonts.\n * Represents the max descent across all runs on each line.\n * Only populated when text contains tag markup.\n * @internal\n */\n public lineDescents?: number[];\n\n /**\n * Per-line heights for tagged text with mixed fonts.\n * Each line may have different height based on the fonts used.\n * Only populated when text contains tag markup.\n * @internal\n */\n public lineHeights?: number[];\n\n /**\n * Whether any run in the tagged text has a drop shadow.\n * Cached during measurement to avoid per-render iteration.\n * Only populated when text contains tag markup.\n * @internal\n */\n public hasDropShadow?: boolean;\n\n /**\n * String used for calculate font metrics.\n * These characters are all tall to help calculate the height required for text.\n */\n public static METRICS_STRING = '|ÉqÅ';\n\n /** Baseline symbol for calculate font metrics. */\n public static BASELINE_SYMBOL = 'M';\n\n /** Baseline multiplier for calculate font metrics. */\n public static BASELINE_MULTIPLIER = 1.4;\n\n /** Height multiplier for setting height of canvas to calculate font metrics. */\n public static HEIGHT_MULTIPLIER = 2.0;\n\n /**\n * A Unicode \"character\", or \"grapheme cluster\", can be composed of multiple Unicode code points,\n * such as letters with diacritical marks (e.g. `'\\u0065\\u0301'`, letter e with acute)\n * or emojis with modifiers (e.g. `'\\uD83E\\uDDD1\\u200D\\uD83D\\uDCBB'`, technologist).\n * The new `Intl.Segmenter` API in ES2022 can split the string into grapheme clusters correctly. If it is not available,\n * PixiJS will fallback to use the iterator of String, which can only spilt the string into code points.\n * If you want to get full functionality in environments that don't support `Intl.Segmenter` (such as Firefox),\n * you can use other libraries such as [grapheme-splitter]{@link https://www.npmjs.com/package/grapheme-splitter}\n * or [graphemer]{@link https://www.npmjs.com/package/graphemer} to create a polyfill. Since these libraries can be\n * relatively large in size to handle various Unicode grapheme clusters properly, PixiJS won't use them directly.\n */\n public static graphemeSegmenter: (s: string) => string[] = (() =>\n {\n if (typeof (Intl as IIntl)?.Segmenter === 'function')\n {\n const segmenter = new (Intl as IIntl).Segmenter();\n\n return (s: string) =>\n {\n const segments = segmenter.segment(s);\n const result = [];\n\n let i = 0;\n\n for (const segment of segments)\n {\n result[i++] = (segment.segment);\n }\n\n return result;\n };\n }\n\n return (s: string) => [...s];\n })();\n\n public static _experimentalLetterSpacingSupported?: boolean;\n\n /**\n * Checking that we can use modern canvas 2D API.\n *\n * Note: This is an unstable API, Chrome < 94 use `textLetterSpacing`, later versions use `letterSpacing`.\n * @see CanvasTextMetrics.experimentalLetterSpacing\n * @see https://developer.mozilla.org/en-US/docs/Web/API/ICanvasRenderingContext2D/letterSpacing\n * @see https://developer.chrome.com/origintrials/#/view_trial/3585991203293757441\n */\n public static get experimentalLetterSpacingSupported(): boolean\n {\n let result = CanvasTextMetrics._experimentalLetterSpacingSupported;\n\n if (result === undefined)\n {\n const proto = DOMAdapter.get().getCanvasRenderingContext2D().prototype;\n\n result\n = CanvasTextMetrics._experimentalLetterSpacingSupported\n = 'letterSpacing' in proto || 'textLetterSpacing' in proto;\n }\n\n return result;\n }\n\n /**\n * New rendering behavior for letter-spacing which uses Chrome's new native API. This will\n * lead to more accurate letter-spacing results because it does not try to manually draw\n * each character. However, this Chrome API is experimental and may not serve all cases yet.\n * @see CanvasTextMetrics.experimentalLetterSpacingSupported\n */\n public static experimentalLetterSpacing = false;\n\n /** Cache of {@link TextMetrics.FontMetrics} objects. */\n private static _fonts: Record<string, FontMetrics> = {};\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private static __canvas: ICanvas;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private static __context: ICanvasRenderingContext2D;\n\n /** Cache for measured text metrics */\n private static readonly _measurementCache = lru<CanvasTextMetrics>(1000);\n\n /**\n * @param text - the text that was measured\n * @param style - the style that was measured\n * @param width - the measured width of the text\n * @param height - the measured height of the text\n * @param lines - an array of the lines of text broken by new lines and wrapping if specified in style\n * @param lineWidths - an array of the line widths for each line matched to `lines`\n * @param lineHeight - the measured line height for this style\n * @param maxLineWidth - the maximum line width for all measured lines\n * @param fontProperties - the font properties object from TextMetrics.measureFont\n * @param taggedData - optional object containing tagged text specific data\n * @param taggedData.runsByLine - per-line style runs for tagged text\n * @param taggedData.lineAscents - per-line ascent values for tagged text\n * @param taggedData.lineDescents - per-line descent values for tagged text\n * @param taggedData.lineHeights - per-line height values for tagged text\n * @param taggedData.hasDropShadow - whether any run has a drop shadow\n */\n constructor(\n text: string,\n style: TextStyle,\n width: number,\n height: number,\n lines: string[],\n lineWidths: number[],\n lineHeight: number,\n maxLineWidth: number,\n fontProperties: FontMetrics,\n taggedData?: {\n runsByLine?: TextStyleRun[][],\n lineAscents?: number[],\n lineDescents?: number[],\n lineHeights?: number[],\n hasDropShadow?: boolean,\n },\n )\n {\n this.text = text;\n this.style = style;\n this.width = width;\n this.height = height;\n this.lines = lines;\n this.lineWidths = lineWidths;\n this.lineHeight = lineHeight;\n this.maxLineWidth = maxLineWidth;\n this.fontProperties = fontProperties;\n\n if (taggedData)\n {\n this.runsByLine = taggedData.runsByLine;\n this.lineAscents = taggedData.lineAscents;\n this.lineDescents = taggedData.lineDescents;\n this.lineHeights = taggedData.lineHeights;\n this.hasDropShadow = taggedData.hasDropShadow;\n }\n }\n\n /**\n * Measures the supplied string of text and returns a Rectangle.\n * @param text - The text to measure.\n * @param style - The text style to use for measuring\n * @param canvas - optional specification of the canvas to use for measuring.\n * @param wordWrap\n * @returns Measured width and height of the text.\n */\n public static measureText(\n text = ' ',\n style: TextStyle,\n canvas: ICanvas = CanvasTextMetrics._canvas,\n wordWrap: boolean = style.wordWrap,\n ): CanvasTextMetrics\n {\n const textKey = `${text}-${style.styleKey}-wordWrap-${wordWrap}`;\n\n // check if we have already measured this text with the same style\n if (CanvasTextMetrics._measurementCache.has(textKey))\n {\n return CanvasTextMetrics._measurementCache.get(textKey);\n }\n\n // Check if we need to use tagged text measurement\n const isTagged = hasTagStyles(style) && hasTagMarkup(text);\n\n if (isTagged)\n {\n const result = measureTaggedText(\n text,\n style,\n wordWrap,\n CanvasTextMetrics._context,\n CanvasTextMetrics._measureText,\n CanvasTextMetrics._measureTextAdvance,\n CanvasTextMetrics.measureFont,\n CanvasTextMetrics.canBreakChars,\n CanvasTextMetrics.wordWrapSplit,\n );\n\n const measurements = new CanvasTextMetrics(\n text,\n style,\n result.width,\n result.height,\n result.lines,\n result.lineWidths,\n result.lineHeight,\n result.maxLineWidth,\n result.fontProperties,\n {\n runsByLine: result.runsByLine,\n lineAscents: result.lineAscents,\n lineDescents: result.lineDescents,\n lineHeights: result.lineHeights,\n hasDropShadow: result.hasDropShadow,\n },\n );\n\n CanvasTextMetrics._measurementCache.set(textKey, measurements);\n\n return measurements;\n }\n\n const font = style._fontString;\n const fontProperties = CanvasTextMetrics.measureFont(font);\n\n // fallback in case UA disallow canvas data extraction\n if (fontProperties.fontSize === 0)\n {\n fontProperties.fontSize = style.fontSize as number;\n fontProperties.ascent = style.fontSize as number;\n fontProperties.descent = 0;\n }\n\n const context = CanvasTextMetrics._context;\n\n context.font = font;\n\n const outputText = wordWrap\n ? CanvasTextMetrics._wordWrap(text, style, canvas)\n : text;\n const lines = outputText.split(NEWLINE_MATCH_REGEX);\n const lineWidths = new Array<number>(lines.length);\n let maxLineWidth = 0;\n\n for (let i = 0; i < lines.length; i++)\n {\n const lineWidth = CanvasTextMetrics._measureText(lines[i], style.letterSpacing, context);\n\n lineWidths[i] = lineWidth;\n maxLineWidth = Math.max(maxLineWidth, lineWidth);\n }\n\n const strokeWidth = style._stroke?.width ?? 0;\n const lineHeight = style.lineHeight || fontProperties.fontSize;\n\n const width = CanvasTextMetrics._adjustWidthForStyle(maxLineWidth, style);\n\n // Calculate height\n const baseHeight = Math.max(lineHeight, fontProperties.fontSize + strokeWidth)\n + ((lines.length - 1) * (lineHeight + style.leading));\n const height = CanvasTextMetrics._adjustHeightForStyle(baseHeight, style);\n\n const measurements = new CanvasTextMetrics(\n text,\n style,\n width,\n height,\n lines,\n lineWidths,\n lineHeight + style.leading,\n maxLineWidth,\n fontProperties\n );\n\n // cache the measurements\n CanvasTextMetrics._measurementCache.set(textKey, measurements);\n\n return measurements;\n }\n\n /**\n * Adjusts the measured width to account for stroke and drop shadow.\n * @param baseWidth - The base content width\n * @param style - The text style\n * @returns The adjusted width\n */\n private static _adjustWidthForStyle(baseWidth: number, style: TextStyle): number\n {\n const strokeWidth = style._stroke?.width || 0;\n let width = baseWidth + strokeWidth;\n\n if (style.dropShadow)\n {\n width += style.dropShadow.distance;\n }\n\n return width;\n }\n\n /**\n * Adjusts the measured height to account for drop shadow.\n * @param baseHeight - The base content height\n * @param style - The text style\n * @returns The adjusted height\n */\n private static _adjustHeightForStyle(baseHeight: number, style: TextStyle): number\n {\n let height = baseHeight;\n\n if (style.dropShadow)\n {\n height += style.dropShadow.distance;\n }\n\n return height;\n }\n\n /**\n * Measures the rendered width of a string, accounting for letter spacing and using the provided context.\n * Returns the larger of the advance width and the bounding box width.\n * @param text - The text to measure\n * @param letterSpacing - Letter spacing in pixels\n * @param context - Canvas 2D context\n * @returns The measured width of the text with spacing\n * @internal\n */\n public static _measureText(\n text: string,\n letterSpacing: number,\n context: ICanvasRenderingContext2D\n ): number\n {\n const { metricWidth, metrics, letterSpacingVal } = CanvasTextMetrics._measureTextCore(text, letterSpacing, context);\n\n const actualBoundingBoxLeft = -(metrics.actualBoundingBoxLeft ?? 0);\n const actualBoundingBoxRight = metrics.actualBoundingBoxRight ?? 0;\n let boundsWidth = actualBoundingBoxRight - actualBoundingBoxLeft;\n\n if (metrics.width > 0)\n {\n boundsWidth += letterSpacingVal;\n }\n\n return Math.max(metricWidth, boundsWidth);\n }\n\n /**\n * Measures advance width only (no bounding box). Advance widths are additive,\n * making this suitable for word wrap line-fitting where per-token widths must sum correctly.\n * @param text - The text to measure\n * @param letterSpacing - Letter spacing in pixels\n * @param context - Canvas 2D context\n * @returns The advance width of the text\n * @internal\n */\n public static _measureTextAdvance(\n text: string,\n letterSpacing: number,\n context: ICanvasRenderingContext2D\n ): number\n {\n return CanvasTextMetrics._measureTextCore(text, letterSpacing, context).metricWidth;\n }\n\n /**\n * Shared measurement core: sets up letter spacing on the context, calls\n * context.measureText, and adjusts the advance width for letter spacing.\n * @param text\n * @param letterSpacing\n * @param context\n * @internal\n */\n private static _measureTextCore(\n text: string,\n letterSpacing: number,\n context: ICanvasRenderingContext2D,\n ): { metricWidth: number; metrics: TextMetrics; letterSpacingVal: number }\n {\n let useExperimentalLetterSpacing = false;\n\n if (CanvasTextMetrics.experimentalLetterSpacingSupported)\n {\n if (CanvasTextMetrics.experimentalLetterSpacing)\n {\n context.letterSpacing = `${letterSpacing}px`;\n context.textLetterSpacing = `${letterSpacing}px`;\n useExperimentalLetterSpacing = true;\n }\n else\n {\n context.letterSpacing = '0px';\n context.textLetterSpacing = '0px';\n }\n }\n\n const metrics = context.measureText(text);\n let metricWidth = metrics.width;\n let letterSpacingVal = 0;\n\n if (metricWidth > 0)\n {\n if (useExperimentalLetterSpacing)\n {\n letterSpacingVal = -letterSpacing;\n }\n else\n {\n letterSpacingVal = (CanvasTextMetrics.graphemeSegmenter(text).length - 1) * letterSpacing;\n }\n metricWidth += letterSpacingVal;\n }\n\n return { metricWidth, metrics, letterSpacingVal };\n }\n\n /**\n * Applies newlines to a string to have it optimally fit into the horizontal\n * bounds set by the Text object's wordWrapWidth property.\n * @param text - String to apply word wrapping to\n * @param style - the style to use when wrapping\n * @param canvas - optional specification of the canvas to use for measuring.\n * @returns New string with new lines applied where required\n */\n private static _wordWrap(\n text: string,\n style: TextStyle,\n canvas: ICanvas = CanvasTextMetrics._canvas\n ): string\n {\n return wordWrap(\n text,\n style,\n canvas,\n CanvasTextMetrics._measureTextAdvance,\n CanvasTextMetrics.canBreakWords,\n CanvasTextMetrics.canBreakChars,\n CanvasTextMetrics.wordWrapSplit,\n );\n }\n\n /**\n * Determines if char is a breaking whitespace.\n *\n * It allows one to determine whether char should be a breaking whitespace\n * For example certain characters in CJK langs or numbers.\n * It must return a boolean.\n * @param char - The character\n * @param [_nextChar] - The next character\n * @returns True if whitespace, False otherwise.\n */\n public static isBreakingSpace(char: string, _nextChar?: string): boolean\n {\n return isBreakingSpaceUtil(char, _nextChar);\n }\n\n /**\n * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.\n *\n * It allows one to customise which words should break\n * Examples are if the token is CJK or numbers.\n * It must return a boolean.\n * @param _token - The token\n * @param breakWords - The style attr break words\n * @returns Whether to break word or not\n */\n public static canBreakWords(_token: string, breakWords: boolean): boolean\n {\n return breakWords;\n }\n\n /**\n * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.\n *\n * It allows one to determine whether a pair of characters\n * should be broken by newlines\n * For example certain characters in CJK langs or numbers.\n * It must return a boolean.\n * @param _char - The character\n * @param _nextChar - The next character\n * @param _token - The token/word the characters are from\n * @param _index - The index in the token of the char\n * @param _breakWords - The style attr break words\n * @returns whether to break word or not\n */\n public static canBreakChars(_char: string, _nextChar: string, _token: string, _index: number,\n _breakWords: boolean): boolean\n {\n return true;\n }\n\n /**\n * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.\n *\n * It is called when a token (usually a word) has to be split into separate pieces\n * in order to determine the point to break a word.\n * It must return an array of characters.\n * @param token - The token to split\n * @returns The characters of the token\n * @see CanvasTextMetrics.graphemeSegmenter\n */\n public static wordWrapSplit(token: string): string[]\n {\n return CanvasTextMetrics.graphemeSegmenter(token);\n }\n\n /**\n * Calculates the ascent, descent and fontSize of a given font-style\n * @param font - String representing the style of the font\n * @returns Font properties object\n */\n public static measureFont(font: string): FontMetrics\n {\n // as this method is used for preparing assets, don't recalculate things if we don't need to\n if (CanvasTextMetrics._fonts[font])\n {\n return CanvasTextMetrics._fonts[font];\n }\n\n const context = CanvasTextMetrics._context;\n\n context.font = font;\n const metrics = context.measureText(CanvasTextMetrics.METRICS_STRING + CanvasTextMetrics.BASELINE_SYMBOL);\n\n const ascent = metrics.actualBoundingBoxAscent ?? 0;\n const descent = metrics.actualBoundingBoxDescent ?? 0;\n\n const properties = {\n ascent,\n descent,\n fontSize: ascent + descent\n };\n\n CanvasTextMetrics._fonts[font] = properties;\n\n return properties;\n }\n\n /**\n * Clear font metrics in metrics cache.\n * @param {string} [font] - font name. If font name not set then clear cache for all fonts.\n */\n public static clearMetrics(font = ''): void\n {\n if (font)\n {\n delete CanvasTextMetrics._fonts[font];\n }\n else\n {\n CanvasTextMetrics._fonts = {};\n }\n }\n\n /**\n * Cached canvas element for measuring text\n * TODO: this should be private, but isn't because of backward compat, will fix later.\n * @ignore\n */\n public static get _canvas(): ICanvas\n {\n if (!CanvasTextMetrics.__canvas)\n {\n let canvas: ICanvas;\n\n try\n {\n // OffscreenCanvas2D measureText can be up to 40% faster.\n const c = new OffscreenCanvas(0, 0);\n const context = c.getContext('2d', contextSettings);\n\n if (context?.measureText)\n {\n CanvasTextMetrics.__canvas = c as ICanvas;\n\n return c as ICanvas;\n }\n\n canvas = DOMAdapter.get().createCanvas();\n }\n catch (_cx)\n {\n canvas = DOMAdapter.get().createCanvas();\n }\n canvas.width = canvas.height = 10;\n CanvasTextMetrics.__canvas = canvas;\n }\n\n return CanvasTextMetrics.__canvas;\n }\n\n /**\n * TODO: this should be private, but isn't because of backward compat, will fix later.\n * @ignore\n */\n public static get _context(): ICanvasRenderingContext2D\n {\n if (!CanvasTextMetrics.__context)\n {\n CanvasTextMetrics.__context = CanvasTextMetrics._canvas.getContext('2d', contextSettings);\n }\n\n return CanvasTextMetrics.__context;\n }\n}\n","import { browserExt } from './environment-browser/browserExt';\nimport { webworkerExt } from './environment-webworker/webworkerExt';\nimport { extensions } from './extensions/Extensions';\nimport './rendering/init';\nimport './spritesheet/init';\n\nexport * from './accessibility';\nexport * from './advanced-blend-modes';\nexport * from './app';\nexport * from './assets';\nexport * from './color';\nexport * from './compressed-textures';\nexport * from './culling';\nexport * from './dom';\nexport * from './environment';\nexport * from './environment-browser';\nexport * from './environment-webworker';\nexport * from './events';\nexport * from './extensions';\nexport * from './filters';\nexport * from './maths';\nexport * from './prepare';\nexport * from './rendering';\nexport * from './scene';\nexport * from './spritesheet';\nexport * from './ticker';\nexport * from './utils';\n\nextensions.add(browserExt, webworkerExt);\n"],"names":["type","load","extension","priority","Environment","name","wordWrap","measurements","isBreakingSpaceUtil","currentPosition"],"mappings":"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","ignoreList":[2,8,9,10,14,15,16,17,18,19,20,21,22,23,24,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40]}