visualfries 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +213 -0
  3. package/dist/DIContainer.d.ts +4 -0
  4. package/dist/DIContainer.js +145 -0
  5. package/dist/SceneBuilder.svelte.d.ts +8574 -0
  6. package/dist/SceneBuilder.svelte.js +409 -0
  7. package/dist/adapters/subtitleHelpers.d.ts +2 -0
  8. package/dist/adapters/subtitleHelpers.js +187 -0
  9. package/dist/animations/AnimationContext.d.ts +17 -0
  10. package/dist/animations/AnimationContext.js +72 -0
  11. package/dist/animations/AnimationPresetsRegister.d.ts +362 -0
  12. package/dist/animations/AnimationPresetsRegister.js +20 -0
  13. package/dist/animations/AnimationSetup.d.ts +8 -0
  14. package/dist/animations/AnimationSetup.js +30 -0
  15. package/dist/animations/SplitTextCache.d.ts +28 -0
  16. package/dist/animations/SplitTextCache.js +68 -0
  17. package/dist/animations/animationBuilder.d.ts +31 -0
  18. package/dist/animations/animationBuilder.js +255 -0
  19. package/dist/animations/animationPreset.d.ts +7 -0
  20. package/dist/animations/animationPreset.js +31 -0
  21. package/dist/animations/builders/AnimationPresetFactory.d.ts +43 -0
  22. package/dist/animations/builders/AnimationPresetFactory.js +139 -0
  23. package/dist/animations/builders/LineHighlighterAnimationBuilder.d.ts +16 -0
  24. package/dist/animations/builders/LineHighlighterAnimationBuilder.js +183 -0
  25. package/dist/animations/builders/WordHighlighterAnimationBuilder.d.ts +15 -0
  26. package/dist/animations/builders/WordHighlighterAnimationBuilder.js +180 -0
  27. package/dist/animations/engines/AnimationEngineAdaptor.d.ts +107 -0
  28. package/dist/animations/engines/AnimationEngineAdaptor.js +1 -0
  29. package/dist/animations/engines/GSAPEngineAdaptor.d.ts +21 -0
  30. package/dist/animations/engines/GSAPEngineAdaptor.js +145 -0
  31. package/dist/animations/presets/index.d.ts +2 -0
  32. package/dist/animations/presets/index.js +3 -0
  33. package/dist/animations/presets/lines.d.ts +52 -0
  34. package/dist/animations/presets/lines.js +547 -0
  35. package/dist/animations/presets/words.d.ts +31 -0
  36. package/dist/animations/presets/words.js +268 -0
  37. package/dist/animations/transformers/AnimationReferenceTransformer.d.ts +9 -0
  38. package/dist/animations/transformers/AnimationReferenceTransformer.js +114 -0
  39. package/dist/builders/PixiComponentBuilder.d.ts +63 -0
  40. package/dist/builders/PixiComponentBuilder.js +112 -0
  41. package/dist/builders/_ComponentState.svelte.d.ts +795 -0
  42. package/dist/builders/_ComponentState.svelte.js +203 -0
  43. package/dist/builders/html/HtmlBuilder.d.ts +66 -0
  44. package/dist/builders/html/HtmlBuilder.js +171 -0
  45. package/dist/builders/html/HtmlBuilderFactory.d.ts +27 -0
  46. package/dist/builders/html/HtmlBuilderFactory.js +30 -0
  47. package/dist/builders/html/StyleBuilder.d.ts +13 -0
  48. package/dist/builders/html/StyleBuilder.js +133 -0
  49. package/dist/builders/html/StyleProcessor.d.ts +9 -0
  50. package/dist/builders/html/StyleProcessor.js +1 -0
  51. package/dist/builders/html/TextComponentHtmlBuilder.d.ts +16 -0
  52. package/dist/builders/html/TextComponentHtmlBuilder.js +93 -0
  53. package/dist/builders/html/TextShadowBuilder.d.ts +60 -0
  54. package/dist/builders/html/TextShadowBuilder.js +227 -0
  55. package/dist/builders/html/processors/AppearanceStyleProcessor.d.ts +5 -0
  56. package/dist/builders/html/processors/AppearanceStyleProcessor.js +57 -0
  57. package/dist/builders/html/processors/TextAppearanceStyleProcessor.d.ts +5 -0
  58. package/dist/builders/html/processors/TextAppearanceStyleProcessor.js +37 -0
  59. package/dist/builders/html/processors/TextEffectsStyleProcessor.d.ts +6 -0
  60. package/dist/builders/html/processors/TextEffectsStyleProcessor.js +68 -0
  61. package/dist/commands/Command.d.ts +6 -0
  62. package/dist/commands/Command.js +1 -0
  63. package/dist/commands/CommandRunner.d.ts +28 -0
  64. package/dist/commands/CommandRunner.js +81 -0
  65. package/dist/commands/CommandTypes.d.ts +11 -0
  66. package/dist/commands/CommandTypes.js +13 -0
  67. package/dist/commands/PauseCommand.d.ts +4 -0
  68. package/dist/commands/PauseCommand.js +5 -0
  69. package/dist/commands/PlayCommand.d.ts +4 -0
  70. package/dist/commands/PlayCommand.js +6 -0
  71. package/dist/commands/RenderCommand.d.ts +15 -0
  72. package/dist/commands/RenderCommand.js +18 -0
  73. package/dist/commands/RenderFrameCommand.d.ts +17 -0
  74. package/dist/commands/RenderFrameCommand.js +93 -0
  75. package/dist/commands/ReplaceSourceOnTimeCommand.d.ts +4 -0
  76. package/dist/commands/ReplaceSourceOnTimeCommand.js +22 -0
  77. package/dist/commands/SeekCommand.d.ts +15 -0
  78. package/dist/commands/SeekCommand.js +39 -0
  79. package/dist/commands/UpdateComponentCommand.d.ts +4 -0
  80. package/dist/commands/UpdateComponentCommand.js +17 -0
  81. package/dist/components/AnimatedGIF.d.ts +201 -0
  82. package/dist/components/AnimatedGIF.js +391 -0
  83. package/dist/components/Component.svelte.d.ts +33 -0
  84. package/dist/components/Component.svelte.js +152 -0
  85. package/dist/components/ComponentContext.svelte.d.ts +33 -0
  86. package/dist/components/ComponentContext.svelte.js +105 -0
  87. package/dist/components/hooks/AnimationHook.d.ts +25 -0
  88. package/dist/components/hooks/AnimationHook.js +180 -0
  89. package/dist/components/hooks/CanvasShapeHook.d.ts +12 -0
  90. package/dist/components/hooks/CanvasShapeHook.js +229 -0
  91. package/dist/components/hooks/HtmlAnimationHook.d.ts +8 -0
  92. package/dist/components/hooks/HtmlAnimationHook.js +70 -0
  93. package/dist/components/hooks/HtmlTextHook.d.ts +16 -0
  94. package/dist/components/hooks/HtmlTextHook.js +102 -0
  95. package/dist/components/hooks/HtmlToCanvasHook.d.ts +16 -0
  96. package/dist/components/hooks/HtmlToCanvasHook.js +148 -0
  97. package/dist/components/hooks/ImageHook.d.ts +10 -0
  98. package/dist/components/hooks/ImageHook.js +45 -0
  99. package/dist/components/hooks/MediaHook.d.ts +15 -0
  100. package/dist/components/hooks/MediaHook.js +252 -0
  101. package/dist/components/hooks/MediaSeekingHook.d.ts +12 -0
  102. package/dist/components/hooks/MediaSeekingHook.js +204 -0
  103. package/dist/components/hooks/PixiDisplayObjectHook.d.ts +15 -0
  104. package/dist/components/hooks/PixiDisplayObjectHook.js +77 -0
  105. package/dist/components/hooks/PixiGifHook.d.ts +15 -0
  106. package/dist/components/hooks/PixiGifHook.js +97 -0
  107. package/dist/components/hooks/PixiProgressShapeHook.d.ts +12 -0
  108. package/dist/components/hooks/PixiProgressShapeHook.js +128 -0
  109. package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.d.ts +21 -0
  110. package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.js +210 -0
  111. package/dist/components/hooks/PixiTextureHook.d.ts +7 -0
  112. package/dist/components/hooks/PixiTextureHook.js +29 -0
  113. package/dist/components/hooks/PixiVideoTextureHook.d.ts +10 -0
  114. package/dist/components/hooks/PixiVideoTextureHook.js +35 -0
  115. package/dist/components/hooks/SubtitlesHook.d.ts +88 -0
  116. package/dist/components/hooks/SubtitlesHook.js +199 -0
  117. package/dist/components/hooks/VerifyGifHook.d.ts +7 -0
  118. package/dist/components/hooks/VerifyGifHook.js +27 -0
  119. package/dist/components/hooks/VerifyImageHook.d.ts +7 -0
  120. package/dist/components/hooks/VerifyImageHook.js +27 -0
  121. package/dist/components/hooks/VerifyMediaHook.d.ts +7 -0
  122. package/dist/components/hooks/VerifyMediaHook.js +21 -0
  123. package/dist/components/hooks/shapes/progress/CustomProgressRenderer.d.ts +8 -0
  124. package/dist/components/hooks/shapes/progress/CustomProgressRenderer.js +53 -0
  125. package/dist/components/hooks/shapes/progress/DoubleProgressRenderer.d.ts +8 -0
  126. package/dist/components/hooks/shapes/progress/DoubleProgressRenderer.js +69 -0
  127. package/dist/components/hooks/shapes/progress/LinearProgressRenderer.d.ts +8 -0
  128. package/dist/components/hooks/shapes/progress/LinearProgressRenderer.js +60 -0
  129. package/dist/components/hooks/shapes/progress/PerimeterProgressRenderer.d.ts +9 -0
  130. package/dist/components/hooks/shapes/progress/PerimeterProgressRenderer.js +213 -0
  131. package/dist/components/hooks/shapes/progress/ProgressRenderer.d.ts +17 -0
  132. package/dist/components/hooks/shapes/progress/ProgressRenderer.js +75 -0
  133. package/dist/components/hooks/shapes/progress/RadialProgressRenderer.d.ts +8 -0
  134. package/dist/components/hooks/shapes/progress/RadialProgressRenderer.js +50 -0
  135. package/dist/components/hooks/shapes/progress/index.d.ts +6 -0
  136. package/dist/components/hooks/shapes/progress/index.js +6 -0
  137. package/dist/composers/componentComposer.d.ts +55 -0
  138. package/dist/composers/componentComposer.js +118 -0
  139. package/dist/composers/layerComposer.d.ts +46 -0
  140. package/dist/composers/layerComposer.js +79 -0
  141. package/dist/composers/sceneComposer.d.ts +48 -0
  142. package/dist/composers/sceneComposer.js +92 -0
  143. package/dist/constants.d.ts +12 -0
  144. package/dist/constants.js +14 -0
  145. package/dist/directors/ComponentDirector.d.ts +20 -0
  146. package/dist/directors/ComponentDirector.js +86 -0
  147. package/dist/factories/SceneBuilderFactory.d.ts +15 -0
  148. package/dist/factories/SceneBuilderFactory.js +51 -0
  149. package/dist/fonts/GoogleFontsProvider.d.ts +12 -0
  150. package/dist/fonts/GoogleFontsProvider.js +125 -0
  151. package/dist/fonts/fontLoader.d.ts +15 -0
  152. package/dist/fonts/fontLoader.js +41 -0
  153. package/dist/fonts/types.d.ts +1 -0
  154. package/dist/fonts/types.js +1 -0
  155. package/dist/index.d.ts +11 -0
  156. package/dist/index.js +14 -0
  157. package/dist/layers/Layer.svelte.d.ts +8492 -0
  158. package/dist/layers/Layer.svelte.js +125 -0
  159. package/dist/managers/AppManager.svelte.d.ts +23 -0
  160. package/dist/managers/AppManager.svelte.js +89 -0
  161. package/dist/managers/ComponentsManager.svelte.d.ts +49 -0
  162. package/dist/managers/ComponentsManager.svelte.js +247 -0
  163. package/dist/managers/DomManager.d.ts +18 -0
  164. package/dist/managers/DomManager.js +73 -0
  165. package/dist/managers/EventManager.d.ts +7 -0
  166. package/dist/managers/EventManager.js +22 -0
  167. package/dist/managers/LayersManager.svelte.d.ts +8499 -0
  168. package/dist/managers/LayersManager.svelte.js +176 -0
  169. package/dist/managers/MediaManager.d.ts +32 -0
  170. package/dist/managers/MediaManager.js +243 -0
  171. package/dist/managers/RenderManager.d.ts +23 -0
  172. package/dist/managers/RenderManager.js +59 -0
  173. package/dist/managers/StateManager.svelte.d.ts +8746 -0
  174. package/dist/managers/StateManager.svelte.js +272 -0
  175. package/dist/managers/SubtitlesManager.svelte.d.ts +261 -0
  176. package/dist/managers/SubtitlesManager.svelte.js +1385 -0
  177. package/dist/managers/TimeManager.svelte.d.ts +6 -0
  178. package/dist/managers/TimeManager.svelte.js +18 -0
  179. package/dist/managers/TimelineManager.svelte.d.ts +25 -0
  180. package/dist/managers/TimelineManager.svelte.js +152 -0
  181. package/dist/registers.d.ts +12 -0
  182. package/dist/registers.js +29 -0
  183. package/dist/schemas/runtime/index.d.ts +3 -0
  184. package/dist/schemas/runtime/index.js +4 -0
  185. package/dist/schemas/runtime/types.d.ts +323 -0
  186. package/dist/schemas/runtime/types.js +12 -0
  187. package/dist/schemas/scene/animations.d.ts +89738 -0
  188. package/dist/schemas/scene/animations.js +211 -0
  189. package/dist/schemas/scene/components.js +515 -0
  190. package/dist/schemas/scene/core.js +160 -0
  191. package/dist/schemas/scene/index.d.ts +22 -0
  192. package/dist/schemas/scene/index.js +10 -0
  193. package/dist/schemas/scene/properties.d.ts +914 -0
  194. package/dist/schemas/scene/properties.js +398 -0
  195. package/dist/schemas/scene/subtitles.d.ts +1141 -0
  196. package/dist/schemas/scene/subtitles.js +111 -0
  197. package/dist/schemas/scene/utils.d.ts +1 -0
  198. package/dist/schemas/scene/utils.js +5 -0
  199. package/dist/seeds/SeedFactory.d.ts +59 -0
  200. package/dist/seeds/SeedFactory.js +99 -0
  201. package/dist/seeds/index.d.ts +8 -0
  202. package/dist/seeds/index.js +8 -0
  203. package/dist/transformers/ColorTransformer.d.ts +5 -0
  204. package/dist/transformers/ColorTransformer.js +67 -0
  205. package/dist/transformers/PixiColorTransformer.d.ts +22 -0
  206. package/dist/transformers/PixiColorTransformer.js +104 -0
  207. package/dist/utils/canvas.d.ts +6 -0
  208. package/dist/utils/canvas.js +18 -0
  209. package/dist/utils/document.d.ts +2 -0
  210. package/dist/utils/document.js +36 -0
  211. package/dist/utils/emoji.d.ts +10 -0
  212. package/dist/utils/emoji.js +51 -0
  213. package/dist/utils/html.d.ts +4 -0
  214. package/dist/utils/html.js +45 -0
  215. package/dist/utils/svgGenerator.d.ts +20 -0
  216. package/dist/utils/svgGenerator.js +103 -0
  217. package/dist/utils/utils.d.ts +5 -0
  218. package/dist/utils/utils.js +125 -0
  219. package/package.json +96 -0
@@ -0,0 +1,45 @@
1
+ import DOMPurify from 'dompurify';
2
+ export const sanitizeText = (str) => {
3
+ return DOMPurify.sanitize(str, {
4
+ ALLOWED_TAGS: [
5
+ 'em',
6
+ 'strong',
7
+ 'b',
8
+ 'i',
9
+ 'u',
10
+ 's',
11
+ 'br',
12
+ 'span',
13
+ 'h1',
14
+ 'h2',
15
+ 'h3',
16
+ 'h4',
17
+ 'h5',
18
+ 'h6'
19
+ // 'p' // schvalne zakazane
20
+ ],
21
+ ALLOWED_ATTR: ['class', 'style'],
22
+ ALLOW_DATA_ATTR: false,
23
+ ALLOW_UNKNOWN_PROTOCOLS: false
24
+ });
25
+ };
26
+ export const sanitizeHtml = (html) => {
27
+ return DOMPurify.sanitize(html);
28
+ };
29
+ export const sanitizeElement = (element) => {
30
+ const sanitized = sanitizeHtml(element.outerHTML);
31
+ const isSame = element.outerHTML === sanitized;
32
+ if (isSame) {
33
+ return element;
34
+ }
35
+ const parsed = new DOMParser().parseFromString(sanitized, 'text/html').body.firstChild;
36
+ if (!parsed) {
37
+ throw new Error('Failed to parse sanitized HTML.');
38
+ }
39
+ return parsed;
40
+ };
41
+ export const wrapEmojis = function (text) {
42
+ ///(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/gm;
43
+ const emojiRegex = /([\uD800-\uDBFF][\uDC00-\uDFFF](?:[\u200D\uFE0F][\uD800-\uDBFF][\uDC00-\uDFFF]){2,}|\uD83D\uDC69(?:\u200D(?:(?:\uD83D\uDC69\u200D)?\uD83D\uDC67|(?:\uD83D\uDC69\u200D)?\uD83D\uDC66)|\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D(?:\uD83D\uDC69\u200D)?\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D(?:\uD83D\uDC69\u200D)?\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]\uFE0F|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC6F\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3C-\uDD3E\uDDD6-\uDDDF])\u200D[\u2640\u2642]\uFE0F|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F\u200D[\u2640\u2642]|(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642])\uFE0F|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2695\u2696\u2708]|\uD83D\uDC69\u200D[\u2695\u2696\u2708]|\uD83D\uDC68(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708]))\uFE0F|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83D\uDC69\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|\uD83D\uDC68(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC66\u200D\uD83D\uDC66|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|(?:\uD83C[\uDFFB-\uDFFF])\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDD1-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\u200D(?:(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC67|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC66)|\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC69\uDC6E\uDC70-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD18-\uDD1C\uDD1E\uDD1F\uDD26\uDD30-\uDD39\uDD3D\uDD3E\uDDD1-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])?|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDEEB\uDEEC\uDEF4-\uDEF8]|\uD83E[\uDD10-\uDD3A\uDD3C-\uDD3E\uDD40-\uDD45\uDD47-\uDD4C\uDD50-\uDD6B\uDD80-\uDD97\uDDC0\uDDD0-\uDDE6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEF8]|\uD83E[\uDD10-\uDD3A\uDD3C-\uDD3E\uDD40-\uDD45\uDD47-\uDD4C\uDD50-\uDD6B\uDD80-\uDD97\uDDC0\uDDD0-\uDDE6])\uFE0F)/gm;
44
+ return text.replace(emojiRegex, '<span class="cf-emoji">$1</span>');
45
+ };
@@ -0,0 +1,20 @@
1
+ import type { TextAppearance } from '..';
2
+ export declare class SVGGenerator {
3
+ private fontCache;
4
+ private emojiCache;
5
+ private fontDataBase64Cache;
6
+ private fontDataBase64Inflight;
7
+ private static instance;
8
+ static getInstance(): SVGGenerator;
9
+ generateSVG(el: HTMLElement, config: TextAppearance, width: number, height: number, svgParentId?: string, fontText?: string): Promise<{
10
+ base: string;
11
+ content: string;
12
+ end: string;
13
+ }>;
14
+ private isTextEmoji;
15
+ private getFontDataArrayBuffer;
16
+ private arrayBufferToDataURL;
17
+ private getFontDataBase64;
18
+ clearCache(): void;
19
+ }
20
+ export declare const svgGenerator: SVGGenerator;
@@ -0,0 +1,103 @@
1
+ import { fetchFont } from '../fonts/fontLoader.js';
2
+ import { loadEmoji, getIconCode } from './emoji.js';
3
+ import { sanitizeHtml } from './html.js';
4
+ export class SVGGenerator {
5
+ fontCache = new Map();
6
+ emojiCache = new Map();
7
+ fontDataBase64Cache = {};
8
+ fontDataBase64Inflight = new Map();
9
+ static instance;
10
+ static getInstance() {
11
+ if (!SVGGenerator.instance) {
12
+ SVGGenerator.instance = new SVGGenerator();
13
+ }
14
+ return SVGGenerator.instance;
15
+ }
16
+ async generateSVG(el, config, width, height, svgParentId, fontText) {
17
+ const fontFamily = config.fontFamily
18
+ ? config.fontFamily.replace(/\s+/g, '+').replace(/^(.)/, (match) => match.toUpperCase())
19
+ : null;
20
+ const fontFamilyName = config.fontFamily
21
+ ? config.fontFamily.replace(/^(.)/, (match) => match.toUpperCase())
22
+ : null;
23
+ const weightAppend = config.fontWeight && config.fontWeight !== 'normal' && config.fontWeight !== '400'
24
+ ? `:wght@${config.fontWeight}`
25
+ : '';
26
+ const isEmoji = /^(\p{Emoji_Presentation}|\p{Emoji}\uFE0F|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\s)+$/u.test(el.textContent || '');
27
+ const getFontText = isEmoji ? 'a' : fontText || el.textContent;
28
+ let fontData = null;
29
+ if (fontFamily && !isEmoji) {
30
+ const cacheKey = `${fontFamily + weightAppend}_${getFontText}`;
31
+ if (cacheKey in this.fontDataBase64Cache) {
32
+ fontData = this.fontDataBase64Cache[cacheKey];
33
+ }
34
+ else if (this.fontDataBase64Inflight.has(cacheKey)) {
35
+ fontData = await this.fontDataBase64Inflight.get(cacheKey);
36
+ }
37
+ else {
38
+ const inflight = this.getFontDataBase64(fontFamily + weightAppend, getFontText || '').finally(() => this.fontDataBase64Inflight.delete(cacheKey));
39
+ this.fontDataBase64Inflight.set(cacheKey, inflight);
40
+ fontData = await inflight;
41
+ }
42
+ }
43
+ const styleTag = fontData
44
+ ? `<style>@font-face { font-family: ${fontFamilyName}; src: url('${fontData}') }</style>`
45
+ : '';
46
+ const correctedHTML = sanitizeHtml(el.outerHTML).replace(/<br\s*>/gi, '<br />');
47
+ // const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" version="1.1">${styleTag}<foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" style="transform: scale(1); transform-origin: top left; display: inline-block;" id="base">${el.outerHTML}</div></foreignObject></svg>`;
48
+ return {
49
+ base: `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" version="1.1">${styleTag}<foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" style="transform-origin: 0 0;">`,
50
+ content: correctedHTML,
51
+ end: `</div></foreignObject></svg>`
52
+ };
53
+ }
54
+ isTextEmoji(text) {
55
+ return /^(\p{Emoji_Presentation}|\p{Emoji}\uFE0F|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\s)+$/u.test(text);
56
+ }
57
+ async getFontDataArrayBuffer(fontFamily, text) {
58
+ const isEmoji = /^(\p{Emoji_Presentation}|\p{Emoji}\uFE0F|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\s)+$/u.test(text || '');
59
+ const cacheKey = isEmoji ? 'emojitext' : `${fontFamily}_${text}`;
60
+ if (!this.fontCache.has(cacheKey)) {
61
+ const fontData = await fetchFont(isEmoji ? 'Noto+Sans' : fontFamily, isEmoji ? 'a' : text);
62
+ if (!fontData) {
63
+ console.error('Failed to fetch font data: ' + cacheKey);
64
+ this.fontCache.set(cacheKey, null);
65
+ return null;
66
+ }
67
+ this.fontCache.set(cacheKey, fontData);
68
+ }
69
+ return this.fontCache.get(cacheKey);
70
+ }
71
+ async arrayBufferToDataURL(buffer, mimeType) {
72
+ // const uint = new Uint8Array(buffer);
73
+ // const base64 = 'data:' + mimeType + ';base64,' + (await toBase64(uint));
74
+ // return base64;
75
+ return new Promise((resolve, reject) => {
76
+ const blob = new Blob([buffer], { type: mimeType });
77
+ const reader = new FileReader();
78
+ reader.onload = () => resolve(reader.result);
79
+ reader.onerror = reject;
80
+ reader.readAsDataURL(blob);
81
+ });
82
+ }
83
+ async getFontDataBase64(fontFamily, text) {
84
+ const cacheKey = `${fontFamily}_${text}`;
85
+ if (cacheKey in this.fontDataBase64Cache) {
86
+ return this.fontDataBase64Cache[cacheKey];
87
+ }
88
+ const fontData = await this.getFontDataArrayBuffer(fontFamily, text);
89
+ if (fontData) {
90
+ const base64Data = await this.arrayBufferToDataURL(fontData, 'font/woff2');
91
+ this.fontDataBase64Cache[cacheKey] = base64Data;
92
+ return base64Data;
93
+ }
94
+ this.fontDataBase64Cache[cacheKey] = null;
95
+ return null;
96
+ }
97
+ clearCache() {
98
+ this.fontCache.clear();
99
+ this.emojiCache.clear();
100
+ this.fontDataBase64Cache = {};
101
+ }
102
+ }
103
+ export const svgGenerator = SVGGenerator.getInstance();
@@ -0,0 +1,5 @@
1
+ import type { Appearance, SceneLayer, SubtitleCollection } from '..';
2
+ import * as PIXI from 'pixi.js-legacy';
3
+ export declare function changeIdDeep<T>(obj: T): T;
4
+ export declare const buildCharactersListFromComponentsAndSubtitles: (layers: SceneLayer[], subtitles: Record<string, SubtitleCollection>) => string[];
5
+ export declare const setPlacementAndOpacity: (obj: PIXI.Sprite | PIXI.Graphics, c: Appearance) => void;
@@ -0,0 +1,125 @@
1
+ import { AppearanceShape, TextComponentShape } from '..';
2
+ import * as PIXI from 'pixi.js-legacy';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ export function changeIdDeep(obj) {
5
+ if (Array.isArray(obj)) {
6
+ return obj.map(changeIdDeep);
7
+ }
8
+ else if (obj !== null && typeof obj === 'object') {
9
+ const newObj = {};
10
+ for (const key in obj) {
11
+ if (key === 'id') {
12
+ newObj[key] = uuidv4(); // Replace this with the logic to generate new id
13
+ }
14
+ else {
15
+ newObj[key] = changeIdDeep(obj[key]);
16
+ }
17
+ }
18
+ return newObj;
19
+ }
20
+ return obj;
21
+ }
22
+ export const buildCharactersListFromComponentsAndSubtitles = function (layers, subtitles) {
23
+ const characters = ' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-,;:!$?\'"';
24
+ const charactestList = characters.split('');
25
+ const components = layers.flatMap((layer) => layer.components);
26
+ components.forEach((component) => {
27
+ if (component.type === 'TEXT') {
28
+ const c = component;
29
+ const text = c.text;
30
+ if (text) {
31
+ const textList = text.split('');
32
+ const missingChars = textList.filter((char) => {
33
+ // Check if the character is not whitespace, not in the characters list,
34
+ // and is a Unicode letter or number
35
+ return !/\s/.test(char) && !characters.includes(char) && /\p{L}|\p{N}/u.test(char);
36
+ });
37
+ // Add both uppercase and lowercase variants of missing chars
38
+ const variantChars = missingChars.flatMap((char) => [
39
+ char.toLowerCase(),
40
+ char.toUpperCase()
41
+ ]);
42
+ charactestList.push(...new Set(variantChars));
43
+ }
44
+ }
45
+ if (component.type === 'SUBTITLES' &&
46
+ component.source &&
47
+ component.source?.assetId &&
48
+ subtitles[component.source.assetId]) {
49
+ const c = component;
50
+ const source = c.source;
51
+ if (source && source.assetId && subtitles[source.assetId]) {
52
+ for (const langSubs of Object.values(subtitles[source.assetId])) {
53
+ for (const subtitle of langSubs) {
54
+ const textList = subtitle.text.split('');
55
+ const missingChars = textList.filter((char) => {
56
+ // Check if the character is not whitespace, not in the characters list,
57
+ // and is a Unicode letter or number
58
+ return !/\s/.test(char) && !characters.includes(char) && /\p{L}|\p{N}/u.test(char);
59
+ });
60
+ // Add both uppercase and lowercase variants of missing chars
61
+ const variantChars = missingChars.flatMap((char) => [
62
+ char.toLowerCase(),
63
+ char.toUpperCase()
64
+ ]);
65
+ charactestList.push(...new Set(variantChars));
66
+ }
67
+ }
68
+ }
69
+ }
70
+ });
71
+ return charactestList;
72
+ };
73
+ const rotationAwareConfig = function (config) {
74
+ const conf = AppearanceShape.safeParse(config);
75
+ if (!conf.success) {
76
+ return config;
77
+ }
78
+ const { rotation } = conf.data;
79
+ if (rotation) {
80
+ const { x, y, width, height } = conf.data;
81
+ const halfWidth = width / 2;
82
+ const halfHeight = height / 2;
83
+ const offsetX = halfWidth;
84
+ const offsetY = halfHeight;
85
+ const rotatedX = x + halfWidth;
86
+ const rotatedY = y + halfHeight;
87
+ return {
88
+ ...config,
89
+ x: rotatedX,
90
+ y: rotatedY,
91
+ offsetX,
92
+ offsetY,
93
+ rotation
94
+ };
95
+ }
96
+ return config;
97
+ };
98
+ export const setPlacementAndOpacity = function (obj, c) {
99
+ const conf = AppearanceShape.safeParse(c);
100
+ if (!conf.success) {
101
+ return;
102
+ }
103
+ const config = rotationAwareConfig(c);
104
+ const offsetX = config.offsetX ? config.offsetX : 0;
105
+ const offsetY = config.offsetY ? config.offsetY : 0;
106
+ obj.x = config.x;
107
+ obj.y = config.y;
108
+ obj.width = config.width;
109
+ obj.height = config.height;
110
+ obj.alpha = config.opacity || 1;
111
+ if (config.rotation) {
112
+ obj.angle = config.rotation;
113
+ }
114
+ if (obj instanceof PIXI.Sprite) {
115
+ if (config.rotation) {
116
+ obj.anchor.set(0.5);
117
+ // obj.pivot.x = offsetX;
118
+ // obj.pivot.y = offsetY;
119
+ }
120
+ }
121
+ else {
122
+ obj.pivot.x = offsetX;
123
+ obj.pivot.y = offsetY;
124
+ }
125
+ };
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "visualfries",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "author": "ContentFries",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/contentfries/visualfries"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/contentfries/visualfries/issues"
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "!dist/**/*.test.*",
16
+ "!dist/**/*.spec.*",
17
+ "!dist/stories/**"
18
+ ],
19
+ "sideEffects": [
20
+ "**/*.css"
21
+ ],
22
+ "@parcel/resolver-default": {
23
+ "packageExports": true
24
+ },
25
+ "main": "./dist/index.js",
26
+ "module": "./dist/index.js",
27
+ "svelte": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "type": "module",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "svelte": "./dist/index.js",
34
+ "import": "./dist/index.js",
35
+ "default": "./dist/index.js"
36
+ }
37
+ },
38
+ "peerDependencies": {
39
+ "svelte": "^5.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "@sveltejs/adapter-auto": "^3.0.0",
43
+ "@sveltejs/kit": "^2.46.4",
44
+ "@sveltejs/package": "^2.0.0",
45
+ "@sveltejs/vite-plugin-svelte": "^4.0.0",
46
+ "@tailwindcss/aspect-ratio": "^0.4.2",
47
+ "@tailwindcss/typography": "^0.5.16",
48
+ "@types/lodash-es": "^4.17.12",
49
+ "@types/md5": "^2.3.5",
50
+ "@types/node": "^20.17.30",
51
+ "@types/tinycolor2": "^1.4.6",
52
+ "@types/uuid": "^10.0.0",
53
+ "autoprefixer": "^10.4.20",
54
+ "daisyui": "^4.12.13",
55
+ "eslint": "^9.7.0",
56
+ "jsdom": "^26.1.0",
57
+ "knip": "^5.65.0",
58
+ "md5": "^2.3.0",
59
+ "postcss": "^8.4.47",
60
+ "prettier": "^3.3.2",
61
+ "prettier-plugin-svelte": "^3.2.6",
62
+ "prettier-plugin-tailwindcss": "^0.7.0",
63
+ "publint": "^0.2.0",
64
+ "svelte": "^5.0.0",
65
+ "svelte-check": "^4.0.0",
66
+ "tailwindcss": "^3.4.14",
67
+ "typescript": "^5.8.3",
68
+ "vite": "^5.0.11",
69
+ "vitest": "^2.0.4"
70
+ },
71
+ "dependencies": {
72
+ "awilix": "^12.0.3",
73
+ "dompurify": "^3.3.0",
74
+ "gifuct-js": "^2.1.2",
75
+ "gsap": "^3.13.0",
76
+ "hls.js": "^1.5.17",
77
+ "lodash-es": "^4.17.21",
78
+ "pixi.js-legacy": "^7.4.3",
79
+ "tinycolor2": "^1.6.0",
80
+ "uuid": "^10.0.0",
81
+ "zod": "^3.25.76"
82
+ },
83
+ "scripts": {
84
+ "dev": "vite dev",
85
+ "build": "vite build && pnpm run package",
86
+ "preview": "vite preview",
87
+ "package": "svelte-kit sync && svelte-package && publint",
88
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
89
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
90
+ "test": "pnpm run test:unit -- --run",
91
+ "test:unit": "vitest",
92
+ "lint": "eslint . && prettier --check .",
93
+ "format": "prettier --write .",
94
+ "knip": "knip"
95
+ }
96
+ }