super-three 0.133.3 → 0.136.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 (354) hide show
  1. package/build/three.js +1059 -783
  2. package/build/three.min.js +1 -1
  3. package/build/three.module.js +1424 -895
  4. package/examples/fonts/open-sans/open-sans-v15-cyrillic-ext_greek_greek-ext_cyrillic_latin_latin-ext_vietnamese-regular.woff +0 -0
  5. package/examples/fonts/open-sans/open-sans-v15-cyrillic-ext_greek_greek-ext_cyrillic_latin_latin-ext_vietnamese-regular.woff2 +0 -0
  6. package/examples/fonts/open-sans/open-sans.css +9 -0
  7. package/examples/fonts/tabler-icons/fonts/tabler-icons.eot +0 -0
  8. package/examples/fonts/tabler-icons/fonts/tabler-icons.svg +3966 -0
  9. package/examples/fonts/tabler-icons/fonts/tabler-icons.ttf +0 -0
  10. package/examples/fonts/tabler-icons/fonts/tabler-icons.woff +0 -0
  11. package/examples/fonts/tabler-icons/fonts/tabler-icons.woff2 +0 -0
  12. package/examples/fonts/tabler-icons/tabler-icons.min.css +4 -0
  13. package/examples/js/animation/CCDIKSolver.js +0 -1
  14. package/examples/js/animation/MMDPhysics.js +1 -3
  15. package/examples/js/controls/ArcballControls.js +99 -72
  16. package/examples/js/controls/DragControls.js +7 -0
  17. package/examples/js/controls/OrbitControls.js +5 -36
  18. package/examples/js/controls/TrackballControls.js +3 -2
  19. package/examples/js/controls/TransformControls.js +24 -1
  20. package/examples/js/csm/CSM.js +2 -2
  21. package/examples/js/csm/CSMFrustum.js +133 -0
  22. package/examples/js/curves/CurveExtras.js +0 -2
  23. package/examples/js/effects/AsciiEffect.js +2 -9
  24. package/examples/js/exporters/GLTFExporter.js +148 -64
  25. package/examples/js/exporters/USDZExporter.js +45 -26
  26. package/examples/js/geometries/TeapotGeometry.js +0 -1
  27. package/examples/js/interactive/SelectionBox.js +2 -0
  28. package/examples/js/interactive/SelectionHelper.js +22 -7
  29. package/examples/js/lights/RectAreaLightUniformsLib.js +4 -0
  30. package/examples/js/lines/LineMaterial.js +58 -20
  31. package/examples/js/lines/LineSegments2.js +29 -24
  32. package/examples/js/loaders/3DMLoader.js +24 -11
  33. package/examples/js/loaders/3MFLoader.js +2 -2
  34. package/examples/js/loaders/AMFLoader.js +0 -2
  35. package/examples/js/loaders/ColladaLoader.js +61 -4
  36. package/examples/js/loaders/EXRLoader.js +185 -262
  37. package/examples/js/loaders/FBXLoader.js +4 -5
  38. package/examples/js/loaders/GLTFLoader.js +96 -33
  39. package/examples/js/loaders/HDRCubeTextureLoader.js +0 -8
  40. package/examples/js/loaders/KTX2Loader.js +23 -2
  41. package/examples/js/loaders/KTXLoader.js +1 -1
  42. package/examples/js/loaders/LDrawLoader.js +26 -30
  43. package/examples/js/loaders/LUT3dlLoader.js +2 -0
  44. package/examples/js/loaders/LUTCubeLoader.js +2 -0
  45. package/examples/js/loaders/LWOLoader.js +8 -6
  46. package/examples/js/loaders/LogLuvLoader.js +766 -0
  47. package/examples/js/loaders/MMDLoader.js +0 -1
  48. package/examples/js/loaders/NRRDLoader.js +9 -2
  49. package/examples/js/loaders/OBJLoader.js +0 -2
  50. package/examples/js/loaders/PLYLoader.js +33 -8
  51. package/examples/js/loaders/RGBELoader.js +2 -16
  52. package/examples/js/loaders/RGBMLoader.js +55 -5
  53. package/examples/js/loaders/SVGLoader.js +9 -5
  54. package/examples/js/loaders/TDSLoader.js +237 -271
  55. package/examples/js/loaders/VOXLoader.js +1 -0
  56. package/examples/js/loaders/VRMLLoader.js +2 -1
  57. package/examples/js/loaders/lwo/LWO2Parser.js +1 -0
  58. package/examples/js/loaders/lwo/LWO3Parser.js +4 -2
  59. package/examples/js/math/ImprovedNoise.js +1 -1
  60. package/examples/js/misc/GPUComputationRenderer.js +3 -1
  61. package/examples/js/objects/Lensflare.js +2 -10
  62. package/examples/js/objects/MarchingCubes.js +42 -128
  63. package/examples/js/objects/Reflector.js +7 -0
  64. package/examples/js/objects/Refractor.js +7 -0
  65. package/examples/js/objects/Sky.js +1 -1
  66. package/examples/js/objects/Water.js +2 -2
  67. package/examples/js/objects/Water2.js +4 -7
  68. package/examples/js/postprocessing/GlitchPass.js +3 -1
  69. package/examples/js/postprocessing/SSAOPass.js +1 -0
  70. package/examples/js/renderers/CSS2DRenderer.js +4 -4
  71. package/examples/js/renderers/CSS3DRenderer.js +4 -4
  72. package/examples/js/shaders/ConvolutionShader.js +0 -1
  73. package/examples/js/shaders/FXAAShader.js +1 -1
  74. package/examples/js/shaders/FilmShader.js +1 -1
  75. package/examples/js/shaders/GammaCorrectionShader.js +1 -1
  76. package/examples/js/shaders/HorizontalBlurShader.js +1 -2
  77. package/examples/js/shaders/SSRShader.js +1 -1
  78. package/examples/js/shaders/SSRrShader.js +1 -1
  79. package/examples/js/shaders/VerticalBlurShader.js +1 -2
  80. package/examples/js/utils/GeometryUtils.js +1 -1
  81. package/examples/js/utils/RoughnessMipmapper.js +18 -28
  82. package/examples/jsm/animation/CCDIKSolver.js +0 -1
  83. package/examples/jsm/animation/MMDPhysics.js +0 -2
  84. package/examples/jsm/controls/ArcballControls.js +80 -77
  85. package/examples/jsm/controls/DragControls.js +7 -0
  86. package/examples/jsm/controls/OrbitControls.js +9 -51
  87. package/examples/jsm/controls/TrackballControls.js +1 -1
  88. package/examples/jsm/controls/TransformControls.js +24 -1
  89. package/examples/jsm/csm/CSM.js +3 -3
  90. package/examples/jsm/csm/{Frustum.js → CSMFrustum.js} +3 -3
  91. package/examples/jsm/curves/CurveExtras.js +0 -2
  92. package/examples/jsm/effects/AsciiEffect.js +2 -9
  93. package/examples/jsm/exporters/GLTFExporter.js +161 -75
  94. package/examples/jsm/exporters/USDZExporter.js +47 -26
  95. package/examples/jsm/geometries/TeapotGeometry.js +0 -1
  96. package/examples/jsm/interactive/SelectionBox.js +1 -0
  97. package/examples/jsm/interactive/SelectionHelper.js +19 -7
  98. package/examples/jsm/libs/flow.module.js +3338 -0
  99. package/examples/jsm/libs/lil-gui.module.min.js +8 -0
  100. package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
  101. package/examples/jsm/lights/RectAreaLightUniformsLib.js +7 -0
  102. package/examples/jsm/lines/LineMaterial.js +59 -23
  103. package/examples/jsm/lines/LineSegments2.js +22 -18
  104. package/examples/jsm/loaders/3DMLoader.js +18 -12
  105. package/examples/jsm/loaders/3MFLoader.js +2 -2
  106. package/examples/jsm/loaders/AMFLoader.js +0 -2
  107. package/examples/jsm/loaders/ColladaLoader.js +61 -4
  108. package/examples/jsm/loaders/EXRLoader.js +184 -293
  109. package/examples/jsm/loaders/FBXLoader.js +4 -5
  110. package/examples/jsm/loaders/GLTFLoader.js +101 -37
  111. package/examples/jsm/loaders/HDRCubeTextureLoader.js +1 -14
  112. package/examples/jsm/loaders/KTX2Loader.js +30 -2
  113. package/examples/jsm/loaders/KTXLoader.js +1 -1
  114. package/examples/jsm/loaders/LDrawLoader.js +23 -24
  115. package/examples/jsm/loaders/LUT3dlLoader.js +2 -0
  116. package/examples/jsm/loaders/LUTCubeLoader.js +2 -0
  117. package/examples/jsm/loaders/LWOLoader.js +8 -6
  118. package/examples/jsm/loaders/LogLuvLoader.js +606 -0
  119. package/examples/jsm/loaders/MMDLoader.js +0 -1
  120. package/examples/jsm/loaders/NRRDLoader.js +10 -2
  121. package/examples/jsm/loaders/OBJLoader.js +0 -2
  122. package/examples/jsm/loaders/PLYLoader.js +34 -8
  123. package/examples/jsm/loaders/RGBELoader.js +0 -20
  124. package/examples/jsm/loaders/RGBMLoader.js +61 -7
  125. package/examples/jsm/loaders/SVGLoader.js +9 -6
  126. package/examples/jsm/loaders/TDSLoader.js +236 -275
  127. package/examples/jsm/loaders/VOXLoader.js +1 -0
  128. package/examples/jsm/loaders/VRMLLoader.js +2 -1
  129. package/examples/jsm/loaders/lwo/LWO2Parser.js +1 -0
  130. package/examples/jsm/loaders/lwo/LWO3Parser.js +2 -2
  131. package/examples/jsm/math/ImprovedNoise.js +1 -1
  132. package/examples/jsm/misc/GPUComputationRenderer.js +3 -1
  133. package/examples/jsm/node-editor/NodeEditor.js +456 -0
  134. package/examples/jsm/node-editor/accessors/NormalEditor.js +30 -0
  135. package/examples/jsm/node-editor/accessors/PositionEditor.js +30 -0
  136. package/examples/jsm/node-editor/accessors/UVEditor.js +26 -0
  137. package/examples/jsm/node-editor/display/BlendEditor.js +43 -0
  138. package/examples/jsm/node-editor/examples/animate-uv.json +1 -0
  139. package/examples/jsm/node-editor/examples/fake-top-light.json +1 -0
  140. package/examples/jsm/node-editor/examples/oscillator-color.json +1 -0
  141. package/examples/jsm/node-editor/examples/rim.json +1 -0
  142. package/examples/jsm/node-editor/inputs/ColorEditor.js +91 -0
  143. package/examples/jsm/node-editor/inputs/FloatEditor.js +24 -0
  144. package/examples/jsm/node-editor/inputs/SliderEditor.js +68 -0
  145. package/examples/jsm/node-editor/inputs/Vector2Editor.js +28 -0
  146. package/examples/jsm/node-editor/inputs/Vector3Editor.js +30 -0
  147. package/examples/jsm/node-editor/inputs/Vector4Editor.js +37 -0
  148. package/examples/jsm/node-editor/materials/StandardMaterialEditor.js +108 -0
  149. package/examples/jsm/node-editor/math/DotEditor.js +36 -0
  150. package/examples/jsm/node-editor/math/InvertEditor.js +38 -0
  151. package/examples/jsm/node-editor/math/LimiterEditor.js +48 -0
  152. package/examples/jsm/node-editor/math/NormalizeEditor.js +26 -0
  153. package/examples/jsm/node-editor/math/OperatorEditor.js +50 -0
  154. package/examples/jsm/node-editor/math/PowerEditor.js +34 -0
  155. package/examples/jsm/node-editor/math/TrigonometryEditor.js +39 -0
  156. package/examples/jsm/node-editor/procedural/CheckerEditor.js +26 -0
  157. package/examples/jsm/node-editor/utils/OscillatorEditor.js +42 -0
  158. package/examples/jsm/node-editor/utils/TimerEditor.js +57 -0
  159. package/examples/jsm/nodes/core/NodeBuilder.js +2 -2
  160. package/examples/jsm/nodes/materials/StandardNodeMaterial.js +1 -1
  161. package/examples/jsm/nodes/materials/nodes/StandardNode.js +7 -6
  162. package/examples/jsm/nodes/math/MathNode.js +12 -0
  163. package/examples/jsm/nodes/misc/BumpMapNode.js +1 -1
  164. package/examples/jsm/nodes/misc/TextureCubeUVNode.js +1 -4
  165. package/examples/jsm/nodes/utils/ColorSpaceNode.js +1 -164
  166. package/examples/jsm/objects/Lensflare.js +3 -14
  167. package/examples/jsm/objects/MarchingCubes.js +46 -152
  168. package/examples/jsm/objects/Reflector.js +7 -0
  169. package/examples/jsm/objects/Refractor.js +7 -0
  170. package/examples/jsm/objects/Sky.js +1 -1
  171. package/examples/jsm/objects/Water.js +2 -2
  172. package/examples/jsm/objects/Water2.js +4 -8
  173. package/examples/jsm/postprocessing/AdaptiveToneMappingPass.js +1 -1
  174. package/examples/jsm/postprocessing/AfterimagePass.js +1 -1
  175. package/examples/jsm/postprocessing/BloomPass.js +1 -1
  176. package/examples/jsm/postprocessing/BokehPass.js +1 -1
  177. package/examples/jsm/postprocessing/ClearPass.js +1 -1
  178. package/examples/jsm/postprocessing/CubeTexturePass.js +1 -1
  179. package/examples/jsm/postprocessing/DotScreenPass.js +1 -1
  180. package/examples/jsm/postprocessing/EffectComposer.js +3 -3
  181. package/examples/jsm/postprocessing/FilmPass.js +1 -1
  182. package/examples/jsm/postprocessing/GlitchPass.js +4 -2
  183. package/examples/jsm/postprocessing/HalftonePass.js +1 -1
  184. package/examples/jsm/postprocessing/MaskPass.js +1 -1
  185. package/examples/jsm/postprocessing/OutlinePass.js +1 -1
  186. package/examples/jsm/postprocessing/RenderPass.js +1 -1
  187. package/examples/jsm/postprocessing/SAOPass.js +2 -2
  188. package/examples/jsm/postprocessing/SMAAPass.js +1 -1
  189. package/examples/jsm/postprocessing/SSAARenderPass.js +1 -1
  190. package/examples/jsm/postprocessing/SSAOPass.js +2 -1
  191. package/examples/jsm/postprocessing/SSRPass.js +1 -1
  192. package/examples/jsm/postprocessing/SSRrPass.js +1 -1
  193. package/examples/jsm/postprocessing/SavePass.js +1 -1
  194. package/examples/jsm/postprocessing/ShaderPass.js +1 -1
  195. package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
  196. package/examples/jsm/postprocessing/TexturePass.js +1 -1
  197. package/examples/jsm/postprocessing/UnrealBloomPass.js +1 -1
  198. package/examples/jsm/renderers/CSS2DRenderer.js +5 -4
  199. package/examples/jsm/renderers/CSS3DRenderer.js +5 -4
  200. package/examples/jsm/renderers/nodes/Nodes.js +15 -13
  201. package/examples/jsm/renderers/nodes/ShaderNode.js +194 -41
  202. package/examples/jsm/renderers/nodes/accessors/MaterialNode.js +6 -6
  203. package/examples/jsm/renderers/nodes/accessors/ModelViewProjectionNode.js +5 -5
  204. package/examples/jsm/renderers/nodes/accessors/NormalNode.js +14 -3
  205. package/examples/jsm/renderers/nodes/accessors/PointUVNode.js +3 -3
  206. package/examples/jsm/renderers/nodes/accessors/PositionNode.js +15 -5
  207. package/examples/jsm/renderers/nodes/accessors/SkinningNode.js +107 -0
  208. package/examples/jsm/renderers/nodes/accessors/UVNode.js +7 -5
  209. package/examples/jsm/renderers/nodes/core/ArrayInputNode.js +3 -3
  210. package/examples/jsm/renderers/nodes/core/AttributeNode.js +6 -0
  211. package/examples/jsm/renderers/nodes/core/BypassNode.js +38 -0
  212. package/examples/jsm/renderers/nodes/core/CodeNode.js +3 -3
  213. package/examples/jsm/renderers/nodes/core/ContextNode.js +4 -19
  214. package/examples/jsm/renderers/nodes/core/ExpressionNode.js +13 -2
  215. package/examples/jsm/renderers/nodes/core/FunctionNode.js +19 -132
  216. package/examples/jsm/renderers/nodes/core/InputNode.js +13 -3
  217. package/examples/jsm/renderers/nodes/core/Node.js +32 -10
  218. package/examples/jsm/renderers/nodes/core/NodeBuilder.js +146 -128
  219. package/examples/jsm/renderers/nodes/core/NodeFunction.js +22 -0
  220. package/examples/jsm/renderers/nodes/core/NodeFunctionInput.js +4 -4
  221. package/examples/jsm/renderers/nodes/core/NodeKeywords.js +18 -179
  222. package/examples/jsm/renderers/nodes/core/NodeParser.js +11 -0
  223. package/examples/jsm/renderers/nodes/core/NodeVar.js +2 -2
  224. package/examples/jsm/renderers/nodes/core/PropertyNode.js +14 -2
  225. package/examples/jsm/renderers/nodes/core/TempNode.js +10 -13
  226. package/examples/jsm/renderers/nodes/core/VarNode.js +12 -7
  227. package/examples/jsm/renderers/nodes/core/VaryNode.js +23 -8
  228. package/examples/jsm/renderers/nodes/core/constants.js +2 -0
  229. package/examples/jsm/renderers/nodes/display/ColorSpaceNode.js +60 -43
  230. package/examples/jsm/renderers/nodes/display/NormalMapNode.js +21 -22
  231. package/examples/jsm/renderers/nodes/functions/BSDFs.js +64 -101
  232. package/examples/jsm/renderers/nodes/functions/PhysicalMaterialFunctions.js +27 -0
  233. package/examples/jsm/renderers/nodes/inputs/BufferNode.js +25 -0
  234. package/examples/jsm/renderers/nodes/inputs/IntNode.js +17 -0
  235. package/examples/jsm/renderers/nodes/inputs/TextureNode.js +10 -2
  236. package/examples/jsm/renderers/nodes/lights/LightContextNode.js +20 -14
  237. package/examples/jsm/renderers/nodes/lights/LightNode.js +32 -36
  238. package/examples/jsm/renderers/nodes/math/CondNode.js +60 -0
  239. package/examples/jsm/renderers/nodes/math/MathNode.js +90 -37
  240. package/examples/jsm/renderers/nodes/math/OperatorNode.js +124 -31
  241. package/examples/jsm/renderers/nodes/parsers/GLSLNodeFunction.js +137 -0
  242. package/examples/jsm/renderers/nodes/parsers/GLSLNodeParser.js +14 -0
  243. package/examples/jsm/renderers/nodes/parsers/WGSLNodeFunction.js +89 -0
  244. package/examples/jsm/renderers/nodes/parsers/WGSLNodeParser.js +14 -0
  245. package/examples/jsm/renderers/nodes/procedural/CheckerNode.js +7 -9
  246. package/examples/jsm/renderers/nodes/utils/ArrayElementNode.js +31 -0
  247. package/examples/jsm/renderers/nodes/utils/ConvertNode.js +33 -0
  248. package/examples/jsm/renderers/nodes/utils/JoinNode.js +7 -7
  249. package/examples/jsm/renderers/nodes/utils/OscNode.js +58 -0
  250. package/examples/jsm/renderers/nodes/utils/SplitNode.js +18 -8
  251. package/examples/jsm/renderers/nodes/utils/SpriteSheetUVNode.js +7 -7
  252. package/examples/jsm/renderers/nodes/utils/TimerNode.js +1 -1
  253. package/examples/jsm/renderers/webgl/nodes/SlotNode.js +22 -0
  254. package/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +192 -95
  255. package/examples/jsm/renderers/webgl/nodes/WebGLNodes.js +2 -2
  256. package/examples/jsm/renderers/webgl/nodes/WebGLPhysicalContextNode.js +2 -2
  257. package/examples/jsm/renderers/webgpu/WebGPUBackground.js +1 -1
  258. package/examples/jsm/renderers/webgpu/WebGPUBindings.js +10 -9
  259. package/examples/jsm/renderers/webgpu/WebGPUComputePipelines.js +2 -4
  260. package/examples/jsm/renderers/webgpu/WebGPUProgrammableStage.js +2 -4
  261. package/examples/jsm/renderers/webgpu/WebGPURenderPipeline.js +15 -23
  262. package/examples/jsm/renderers/webgpu/WebGPURenderPipelines.js +44 -65
  263. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +12 -28
  264. package/examples/jsm/renderers/webgpu/WebGPUTextureUtils.js +61 -28
  265. package/examples/jsm/renderers/webgpu/WebGPUTextures.js +34 -27
  266. package/examples/jsm/renderers/webgpu/constants.js +2 -2
  267. package/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js +453 -95
  268. package/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js +1 -1
  269. package/examples/jsm/shaders/ConvolutionShader.js +0 -1
  270. package/examples/jsm/shaders/FXAAShader.js +1 -1
  271. package/examples/jsm/shaders/FilmShader.js +1 -1
  272. package/examples/jsm/shaders/GammaCorrectionShader.js +1 -1
  273. package/examples/jsm/shaders/HorizontalBlurShader.js +1 -2
  274. package/examples/jsm/shaders/SSRShader.js +1 -1
  275. package/examples/jsm/shaders/SSRrShader.js +1 -1
  276. package/examples/jsm/shaders/VerticalBlurShader.js +1 -2
  277. package/examples/jsm/utils/GeometryUtils.js +1 -1
  278. package/examples/jsm/utils/RoughnessMipmapper.js +19 -31
  279. package/examples/jsm/utils/WorkerPool.js +11 -11
  280. package/examples/jsm/webxr/OculusHandPointerModel.js +6 -6
  281. package/package.json +24 -18
  282. package/src/Three.Legacy.js +18 -0
  283. package/src/Three.js +1 -3
  284. package/src/cameras/StereoCamera.js +8 -7
  285. package/src/constants.js +1 -8
  286. package/src/core/Layers.js +7 -1
  287. package/src/core/Object3D.js +3 -1
  288. package/src/extras/PMREMGenerator.js +23 -109
  289. package/src/extras/core/Interpolations.js +1 -1
  290. package/src/geometries/LatheGeometry.js +70 -47
  291. package/src/helpers/CameraHelper.js +1 -1
  292. package/src/loaders/FileLoader.js +98 -144
  293. package/src/loaders/ImageLoader.js +9 -4
  294. package/src/loaders/LoaderUtils.js +26 -0
  295. package/src/loaders/MaterialLoader.js +7 -4
  296. package/src/loaders/ObjectLoader.js +2 -0
  297. package/src/materials/Material.js +4 -4
  298. package/src/materials/MeshPhysicalMaterial.js +20 -14
  299. package/src/math/Color.js +0 -38
  300. package/src/math/MathUtils.js +5 -16
  301. package/src/math/Ray.js +2 -2
  302. package/src/math/Sphere.js +10 -1
  303. package/src/objects/Skeleton.js +1 -0
  304. package/src/renderers/WebGLMultisampleRenderTarget.js +7 -1
  305. package/src/renderers/WebGLRenderer.js +105 -132
  306. package/src/renderers/shaders/ShaderChunk/bsdfs.glsl.js +2 -2
  307. package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +1 -1
  308. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +2 -24
  309. package/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl.js +0 -74
  310. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +0 -1
  311. package/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl.js +1 -1
  312. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +19 -6
  313. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +28 -2
  314. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +1 -1
  315. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  316. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +1 -1
  317. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +23 -5
  318. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +2 -1
  319. package/src/renderers/shaders/ShaderLib.js +6 -4
  320. package/src/renderers/shaders/UniformsLib.js +1 -2
  321. package/src/renderers/webgl/WebGLCapabilities.js +0 -2
  322. package/src/renderers/webgl/WebGLExtensions.js +1 -0
  323. package/src/renderers/webgl/WebGLMaterials.js +27 -15
  324. package/src/renderers/webgl/WebGLMorphtargets.js +1 -0
  325. package/src/renderers/webgl/WebGLProgram.js +11 -24
  326. package/src/renderers/webgl/WebGLPrograms.js +194 -33
  327. package/src/renderers/webgl/WebGLRenderLists.js +4 -14
  328. package/src/renderers/webgl/WebGLShaderCache.js +120 -0
  329. package/src/renderers/webgl/WebGLShadowMap.js +14 -5
  330. package/src/renderers/webgl/WebGLState.js +76 -17
  331. package/src/renderers/webgl/WebGLTextures.js +367 -61
  332. package/src/renderers/webgl/WebGLUniforms.js +45 -1
  333. package/src/renderers/webxr/WebXRManager.js +77 -109
  334. package/src/scenes/Scene.js +1 -1
  335. package/src/textures/DataTexture.js +0 -2
  336. package/src/textures/DataTexture2DArray.js +0 -2
  337. package/src/textures/DataTexture3D.js +0 -2
  338. package/src/textures/FramebufferTexture.js +25 -0
  339. package/src/textures/Texture.js +6 -0
  340. package/examples/js/controls/DeviceOrientationControls.js +0 -147
  341. package/examples/js/libs/dat.gui.min.js +0 -14
  342. package/examples/jsm/controls/DeviceOrientationControls.js +0 -153
  343. package/examples/jsm/libs/dat.gui.module.js +0 -3575
  344. package/examples/jsm/libs/glslang.js +0 -78
  345. package/examples/jsm/libs/glslang.wasm +0 -0
  346. package/examples/jsm/renderers/nodes/consts/MathConsts.js +0 -7
  347. package/examples/jsm/renderers/nodes/core/ConstNode.js +0 -39
  348. package/examples/jsm/renderers/nodes/core/NodeSlot.js +0 -13
  349. package/examples/jsm/renderers/nodes/core/StructNode.js +0 -80
  350. package/examples/jsm/renderers/nodes/core/StructVarNode.js +0 -75
  351. package/examples/jsm/renderers/nodes/functions/EncodingFunctions.js +0 -99
  352. package/examples/jsm/renderers/nodes/functions/MathFunctions.js +0 -47
  353. package/examples/jsm/renderers/webgpu/nodes/ShaderLib.js +0 -152
  354. package/src/extras/objects/ImmediateRenderObject.js +0 -31
@@ -0,0 +1,3338 @@
1
+ /**
2
+ * https://github.com/sunag/flow
3
+ */
4
+
5
+ function __flow__addCSS( css ) {
6
+
7
+ try {
8
+
9
+ const style = document.createElement( 'style' );
10
+
11
+ style.setAttribute( 'type', 'text/css' );
12
+ style.innerHTML = css;
13
+ document.head.appendChild( style );
14
+
15
+ } catch( e ) {}
16
+
17
+ }
18
+
19
+ __flow__addCSS( `@keyframes f-animation-open { 0% { transform: scale(.5); opacity: 0; } 100% { transform: scale(1); opacity: 1; }}f-canvas,f-canvas canvas { position: absolute; top: 0; left: 0; margin: 0; padding: 0; width: 100%; height: 100%; -webkit-touch-callout: none; }f-canvas { overflow: auto; cursor: grab;}f-canvas canvas.front { z-index: 10;}body.dragging f-canvas,body.connecting f-canvas { overflow: hidden !important;}body.dragging *:not(.drag) { pointer-events: none !important;}f-canvas.grabbing * { cursor: grabbing; user-select: none;}f-canvas canvas { position: fixed; overflow: hidden; pointer-events: none;}f-canvas::-webkit-scrollbar { width: 8px; height: 8px;}f-canvas::-webkit-scrollbar-thumb:hover{ background: #014fc5;}f-canvas::-webkit-scrollbar-track { background: #363636;}f-canvas::-webkit-scrollbar-thumb { background-color: #666666; border-radius: 10px; border: 0;}f-canvas f-content,f-canvas f-area { position: absolute; display: block;}f-node { position: absolute; margin: 0; padding: 0; user-select: none; width: 320px; z-index: 1; cursor: auto; filter: drop-shadow(0 0 10px #00000061); backdrop-filter: blur(4px);}f-node.selected { z-index: 2;}f-node.selected,f-canvas.dragging-rio f-node:hover,f-canvas.dragging-lio f-node:hover { filter: drop-shadow(0 0 10px #00000061) drop-shadow(0 0 8px #4444dd);}f-node.closed f-element:not(:first-child) { display: none;}f-node.center { top: 50%; left: 50%; transform: translate( -50%, -50% );}f-node.top-right { top: 0; right: 0;}f-node.top-center { top: 0; left: 50%; transform: translateX( -50% );}f-node.top-left { top: 0; left: 0;}f-node { transition: filter 0.2s ease;}f-node { animation: .2s f-animation-open 1 alternate ease-out;}f-drop,f-menu,f-menu button,f-element,f-element input,f-element select,f-element button,f-element textarea { font-family: 'Open Sans', sans-serif; font-size: 13px; text-transform: capitalize; color: #eeeeee; outline: solid 0px #000; letter-spacing: .2px; margin: 0; padding: 0; border: 0; user-select: none; -webkit-tap-highlight-color: transparent; transition: background 0.2s ease;}f-element input { transition: background 0.1s ease;}f-element input,f-element select,f-element button,f-element textarea { background-color: #242427;}f-element { position: relative; width: calc( 100% - 14px ); background: rgba(45, 45, 48, 0.95); pointer-events: auto; border-bottom: 2px solid #232323; display: flex; padding-left: 7px; padding-right: 7px; padding-top: 2px; padding-bottom: 2px;}f-element { height: 24px;}f-element input { margin-top: 2px; margin-bottom: 2px; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%); margin-left: 2px; margin-right: 2px; width: 100%; padding-left: 4px; padding-right: 4px;}f-element input.number { cursor: col-resize;}f-element input:focus[type='text'], f-element input:focus[type='range'], f-element input:focus[type='color'] { background: rgba( 0, 0, 0, 0.6 ); outline: solid 1px rgba( 0, 80, 200, 0.98 );}f-element input[type='color'] { appearance: none; padding: 0; margin-left: 2px; margin-right: 2px; height: calc( 100% - 4px ); margin-top: 2px; border: none; }f-element input[type='color']::-webkit-color-swatch-wrapper { padding: 2px;}f-element input[type='color']::-webkit-color-swatch { border: none; cursor: alias;}f-element input[type='range'] { appearance: none; width: 100%; overflow: hidden; padding: 0; cursor: ew-resize;}f-element input[type='range']::-webkit-slider-runnable-track { appearance: none; height: 10px; color: #13bba4; margin: 0;}f-element input[type='range']::-webkit-slider-thumb { appearance: none; width: 0; background: #434343; box-shadow: -500px 0 0 500px rgba( 0, 120, 255, 0.98 ); border-radius: 50%; border: 0 !important;}f-element input[type='range']::-webkit-slider-runnable-track { margin-left: -4px; margin-right: -5px;}f-element input[type='checkbox'] { appearance: none; cursor: pointer;}f-element input[type='checkbox'].toggle { height: 20px; width: 45px; border-radius: 16px; display: inline-block; position: relative; margin: 0; margin-top: 2px; background: linear-gradient( 0deg, #292929 0%, #0a0a0ac2 100% ); transition: all 0.2s ease;}f-element input[type='checkbox'].toggle:after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: white; box-shadow: 0 1px 2px rgba(44, 44, 44, 0.2); transition: all 0.2s cubic-bezier(0.5, 0.1, 0.75, 1.35);}f-element input[type='checkbox'].toggle:checked { background: linear-gradient( 0deg, #0177fb 0%, #0177fb 100% );}f-element input[type='checkbox'].toggle:checked:after { transform: translatex(25px);}f-element.auto-height { display: table;}f-element textarea { width: calc( 100% - 18px ); padding-top: 1px; padding-bottom: 3px; padding-left: 3px; padding-right: 8px; margin-top: 2px; margin-left: 2px; height: calc( 100% - 8px ); max-height: 300px; border-radius: 2px; resize: none; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%);}f-element.auto-height textarea { resize: auto;}f-element select { width: 100%; margin-top: 2px; margin-bottom: 2px; margin-left: 2px; margin-right: 2px; padding-left: 5px; cursor: pointer; box-shadow: inset 0px 1px 1px rgb(0 0 0 / 20%), 0px 1px 0px rgb(255 255 255 / 5%);}f-element f-toolbar { position: absolute; display: flex; top: 0; width: 100%; height: 100%; align-content: space-around;}f-element.output-right f-toolbar { right: 7px; float: right; justify-content: end;}f-element f-toolbar { margin-top: auto; margin-bottom: auto; margin-left: 3px; margin-right: 3px; font-size: 18px; line-height: 18px;}f-element f-toolbar button { opacity: .7; cursor: pointer; font-size: 14px; width: unset; height: unset; border-radius: unset; border: unset; outline: 0; background-color: unset; box-shadow: unset;}f-element f-toolbar button:hover,f-element f-toolbar button:active { opacity: 1; border: 0; background-color: unset;}f-element input.range-value { width: 60px; text-align: center;}f-menu.context button,f-element button { width: 100%; height: calc( 100% - 4px ); margin-left: 2px; margin-right: 2px; margin-top: 2px; border-radius: 3px; cursor: pointer;}f-element button { box-shadow: inset 1px 1px 1px 0 rgb(255 255 255 / 17%), inset -2px -2px 2px 0 rgb(0 0 0 / 26%);}f-element button:hover { color: #fff; background-color: #2a2a2a;}f-element button:active { border: 1px solid rgba( 0, 120, 255, 0.98 );}f-element f-inputs,f-element f-subinputs { display: flex; width: 100%;}f-element f-inputs { left: 100px; top: 50%; transform: translateY(-50%); position: absolute; width: calc( 100% - 106px ); height: calc( 100% - 4px ); z-index: 1;}f-element.inputs-disable f-inputs { filter: grayscale(100%); opacity: .5;}f-element.inputs-disable f-inputs input { pointer-events: none;}f-element f-label,f-element span { margin: auto; text-shadow: 1px 1px 0px #0007;}f-element f-label { padding-left: 4px; white-space: nowrap; position: absolute; top: 50%; transform: translateY(-50%); width: calc( 100% - 20px );}f-element.right f-label { text-align: right;}f-element f-label i { float: left; font-size: 18px; margin-right: 6px;}f-element f-label.center { width: 100%; text-align: center; display: block;}f-element.title { height: 29px; background-color: #3a3a3ab0; background-color: #3b3b43ed; cursor: all-scroll; border-top-left-radius: 6px; border-top-right-radius: 6px;}f-element.blue { background-color: #014fc5;}f-element.red { background-color: #bd0b0b;}f-element.green { background-color: #148d05;}f-element.yellow { background-color: #d6b100;}f-element.title.left { text-align: left; display: inline-grid; justify-content: start;}f-element.title span { text-align: center; font-size: 15px; padding-top: 2px;}f-element.title i { font-size: 18px; position: absolute; right: 10px; top: 50%; transform: translateY(-50%); opacity: .5;}f-element.output-right.title i { left: 10px; right: unset;}f-element.title.left span { text-align: left;}f-element f-io { border: 2px solid #dadada; width: 7px; height: 7px; position: absolute; background: #242427; border-radius: 8px; float: left; left: -7px; top: calc( 50% - 5px ); cursor: alias; box-shadow: 0 0 3px 2px #0000005e; z-index: 1;}f-element f-io.connect,f-canvas.dragging-rio f-element:hover f-io.lio,f-canvas.dragging-lio f-element:hover f-io.rio { border: 2px solid #0177fb; zoom: 1.4;}f-node.io-connect f-io:not(.connect) { border: 2px solid #dadada !important; zoom: 1 !important;}f-element f-io.rio { float: right; right: -7px; left: unset;}f-element f-disconnect { position: absolute; left: -35px; top: 50%; font-size: 22px; transform: translateY( -50% ); filter: drop-shadow(0 0 5px #000); text-shadow: 0px 0px 5px black; cursor: pointer;}f-element.output-right f-disconnect { right: -35px; left: unset;}f-element f-disconnect:hover { color: #ff3300;}f-element textarea::-webkit-scrollbar { width: 6px;}f-element textarea::-webkit-scrollbar-track { background: #111; } f-element textarea::-webkit-scrollbar-thumb { background: #0177fb; }f-element textarea::-webkit-scrollbar-thumb:hover { background: #1187ff; }f-element.small { height: 18px;}f-element.large { height: 36px;}body.connecting f-node:not(.io-connect) f-element:hover,f-element.select { background-color: rgba(61, 70, 82, 0.98);}f-drop { width: 100%; height: 100%; position: sticky; left: 0; top: 0; background: #02358417; text-align: center; justify-content: center; align-items: center; display: flex; box-shadow: inset 0 0 20px 10px #464ace17; pointer-events: none; transition: all .07s; opacity: 0; visibility: hidden;}f-drop.visible { visibility: unset; opacity: unset; transition: all .23s;}f-drop span { opacity: .5; font-size: 40px; text-shadow: 0px 0px 5px #000; font-weight: bold;}f-tooltip { pointer-events: none;}f-tooltip { position: absolute; left: 0; top: 0; background: rgba(0,0,0,.8); backdrop-filter: blur(4px); font-size: 14px; padding: 7px; border-radius: 10px; top: 50%; transform: translateY(-50%); visibility: hidden; pointer-events: none; opacity: 0; transition: all 0.3s ease; z-index: 150; white-space: nowrap;}f-menu.context { position: absolute; width: 170px; padding: 2px; margin: 0; background: #17171794; z-index: 110; font-size: 12px; border-radius: 6px; backdrop-filter: blur(6px); border: 1px solid #7e7e7e45; box-shadow: 3px 3px 6px rgba(0,0,0,.2); transition: opacity 0.2s ease, transform 0.1s ease;}f-menu.context.hidden { visibility: hidden; opacity: 0;}f-menu.context f-item { display: block; position: relative; margin: 0; padding: 0; white-space: nowrap;}f-menu.context f-item.submenu::after { content: ""; position: absolute; right: 6px; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); border: 5px solid transparent; border-left-color: #808080;}f-menu.context f-item:hover > f-menu,f-menu.context f-item.active > f-menu { visibility: unset; transform: unset; opacity: unset;}f-menu.context f-menu { top: 0px; left: calc( 100% - 4px );}f-menu.context f-item button { overflow: visible; display: block; width: calc( 100% - 6px ); text-align: left; cursor: pointer; white-space: nowrap; padding: 6px 8px; border-radius: 3px; background: #2d2d32; border: 0; color: #ddd; margin: 3px; text-shadow: 1px 1px 0px #0007;}f-menu.context f-item button i { float: left; font-size: 16px;}f-menu.context f-item button span { margin-left: 6px;}f-menu.context f-item:hover > button,f-menu.context f-item.active > button { color: #fff; background: #313136;}f-menu.context f-item button:active { outline: solid 1px rgba( 0, 80, 200, 0.98 );}f-menu.context f-item f-tooltip { margin-left: 120px;}f-menu.circle { position: absolute; left: 30px; top: 30px; z-index: 100;}f-menu.circle f-item { display: flex; justify-content: end; align-content: space-around; margin-bottom: 12px;}f-menu.circle f-item button { width: 50px; height: 50px; font-size: 26px; background: #17171794; border-radius: 50%; backdrop-filter: blur(6px); border: 1px solid #7e7e7e45; line-height: 100%; cursor: pointer; box-shadow: 3px 3px 6px rgba(0,0,0,.2);}f-menu.circle f-item f-tooltip { margin-left: 50px;}.f-rounded f-node f-element,.f-rounded f-node f-element.title.left { border-radius: 10px 5px 10px 5px;}.f-rounded f-node f-element input, .f-rounded f-node f-element select,.f-rounded f-node f-element button,.f-rounded f-node f-element textarea,.f-rounded f-node f-element input[type='checkbox'].toggle,.f-rounded f-node f-element input[type='checkbox'].toggle:after { border-radius: 20px 10px;}.f-rounded f-node f-element input { padding-left: 7px; padding-right: 7px;}.f-rounded f-menu.context,.f-rounded f-menu.context f-item button { border-radius: 20px 10px;}@media (hover: hover) and (pointer: fine) { f-node:not(.selected):hover { filter: drop-shadow(0 0 6px #66666630); } f-element f-toolbar { visibility: hidden; opacity: 0; transition: opacity 0.2s ease; } f-node:hover > f-element f-toolbar { visibility: visible; opacity: 1; } f-element f-io:hover { border: 2px solid #0177fb; zoom: 1.4; } f-menu.circle f-item button:hover { background-color: #2a2a2a; } f-menu.circle f-item button:hover > f-tooltip, f-menu.context f-item button:hover > f-tooltip { visibility: visible; transform: translate(10px, -50%); opacity: 1; } f-menu.circle f-item button:focus > f-tooltip, f-menu.context f-item button:focus > f-tooltip { visibility: hidden; opacity: 0; }}f-canvas { will-change: top, left;}f-node { will-change: transform !important;}` );
20
+
21
+ const REVISION = '1';
22
+
23
+ const Styles = {
24
+ icons: {
25
+ close: '',
26
+ unlink: ''
27
+ }
28
+ };
29
+
30
+ let _id = 0;
31
+
32
+ class Serializer extends EventTarget {
33
+
34
+ constructor() {
35
+
36
+ super();
37
+
38
+ this._id = _id ++;
39
+
40
+ this._serializable = true;
41
+
42
+ }
43
+
44
+ get id() {
45
+
46
+ return this._id;
47
+
48
+ }
49
+
50
+ setSerializable( value ) {
51
+
52
+ this._serializable = value;
53
+
54
+ return this;
55
+
56
+ }
57
+
58
+ getSerializable() {
59
+
60
+ return this._serializable;
61
+
62
+ }
63
+
64
+ serialize( /*data*/ ) {
65
+
66
+ console.warn( 'Serializer: Abstract function.' );
67
+
68
+ }
69
+
70
+ deserialize( /*data*/ ) {
71
+
72
+ console.warn( 'Serializer: Abstract function.' );
73
+
74
+ }
75
+
76
+ toJSON( data = null ) {
77
+
78
+ let object = null;
79
+
80
+ const id = this.id;
81
+
82
+ if ( data !== null ) {
83
+
84
+ const objects = data.objects;
85
+
86
+ object = objects[ id ];
87
+
88
+ if ( object === undefined ) {
89
+
90
+ object = { objects };
91
+
92
+ this.serialize( object );
93
+
94
+ delete object.objects;
95
+
96
+ objects[ id ] = object;
97
+
98
+ }
99
+
100
+ } else {
101
+
102
+ object = { objects: {} };
103
+
104
+ this.serialize( object );
105
+
106
+ }
107
+
108
+ object.id = id;
109
+ object.type = this.constructor.name;
110
+
111
+ return object;
112
+
113
+ }
114
+
115
+ }
116
+
117
+ const draggableDOM = ( dom, callback = null, className = 'dragging' ) => {
118
+
119
+ let dragData = null;
120
+
121
+ const getZoom = () => {
122
+
123
+ let zoomDOM = dom;
124
+
125
+ while ( zoomDOM && zoomDOM !== document ) {
126
+
127
+ const zoom = zoomDOM.style.zoom;
128
+
129
+ if ( zoom ) {
130
+
131
+ return Number( zoom );
132
+
133
+ }
134
+
135
+ zoomDOM = zoomDOM.parentNode;
136
+
137
+ }
138
+
139
+ return 1;
140
+
141
+ };
142
+
143
+ const onMouseDown = ( e ) => {
144
+
145
+ const event = e.touches ? e.touches[ 0 ] : e;
146
+
147
+ e.stopImmediatePropagation();
148
+
149
+ dragData = {
150
+ client: { x: event.clientX, y: event.clientY },
151
+ delta: { x: 0, y: 0 },
152
+ start: { x: dom.offsetLeft, y: dom.offsetTop },
153
+ dragging: false,
154
+ isTouch: !! e.touches
155
+ };
156
+
157
+ window.addEventListener( 'mousemove', onGlobalMouseMove );
158
+ window.addEventListener( 'mouseup', onGlobalMouseUp );
159
+
160
+ window.addEventListener( 'touchmove', onGlobalMouseMove );
161
+ window.addEventListener( 'touchend', onGlobalMouseUp );
162
+
163
+ };
164
+
165
+ const onGlobalMouseMove = ( e ) => {
166
+
167
+ const { start, delta, client } = dragData;
168
+
169
+ const event = e.touches ? e.touches[ 0 ] : e;
170
+
171
+ const zoom = getZoom();
172
+
173
+ delta.x = ( event.clientX - client.x ) / zoom;
174
+ delta.y = ( event.clientY - client.y ) / zoom;
175
+
176
+ dragData.x = start.x + delta.x;
177
+ dragData.y = start.y + delta.y;
178
+
179
+ if ( dragData.dragging === true ) {
180
+
181
+ if ( callback !== null ) {
182
+
183
+ callback( dragData );
184
+
185
+ } else {
186
+
187
+ dom.style.cssText += `; left: ${ dragData.x }px; top: ${ dragData.y }px;`;
188
+
189
+ }
190
+
191
+ e.stopImmediatePropagation();
192
+
193
+ } else {
194
+
195
+ if ( Math.abs( delta.x ) > 2 || Math.abs( delta.y ) > 2 ) {
196
+
197
+ dragData.dragging = true;
198
+
199
+ dom.classList.add( 'drag' );
200
+
201
+ if ( className ) document.body.classList.add( className );
202
+
203
+ e.stopImmediatePropagation();
204
+
205
+ }
206
+
207
+ }
208
+
209
+ };
210
+
211
+ const onGlobalMouseUp = ( e ) => {
212
+
213
+ e.stopImmediatePropagation();
214
+
215
+ dom.classList.remove( 'drag' );
216
+
217
+ if ( className ) document.body.classList.remove( className );
218
+
219
+ window.removeEventListener( 'mousemove', onGlobalMouseMove );
220
+ window.removeEventListener( 'mouseup', onGlobalMouseUp );
221
+
222
+ window.removeEventListener( 'touchmove', onGlobalMouseMove );
223
+ window.removeEventListener( 'touchend', onGlobalMouseUp );
224
+
225
+ if ( callback === null ) {
226
+
227
+ dom.removeEventListener( 'mousedown', onMouseDown );
228
+ dom.removeEventListener( 'touchstart', onMouseDown );
229
+
230
+ }
231
+
232
+ dragData.dragging = false;
233
+
234
+ if ( callback !== null ) {
235
+
236
+ callback( dragData );
237
+
238
+ }
239
+
240
+ };
241
+
242
+ if ( dom instanceof Event ) {
243
+
244
+ const e = dom;
245
+ dom = e.target;
246
+
247
+ onMouseDown( e );
248
+
249
+ } else {
250
+
251
+ dom.addEventListener( 'mousedown', onMouseDown );
252
+ dom.addEventListener( 'touchstart', onMouseDown );
253
+
254
+ }
255
+
256
+ };
257
+
258
+ const dispatchEventList = ( list, ...params ) => {
259
+
260
+ for ( const callback of list ) {
261
+
262
+ callback( ...params );
263
+
264
+ }
265
+
266
+ };
267
+
268
+ const toPX = ( val ) => {
269
+
270
+ if ( isNaN( val ) === false ) {
271
+
272
+ val = `${ val }px`;
273
+
274
+ }
275
+
276
+ return val;
277
+
278
+ };
279
+
280
+ const toHex = ( val ) => {
281
+
282
+ if ( isNaN( val ) === false ) {
283
+
284
+ val = `#${ val.toString( 16 ).padStart( 6, '0' ) }`;
285
+
286
+ }
287
+
288
+ return val;
289
+
290
+ };
291
+
292
+ var Utils = /*#__PURE__*/Object.freeze({
293
+ __proto__: null,
294
+ draggableDOM: draggableDOM,
295
+ dispatchEventList: dispatchEventList,
296
+ toPX: toPX,
297
+ toHex: toHex
298
+ });
299
+
300
+ class Link {
301
+
302
+ constructor( inputElement = null, outputElement = null ) {
303
+
304
+ this.inputElement = inputElement;
305
+ this.outputElement = outputElement;
306
+
307
+ }
308
+
309
+ get lioElement() {
310
+
311
+ if ( Link.InputDirection === 'left' ) {
312
+
313
+ return this.outputElement;
314
+
315
+ } else {
316
+
317
+ return this.inputElement;
318
+
319
+ }
320
+
321
+ }
322
+
323
+ get rioElement() {
324
+
325
+ if ( Link.InputDirection === 'left' ) {
326
+
327
+ return this.inputElement;
328
+
329
+ } else {
330
+
331
+ return this.outputElement;
332
+
333
+ }
334
+
335
+ }
336
+
337
+ }
338
+
339
+ //Link.InputDirection = 'right';
340
+ Link.InputDirection = 'left';
341
+
342
+ let selected = null;
343
+
344
+ class Element extends Serializer {
345
+
346
+ constructor( draggable = false ) {
347
+
348
+ super();
349
+
350
+ const dom = document.createElement( 'f-element' );
351
+ dom.element = this;
352
+
353
+ const onSelect = ( e ) => {
354
+
355
+ let element = this;
356
+
357
+ if ( e.changedTouches && e.changedTouches.length > 0 ) {
358
+
359
+ const touch = e.changedTouches[ 0 ];
360
+
361
+ let overDOM = document.elementFromPoint( touch.clientX, touch.clientY );
362
+
363
+ while ( overDOM && ( ! overDOM.element || ! overDOM.element.isElement ) ) {
364
+
365
+ overDOM = overDOM.parentNode;
366
+
367
+ }
368
+
369
+ element = overDOM ? overDOM.element : null;
370
+
371
+ }
372
+
373
+ selected = element;
374
+
375
+ };
376
+
377
+ if ( draggable === false ) {
378
+
379
+ dom.ontouchstart = dom.onmousedown = ( e ) => {
380
+
381
+ e.stopPropagation();
382
+
383
+ };
384
+
385
+ }
386
+
387
+ dom.addEventListener( 'mouseup', onSelect, true );
388
+ dom.addEventListener( 'touchend', onSelect );
389
+
390
+ this.inputs = [];
391
+
392
+ this.links = [];
393
+
394
+ this.dom = dom;
395
+
396
+ this.lioLength = 0;
397
+ this.rioLength = 0;
398
+
399
+ this.events = {
400
+ 'connect': [],
401
+ 'connectChildren': []
402
+ };
403
+
404
+ this.node = null;
405
+
406
+ this.style = '';
407
+
408
+ this.extra = null;
409
+
410
+ this.enabledInputs = true;
411
+
412
+ this.visible = true;
413
+
414
+ this.inputsDOM = dom;
415
+
416
+ this.disconnectDOM = null;
417
+
418
+ this.lioDOM = this._createIO( 'lio' );
419
+ this.rioDOM = this._createIO( 'rio' );
420
+
421
+ this.dom.classList.add( `output-${ Link.InputDirection }` );
422
+
423
+ this.dom.appendChild( this.lioDOM );
424
+ this.dom.appendChild( this.rioDOM );
425
+
426
+ this.addEventListener( 'connect', ( ) => {
427
+
428
+ dispatchEventList( this.events.connect, this );
429
+
430
+ } );
431
+
432
+ this.addEventListener( 'connectChildren', ( ) => {
433
+
434
+ dispatchEventList( this.events.connectChildren, this );
435
+
436
+ } );
437
+
438
+ }
439
+
440
+ onConnect( callback, childrens = false ) {
441
+
442
+ this.events.connect.push( callback );
443
+
444
+ if ( childrens ) {
445
+
446
+ this.events.connectChildren.push( callback );
447
+
448
+ }
449
+
450
+ return this;
451
+
452
+ }
453
+
454
+ setExtra( value ) {
455
+
456
+ this.extra = value;
457
+
458
+ return this;
459
+
460
+ }
461
+
462
+ getExtra() {
463
+
464
+ return this.extra;
465
+
466
+ }
467
+
468
+ setVisible( value ) {
469
+
470
+ this.visible = value;
471
+
472
+ this.dom.style.display = value ? '' : 'none';
473
+
474
+ return this;
475
+
476
+ }
477
+
478
+ getVisible() {
479
+
480
+ return this.visible;
481
+
482
+ }
483
+
484
+ setEnabledInputs( value ) {
485
+
486
+ const dom = this.dom;
487
+
488
+ if ( !this.enabledInputs ) dom.classList.remove( 'inputs-disable');
489
+
490
+ if ( !value ) dom.classList.add( 'inputs-disable' );
491
+
492
+ this.enabledInputs = value;
493
+
494
+ return this;
495
+
496
+ }
497
+
498
+ getEnabledInputs() {
499
+
500
+ return this.enabledInputs;
501
+
502
+ }
503
+
504
+ setStyle( style ) {
505
+
506
+ const dom = this.dom;
507
+
508
+ if ( this.style ) dom.classList.remove( this.style );
509
+
510
+ if ( style ) dom.classList.add( style );
511
+
512
+ this.style = style;
513
+
514
+ return this;
515
+
516
+ }
517
+
518
+ setInput( length ) {
519
+
520
+ if ( Link.InputDirection === 'left' ) {
521
+
522
+ return this.setLIO( length );
523
+
524
+ } else {
525
+
526
+ return this.setRIO( length );
527
+
528
+ }
529
+
530
+ }
531
+
532
+ setOutput( length ) {
533
+
534
+ if ( Link.InputDirection === 'left' ) {
535
+
536
+ return this.setRIO( length );
537
+
538
+ } else {
539
+
540
+ return this.setLIO( length );
541
+
542
+ }
543
+
544
+ }
545
+
546
+ get inputLength() {
547
+
548
+ if ( Link.InputDirection === 'left' ) {
549
+
550
+ return this.lioLength;
551
+
552
+ } else {
553
+
554
+ return this.rioLength;
555
+
556
+ }
557
+
558
+ }
559
+
560
+ get outputLength() {
561
+
562
+ if ( Link.InputDirection === 'left' ) {
563
+
564
+ return this.rioLength;
565
+
566
+ } else {
567
+
568
+ return this.lioLength;
569
+
570
+ }
571
+
572
+ }
573
+
574
+ setLIO( length ) {
575
+
576
+ this.lioLength = length;
577
+
578
+ this.lioDOM.style.visibility = length > 0 ? '' : 'hidden';
579
+
580
+ return this;
581
+
582
+ }
583
+
584
+ setRIO( length ) {
585
+
586
+ this.rioLength = length;
587
+
588
+ this.rioDOM.style.visibility = length > 0 ? '' : 'hidden';
589
+
590
+ return this;
591
+
592
+ }
593
+
594
+ add( input ) {
595
+
596
+ this.inputs.push( input );
597
+
598
+ input.element = this;
599
+
600
+ this.inputsDOM.appendChild( input.dom );
601
+
602
+ return this;
603
+
604
+ }
605
+
606
+ setHeight( val ) {
607
+
608
+ this.dom.style.height = toPX( val );
609
+
610
+ return this;
611
+
612
+ }
613
+
614
+ getHeight() {
615
+
616
+ return this.dom.style.height;
617
+
618
+ }
619
+
620
+ connect( element = null ) {
621
+
622
+ if ( this.disconnectDOM !== null ) {
623
+
624
+ // remove the current input
625
+
626
+ this.disconnectDOM.dispatchEvent( new Event( 'disconnect' ) );
627
+
628
+ }
629
+
630
+ if ( element !== null ) {
631
+
632
+ const link = new Link( this, element );
633
+
634
+ this.links.push( link );
635
+
636
+ if ( this.disconnectDOM === null ) {
637
+
638
+ this.disconnectDOM = document.createElement( 'f-disconnect' );
639
+ this.disconnectDOM.innerHTML = Styles.icons.unlink ? `<i class='${ Styles.icons.unlink }'></i>` : '✖';
640
+
641
+ this.dom.appendChild( this.disconnectDOM );
642
+
643
+ const onDisconnect = () => {
644
+
645
+ this.links = [];
646
+ this.dom.removeChild( this.disconnectDOM );
647
+
648
+ this.disconnectDOM.removeEventListener( 'mousedown', onClick, true );
649
+ this.disconnectDOM.removeEventListener( 'touchstart', onClick, true );
650
+ this.disconnectDOM.removeEventListener( 'disconnect', onDisconnect, true );
651
+
652
+ element.removeEventListener( 'connect', onConnect );
653
+ element.removeEventListener( 'connectChildren', onConnect );
654
+ element.removeEventListener( 'nodeConnect', onConnect );
655
+ element.removeEventListener( 'nodeConnectChildren', onConnect );
656
+ element.removeEventListener( 'dispose', onDispose );
657
+
658
+ this.disconnectDOM = null;
659
+
660
+ };
661
+
662
+ const onConnect = ( e ) => {
663
+
664
+ this.dispatchEvent( new Event( 'connectChildren' ) );
665
+
666
+ };
667
+
668
+ const onDispose = () => {
669
+
670
+ this.connect();
671
+
672
+ };
673
+
674
+ const onClick = ( e ) => {
675
+
676
+ e.stopPropagation();
677
+
678
+ this.connect();
679
+
680
+ };
681
+
682
+ this.disconnectDOM.addEventListener( 'mousedown', onClick, true );
683
+ this.disconnectDOM.addEventListener( 'touchstart', onClick, true );
684
+ this.disconnectDOM.addEventListener( 'disconnect', onDisconnect, true );
685
+ element.addEventListener( 'connect', onConnect );
686
+ element.addEventListener( 'connectChildren', onConnect );
687
+ element.addEventListener( 'nodeConnect', onConnect );
688
+ element.addEventListener( 'nodeConnectChildren', onConnect );
689
+ element.addEventListener( 'dispose', onDispose );
690
+
691
+ }
692
+
693
+ }
694
+
695
+ this.dispatchEvent( new Event( 'connect' ) );
696
+
697
+ return this;
698
+
699
+ }
700
+
701
+ dispose() {
702
+
703
+ this.dispatchEvent( new Event( 'dispose' ) );
704
+
705
+ }
706
+
707
+ serialize( data ) {
708
+
709
+ const height = this.getHeight();
710
+
711
+ const inputs = [];
712
+ const links = [];
713
+
714
+ for ( const input of this.inputs ) {
715
+
716
+ inputs.push( input.toJSON( data ).id );
717
+
718
+ }
719
+
720
+ for ( const link of this.links ) {
721
+
722
+ if ( link.inputElement !== null && link.outputElement !== null ) {
723
+
724
+ links.push( link.outputElement.toJSON( data ).id );
725
+
726
+ }
727
+
728
+ }
729
+
730
+ if ( this.inputLength > 0 ) data.inputLength = this.inputLength;
731
+ if ( this.outputLength > 0 ) data.outputLength = this.outputLength;
732
+
733
+ if ( inputs.length > 0 ) data.inputs = inputs;
734
+ if ( links.length > 0 ) data.links = links;
735
+
736
+ if ( this.style !== '' ) {
737
+
738
+ data.style = this.style;
739
+
740
+ }
741
+
742
+ if ( height !== '' ) {
743
+
744
+ data.height = height;
745
+
746
+ }
747
+
748
+ }
749
+
750
+ deserialize( data ) {
751
+
752
+ if ( data.inputLength !== undefined ) this.setInput( data.inputLength );
753
+ if ( data.outputLength !== undefined ) this.setOutput( data.outputLength );
754
+
755
+ if ( data.inputs !== undefined ) {
756
+
757
+ const inputs = this.inputs;
758
+
759
+ if ( inputs.length > 0 ) {
760
+
761
+ let index = 0;
762
+
763
+ for ( const id of data.inputs ) {
764
+
765
+ data.objects[ id ] = inputs[ index ++ ];
766
+
767
+ }
768
+
769
+ } else {
770
+
771
+ for ( const id of data.inputs ) {
772
+
773
+ this.add( data.objects[ id ] );
774
+
775
+ }
776
+
777
+ }
778
+
779
+ }
780
+
781
+ if ( data.links !== undefined ) {
782
+
783
+ for ( const id of data.links ) {
784
+
785
+ this.connect( data.objects[ id ] );
786
+
787
+ }
788
+
789
+ }
790
+
791
+ if ( data.style !== undefined ) {
792
+
793
+ this.setStyle( data.style );
794
+
795
+ }
796
+
797
+ if ( data.height !== undefined ) {
798
+
799
+ this.setHeight( data.height );
800
+
801
+ }
802
+
803
+ }
804
+
805
+ get linkedExtra() {
806
+
807
+ const linkedElement = this.linkedElement;
808
+
809
+ return linkedElement ? linkedElement.getExtra() : null;
810
+
811
+ }
812
+
813
+ get linkedElement() {
814
+
815
+ const link = this.link;
816
+
817
+ return link ? link.outputElement : null;
818
+
819
+ }
820
+
821
+ get link() {
822
+
823
+ return this.links[ 0 ];
824
+
825
+ }
826
+
827
+ _createIO( type ) {
828
+
829
+ const { dom } = this;
830
+
831
+ const ioDOM = document.createElement( 'f-io' );
832
+ ioDOM.style.visibility = 'hidden';
833
+ ioDOM.className = type;
834
+
835
+ const onConnectEvent = ( e ) => {
836
+
837
+ e.preventDefault();
838
+
839
+ e.stopPropagation();
840
+
841
+ selected = null;
842
+
843
+ const nodeDOM = this.node.dom;
844
+
845
+ nodeDOM.classList.add( 'io-connect' );
846
+
847
+ ioDOM.classList.add( 'connect' );
848
+ dom.classList.add( 'select' );
849
+
850
+ const defaultOutput = Link.InputDirection === 'left' ? 'lio' : 'rio';
851
+
852
+ const link = type === defaultOutput ? new Link( this ) : new Link( null, this );
853
+
854
+ this.links.push( link );
855
+
856
+ draggableDOM( e, ( data ) => {
857
+
858
+ if ( data.dragging === false ) {
859
+
860
+ nodeDOM.classList.remove( 'io-connect' );
861
+
862
+ ioDOM.classList.remove( 'connect' );
863
+ dom.classList.remove( 'select' );
864
+
865
+ this.links.splice( this.links.indexOf( link ), 1 );
866
+
867
+ if ( selected !== null ) {
868
+
869
+ if ( type === defaultOutput ) {
870
+
871
+ link.outputElement = selected;
872
+
873
+ } else {
874
+
875
+ link.inputElement = selected;
876
+
877
+ }
878
+
879
+ // check if is an is circular link
880
+
881
+ if ( link.outputElement.node.isCircular( link.inputElement.node ) ) {
882
+
883
+ return;
884
+
885
+ }
886
+
887
+ //
888
+
889
+ if ( link.inputElement.inputLength > 0 && link.outputElement.outputLength > 0 ) {
890
+
891
+ link.inputElement.connect( link.outputElement );
892
+
893
+ }
894
+
895
+ }
896
+
897
+ }
898
+
899
+ }, 'connecting' );
900
+
901
+ };
902
+
903
+ ioDOM.addEventListener( 'mousedown', onConnectEvent, true );
904
+ ioDOM.addEventListener( 'touchstart', onConnectEvent, true );
905
+
906
+ return ioDOM;
907
+
908
+ }
909
+
910
+ }
911
+
912
+ Element.prototype.isElement = true;
913
+
914
+ class Input extends Serializer {
915
+
916
+ constructor( dom ) {
917
+
918
+ super();
919
+
920
+ this.dom = dom;
921
+
922
+ this.element = null;
923
+
924
+ this.extra = null;
925
+
926
+ this.events = {
927
+ 'change': [],
928
+ 'click': []
929
+ };
930
+
931
+ this.addEventListener( 'change', ( ) => {
932
+
933
+ dispatchEventList( this.events.change, this );
934
+
935
+ } );
936
+
937
+ this.addEventListener( 'click', ( ) => {
938
+
939
+ dispatchEventList( this.events.click, this );
940
+
941
+ } );
942
+
943
+ }
944
+
945
+ setExtra( value ) {
946
+
947
+ this.extra = value;
948
+
949
+ return this;
950
+
951
+ }
952
+
953
+ getExtra() {
954
+
955
+ return this.extra;
956
+
957
+ }
958
+
959
+ setToolTip( text ) {
960
+
961
+ const div = document.createElement( 'f-tooltip' );
962
+ div.innerText = text;
963
+
964
+ this.dom.appendChild( div );
965
+
966
+ return this;
967
+
968
+ }
969
+
970
+ onChange( callback ) {
971
+
972
+ this.events.change.push( callback );
973
+
974
+ return this;
975
+
976
+ }
977
+
978
+ onClick( callback ) {
979
+
980
+ this.events.click.push( callback );
981
+
982
+ return this;
983
+
984
+ }
985
+
986
+ setValue( value, dispatch = true ) {
987
+
988
+ this.dom.value = value;
989
+
990
+ if ( dispatch ) this.dispatchEvent( new Event( 'change' ) );
991
+
992
+ return this;
993
+
994
+ }
995
+
996
+ getValue() {
997
+
998
+ return this.dom.value;
999
+
1000
+ }
1001
+
1002
+ serialize( data ) {
1003
+
1004
+ data.value = this.getValue();
1005
+
1006
+ }
1007
+
1008
+ deserialize( data ) {
1009
+
1010
+ this.setValue( data.value );
1011
+
1012
+ }
1013
+
1014
+ }
1015
+
1016
+ Input.prototype.isInput = true;
1017
+
1018
+ class Node extends Serializer {
1019
+
1020
+ constructor() {
1021
+
1022
+ super();
1023
+
1024
+ const dom = document.createElement( 'f-node' );
1025
+
1026
+ const onDown = () => {
1027
+
1028
+ const canvas = this.canvas;
1029
+
1030
+ if ( canvas !== null ) {
1031
+
1032
+ canvas.select( this );
1033
+
1034
+ }
1035
+
1036
+ };
1037
+
1038
+ dom.addEventListener( 'mousedown', onDown, true );
1039
+ dom.addEventListener( 'touchstart', onDown, true );
1040
+
1041
+ this._onConnect = ( e ) => {
1042
+
1043
+ const { target } = e;
1044
+
1045
+ for ( const element of this.elements ) {
1046
+
1047
+ if ( element !== target ) {
1048
+
1049
+ element.dispatchEvent( new Event( 'nodeConnect' ) );
1050
+
1051
+ }
1052
+
1053
+ }
1054
+
1055
+ };
1056
+
1057
+ this._onConnectChildren = ( e ) => {
1058
+
1059
+ const { target } = e;
1060
+
1061
+ for ( const element of this.elements ) {
1062
+
1063
+ if ( element !== target ) {
1064
+
1065
+ element.dispatchEvent( new Event( 'nodeConnectChildren' ) );
1066
+
1067
+ }
1068
+
1069
+ }
1070
+
1071
+ };
1072
+
1073
+ this.dom = dom;
1074
+
1075
+ this.style = '';
1076
+
1077
+ this.canvas = null;
1078
+
1079
+ this.elements = [];
1080
+
1081
+ this.events = {
1082
+ 'focus': [],
1083
+ 'blur': []
1084
+ };
1085
+
1086
+ this.setWidth( 300 ).setPosition( 0, 0 );
1087
+
1088
+ }
1089
+
1090
+ onFocus( callback ) {
1091
+
1092
+ this.events.focus.push( callback );
1093
+
1094
+ return this;
1095
+
1096
+ }
1097
+
1098
+ onBlur( callback ) {
1099
+
1100
+ this.events.blur.push( callback );
1101
+
1102
+ return this;
1103
+
1104
+ }
1105
+
1106
+ setStyle( style ) {
1107
+
1108
+ const dom = this.dom;
1109
+
1110
+ if ( this.style ) dom.classList.remove( this.style );
1111
+
1112
+ if ( style ) dom.classList.add( style );
1113
+
1114
+ this.style = style;
1115
+
1116
+ return this;
1117
+
1118
+ }
1119
+
1120
+ setPosition( x, y ) {
1121
+
1122
+ const dom = this.dom;
1123
+
1124
+ dom.style.left = toPX( x );
1125
+ dom.style.top = toPX( y );
1126
+
1127
+ return this;
1128
+
1129
+ }
1130
+
1131
+ getPosition() {
1132
+
1133
+ const dom = this.dom;
1134
+
1135
+ return {
1136
+ x: parseInt( dom.style.left ),
1137
+ y: parseInt( dom.style.top )
1138
+ };
1139
+
1140
+ }
1141
+
1142
+ setWidth( val ) {
1143
+
1144
+ this.dom.style.width = toPX( val );
1145
+
1146
+ return this;
1147
+
1148
+ }
1149
+
1150
+ getWidth() {
1151
+
1152
+ return parseInt( this.dom.style.width );
1153
+
1154
+ }
1155
+
1156
+ add( element ) {
1157
+
1158
+ this.elements.push( element );
1159
+
1160
+ element.node = this;
1161
+ element.addEventListener( 'connect', this._onConnect );
1162
+ element.addEventListener( 'connectChildren', this._onConnectChildren );
1163
+
1164
+ this.dom.appendChild( element.dom );
1165
+
1166
+ return this;
1167
+
1168
+ }
1169
+
1170
+ remove( element ) {
1171
+
1172
+ this.elements.splice( this.elements.indexOf( element ), 1 );
1173
+
1174
+ element.node = null;
1175
+ element.removeEventListener( 'connect', this._onConnect );
1176
+ element.removeEventListener( 'connectChildren', this._onConnectChildren );
1177
+
1178
+ this.dom.removeChild( element.dom );
1179
+
1180
+ return this;
1181
+
1182
+ }
1183
+
1184
+ dispose() {
1185
+
1186
+ const canvas = this.canvas;
1187
+
1188
+ if ( canvas !== null ) canvas.remove( this );
1189
+
1190
+ for ( const element of this.elements ) {
1191
+
1192
+ element.dispose();
1193
+
1194
+ }
1195
+
1196
+ this.dispatchEvent( new Event( 'dispose' ) );
1197
+
1198
+ }
1199
+
1200
+ isCircular( node ) {
1201
+
1202
+ if ( node === this ) return true;
1203
+
1204
+ const links = this.getLinks();
1205
+
1206
+ for ( const link of links ) {
1207
+
1208
+ if ( link.outputElement.node.isCircular( node ) ) {
1209
+
1210
+ return true;
1211
+
1212
+ }
1213
+
1214
+ }
1215
+
1216
+ return false;
1217
+
1218
+ }
1219
+
1220
+ getLinks() {
1221
+
1222
+ const links = [];
1223
+
1224
+ for ( const element of this.elements ) {
1225
+
1226
+ links.push( ...element.links );
1227
+
1228
+ }
1229
+
1230
+ return links;
1231
+
1232
+ }
1233
+
1234
+ serialize( data ) {
1235
+
1236
+ const { x, y, style } = this.getPosition();
1237
+
1238
+ const elements = [];
1239
+
1240
+ for ( const element of this.elements ) {
1241
+
1242
+ elements.push( element.toJSON( data ).id );
1243
+
1244
+ }
1245
+
1246
+ data.x = x;
1247
+ data.y = y;
1248
+ data.width = this.getWidth();
1249
+ data.elements = elements;
1250
+
1251
+ if ( style !== '' ) {
1252
+
1253
+ data.style = style;
1254
+
1255
+ }
1256
+
1257
+ }
1258
+
1259
+ deserialize( data ) {
1260
+
1261
+ this.setPosition( data.x, data.y );
1262
+ this.setWidth( data.width );
1263
+
1264
+ if ( data.style !== undefined ) {
1265
+
1266
+ this.setStyle( data.style );
1267
+
1268
+ }
1269
+
1270
+ const elements = this.elements;
1271
+
1272
+ if ( elements.length > 0 ) {
1273
+
1274
+ let index = 0;
1275
+
1276
+ for ( const id of data.elements ) {
1277
+
1278
+ data.objects[ id ] = elements[ index ++ ];
1279
+
1280
+ }
1281
+
1282
+ } else {
1283
+
1284
+ for ( const id of data.elements ) {
1285
+
1286
+ this.add( data.objects[ id ] );
1287
+
1288
+ }
1289
+
1290
+ }
1291
+
1292
+ }
1293
+
1294
+ }
1295
+
1296
+ Node.prototype.isNode = true;
1297
+
1298
+ class DraggableElement extends Element {
1299
+
1300
+ constructor( draggable = true ) {
1301
+
1302
+ super( true );
1303
+
1304
+ this.draggable = draggable;
1305
+
1306
+ const onDrag = ( e ) => {
1307
+
1308
+ e.preventDefault();
1309
+
1310
+ if ( this.draggable === true ) {
1311
+
1312
+ draggableDOM( this.node.dom );
1313
+
1314
+ }
1315
+
1316
+ };
1317
+
1318
+ const { dom } = this;
1319
+
1320
+ dom.addEventListener( 'mousedown', onDrag, true );
1321
+ dom.addEventListener( 'touchstart', onDrag, true );
1322
+
1323
+ }
1324
+
1325
+ }
1326
+
1327
+ class TitleElement extends DraggableElement {
1328
+
1329
+ constructor( title, draggable = true ) {
1330
+
1331
+ super( draggable );
1332
+
1333
+ const { dom } = this;
1334
+
1335
+ dom.className = 'title';
1336
+
1337
+ const spanDOM = document.createElement( 'span' );
1338
+ spanDOM.innerText = title;
1339
+
1340
+ const iconDOM = document.createElement( 'i' );
1341
+
1342
+ const toolbarDOM = document.createElement( 'f-toolbar' );
1343
+
1344
+ this.buttons = [];
1345
+
1346
+ this.spanDOM = spanDOM;
1347
+ this.iconDOM = iconDOM;
1348
+ this.toolbarDOM = toolbarDOM;
1349
+
1350
+ dom.appendChild( spanDOM );
1351
+ dom.appendChild( iconDOM );
1352
+ dom.appendChild( toolbarDOM );
1353
+
1354
+ }
1355
+
1356
+ setIcon( value ) {
1357
+
1358
+ this.iconDOM.className = value;
1359
+
1360
+ return this;
1361
+
1362
+ }
1363
+
1364
+ getIcon() {
1365
+
1366
+ return this.iconDOM.className;
1367
+
1368
+ }
1369
+
1370
+ setTitle( value ) {
1371
+
1372
+ this.spanDOM.innerText = value;
1373
+
1374
+ return this;
1375
+
1376
+ }
1377
+
1378
+ getTitle() {
1379
+
1380
+ return this.spanDOM.innerText;
1381
+
1382
+ }
1383
+
1384
+ addButton( button ) {
1385
+
1386
+ this.buttons.push( button );
1387
+
1388
+ this.toolbarDOM.appendChild( button.dom );
1389
+
1390
+ return this;
1391
+
1392
+ }
1393
+
1394
+ serialize( data ) {
1395
+
1396
+ super.serialize( data );
1397
+
1398
+ const title = this.getTitle();
1399
+ const icon = this.getIcon();
1400
+
1401
+ data.title = title;
1402
+
1403
+ if ( icon !== '' ) {
1404
+
1405
+ data.icon = icon;
1406
+
1407
+ }
1408
+
1409
+ }
1410
+
1411
+ deserialize( data ) {
1412
+
1413
+ super.deserialize( data );
1414
+
1415
+ this.setTitle( data.title );
1416
+
1417
+ if ( data.icon !== undefined ) {
1418
+
1419
+ this.setIcon( data.icon );
1420
+
1421
+ }
1422
+
1423
+ }
1424
+
1425
+ }
1426
+
1427
+ const drawLine = ( p1x, p1y, p2x, p2y, invert, size, color, ctx ) => {
1428
+
1429
+ const offset = 100 * ( invert ? - 1 : 1 );
1430
+
1431
+ ctx.beginPath();
1432
+
1433
+ ctx.moveTo( p1x, p1y );
1434
+
1435
+ ctx.bezierCurveTo(
1436
+ p1x + offset, p1y,
1437
+ p2x - offset, p2y,
1438
+ p2x, p2y
1439
+ );
1440
+
1441
+ ctx.lineWidth = size;
1442
+ ctx.strokeStyle = color;
1443
+ ctx.stroke();
1444
+
1445
+ };
1446
+
1447
+ const colors = [
1448
+ '#ff4444',
1449
+ '#44ff44',
1450
+ '#4444ff'
1451
+ ];
1452
+
1453
+ const dropNode = new Node().add( new TitleElement( 'File' ) ).setWidth( 250 );
1454
+
1455
+ class Canvas extends Serializer {
1456
+
1457
+ constructor() {
1458
+
1459
+ super();
1460
+
1461
+ const dom = document.createElement( 'f-canvas' );
1462
+ const contentDOM = document.createElement( 'f-content' );
1463
+ const areaDOM = document.createElement( 'f-area' );
1464
+ const dropDOM = document.createElement( 'f-drop' );
1465
+
1466
+ const canvas = document.createElement( 'canvas' );
1467
+ const frontCanvas = document.createElement( 'canvas' );
1468
+
1469
+ const context = canvas.getContext( '2d' );
1470
+ const frontContext = frontCanvas.getContext( '2d' );
1471
+
1472
+ this.dom = dom;
1473
+
1474
+ this.contentDOM = contentDOM;
1475
+ this.areaDOM = areaDOM;
1476
+ this.dropDOM = dropDOM;
1477
+
1478
+ this.canvas = canvas;
1479
+ this.frontCanvas = frontCanvas;
1480
+
1481
+ this.context = context;
1482
+ this.frontContext = frontContext;
1483
+
1484
+ this.width = 10000;
1485
+ this.height = 10000;
1486
+
1487
+ this.clientX = 0;
1488
+ this.clientY = 0;
1489
+
1490
+ this.relativeClientX = 0;
1491
+ this.relativeClientY = 0;
1492
+
1493
+ this.zoom = 1;
1494
+
1495
+ this.nodes = [];
1496
+
1497
+ this.selected = null;
1498
+
1499
+ this.updating = false;
1500
+
1501
+ this.droppedItems = [];
1502
+
1503
+ this.events = {
1504
+ 'drop': []
1505
+ };
1506
+
1507
+ frontCanvas.className = 'front';
1508
+
1509
+ contentDOM.style.left = toPX( this.centerX );
1510
+ contentDOM.style.top = toPX( this.centerY );
1511
+
1512
+ areaDOM.style.width = `calc( 100% + ${ this.width }px )`;
1513
+ areaDOM.style.height = `calc( 100% + ${ this.height }px )`;
1514
+
1515
+ dropDOM.innerHTML = '<span>drop your file</span>';
1516
+
1517
+ dom.appendChild( dropDOM );
1518
+ dom.appendChild( canvas );
1519
+ dom.appendChild( frontCanvas );
1520
+ dom.appendChild( contentDOM );
1521
+ dom.appendChild( areaDOM );
1522
+ /*
1523
+ let zoomTouchData = null;
1524
+
1525
+ const onZoomStart = () => {
1526
+
1527
+ zoomTouchData = null;
1528
+
1529
+ };
1530
+ */
1531
+ const onZoom = ( e ) => {
1532
+
1533
+ if ( e.touches ) {
1534
+
1535
+ if ( e.touches.length === 2 ) {
1536
+
1537
+ e.preventDefault();
1538
+
1539
+ e.stopImmediatePropagation();
1540
+ /*
1541
+ const clientX = ( e.touches[ 0 ].clientX + e.touches[ 1 ].clientX ) / 2;
1542
+ const clientY = ( e.touches[ 0 ].clientY + e.touches[ 1 ].clientY ) / 2;
1543
+
1544
+ const distance = Math.hypot(
1545
+ e.touches[ 0 ].clientX - e.touches[ 1 ].clientX,
1546
+ e.touches[ 0 ].clientY - e.touches[ 1 ].clientY
1547
+ );
1548
+
1549
+ if ( zoomTouchData === null ) {
1550
+
1551
+ zoomTouchData = {
1552
+ distance
1553
+ };
1554
+
1555
+ }
1556
+
1557
+ const delta = ( zoomTouchData.distance - distance );
1558
+ zoomTouchData.distance = distance;
1559
+
1560
+ let zoom = Math.min( Math.max( this.zoom - delta * .01, .5 ), 1.2 );
1561
+
1562
+ if ( zoom < .52 ) zoom = .5;
1563
+ else if ( zoom > .98 ) zoom = 1;
1564
+
1565
+ contentDOM.style.left = toPX( this.centerX / zoom );
1566
+ contentDOM.style.top = toPX( this.centerY / zoom );
1567
+ contentDOM.style.zoom = this.zoom = zoom;
1568
+ */
1569
+
1570
+ }
1571
+
1572
+ } else {
1573
+
1574
+ e.preventDefault();
1575
+
1576
+ e.stopImmediatePropagation();
1577
+ /*
1578
+ const delta = e.deltaY / 100;
1579
+ const zoom = Math.min( Math.max( this.zoom - delta * .1, .5 ), 1 );
1580
+
1581
+ contentDOM.style.left = toPX( this.centerX / zoom );
1582
+ contentDOM.style.top = toPX( this.centerY / zoom );
1583
+ contentDOM.style.zoom = this.zoom = zoom;
1584
+ */
1585
+
1586
+ }
1587
+
1588
+ };
1589
+
1590
+ dom.addEventListener( 'wheel', onZoom );
1591
+ dom.addEventListener( 'touchmove', onZoom );
1592
+ //dom.addEventListener( 'touchstart', onZoomStart );
1593
+
1594
+ let dropEnterCount = 0;
1595
+
1596
+ const dragState = ( enter ) => {
1597
+
1598
+ if ( enter ) {
1599
+
1600
+ if ( dropEnterCount ++ === 0 ) {
1601
+
1602
+ this.droppedItems = [];
1603
+
1604
+ dropDOM.classList.add( 'visible' );
1605
+
1606
+ this.add( dropNode );
1607
+
1608
+ }
1609
+
1610
+ } else if ( -- dropEnterCount === 0 ) {
1611
+
1612
+ dropDOM.classList.remove( 'visible' );
1613
+
1614
+ this.remove( dropNode );
1615
+
1616
+ }
1617
+
1618
+ };
1619
+
1620
+ dom.addEventListener( 'dragenter', () => {
1621
+
1622
+ dragState( true );
1623
+
1624
+ } );
1625
+
1626
+ dom.addEventListener( 'dragleave', () => {
1627
+
1628
+ dragState( false );
1629
+
1630
+ } );
1631
+
1632
+ dom.addEventListener( 'dragover', ( e ) => {
1633
+
1634
+ e.preventDefault();
1635
+
1636
+ const { relativeClientX, relativeClientY } = this;
1637
+
1638
+ const centerNodeX = dropNode.getWidth() / 2;
1639
+
1640
+ dropNode.setPosition( relativeClientX - centerNodeX, relativeClientY - 20 );
1641
+
1642
+ } );
1643
+
1644
+ dom.addEventListener( 'drop', ( e ) => {
1645
+
1646
+ e.preventDefault();
1647
+
1648
+ dragState( false );
1649
+
1650
+ this.droppedItems = e.dataTransfer.items;
1651
+
1652
+ dispatchEventList( this.events.drop, this );
1653
+
1654
+ } );
1655
+
1656
+ draggableDOM( dom, ( data ) => {
1657
+
1658
+ const { delta, isTouch } = data;
1659
+
1660
+ if ( ! isTouch ) {
1661
+
1662
+ if ( data.scrollTop === undefined ) {
1663
+
1664
+ data.scrollLeft = dom.scrollLeft;
1665
+ data.scrollTop = dom.scrollTop;
1666
+
1667
+ }
1668
+
1669
+ dom.scrollLeft = data.scrollLeft - delta.x;
1670
+ dom.scrollTop = data.scrollTop - delta.y;
1671
+
1672
+ }
1673
+
1674
+ if ( data.dragging ) {
1675
+
1676
+ dom.classList.add( 'grabbing' );
1677
+
1678
+ } else {
1679
+
1680
+ dom.classList.remove( 'grabbing' );
1681
+
1682
+ }
1683
+
1684
+ }, 'dragging-canvas' );
1685
+
1686
+ this._onMoveEvent = ( e ) => {
1687
+
1688
+ const event = e.touches ? e.touches[ 0 ] : e;
1689
+ const { zoom, rect } = this;
1690
+
1691
+ this.clientX = event.clientX;
1692
+ this.clientY = event.clientY;
1693
+
1694
+ this.relativeClientX = ( ( ( dom.scrollLeft - this.centerX ) + event.clientX ) - rect.left ) / zoom;
1695
+ this.relativeClientY = ( ( ( dom.scrollTop - this.centerY ) + event.clientY ) - rect.top ) / zoom;
1696
+
1697
+ };
1698
+
1699
+ this._onContentLoaded = () => {
1700
+
1701
+ this.centralize();
1702
+
1703
+ };
1704
+
1705
+ this._onUpdate = () => {
1706
+
1707
+ this.update();
1708
+
1709
+ };
1710
+
1711
+ this.start();
1712
+
1713
+ }
1714
+
1715
+ get rect() {
1716
+
1717
+ return this.dom.getBoundingClientRect();
1718
+
1719
+ }
1720
+
1721
+ get relativeX() {
1722
+
1723
+ return this.dom.scrollLeft - this.centerX;
1724
+
1725
+ }
1726
+
1727
+ get relativeY() {
1728
+
1729
+ return this.dom.scrollTop - this.centerY;
1730
+
1731
+ }
1732
+
1733
+ get centerX() {
1734
+
1735
+ return this.width / 2;
1736
+
1737
+ }
1738
+
1739
+ get centerY() {
1740
+
1741
+ return this.height / 2;
1742
+
1743
+ }
1744
+
1745
+ onDrop( callback ) {
1746
+
1747
+ this.events.drop.push( callback );
1748
+
1749
+ return this;
1750
+
1751
+ }
1752
+
1753
+ start() {
1754
+
1755
+ this.updating = true;
1756
+
1757
+ document.addEventListener( 'wheel', this._onMoveEvent, true );
1758
+
1759
+ document.addEventListener( 'mousedown', this._onMoveEvent, true );
1760
+ document.addEventListener( 'touchstart', this._onMoveEvent, true );
1761
+
1762
+ document.addEventListener( 'mousemove', this._onMoveEvent, true );
1763
+ document.addEventListener( 'touchmove', this._onMoveEvent, true );
1764
+
1765
+ document.addEventListener( 'dragover', this._onMoveEvent, true );
1766
+
1767
+ document.addEventListener( 'DOMContentLoaded', this._onContentLoaded );
1768
+
1769
+ requestAnimationFrame( this._onUpdate );
1770
+
1771
+ }
1772
+
1773
+ stop() {
1774
+
1775
+ this.updating = false;
1776
+
1777
+ document.removeEventListener( 'wheel', this._onMoveEvent, true );
1778
+
1779
+ document.removeEventListener( 'mousedown', this._onMoveEvent, true );
1780
+ document.removeEventListener( 'touchstart', this._onMoveEvent, true );
1781
+
1782
+ document.removeEventListener( 'mousemove', this._onMoveEvent, true );
1783
+ document.removeEventListener( 'touchmove', this._onMoveEvent, true );
1784
+
1785
+ document.removeEventListener( 'dragover', this._onMoveEvent, true );
1786
+
1787
+ document.removeEventListener( 'DOMContentLoaded', this._onContentLoaded );
1788
+
1789
+ }
1790
+
1791
+ add( node ) {
1792
+
1793
+ this.nodes.push( node );
1794
+
1795
+ node.canvas = this;
1796
+
1797
+ this.contentDOM.appendChild( node.dom );
1798
+
1799
+ return this;
1800
+
1801
+ }
1802
+
1803
+ remove( node ) {
1804
+
1805
+ if ( node === this.selected ) {
1806
+
1807
+ this.select();
1808
+
1809
+ }
1810
+
1811
+ this.unlink( node );
1812
+
1813
+ const nodes = this.nodes;
1814
+
1815
+ nodes.splice( nodes.indexOf( node ), 1 );
1816
+
1817
+ node.canvas = null;
1818
+
1819
+ this.contentDOM.removeChild( node.dom );
1820
+
1821
+ return this;
1822
+
1823
+ }
1824
+
1825
+ clear() {
1826
+
1827
+ const nodes = this.nodes;
1828
+
1829
+ while ( nodes.length > 0 ) {
1830
+
1831
+ this.remove( nodes[ 0 ] );
1832
+
1833
+ }
1834
+
1835
+ return this;
1836
+
1837
+ }
1838
+
1839
+ unlink( node ) {
1840
+
1841
+ const links = this.getLinks();
1842
+
1843
+ for ( const link of links ) {
1844
+
1845
+ if ( link.outputElement && link.outputElement.node === node ) {
1846
+
1847
+ link.inputElement.connect();
1848
+
1849
+ }
1850
+
1851
+ }
1852
+
1853
+ }
1854
+
1855
+ getLinks() {
1856
+
1857
+ const links = [];
1858
+
1859
+ for ( const node of this.nodes ) {
1860
+
1861
+ links.push( ...node.getLinks() );
1862
+
1863
+ }
1864
+
1865
+ return links;
1866
+
1867
+ }
1868
+
1869
+ centralize() {
1870
+
1871
+ this.dom.scroll( this.centerX, this.centerY );
1872
+
1873
+ return this;
1874
+
1875
+ }
1876
+
1877
+ select( node = null ) {
1878
+
1879
+ if ( node === this.selected ) return;
1880
+
1881
+ const previousNode = this.selected;
1882
+
1883
+ if ( previousNode !== null ) {
1884
+
1885
+ previousNode.dom.classList.remove( 'selected' );
1886
+
1887
+ this.selected = null;
1888
+
1889
+ dispatchEventList( previousNode.events.blur, previousNode );
1890
+
1891
+ }
1892
+
1893
+ if ( node !== null ) {
1894
+
1895
+ node.dom.classList.add( 'selected' );
1896
+
1897
+ this.selected = node;
1898
+
1899
+ dispatchEventList( node.events.focus, node );
1900
+
1901
+ }
1902
+
1903
+ }
1904
+
1905
+ update() {
1906
+
1907
+ if ( this.updating === false ) return;
1908
+
1909
+ requestAnimationFrame( this._onUpdate );
1910
+
1911
+ const { dom, zoom, canvas, frontCanvas, frontContext, context } = this;
1912
+
1913
+ const width = window.innerWidth;
1914
+ const height = window.innerHeight;
1915
+
1916
+ const domRect = this.rect;
1917
+
1918
+ if ( canvas.width !== width || canvas.height !== height ) {
1919
+
1920
+ canvas.width = width;
1921
+ canvas.height = height;
1922
+
1923
+ frontCanvas.width = width;
1924
+ frontCanvas.height = height;
1925
+
1926
+ }
1927
+
1928
+ context.clearRect( 0, 0, width, height );
1929
+ frontContext.clearRect( 0, 0, width, height );
1930
+
1931
+ context.globalCompositeOperation = 'lighter';
1932
+ frontContext.globalCompositeOperation = 'source-over';
1933
+
1934
+ const links = this.getLinks();
1935
+
1936
+ const aPos = { x: 0, y: 0 };
1937
+ const bPos = { x: 0, y: 0 };
1938
+
1939
+ const offsetIORadius = 10;
1940
+
1941
+ let dragging = '';
1942
+
1943
+ for ( const link of links ) {
1944
+
1945
+ const { lioElement, rioElement } = link;
1946
+
1947
+ let draggingLink = '';
1948
+ let length = 0;
1949
+
1950
+ if ( lioElement !== null ) {
1951
+
1952
+ const rect = lioElement.dom.getBoundingClientRect();
1953
+
1954
+ length = Math.max( length, lioElement.rioLength );
1955
+
1956
+ aPos.x = rect.x + rect.width;
1957
+ aPos.y = rect.y + ( rect.height / 2 );
1958
+
1959
+ } else {
1960
+
1961
+ aPos.x = this.clientX;
1962
+ aPos.y = this.clientY;
1963
+
1964
+ draggingLink = 'lio';
1965
+
1966
+ }
1967
+
1968
+ if ( rioElement !== null ) {
1969
+
1970
+ const rect = rioElement.dom.getBoundingClientRect();
1971
+
1972
+ length = Math.max( length, rioElement.lioLength );
1973
+
1974
+ bPos.x = rect.x;
1975
+ bPos.y = rect.y + ( rect.height / 2 );
1976
+
1977
+ } else {
1978
+
1979
+ bPos.x = this.clientX;
1980
+ bPos.y = this.clientY;
1981
+
1982
+ draggingLink = 'rio';
1983
+
1984
+ }
1985
+
1986
+ dragging = dragging || draggingLink;
1987
+
1988
+ const drawContext = draggingLink ? frontContext : context;
1989
+
1990
+ if ( draggingLink || length === 1 ) {
1991
+
1992
+ if ( draggingLink === 'rio' ) {
1993
+
1994
+ aPos.x += offsetIORadius;
1995
+ bPos.x /= zoom;
1996
+ bPos.y /= zoom;
1997
+
1998
+ } else if ( draggingLink === 'lio' ) {
1999
+
2000
+ bPos.x -= offsetIORadius;
2001
+ aPos.x /= zoom;
2002
+ aPos.y /= zoom;
2003
+
2004
+ }
2005
+
2006
+ drawLine(
2007
+ aPos.x * zoom, aPos.y * zoom,
2008
+ bPos.x * zoom, bPos.y * zoom,
2009
+ false, 2, '#ffffff', drawContext
2010
+ );
2011
+
2012
+ } else {
2013
+
2014
+ length = Math.min( length, 4 );
2015
+
2016
+ for ( let i = 0; i < length; i ++ ) {
2017
+
2018
+ const color = colors[ i ] || '#ffffff';
2019
+
2020
+ const marginY = 4;
2021
+
2022
+ const rioLength = Math.min( lioElement.rioLength, length );
2023
+ const lioLength = Math.min( rioElement.lioLength, length );
2024
+
2025
+ const aCenterY = ( ( rioLength * marginY ) * .5 ) - ( marginY / 2 );
2026
+ const bCenterY = ( ( lioLength * marginY ) * .5 ) - ( marginY / 2 );
2027
+
2028
+ const aIndex = Math.min( i, rioLength - 1 );
2029
+ const bIndex = Math.min( i, lioLength - 1 );
2030
+
2031
+ const aPosY = aIndex * marginY;
2032
+ const bPosY = bIndex * marginY;
2033
+
2034
+ drawLine(
2035
+ aPos.x * zoom, ( ( aPos.y + aPosY ) - aCenterY ) * zoom,
2036
+ bPos.x * zoom, ( ( bPos.y + bPosY ) - bCenterY ) * zoom,
2037
+ false, 2, color, drawContext
2038
+ );
2039
+
2040
+ }
2041
+
2042
+ }
2043
+
2044
+ }
2045
+
2046
+ context.globalCompositeOperation = 'destination-in';
2047
+
2048
+ context.fillRect( domRect.x, domRect.y, domRect.width, domRect.height );
2049
+
2050
+ if ( dragging !== '' ) {
2051
+
2052
+ dom.classList.add( 'dragging-' + dragging );
2053
+
2054
+ } else {
2055
+
2056
+ dom.classList.remove( 'dragging-lio' );
2057
+ dom.classList.remove( 'dragging-rio' );
2058
+
2059
+ }
2060
+
2061
+ }
2062
+
2063
+ serialize( data ) {
2064
+
2065
+ const nodes = [];
2066
+
2067
+ for ( const node of this.nodes ) {
2068
+
2069
+ nodes.push( node.toJSON( data ).id );
2070
+
2071
+ }
2072
+
2073
+ data.nodes = nodes;
2074
+
2075
+ }
2076
+
2077
+ deserialize( data ) {
2078
+
2079
+ for ( const id of data.nodes ) {
2080
+
2081
+ this.add( data.objects[ id ] );
2082
+
2083
+ }
2084
+
2085
+ }
2086
+
2087
+ }
2088
+
2089
+ class ButtonInput extends Input {
2090
+
2091
+ constructor( innterText = '' ) {
2092
+
2093
+ const dom = document.createElement( 'button' );
2094
+
2095
+ const spanDOM = document.createElement( 'span' );
2096
+ dom.appendChild( spanDOM );
2097
+
2098
+ const iconDOM = document.createElement( 'i' );
2099
+ dom.appendChild( iconDOM );
2100
+
2101
+ super( dom );
2102
+
2103
+ this.spanDOM = spanDOM;
2104
+ this.iconDOM = iconDOM;
2105
+
2106
+ spanDOM.innerText = innterText;
2107
+
2108
+ dom.onmouseover = () => {
2109
+
2110
+ this.dispatchEvent( new Event( 'mouseover' ) );
2111
+
2112
+ };
2113
+
2114
+ dom.onclick = dom.ontouchstart = ( e ) => {
2115
+
2116
+ e.preventDefault();
2117
+
2118
+ e.stopPropagation();
2119
+
2120
+ this.dispatchEvent( new Event( 'click' ) );
2121
+
2122
+ };
2123
+
2124
+ }
2125
+
2126
+ setIcon( className ) {
2127
+
2128
+ this.iconDOM.className = className;
2129
+
2130
+ return this;
2131
+
2132
+ }
2133
+
2134
+ setValue( val ) {
2135
+
2136
+ this.spanDOM.innerText = val;
2137
+
2138
+ return this;
2139
+
2140
+ }
2141
+
2142
+ getValue() {
2143
+
2144
+ return this.spanDOM.innerText;
2145
+
2146
+ }
2147
+
2148
+ }
2149
+
2150
+ class ObjectNode extends Node {
2151
+
2152
+ constructor( name, inputLength, extra = null, width = 300 ) {
2153
+
2154
+ super();
2155
+
2156
+ this.setWidth( width );
2157
+
2158
+ const title = new TitleElement( name )
2159
+ .setExtra( extra )
2160
+ .setOutput( inputLength );
2161
+
2162
+ const closeButton = new ButtonInput( Styles.icons.close || '✕' ).onClick( () => {
2163
+
2164
+ this.dispose();
2165
+
2166
+ } ).setIcon( Styles.icons.close );
2167
+
2168
+ title.addButton( closeButton );
2169
+
2170
+ this.add( title );
2171
+
2172
+ this.title = title;
2173
+ this.closeButton = closeButton;
2174
+
2175
+ }
2176
+
2177
+ setExtra( value ) {
2178
+
2179
+ this.title.setExtra( value );
2180
+
2181
+ return this;
2182
+
2183
+ }
2184
+
2185
+ getExtra( value ) {
2186
+
2187
+ return this.title.getExtra();
2188
+
2189
+ }
2190
+
2191
+ invalidate() {
2192
+
2193
+ this.title.dispatchEvent( new Event( 'connect' ) );
2194
+
2195
+ }
2196
+
2197
+ }
2198
+
2199
+ const ENTER_KEY$1 = 13;
2200
+
2201
+ class StringInput extends Input {
2202
+
2203
+ constructor( value = '' ) {
2204
+
2205
+ const dom = document.createElement( 'input' );
2206
+ super( dom );
2207
+
2208
+ dom.type = 'text';
2209
+ dom.value = value;
2210
+ dom.spellcheck = false;
2211
+ dom.autocomplete = 'off';
2212
+
2213
+ dom.onblur = () => {
2214
+
2215
+ this.dispatchEvent( new Event( 'blur' ) );
2216
+
2217
+ };
2218
+
2219
+ dom.onchange = () => {
2220
+
2221
+ this.dispatchEvent( new Event( 'change' ) );
2222
+
2223
+ };
2224
+
2225
+ dom.onkeyup = ( e ) => {
2226
+
2227
+ if ( e.keyCode === ENTER_KEY$1 ) {
2228
+
2229
+ e.target.blur();
2230
+
2231
+ }
2232
+
2233
+ e.stopPropagation();
2234
+
2235
+ this.dispatchEvent( new Event( 'change' ) );
2236
+
2237
+ };
2238
+
2239
+ }
2240
+
2241
+ }
2242
+
2243
+ const ENTER_KEY = 13;
2244
+
2245
+ class NumberInput extends Input {
2246
+
2247
+ constructor( value = 0, min = - Infinity, max = Infinity, step = .01 ) {
2248
+
2249
+ const dom = document.createElement( 'input' );
2250
+ super( dom );
2251
+
2252
+ this.min = min;
2253
+ this.max = max;
2254
+ this.step = step;
2255
+
2256
+ this.integer = false;
2257
+
2258
+ dom.type = 'text';
2259
+ dom.className = 'number';
2260
+ dom.value = this._getString( value );
2261
+ dom.spellcheck = false;
2262
+ dom.autocomplete = 'off';
2263
+
2264
+ dom.ondragstart = dom.oncontextmenu = ( e ) => {
2265
+
2266
+ e.preventDefault();
2267
+
2268
+ e.stopPropagation();
2269
+
2270
+ };
2271
+
2272
+ dom.onfocus = dom.onclick = () => {
2273
+
2274
+ dom.select();
2275
+
2276
+ };
2277
+
2278
+ dom.onblur = () => {
2279
+
2280
+ this.dispatchEvent( new Event( 'blur' ) );
2281
+
2282
+ };
2283
+
2284
+ dom.onchange = () => {
2285
+
2286
+ this.dispatchEvent( new Event( 'change' ) );
2287
+
2288
+ };
2289
+
2290
+ dom.onkeydown = ( e ) => {
2291
+
2292
+ if ( e.key.length === 1 && /\d|\./.test( e.key ) !== true ) {
2293
+
2294
+ return false;
2295
+
2296
+ }
2297
+
2298
+ if ( e.keyCode === ENTER_KEY ) {
2299
+
2300
+ e.target.blur();
2301
+
2302
+ }
2303
+
2304
+ e.stopPropagation();
2305
+
2306
+ };
2307
+
2308
+ draggableDOM( dom, ( data ) => {
2309
+
2310
+ const { delta } = data;
2311
+
2312
+ if ( data.value === undefined ) {
2313
+
2314
+ data.value = this.getValue();
2315
+
2316
+ }
2317
+
2318
+ const diff = delta.x - delta.y;
2319
+
2320
+ const value = data.value + ( diff * this.step );
2321
+
2322
+ this.dom.value = this._getString( value.toFixed( this.precision ) );
2323
+
2324
+ this.dispatchEvent( new Event( 'change' ) );
2325
+
2326
+ } );
2327
+
2328
+ }
2329
+
2330
+ setRange( min, max, step ) {
2331
+
2332
+ this.min = min;
2333
+ this.max = max;
2334
+ this.step = step;
2335
+
2336
+ this.dispatchEvent( new Event( 'range' ) );
2337
+
2338
+ return this.setValue( this.getValue() );
2339
+
2340
+ }
2341
+
2342
+ get precision() {
2343
+
2344
+ if ( this.integer === true ) return 0;
2345
+
2346
+ const fract = this.step % 1;
2347
+
2348
+ return fract !== 0 ? fract.toString().split( '.' )[ 1 ].length : 1;
2349
+
2350
+ }
2351
+
2352
+ setValue( val, dispatch = true ) {
2353
+
2354
+ return super.setValue( this._getString( val ), dispatch );
2355
+
2356
+ }
2357
+
2358
+ getValue() {
2359
+
2360
+ return Number( this.dom.value );
2361
+
2362
+ }
2363
+
2364
+ serialize( data ) {
2365
+
2366
+ const { min, max } = this;
2367
+
2368
+ if ( min !== - Infinity && max !== Infinity ) {
2369
+
2370
+ data.min = this.min;
2371
+ data.max = this.max;
2372
+ data.step = this.step;
2373
+
2374
+ }
2375
+
2376
+ super.serialize( data );
2377
+
2378
+ }
2379
+
2380
+ deserialize( data ) {
2381
+
2382
+ if ( data.min !== undefined ) {
2383
+
2384
+ const { min, max, step } = this;
2385
+
2386
+ this.setRange( min, max, step );
2387
+
2388
+ }
2389
+
2390
+ super.deserialize( data );
2391
+
2392
+ }
2393
+
2394
+ _getString( value ) {
2395
+
2396
+ let num = Math.min( Math.max( Number( value ), this.min ), this.max );
2397
+
2398
+ if ( this.integer === true ) {
2399
+
2400
+ return Math.floor( num );
2401
+
2402
+ } else {
2403
+
2404
+ return num + ( num % 1 ? '' : '.0' );
2405
+
2406
+ }
2407
+
2408
+ }
2409
+
2410
+ }
2411
+
2412
+ const getStep = ( min, max ) => {
2413
+
2414
+ const sensibility = .001;
2415
+
2416
+ return ( max - min ) * sensibility;
2417
+
2418
+ };
2419
+
2420
+ class SliderInput extends Input {
2421
+
2422
+ constructor( value = 0, min = 0, max = 100 ) {
2423
+
2424
+ const dom = document.createElement( 'f-subinputs' );
2425
+ super( dom );
2426
+
2427
+ value = Math.min( Math.max( value, min ), max );
2428
+
2429
+ const step = getStep( min, max );
2430
+
2431
+ const rangeDOM = document.createElement( 'input' );
2432
+ rangeDOM.type = 'range';
2433
+ rangeDOM.min = min;
2434
+ rangeDOM.max = max;
2435
+ rangeDOM.step = step;
2436
+ rangeDOM.value = value;
2437
+
2438
+ const field = new NumberInput( value, min, max, step );
2439
+ field.dom.className = 'range-value';
2440
+ field.onChange( () => {
2441
+
2442
+ rangeDOM.value = field.getValue();
2443
+
2444
+ } );
2445
+
2446
+ field.addEventListener( 'range', () => {
2447
+
2448
+ rangeDOM.min = field.min;
2449
+ rangeDOM.max = field.max;
2450
+ rangeDOM.step = field.step;
2451
+ rangeDOM.value = field.getValue();
2452
+
2453
+ } );
2454
+
2455
+ dom.appendChild( rangeDOM );
2456
+ dom.appendChild( field.dom );
2457
+
2458
+ this.rangeDOM = rangeDOM;
2459
+ this.field = field;
2460
+
2461
+ const updateRangeValue = () => {
2462
+
2463
+ let value = Number( rangeDOM.value );
2464
+
2465
+ if ( value !== this.max && value + this.step >= this.max ) {
2466
+
2467
+ // fix not end range fraction
2468
+
2469
+ rangeDOM.value = value = this.max;
2470
+
2471
+ }
2472
+
2473
+ this.field.setValue( value );
2474
+
2475
+ };
2476
+
2477
+ draggableDOM( rangeDOM, () => {
2478
+
2479
+ updateRangeValue();
2480
+
2481
+ this.dispatchEvent( new Event( 'change' ) );
2482
+
2483
+ }, '' );
2484
+
2485
+ }
2486
+
2487
+ get min() {
2488
+
2489
+ return this.field.min;
2490
+
2491
+ }
2492
+
2493
+ get max() {
2494
+
2495
+ return this.field.max;
2496
+
2497
+ }
2498
+
2499
+ get step() {
2500
+
2501
+ return this.field.step;
2502
+
2503
+ }
2504
+
2505
+ setRange( min, max ) {
2506
+
2507
+ this.field.setRange( min, max, getStep( min, max ) );
2508
+
2509
+ this.dispatchEvent( new Event( 'range' ) );
2510
+ this.dispatchEvent( new Event( 'change' ) );
2511
+
2512
+ return this;
2513
+
2514
+ }
2515
+
2516
+ setValue( val, dispatch = true ) {
2517
+
2518
+ this.field.setValue( val );
2519
+ this.rangeDOM.value = val;
2520
+
2521
+ if ( dispatch ) this.dispatchEvent( new Event( 'change' ) );
2522
+
2523
+ return this;
2524
+
2525
+ }
2526
+
2527
+ getValue() {
2528
+
2529
+ return this.field.getValue();
2530
+
2531
+ }
2532
+
2533
+ serialize( data ) {
2534
+
2535
+ data.min = this.min;
2536
+ data.max = this.max;
2537
+
2538
+ super.serialize( data );
2539
+
2540
+ }
2541
+
2542
+ deserialize( data ) {
2543
+
2544
+ const { min, max } = data;
2545
+
2546
+ this.setRange( min, max );
2547
+
2548
+ super.deserialize( data );
2549
+
2550
+ }
2551
+
2552
+ }
2553
+
2554
+ class ColorInput extends Input {
2555
+
2556
+ constructor( value = 0x0099ff ) {
2557
+
2558
+ const dom = document.createElement( 'input' );
2559
+ super( dom );
2560
+
2561
+ dom.type = 'color';
2562
+ dom.value = toHex( value );
2563
+
2564
+ dom.oninput = () => {
2565
+
2566
+ this.dispatchEvent( new Event( 'change' ) );
2567
+
2568
+ };
2569
+
2570
+ }
2571
+
2572
+ setValue( value, dispatch = true ) {
2573
+
2574
+ return super.setValue( toHex( value ), dispatch );
2575
+
2576
+ }
2577
+
2578
+ getValue() {
2579
+
2580
+ return parseInt( super.getValue().substr( 1 ), 16 );
2581
+
2582
+ }
2583
+
2584
+ }
2585
+
2586
+ class TextInput extends Input {
2587
+
2588
+ constructor( innerText = '' ) {
2589
+
2590
+ const dom = document.createElement( 'textarea' );
2591
+ super( dom );
2592
+
2593
+ dom.innerText = innerText;
2594
+
2595
+ }
2596
+
2597
+ setValue( val ) {
2598
+
2599
+ this.dom.innerText = val;
2600
+
2601
+ return this;
2602
+
2603
+ }
2604
+
2605
+ getValue() {
2606
+
2607
+ return this.dom.innerText;
2608
+
2609
+ }
2610
+
2611
+ }
2612
+
2613
+ class LabelElement extends Element {
2614
+
2615
+ constructor( label = '', align = '' ) {
2616
+
2617
+ super();
2618
+
2619
+ this.labelDOM = document.createElement( 'f-label' );
2620
+ this.inputsDOM = document.createElement( 'f-inputs' );
2621
+
2622
+ const spanDOM = document.createElement( 'span' );
2623
+ const iconDOM = document.createElement( 'i' );
2624
+
2625
+ this.spanDOM = spanDOM;
2626
+ this.iconDOM = iconDOM;
2627
+
2628
+ this.labelDOM.appendChild( this.spanDOM );
2629
+ this.labelDOM.appendChild( this.iconDOM );
2630
+
2631
+ this.dom.appendChild( this.labelDOM );
2632
+ this.dom.appendChild( this.inputsDOM );
2633
+
2634
+ this.setLabel( label );
2635
+ this.setAlign( align );
2636
+
2637
+ }
2638
+
2639
+ setIcon( value ) {
2640
+
2641
+ this.iconDOM.className = value;
2642
+
2643
+ return this;
2644
+
2645
+ }
2646
+
2647
+ getIcon() {
2648
+
2649
+ return this.iconDOM.className;
2650
+
2651
+ }
2652
+
2653
+ setAlign( align ) {
2654
+
2655
+ this.labelDOM.className = align;
2656
+
2657
+ }
2658
+
2659
+ setLabel( val ) {
2660
+
2661
+ this.spanDOM.innerText = val;
2662
+
2663
+ }
2664
+
2665
+ getLabel() {
2666
+
2667
+ return this.spanDOM.innerText;
2668
+
2669
+ }
2670
+
2671
+ serialize( data ) {
2672
+
2673
+ super.serialize( data );
2674
+
2675
+ const label = this.getLabel();
2676
+ const icon = this.getIcon();
2677
+
2678
+ data.label = label;
2679
+
2680
+ if ( icon !== '' ) {
2681
+
2682
+ data.icon = icon;
2683
+
2684
+ }
2685
+
2686
+ }
2687
+
2688
+ deserialize( data ) {
2689
+
2690
+ super.deserialize( data );
2691
+
2692
+ this.setLabel( data.label );
2693
+
2694
+ if ( data.icon !== undefined ) {
2695
+
2696
+ this.setIcon( data.icon );
2697
+
2698
+ }
2699
+
2700
+ }
2701
+
2702
+ }
2703
+
2704
+ class PanelNode extends Node {
2705
+
2706
+ constructor( title = 'Panel', align = 'top-right' ) {
2707
+
2708
+ super();
2709
+
2710
+ const titleElement = new TitleElement( title );
2711
+ this.add( titleElement );
2712
+
2713
+ const collapseButton = new ButtonInput( '🗕' );
2714
+ collapseButton.onClick( () => {
2715
+
2716
+ this.setCollapse( ! this.collapsed );
2717
+
2718
+ } );
2719
+
2720
+ titleElement.addButton( collapseButton );
2721
+
2722
+ this.collapseButton = collapseButton;
2723
+ this.titleElement = titleElement;
2724
+ this.align = align;
2725
+ this.collapsed = false;
2726
+
2727
+ this.setAlign( align );
2728
+ this.setStyle( 'rouded' );
2729
+
2730
+ }
2731
+
2732
+ setCollapse( value ) {
2733
+
2734
+ const cssClass = 'closed';
2735
+
2736
+ this.dom.classList.remove( cssClass );
2737
+
2738
+ this.collapsed = value;
2739
+
2740
+ this.collapseButton.value = value ? '🗖' : '🗕';
2741
+
2742
+ if ( value === true ) {
2743
+
2744
+ this.dom.classList.add( cssClass );
2745
+
2746
+ }
2747
+
2748
+ return this;
2749
+
2750
+ }
2751
+
2752
+ setAlign( align ) {
2753
+
2754
+ if ( this.align ) this.dom.classList.remove( this.align );
2755
+ this.dom.classList.add( align );
2756
+
2757
+ this.align = align;
2758
+
2759
+ return this;
2760
+
2761
+ }
2762
+
2763
+ addInput( inputClass, object, property, ...params ) {
2764
+
2765
+ const value = object[ property ];
2766
+
2767
+ const input = new inputClass( value, ...params );
2768
+ input.onChange( () => {
2769
+
2770
+ object[ property ] = input.value;
2771
+
2772
+ } );
2773
+
2774
+ this.add( new LabelElement( property ).add( input ) );
2775
+
2776
+ return input;
2777
+
2778
+ }
2779
+
2780
+ addSlider( object, property, min, max ) {
2781
+
2782
+ return this.addInput( SliderInput, object, property, min, max );
2783
+
2784
+ }
2785
+
2786
+ addNumber( object, property ) {
2787
+
2788
+ return this.addInput( NumberInput, object, property );
2789
+
2790
+ }
2791
+
2792
+ addColor( object, property ) {
2793
+
2794
+ return this.addInput( ColorInput, object, property );
2795
+
2796
+ }
2797
+
2798
+ addString( object, property ) {
2799
+
2800
+ return this.addInput( StringInput, object, property );
2801
+
2802
+ }
2803
+
2804
+ addText( object, property ) {
2805
+
2806
+ const input = this.addInput( TextInput, object, property );
2807
+ input.element.setHeight( 70 );
2808
+
2809
+ return input;
2810
+
2811
+ }
2812
+
2813
+ addButton( name ) {
2814
+
2815
+ const input = new ButtonInput( name );
2816
+
2817
+ this.add( new Element().setHeight( 34 ).add( input ) );
2818
+
2819
+ return input;
2820
+
2821
+ }
2822
+
2823
+ }
2824
+
2825
+ class Menu extends EventTarget {
2826
+
2827
+ constructor( className, target = null ) {
2828
+
2829
+ super();
2830
+
2831
+ const dom = document.createElement( 'f-menu' );
2832
+ dom.className = className + ' hidden';
2833
+
2834
+ this.dom = dom;
2835
+
2836
+ this.visible = false;
2837
+
2838
+ this.subMenus = new WeakMap();
2839
+ this.domButtons = new WeakMap();
2840
+
2841
+ this.events = {
2842
+ 'context': []
2843
+ };
2844
+
2845
+ this.addEventListener( 'context', ( ) => {
2846
+
2847
+ dispatchEventList( this.events.context, this );
2848
+
2849
+ } );
2850
+
2851
+ this._lastButtonClick = null;
2852
+
2853
+ this._onButtonClick = ( e = null ) => {
2854
+
2855
+ const button = e ? e.target : null;
2856
+
2857
+ if ( this._lastButtonClick ) {
2858
+
2859
+ this._lastButtonClick.dom.parentElement.classList.remove( 'active' );
2860
+
2861
+ }
2862
+
2863
+ this._lastButtonClick = button;
2864
+
2865
+ if ( button ) {
2866
+
2867
+ if ( this.subMenus.has( button ) ) {
2868
+
2869
+ this.subMenus.get( button )._onButtonClick();
2870
+
2871
+ }
2872
+
2873
+ button.dom.parentElement.classList.add( 'active' );
2874
+
2875
+ }
2876
+
2877
+ };
2878
+
2879
+ this._onButtonMouseOver = ( e ) => {
2880
+
2881
+ const button = e.target;
2882
+
2883
+ if ( this.subMenus.has( button ) && this._lastButtonClick !== button ) {
2884
+
2885
+ this._onButtonClick();
2886
+
2887
+ }
2888
+
2889
+ };
2890
+
2891
+ this.setTarget( target );
2892
+
2893
+ }
2894
+
2895
+ onContext( callback ) {
2896
+
2897
+ this.events.context.push( callback );
2898
+
2899
+ return this;
2900
+
2901
+ }
2902
+
2903
+ show( x = null, y = null ) {
2904
+
2905
+ this._onButtonClick();
2906
+
2907
+ if ( x !== null && y !== null ) {
2908
+
2909
+ this.setPosition( x, y );
2910
+
2911
+ }
2912
+
2913
+ this.dom.classList.remove( 'hidden' );
2914
+
2915
+ this.visible = true;
2916
+
2917
+ this.dispatchEvent( new Event( 'show' ) );
2918
+
2919
+ return this;
2920
+
2921
+ }
2922
+
2923
+ hide() {
2924
+
2925
+ this.dom.classList.add( 'hidden' );
2926
+
2927
+ this.dispatchEvent( new Event( 'hide' ) );
2928
+
2929
+ this.visible = false;
2930
+
2931
+ }
2932
+
2933
+ setTarget( target = null ) {
2934
+
2935
+ if ( target !== null ) {
2936
+
2937
+ const onContextMenu = ( e ) => {
2938
+
2939
+ e.preventDefault();
2940
+
2941
+ if ( e.pointerType !== 'mouse' || ( e.pageX === 0 && e.pageY === 0 ) ) return;
2942
+
2943
+ const rect = this.target.getBoundingClientRect();
2944
+
2945
+ this.dispatchEvent( new Event( 'context' ) );
2946
+
2947
+ this.show( e.pageX - rect.left, e.pageY - rect.top );
2948
+
2949
+ };
2950
+
2951
+ const onDown = ( e ) => {
2952
+
2953
+ if ( this.visible === true && e.target.closest( 'f-menu' ) === null ) {
2954
+
2955
+ this.hide();
2956
+
2957
+ }
2958
+
2959
+ };
2960
+
2961
+ this.target = target;
2962
+
2963
+ target.addEventListener( 'mousedown', onDown, true );
2964
+ target.addEventListener( 'touchstart', onDown, true );
2965
+
2966
+ target.addEventListener( 'contextmenu', onContextMenu, false );
2967
+
2968
+ target.appendChild( this.dom );
2969
+
2970
+ }
2971
+
2972
+ return this;
2973
+
2974
+ }
2975
+
2976
+ add( button, submenu = null ) {
2977
+
2978
+ const liDOM = document.createElement( 'f-item' );
2979
+
2980
+ if ( submenu !== null ) {
2981
+
2982
+ liDOM.classList.add( 'submenu' );
2983
+
2984
+ liDOM.appendChild( submenu.dom );
2985
+
2986
+ this.subMenus.set( button, submenu );
2987
+
2988
+ }
2989
+
2990
+ liDOM.appendChild( button.dom );
2991
+
2992
+ button.addEventListener( 'click', this._onButtonClick );
2993
+ button.addEventListener( 'mouseover', this._onButtonMouseOver );
2994
+
2995
+ this.dom.appendChild( liDOM );
2996
+
2997
+ this.domButtons.set( liDOM, button );
2998
+
2999
+ return this;
3000
+
3001
+ }
3002
+
3003
+ setPosition( x, y ) {
3004
+
3005
+ const dom = this.dom;
3006
+
3007
+ dom.style.left = toPX( x );
3008
+ dom.style.top = toPX( y );
3009
+
3010
+ return this;
3011
+
3012
+ }
3013
+
3014
+ }
3015
+
3016
+ let lastContext = null;
3017
+
3018
+ class ContextMenu extends Menu {
3019
+
3020
+ constructor( target = null ) {
3021
+
3022
+ super( 'context', target );
3023
+
3024
+ }
3025
+
3026
+ show( x, y ) {
3027
+
3028
+ if ( lastContext !== null ) {
3029
+
3030
+ lastContext.hide();
3031
+
3032
+ }
3033
+
3034
+ lastContext = this;
3035
+
3036
+ return super.show( x, y );
3037
+
3038
+ }
3039
+
3040
+ hide() {
3041
+
3042
+ if ( lastContext === this ) {
3043
+
3044
+ lastContext = null;
3045
+
3046
+ }
3047
+
3048
+ return super.hide();
3049
+
3050
+ }
3051
+
3052
+ }
3053
+
3054
+ class CircleMenu extends Menu {
3055
+
3056
+ constructor( target = null ) {
3057
+
3058
+ super( 'circle', target );
3059
+
3060
+ }
3061
+
3062
+ }
3063
+
3064
+ class SelectInput extends Input {
3065
+
3066
+ constructor( options = [] ) {
3067
+
3068
+ const dom = document.createElement( 'select' );
3069
+ super( dom );
3070
+
3071
+ dom.onchange = () => {
3072
+
3073
+ this.dispatchEvent( new Event( 'change' ) );
3074
+
3075
+ };
3076
+
3077
+ this.setOptions( options );
3078
+
3079
+ }
3080
+
3081
+ setOptions( options ) {
3082
+
3083
+ const dom = this.dom;
3084
+
3085
+ this.options = options;
3086
+
3087
+ dom.innerHTML = '';
3088
+
3089
+ for ( let index = 0; index < options.length; index ++ ) {
3090
+
3091
+ let opt = options[ index ];
3092
+
3093
+ if ( typeof opt === 'string' ) {
3094
+
3095
+ opt = { name: opt, value: index };
3096
+
3097
+ }
3098
+
3099
+ const option = document.createElement( 'option' );
3100
+ option.innerText = opt.name;
3101
+ option.value = opt.value;
3102
+
3103
+ dom.appendChild( option );
3104
+
3105
+ }
3106
+
3107
+ return this;
3108
+
3109
+ }
3110
+
3111
+ getOptions() {
3112
+
3113
+ return this._options;
3114
+
3115
+ }
3116
+
3117
+ serialize( data ) {
3118
+
3119
+ data.options = [ ...this.options ];
3120
+
3121
+ super.serialize( data );
3122
+
3123
+ }
3124
+
3125
+ deserialize( data ) {
3126
+
3127
+ const currentOptions = this.options;
3128
+
3129
+ if ( currentOptions.length > 0 ) {
3130
+
3131
+ this.setOptions( data.options );
3132
+
3133
+ }
3134
+
3135
+ super.deserialize( data );
3136
+
3137
+ }
3138
+
3139
+ }
3140
+
3141
+ class ToggleInput extends Input {
3142
+
3143
+ constructor( value = false ) {
3144
+
3145
+ const dom = document.createElement( 'input' );
3146
+ super( dom );
3147
+
3148
+ dom.type = 'checkbox';
3149
+ dom.className = 'toggle';
3150
+ dom.checked = value;
3151
+
3152
+ }
3153
+
3154
+ setValue( val ) {
3155
+
3156
+ this.dom.checked = val;
3157
+
3158
+ this.dispatchEvent( new Event( 'change' ) );
3159
+
3160
+ return this;
3161
+
3162
+ }
3163
+
3164
+ getValue() {
3165
+
3166
+ return this.dom.checked;
3167
+
3168
+ }
3169
+
3170
+ }
3171
+
3172
+ var Flow = /*#__PURE__*/Object.freeze({
3173
+ __proto__: null,
3174
+ Element: Element,
3175
+ Input: Input,
3176
+ Node: Node,
3177
+ Canvas: Canvas,
3178
+ Serializer: Serializer,
3179
+ Styles: Styles,
3180
+ ObjectNode: ObjectNode,
3181
+ PanelNode: PanelNode,
3182
+ Menu: Menu,
3183
+ ContextMenu: ContextMenu,
3184
+ CircleMenu: CircleMenu,
3185
+ DraggableElement: DraggableElement,
3186
+ LabelElement: LabelElement,
3187
+ TitleElement: TitleElement,
3188
+ ButtonInput: ButtonInput,
3189
+ ColorInput: ColorInput,
3190
+ NumberInput: NumberInput,
3191
+ SelectInput: SelectInput,
3192
+ SliderInput: SliderInput,
3193
+ StringInput: StringInput,
3194
+ TextInput: TextInput,
3195
+ ToggleInput: ToggleInput
3196
+ });
3197
+
3198
+ class Loader extends EventTarget {
3199
+
3200
+ constructor( parseType = Loader.DEFAULT ) {
3201
+
3202
+ super();
3203
+
3204
+ this.parseType = parseType;
3205
+
3206
+ this.events = {
3207
+ 'load': []
3208
+ };
3209
+
3210
+ }
3211
+
3212
+ setParseType( type ) {
3213
+
3214
+ this.parseType = type;
3215
+
3216
+ return this;
3217
+
3218
+ }
3219
+
3220
+ getParseType() {
3221
+
3222
+ return this.parseType;
3223
+
3224
+ }
3225
+
3226
+ onLoad( callback ) {
3227
+
3228
+ this.events.load.push( callback );
3229
+
3230
+ return this;
3231
+
3232
+ }
3233
+
3234
+ async load( url, lib = null ) {
3235
+
3236
+ return await fetch( url )
3237
+ .then( response => response.json() )
3238
+ .then( result => {
3239
+
3240
+ this.data = this.parse( result, lib );
3241
+
3242
+ dispatchEventList( this.events.load, this );
3243
+
3244
+ return this.data;
3245
+
3246
+ } )
3247
+ .catch( err => {
3248
+
3249
+ console.error( 'Loader:', err );
3250
+
3251
+ } );
3252
+
3253
+ }
3254
+
3255
+ parse( json, lib = null ) {
3256
+
3257
+ json = this._parseObjects( json, lib );
3258
+
3259
+ const parseType = this.parseType;
3260
+
3261
+ if ( parseType === Loader.DEFAULT ) {
3262
+
3263
+ const flowObj = new Flow[ json.type ]();
3264
+
3265
+ if ( flowObj.getSerializable() ) {
3266
+
3267
+ flowObj.deserialize( json );
3268
+
3269
+ }
3270
+
3271
+ return flowObj;
3272
+
3273
+ } else if ( parseType === Loader.OBJECTS ) {
3274
+
3275
+ return json;
3276
+
3277
+ }
3278
+
3279
+ }
3280
+
3281
+ _parseObjects( json, lib = null ) {
3282
+
3283
+ json = { ...json };
3284
+
3285
+ const objects = {};
3286
+
3287
+ for ( const id in json.objects ) {
3288
+
3289
+ const obj = json.objects[ id ];
3290
+ obj.objects = objects;
3291
+
3292
+ const Class = lib && lib[ obj.type ] ? lib[ obj.type ] : Flow[ obj.type ];
3293
+
3294
+ objects[ id ] = new Class();
3295
+
3296
+ }
3297
+
3298
+ const ref = new WeakMap();
3299
+
3300
+ const deserializePass = ( prop = null ) => {
3301
+
3302
+ for ( const id in json.objects ) {
3303
+
3304
+ const newObject = objects[ id ];
3305
+
3306
+ if ( ref.has( newObject ) === false && ( prop === null || newObject[ prop ] === true ) ) {
3307
+
3308
+ ref.set( newObject, true );
3309
+
3310
+ if ( newObject.getSerializable() ) {
3311
+
3312
+ newObject.deserialize( json.objects[ id ] );
3313
+
3314
+ }
3315
+
3316
+ }
3317
+
3318
+ }
3319
+
3320
+ };
3321
+
3322
+ deserializePass( 'isNode' );
3323
+ deserializePass( 'isElement' );
3324
+ deserializePass( 'isInput' );
3325
+ deserializePass();
3326
+
3327
+ json.objects = objects;
3328
+
3329
+ return json;
3330
+
3331
+ }
3332
+
3333
+ }
3334
+
3335
+ Loader.DEFAULT = 'default';
3336
+ Loader.OBJECTS = 'objects';
3337
+
3338
+ export { ButtonInput, Canvas, CircleMenu, ColorInput, ContextMenu, DraggableElement, Element, Input, LabelElement, Loader, Menu, Node, NumberInput, ObjectNode, PanelNode, REVISION, SelectInput, Serializer, SliderInput, StringInput, Styles, TextInput, TitleElement, ToggleInput, Utils };