@vib3code/sdk 2.0.1

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 (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
  3. package/DOCS/CI_TESTING.md +38 -0
  4. package/DOCS/CLI_ONBOARDING.md +75 -0
  5. package/DOCS/CONTROL_REFERENCE.md +64 -0
  6. package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
  7. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
  8. package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
  9. package/DOCS/ENV_SETUP.md +189 -0
  10. package/DOCS/EXPORT_FORMATS.md +417 -0
  11. package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
  12. package/DOCS/LICENSING_TIERS.md +275 -0
  13. package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
  14. package/DOCS/OBS_SETUP_GUIDE.md +98 -0
  15. package/DOCS/PROJECT_SETUP.md +66 -0
  16. package/DOCS/RENDERER_LIFECYCLE.md +40 -0
  17. package/DOCS/REPO_MANIFEST.md +121 -0
  18. package/DOCS/SESSION_014_PLAN.md +195 -0
  19. package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
  20. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
  21. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
  22. package/DOCS/SYSTEM_INVENTORY.md +520 -0
  23. package/DOCS/TELEMETRY_EXPORTS.md +34 -0
  24. package/DOCS/WEBGPU_STATUS.md +38 -0
  25. package/DOCS/XR_BENCHMARKS.md +608 -0
  26. package/LICENSE +21 -0
  27. package/README.md +426 -0
  28. package/docs/.nojekyll +0 -0
  29. package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
  30. package/docs/02-hyperspatial_ego_death.html +346 -0
  31. package/docs/03-post_cartesian_sublime.html +346 -0
  32. package/docs/04-crystalline_void_meditation.html +346 -0
  33. package/docs/05-quantum_decoherence_ballet.html +346 -0
  34. package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
  35. package/docs/07-hyperspatial_ego_death.html +346 -0
  36. package/docs/08-post_cartesian_sublime.html +346 -0
  37. package/docs/09-crystalline_void_meditation.html +346 -0
  38. package/docs/10-quantum_decoherence_ballet.html +346 -0
  39. package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
  40. package/docs/12-hyperspatial_ego_death.html +346 -0
  41. package/docs/13-post_cartesian_sublime.html +346 -0
  42. package/docs/index.html +794 -0
  43. package/docs/test-hub.html +441 -0
  44. package/docs/url-state.js +102 -0
  45. package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
  46. package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
  47. package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
  48. package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
  49. package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
  50. package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
  51. package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
  52. package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
  53. package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
  54. package/docs/vib3-exports/index.html +238 -0
  55. package/docs/webgpu-live.html +702 -0
  56. package/package.json +367 -0
  57. package/src/advanced/AIPresetGenerator.js +777 -0
  58. package/src/advanced/MIDIController.js +703 -0
  59. package/src/advanced/OffscreenWorker.js +1051 -0
  60. package/src/advanced/WebGPUCompute.js +1051 -0
  61. package/src/advanced/WebXRRenderer.js +680 -0
  62. package/src/agent/cli/AgentCLI.js +615 -0
  63. package/src/agent/cli/index.js +14 -0
  64. package/src/agent/index.js +73 -0
  65. package/src/agent/mcp/MCPServer.js +950 -0
  66. package/src/agent/mcp/index.js +9 -0
  67. package/src/agent/mcp/tools.js +548 -0
  68. package/src/agent/telemetry/EventStream.js +669 -0
  69. package/src/agent/telemetry/Instrumentation.js +618 -0
  70. package/src/agent/telemetry/TelemetryExporters.js +427 -0
  71. package/src/agent/telemetry/TelemetryService.js +464 -0
  72. package/src/agent/telemetry/index.js +52 -0
  73. package/src/benchmarks/BenchmarkRunner.js +381 -0
  74. package/src/benchmarks/MetricsCollector.js +299 -0
  75. package/src/benchmarks/index.js +9 -0
  76. package/src/benchmarks/scenes.js +259 -0
  77. package/src/cli/index.js +675 -0
  78. package/src/config/ApiConfig.js +88 -0
  79. package/src/core/CanvasManager.js +217 -0
  80. package/src/core/ErrorReporter.js +117 -0
  81. package/src/core/ParameterMapper.js +333 -0
  82. package/src/core/Parameters.js +396 -0
  83. package/src/core/RendererContracts.js +200 -0
  84. package/src/core/UnifiedResourceManager.js +370 -0
  85. package/src/core/VIB3Engine.js +636 -0
  86. package/src/core/renderers/FacetedRendererAdapter.js +32 -0
  87. package/src/core/renderers/HolographicRendererAdapter.js +29 -0
  88. package/src/core/renderers/QuantumRendererAdapter.js +29 -0
  89. package/src/core/renderers/RendererLifecycleManager.js +63 -0
  90. package/src/creative/ColorPresetsSystem.js +980 -0
  91. package/src/creative/ParameterTimeline.js +1061 -0
  92. package/src/creative/PostProcessingPipeline.js +1113 -0
  93. package/src/creative/TransitionAnimator.js +683 -0
  94. package/src/export/CSSExporter.js +226 -0
  95. package/src/export/CardGeneratorBase.js +279 -0
  96. package/src/export/ExportManager.js +580 -0
  97. package/src/export/FacetedCardGenerator.js +279 -0
  98. package/src/export/HolographicCardGenerator.js +543 -0
  99. package/src/export/LottieExporter.js +552 -0
  100. package/src/export/QuantumCardGenerator.js +315 -0
  101. package/src/export/SVGExporter.js +519 -0
  102. package/src/export/ShaderExporter.js +903 -0
  103. package/src/export/TradingCardGenerator.js +3055 -0
  104. package/src/export/TradingCardManager.js +181 -0
  105. package/src/export/VIB3PackageExporter.js +559 -0
  106. package/src/export/index.js +14 -0
  107. package/src/export/systems/TradingCardSystemFaceted.js +494 -0
  108. package/src/export/systems/TradingCardSystemHolographic.js +452 -0
  109. package/src/export/systems/TradingCardSystemQuantum.js +411 -0
  110. package/src/faceted/FacetedSystem.js +963 -0
  111. package/src/features/CollectionManager.js +433 -0
  112. package/src/gallery/CollectionManager.js +240 -0
  113. package/src/gallery/GallerySystem.js +485 -0
  114. package/src/geometry/GeometryFactory.js +314 -0
  115. package/src/geometry/GeometryLibrary.js +72 -0
  116. package/src/geometry/buffers/BufferBuilder.js +338 -0
  117. package/src/geometry/buffers/index.js +18 -0
  118. package/src/geometry/generators/Crystal.js +420 -0
  119. package/src/geometry/generators/Fractal.js +298 -0
  120. package/src/geometry/generators/KleinBottle.js +197 -0
  121. package/src/geometry/generators/Sphere.js +192 -0
  122. package/src/geometry/generators/Tesseract.js +160 -0
  123. package/src/geometry/generators/Tetrahedron.js +225 -0
  124. package/src/geometry/generators/Torus.js +304 -0
  125. package/src/geometry/generators/Wave.js +341 -0
  126. package/src/geometry/index.js +142 -0
  127. package/src/geometry/warp/HypersphereCore.js +211 -0
  128. package/src/geometry/warp/HypertetraCore.js +386 -0
  129. package/src/geometry/warp/index.js +57 -0
  130. package/src/holograms/HolographicVisualizer.js +1073 -0
  131. package/src/holograms/RealHolographicSystem.js +966 -0
  132. package/src/holograms/variantRegistry.js +69 -0
  133. package/src/integrations/FigmaPlugin.js +854 -0
  134. package/src/integrations/OBSMode.js +754 -0
  135. package/src/integrations/ThreeJsPackage.js +660 -0
  136. package/src/integrations/TouchDesignerExport.js +552 -0
  137. package/src/integrations/frameworks/Vib3React.js +591 -0
  138. package/src/integrations/frameworks/Vib3Svelte.js +654 -0
  139. package/src/integrations/frameworks/Vib3Vue.js +628 -0
  140. package/src/llm/LLMParameterInterface.js +240 -0
  141. package/src/llm/LLMParameterUI.js +577 -0
  142. package/src/math/Mat4x4.js +708 -0
  143. package/src/math/Projection.js +341 -0
  144. package/src/math/Rotor4D.js +637 -0
  145. package/src/math/Vec4.js +476 -0
  146. package/src/math/constants.js +164 -0
  147. package/src/math/index.js +68 -0
  148. package/src/math/projections.js +54 -0
  149. package/src/math/rotations.js +196 -0
  150. package/src/quantum/QuantumEngine.js +906 -0
  151. package/src/quantum/QuantumVisualizer.js +1103 -0
  152. package/src/reactivity/ReactivityConfig.js +499 -0
  153. package/src/reactivity/ReactivityManager.js +586 -0
  154. package/src/reactivity/SpatialInputSystem.js +1783 -0
  155. package/src/reactivity/index.js +93 -0
  156. package/src/render/CommandBuffer.js +465 -0
  157. package/src/render/MultiCanvasBridge.js +340 -0
  158. package/src/render/RenderCommand.js +514 -0
  159. package/src/render/RenderResourceRegistry.js +523 -0
  160. package/src/render/RenderState.js +552 -0
  161. package/src/render/RenderTarget.js +512 -0
  162. package/src/render/ShaderLoader.js +253 -0
  163. package/src/render/ShaderProgram.js +599 -0
  164. package/src/render/UnifiedRenderBridge.js +496 -0
  165. package/src/render/backends/WebGLBackend.js +1108 -0
  166. package/src/render/backends/WebGPUBackend.js +1409 -0
  167. package/src/render/commands/CommandBufferExecutor.js +607 -0
  168. package/src/render/commands/RenderCommandBuffer.js +661 -0
  169. package/src/render/commands/index.js +17 -0
  170. package/src/render/index.js +367 -0
  171. package/src/scene/Disposable.js +498 -0
  172. package/src/scene/MemoryPool.js +618 -0
  173. package/src/scene/Node4D.js +697 -0
  174. package/src/scene/ResourceManager.js +599 -0
  175. package/src/scene/Scene4D.js +540 -0
  176. package/src/scene/index.js +98 -0
  177. package/src/schemas/error.schema.json +84 -0
  178. package/src/schemas/extension.schema.json +88 -0
  179. package/src/schemas/index.js +214 -0
  180. package/src/schemas/parameters.schema.json +142 -0
  181. package/src/schemas/tool-pack.schema.json +44 -0
  182. package/src/schemas/tool-response.schema.json +127 -0
  183. package/src/shaders/common/fullscreen.vert.glsl +5 -0
  184. package/src/shaders/common/fullscreen.vert.wgsl +17 -0
  185. package/src/shaders/common/geometry24.glsl +65 -0
  186. package/src/shaders/common/geometry24.wgsl +54 -0
  187. package/src/shaders/common/rotation4d.glsl +85 -0
  188. package/src/shaders/common/rotation4d.wgsl +86 -0
  189. package/src/shaders/common/uniforms.glsl +44 -0
  190. package/src/shaders/common/uniforms.wgsl +48 -0
  191. package/src/shaders/faceted/faceted.frag.glsl +129 -0
  192. package/src/shaders/faceted/faceted.frag.wgsl +164 -0
  193. package/src/shaders/holographic/holographic.frag.glsl +406 -0
  194. package/src/shaders/holographic/holographic.frag.wgsl +185 -0
  195. package/src/shaders/quantum/quantum.frag.glsl +513 -0
  196. package/src/shaders/quantum/quantum.frag.wgsl +361 -0
  197. package/src/testing/ParallelTestFramework.js +519 -0
  198. package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
  199. package/src/testing/exportFormats.test.js +8 -0
  200. package/src/testing/projections.test.js +14 -0
  201. package/src/testing/rotations.test.js +37 -0
  202. package/src/ui/InteractivityMenu.js +516 -0
  203. package/src/ui/StatusManager.js +96 -0
  204. package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
  205. package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
  206. package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
  207. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
  208. package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
  209. package/src/variations/VariationManager.js +431 -0
  210. package/src/viewer/AudioReactivity.js +505 -0
  211. package/src/viewer/CardBending.js +481 -0
  212. package/src/viewer/GalleryUI.js +832 -0
  213. package/src/viewer/ReactivityManager.js +590 -0
  214. package/src/viewer/TradingCardExporter.js +600 -0
  215. package/src/viewer/ViewerPortal.js +374 -0
  216. package/src/viewer/index.js +12 -0
  217. package/src/wasm/WasmLoader.js +296 -0
  218. package/src/wasm/index.js +132 -0
  219. package/tools/agentic/mcpTools.js +88 -0
  220. package/tools/cli/agent-cli.js +92 -0
  221. package/tools/export/formats.js +24 -0
  222. package/tools/math/rotation-baseline.mjs +64 -0
  223. package/tools/shader-sync-verify.js +937 -0
  224. package/tools/telemetry/manifestPipeline.js +141 -0
  225. package/tools/telemetry/telemetryEvents.js +35 -0
  226. package/types/adaptive-sdk.d.ts +185 -0
  227. package/types/advanced/AIPresetGenerator.d.ts +81 -0
  228. package/types/advanced/MIDIController.d.ts +100 -0
  229. package/types/advanced/OffscreenWorker.d.ts +82 -0
  230. package/types/advanced/WebGPUCompute.d.ts +52 -0
  231. package/types/advanced/WebXRRenderer.d.ts +77 -0
  232. package/types/advanced/index.d.ts +46 -0
  233. package/types/core/ErrorReporter.d.ts +50 -0
  234. package/types/core/VIB3Engine.d.ts +204 -0
  235. package/types/creative/ColorPresetsSystem.d.ts +91 -0
  236. package/types/creative/ParameterTimeline.d.ts +74 -0
  237. package/types/creative/PostProcessingPipeline.d.ts +109 -0
  238. package/types/creative/TransitionAnimator.d.ts +71 -0
  239. package/types/creative/index.d.ts +35 -0
  240. package/types/integrations/FigmaPlugin.d.ts +46 -0
  241. package/types/integrations/OBSMode.d.ts +74 -0
  242. package/types/integrations/ThreeJsPackage.d.ts +62 -0
  243. package/types/integrations/TouchDesignerExport.d.ts +36 -0
  244. package/types/integrations/Vib3React.d.ts +74 -0
  245. package/types/integrations/Vib3Svelte.d.ts +63 -0
  246. package/types/integrations/Vib3Vue.d.ts +55 -0
  247. package/types/integrations/index.d.ts +52 -0
  248. package/types/reactivity/SpatialInputSystem.d.ts +173 -0
  249. package/types/reactivity/index.d.ts +394 -0
  250. package/types/render/CommandBuffer.d.ts +169 -0
  251. package/types/render/RenderCommand.d.ts +312 -0
  252. package/types/render/RenderState.d.ts +279 -0
  253. package/types/render/RenderTarget.d.ts +254 -0
  254. package/types/render/ShaderProgram.d.ts +277 -0
  255. package/types/render/UnifiedRenderBridge.d.ts +143 -0
  256. package/types/render/WebGLBackend.d.ts +168 -0
  257. package/types/render/WebGPUBackend.d.ts +186 -0
  258. package/types/render/index.d.ts +141 -0
@@ -0,0 +1,3055 @@
1
+ /**
2
+ * Trading Card Generator - Creates personalized trading cards from current visualization
3
+ * Allows users to export their current VIB34D state as a shareable trading card
4
+ *
5
+ * REFACTORED: Now uses modular system architecture
6
+ */
7
+
8
+ import { TradingCardSystemFaceted } from './systems/TradingCardSystemFaceted.js';
9
+ import { TradingCardSystemQuantum } from './systems/TradingCardSystemQuantum.js';
10
+ import { TradingCardSystemHolographic } from './systems/TradingCardSystemHolographic.js';
11
+
12
+ export class TradingCardGenerator {
13
+ constructor(engine) {
14
+ this.engine = engine;
15
+ // Detect current system reliably from multiple sources
16
+ this.currentSystem = this.detectCurrentSystem();
17
+ }
18
+
19
+ /**
20
+ * Reliably detect which visualization system is currently active
21
+ */
22
+ detectCurrentSystem() {
23
+ // Method 1: Check active system button in UI
24
+ const activeSystemBtn = document.querySelector('.system-btn.active');
25
+ if (activeSystemBtn?.dataset.system) {
26
+ return activeSystemBtn.dataset.system;
27
+ }
28
+
29
+ // Method 2: Check global variable
30
+ if (window.currentSystem) {
31
+ return window.currentSystem;
32
+ }
33
+
34
+ // Method 3: Check which canvas layers are visible
35
+ const holographicLayers = document.getElementById('holographicLayers');
36
+ const polychoraLayers = document.getElementById('polychoraLayers');
37
+ const vib34dLayers = document.getElementById('vib34dLayers');
38
+
39
+ if (holographicLayers && holographicLayers.style.display !== 'none') {
40
+ return 'holographic';
41
+ } else if (polychoraLayers && polychoraLayers.style.display !== 'none') {
42
+ return 'polychora';
43
+ } else if (vib34dLayers && vib34dLayers.style.display !== 'none') {
44
+ return 'faceted';
45
+ }
46
+
47
+ // Fallback
48
+ console.warn('⚠️ Could not detect current system, defaulting to faceted');
49
+ return 'faceted';
50
+ }
51
+
52
+ /**
53
+ * Generate a trading card from current visualization state
54
+ */
55
+ async generateTradingCard(format = 'classic') {
56
+ console.log('🎴 Generating trading card from current state...');
57
+
58
+ // Capture current parameters
59
+ const state = this.captureCurrentState();
60
+
61
+ // Capture the actual canvas visual as base64 image
62
+ const canvasImage = await this.captureCanvasImage();
63
+
64
+ // Generate card HTML based on format
65
+ const cardHTML = format === 'social' ?
66
+ this.generateSocialCard(state, canvasImage) :
67
+ this.generateClassicCard(state, canvasImage);
68
+
69
+ // Create blob and download
70
+ const blob = new Blob([cardHTML], { type: 'text/html' });
71
+ const url = URL.createObjectURL(blob);
72
+
73
+ // Generate filename with timestamp
74
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
75
+ const filename = `vib34d-card-${state.geometry.toLowerCase()}-${timestamp}.html`;
76
+
77
+ // Trigger download
78
+ const link = document.createElement('a');
79
+ link.href = url;
80
+ link.download = filename;
81
+ document.body.appendChild(link);
82
+ link.click();
83
+ document.body.removeChild(link);
84
+ URL.revokeObjectURL(url);
85
+
86
+ console.log(`🎴 Trading card generated: ${filename}`);
87
+
88
+ // Show success message
89
+ if (this.engine?.statusManager) {
90
+ this.engine.statusManager.success(
91
+ `🎴 Trading Card Created!<br>` +
92
+ `<strong>${state.name}</strong><br>` +
93
+ `Format: ${format === 'social' ? 'Social Media' : 'Classic'}<br>` +
94
+ `<small>File: ${filename}</small>`
95
+ );
96
+ }
97
+
98
+ return { success: true, filename, state };
99
+ }
100
+
101
+ /**
102
+ * Generate trading card HTML without downloading (for viewer.html compatibility)
103
+ * @param {string} format - Card format ('classic' or 'social')
104
+ * @returns {Promise<{success: boolean, html: string}>} Card HTML for navigation
105
+ */
106
+ async generateCardHTML(format = 'classic') {
107
+ console.log('🎴 Generating trading card HTML for navigation...');
108
+
109
+ // Capture current parameters
110
+ const state = this.captureCurrentState();
111
+
112
+ // Capture the actual canvas visual as base64 image
113
+ const canvasImage = await this.captureCanvasImage();
114
+
115
+ // Generate card HTML based on format
116
+ const cardHTML = format === 'social' ?
117
+ this.generateSocialCard(state, canvasImage) :
118
+ this.generateClassicCard(state, canvasImage);
119
+
120
+ return { success: true, html: cardHTML };
121
+ }
122
+
123
+ /**
124
+ * Capture ALL 5 layers from the current active system and composite them properly
125
+ */
126
+ async captureCanvasImage() {
127
+ console.log('📸 Capturing multi-layer visualization from system:', this.currentSystem);
128
+
129
+ // System-specific layer configuration
130
+ const systemLayers = {
131
+ 'faceted': {
132
+ prefix: '',
133
+ layers: ['background-canvas', 'shadow-canvas', 'content-canvas', 'highlight-canvas', 'accent-canvas'],
134
+ name: 'VIB34D Faceted'
135
+ },
136
+ 'holographic': {
137
+ prefix: 'holo-',
138
+ layers: ['background-canvas', 'shadow-canvas', 'content-canvas', 'highlight-canvas', 'accent-canvas'],
139
+ name: 'Active Holograms'
140
+ },
141
+ 'polychora': {
142
+ prefix: 'polychora-',
143
+ layers: ['background-canvas', 'shadow-canvas', 'content-canvas', 'highlight-canvas', 'accent-canvas'],
144
+ name: 'Polychora System'
145
+ }
146
+ };
147
+
148
+ const systemConfig = systemLayers[this.currentSystem] || systemLayers['faceted'];
149
+
150
+ // Layer-specific properties matching the actual system
151
+ const layerProperties = {
152
+ 'background-canvas': { alpha: 0.4, blendMode: 'normal' },
153
+ 'shadow-canvas': { alpha: 0.6, blendMode: 'multiply' },
154
+ 'content-canvas': { alpha: 1.0, blendMode: 'normal' },
155
+ 'highlight-canvas': { alpha: 1.0, blendMode: 'screen' },
156
+ 'accent-canvas': { alpha: 0.8, blendMode: 'overlay' }
157
+ };
158
+
159
+ try {
160
+ // Create high-quality composite canvas
161
+ const compositeCanvas = document.createElement('canvas');
162
+ const targetWidth = 800;
163
+ const targetHeight = 600;
164
+ compositeCanvas.width = targetWidth;
165
+ compositeCanvas.height = targetHeight;
166
+ const ctx = compositeCanvas.getContext('2d');
167
+
168
+ // Start with black background
169
+ ctx.fillStyle = '#000';
170
+ ctx.fillRect(0, 0, targetWidth, targetHeight);
171
+
172
+ // Composite all 5 layers in correct order
173
+ let layersFound = 0;
174
+ for (const layerBase of systemConfig.layers) {
175
+ const layerId = systemConfig.prefix + layerBase;
176
+ const layerCanvas = document.getElementById(layerId);
177
+
178
+ if (layerCanvas && layerCanvas.width > 0 && layerCanvas.height > 0) {
179
+ const props = layerProperties[layerBase];
180
+
181
+ // Set blend mode and alpha
182
+ ctx.globalAlpha = props.alpha;
183
+ ctx.globalCompositeOperation = props.blendMode;
184
+
185
+ // Draw the layer
186
+ ctx.drawImage(layerCanvas, 0, 0, targetWidth, targetHeight);
187
+ layersFound++;
188
+
189
+ console.log(`✅ Composited ${layerId} (alpha: ${props.alpha}, blend: ${props.blendMode})`);
190
+ } else {
191
+ console.warn(`⚠️ Layer ${layerId} not found or empty`);
192
+ }
193
+ }
194
+
195
+ // Reset composite operation
196
+ ctx.globalCompositeOperation = 'normal';
197
+ ctx.globalAlpha = 1.0;
198
+
199
+ if (layersFound === 0) {
200
+ console.error('❌ No layers captured from current system');
201
+ return null;
202
+ }
203
+
204
+ // Convert to high-quality base64
205
+ const imageData = compositeCanvas.toDataURL('image/png', 0.95);
206
+ console.log(`✅ Multi-layer capture complete: ${layersFound} layers from ${systemConfig.name}`);
207
+ return imageData;
208
+
209
+ } catch (error) {
210
+ console.error('❌ Error capturing multi-layer canvas:', error);
211
+ return null;
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Capture current visualization state with improved system detection
217
+ */
218
+ captureCurrentState() {
219
+ // Detect current system more reliably
220
+ const activeSystemBtn = document.querySelector('.system-btn.active');
221
+ const detectedSystem = activeSystemBtn?.dataset.system || window.currentSystem || 'faceted';
222
+ this.currentSystem = detectedSystem;
223
+
224
+ console.log('🎯 Capturing state for system:', this.currentSystem);
225
+
226
+ // Get parameters based on current system
227
+ let params = {};
228
+ let geometryType = 0;
229
+
230
+ if (this.currentSystem === 'faceted' && this.engine) {
231
+ // VIB34D Faceted System
232
+ params = this.engine.parameterManager?.getAllParameters() || {};
233
+ geometryType = params.geometry || this.getActiveGeometryIndex();
234
+ } else if (this.currentSystem === 'holographic') {
235
+ // CRITICAL FIX: Use SAME parameter names as holographicSystem.getParameters()
236
+ // This ensures trading cards match gallery save/load system
237
+ params = {
238
+ geometry: this.getActiveGeometryIndex(),
239
+ gridDensity: parseFloat(document.getElementById('gridDensity')?.value || 15), // Raw value, not divided
240
+ morphFactor: parseFloat(document.getElementById('morphFactor')?.value || 1.0),
241
+ speed: parseFloat(document.getElementById('speed')?.value || 1.0),
242
+ chaos: parseFloat(document.getElementById('chaos')?.value || 0.2),
243
+ hue: parseFloat(document.getElementById('hue')?.value || 320), // Match holographic default
244
+ intensity: parseFloat(document.getElementById('intensity')?.value || 0.6), // Match holographic default
245
+ saturation: parseFloat(document.getElementById('saturation')?.value || 0.8),
246
+ rot4dXW: parseFloat(document.getElementById('rot4dXW')?.value || 0),
247
+ rot4dYW: parseFloat(document.getElementById('rot4dYW')?.value || 0),
248
+ rot4dZW: parseFloat(document.getElementById('rot4dZW')?.value || 0)
249
+ };
250
+ geometryType = params.geometry;
251
+ } else if (this.currentSystem === 'polychora') {
252
+ // Polychora System
253
+ params = {
254
+ polytope: this.getActiveGeometryIndex(),
255
+ gridDensity: parseFloat(document.getElementById('gridDensity')?.value || 15),
256
+ morphFactor: parseFloat(document.getElementById('morphFactor')?.value || 1.0),
257
+ chaos: parseFloat(document.getElementById('chaos')?.value || 0.2),
258
+ speed: parseFloat(document.getElementById('speed')?.value || 1.0),
259
+ hue: parseFloat(document.getElementById('hue')?.value || 200),
260
+ intensity: parseFloat(document.getElementById('intensity')?.value || 0.5),
261
+ saturation: parseFloat(document.getElementById('saturation')?.value || 0.8),
262
+ rot4dXW: parseFloat(document.getElementById('rot4dXW')?.value || 0),
263
+ rot4dYW: parseFloat(document.getElementById('rot4dYW')?.value || 0),
264
+ rot4dZW: parseFloat(document.getElementById('rot4dZW')?.value || 0)
265
+ };
266
+ geometryType = params.polytope;
267
+ }
268
+
269
+ const geometryNames = ['TETRAHEDRON', 'HYPERCUBE', 'SPHERE', 'TORUS', 'KLEIN BOTTLE', 'FRACTAL', 'WAVE', 'CRYSTAL'];
270
+ const systemNames = {
271
+ faceted: 'FACETED',
272
+ holographic: 'HOLOGRAPHIC',
273
+ polychora: 'POLYCHORA'
274
+ };
275
+
276
+ const state = {
277
+ name: `${geometryNames[geometryType] || 'QUANTUM'} ${systemNames[this.currentSystem] || 'SYSTEM'}`,
278
+ geometry: geometryNames[geometryType] || 'QUANTUM',
279
+ system: this.currentSystem,
280
+ dimension: (params.dimension || 3.8).toString(),
281
+ hue: params.hue || 200,
282
+ saturation: ((params.saturation || 0.8) * 100).toFixed(0),
283
+ intensity: ((params.intensity || 0.5) * 100).toFixed(0),
284
+ speed: (params.speed || 1.0).toFixed(1),
285
+ chaos: ((params.chaos || 0) * 100).toFixed(0),
286
+ rarity: this.calculateRarity(params),
287
+ parameters: params,
288
+ portalUrl: window.location.origin + '/vib34d-portal.html'
289
+ };
290
+
291
+ console.log('🎯 Captured state:', state);
292
+ return state;
293
+ }
294
+
295
+ getActiveGeometryIndex() {
296
+ const activeBtn = document.querySelector('.geom-btn.active');
297
+ return activeBtn ? parseInt(activeBtn.dataset.index) : 0;
298
+ }
299
+
300
+ /**
301
+ * Calculate rarity based on parameter extremity
302
+ */
303
+ calculateRarity(params) {
304
+ const extremity =
305
+ Math.abs(params.rot4dXW || 0) +
306
+ Math.abs(params.rot4dYW || 0) +
307
+ Math.abs(params.rot4dZW || 0) +
308
+ (params.chaos || 0) * 2 +
309
+ Math.abs((params.dimension || 3.8) - 3.8);
310
+
311
+ if (extremity > 8) return 'MYTHIC';
312
+ if (extremity > 6) return 'LEGENDARY';
313
+ if (extremity > 4) return 'EPIC';
314
+ if (extremity > 2) return 'RARE';
315
+ return 'COMMON';
316
+ }
317
+
318
+ /**
319
+ * Generate classic vertical trading card HTML - ALWAYS use live WebGL
320
+ */
321
+ generateClassicCard(state, canvasImage) {
322
+ // ALWAYS use live WebGL visualization, never static images
323
+ const visualizationContent = this.generateVisualizationCode(state);
324
+
325
+ return `<!DOCTYPE html>
326
+ <html lang="en">
327
+ <head>
328
+ <meta charset="UTF-8">
329
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
330
+ <title>VIB34D Trading Card - ${state.name}</title>
331
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&display=swap" rel="stylesheet">
332
+ <style>
333
+ * { margin: 0; padding: 0; box-sizing: border-box; }
334
+
335
+ body {
336
+ background: #000;
337
+ color: #fff;
338
+ font-family: 'Orbitron', monospace;
339
+ overflow: hidden;
340
+ height: 100vh;
341
+ display: flex;
342
+ align-items: center;
343
+ justify-content: center;
344
+ background:
345
+ radial-gradient(circle at 20% 20%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
346
+ radial-gradient(circle at 80% 80%, rgba(255, 119, 198, 0.3) 0%, transparent 50%),
347
+ linear-gradient(135deg, #0a0a0a 0%, #1a1a2e 50%, #16213e 100%);
348
+ }
349
+
350
+ .trading-card {
351
+ width: 400px;
352
+ height: auto;
353
+ background: rgba(0, 0, 0, 0.85);
354
+ border: 2px solid rgba(0, 255, 255, 0.3);
355
+ border-radius: 15px;
356
+ padding: 20px;
357
+ transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
358
+ cursor: pointer;
359
+ position: relative;
360
+ overflow: visible;
361
+ transform-style: preserve-3d;
362
+ transform-origin: 50% 50%;
363
+ will-change: transform;
364
+ /* CSS variables for mouse tracking */
365
+ --mouse-x: 50%;
366
+ --mouse-y: 50%;
367
+ --bend-intensity: 0;
368
+ }
369
+
370
+ .trading-card:hover {
371
+ border-color: #00ffff;
372
+ box-shadow:
373
+ 0 30px 60px rgba(0, 255, 255, 0.3),
374
+ inset 0 2px 0 rgba(255, 255, 255, 0.2),
375
+ 0 0 40px rgba(255, 0, 255, 0.4);
376
+ transform:
377
+ perspective(800px)
378
+ rotateY(calc((var(--mouse-x) - 50) * 0.25deg * var(--bend-intensity)))
379
+ rotateX(calc((var(--mouse-y) - 50) * 0.12deg * var(--bend-intensity)))
380
+ translateZ(calc(var(--bend-intensity) * 30px))
381
+ translateY(-10px)
382
+ scale(1.05);
383
+ backdrop-filter: blur(20px);
384
+ z-index: 10;
385
+ }
386
+
387
+ @keyframes cardGlow {
388
+ 0% {
389
+ box-shadow:
390
+ 0 0 50px hsla(${state.hue}, 80%, 50%, 0.3),
391
+ inset 0 0 50px rgba(255, 255, 255, 0.05);
392
+ }
393
+ 100% {
394
+ box-shadow:
395
+ 0 0 80px hsla(${(state.hue + 60) % 360}, 80%, 50%, 0.4),
396
+ inset 0 0 80px rgba(255, 255, 255, 0.1);
397
+ }
398
+ }
399
+
400
+ .card-border {
401
+ position: absolute;
402
+ top: 0; left: 0; right: 0; bottom: 0;
403
+ border-radius: 20px;
404
+ background: linear-gradient(45deg,
405
+ hsl(${state.hue}, 80%, 50%),
406
+ hsl(${(state.hue + 120) % 360}, 80%, 50%),
407
+ hsl(${(state.hue + 240) % 360}, 80%, 50%),
408
+ hsl(${state.hue}, 80%, 50%));
409
+ background-size: 300% 300%;
410
+ animation: borderShift 4s ease-in-out infinite;
411
+ z-index: -1;
412
+ }
413
+
414
+ @keyframes borderShift {
415
+ 0%, 100% { background-position: 0% 50%; }
416
+ 50% { background-position: 100% 50%; }
417
+ }
418
+
419
+ .card-header {
420
+ position: relative;
421
+ z-index: 10;
422
+ padding: 20px;
423
+ text-align: center;
424
+ background: linear-gradient(180deg, rgba(0,0,0,0.8), transparent);
425
+ }
426
+
427
+ .card-title {
428
+ font-size: 1.4rem;
429
+ font-weight: 900;
430
+ color: hsl(${state.hue}, 80%, 60%);
431
+ text-shadow: 0 0 20px hsla(${state.hue}, 80%, 60%, 0.8);
432
+ margin-bottom: 5px;
433
+ letter-spacing: 2px;
434
+ }
435
+
436
+ .card-subtitle {
437
+ font-size: 0.8rem;
438
+ color: rgba(255, 255, 255, 0.7);
439
+ font-weight: 400;
440
+ letter-spacing: 1px;
441
+ }
442
+
443
+ .rarity-badge {
444
+ position: absolute;
445
+ top: 15px;
446
+ right: 15px;
447
+ background: ${state.rarity === 'MYTHIC' ? 'linear-gradient(45deg, #ff00ff, #00ffff)' :
448
+ state.rarity === 'LEGENDARY' ? 'linear-gradient(45deg, #ff6b35, #f7931e)' :
449
+ state.rarity === 'EPIC' ? 'linear-gradient(45deg, #9b59b6, #e74c3c)' :
450
+ state.rarity === 'RARE' ? 'linear-gradient(45deg, #3498db, #2ecc71)' :
451
+ 'linear-gradient(45deg, #95a5a6, #7f8c8d)'};
452
+ color: ${state.rarity === 'COMMON' ? '#fff' : '#000'};
453
+ padding: 5px 15px;
454
+ border-radius: 15px;
455
+ font-size: 0.7rem;
456
+ font-weight: 700;
457
+ text-transform: uppercase;
458
+ letter-spacing: 1px;
459
+ box-shadow: 0 0 15px rgba(255, 255, 255, 0.3);
460
+ animation: rarityPulse 2s ease-in-out infinite;
461
+ }
462
+
463
+ @keyframes rarityPulse {
464
+ 0%, 100% { transform: scale(1); }
465
+ 50% { transform: scale(1.1); }
466
+ }
467
+
468
+ .card-preview {
469
+ width: 100%;
470
+ height: 350px;
471
+ aspect-ratio: 1 / 1;
472
+ border-radius: 12px;
473
+ overflow: visible;
474
+ margin-bottom: 15px;
475
+ background: #111;
476
+ position: relative;
477
+ border: 1px solid rgba(0, 255, 255, 0.2);
478
+ transform-style: preserve-3d;
479
+ transition: all 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
480
+ }
481
+
482
+ /* GALLERY-STYLE: Card preview expands and tilts based on mouse position */
483
+ .trading-card:hover .card-preview {
484
+ /* Match gallery card preview behavior exactly */
485
+ transform:
486
+ perspective(1000px)
487
+ translateZ(30px)
488
+ scale(1.1)
489
+ rotateY(calc((var(--mouse-x) - 50) * 0.2deg))
490
+ rotateX(calc((var(--mouse-y) - 50) * 0.15deg));
491
+ box-shadow:
492
+ 0 0 50px rgba(0, 255, 255, 0.6),
493
+ 0 0 100px rgba(255, 0, 255, 0.4),
494
+ inset 0 0 20px rgba(255, 255, 255, 0.1);
495
+ border: 2px solid rgba(255, 255, 255, 0.8);
496
+ background: rgba(17, 17, 17, 0.7);
497
+ backdrop-filter: blur(15px);
498
+ filter: brightness(1.2) contrast(1.05) saturate(1.1);
499
+ overflow: visible;
500
+ transition: transform 0.1s ease-out;
501
+ }
502
+
503
+ /* Canvas visualization container inside preview - EXACT MATCH */
504
+ .visualization-container {
505
+ width: 100%;
506
+ height: 100%;
507
+ position: relative;
508
+ border-radius: 12px;
509
+ overflow: hidden;
510
+ background: #000;
511
+ }
512
+
513
+ .visualizer-canvas {
514
+ width: 100%;
515
+ height: 100%;
516
+ display: block;
517
+ border-radius: 10px;
518
+ }
519
+
520
+ .stats-panel {
521
+ padding: 0 20px;
522
+ margin-bottom: 20px;
523
+ }
524
+
525
+ .stat-row {
526
+ display: flex;
527
+ justify-content: space-between;
528
+ margin-bottom: 8px;
529
+ font-size: 0.7rem;
530
+ }
531
+
532
+ .stat-label {
533
+ color: rgba(255, 255, 255, 0.6);
534
+ text-transform: uppercase;
535
+ letter-spacing: 1px;
536
+ }
537
+
538
+ .stat-value {
539
+ color: hsl(${state.hue}, 80%, 60%);
540
+ font-weight: 700;
541
+ text-shadow: 0 0 10px hsla(${state.hue}, 80%, 60%, 0.5);
542
+ }
543
+
544
+ .action-panel {
545
+ position: absolute;
546
+ bottom: 0;
547
+ left: 0;
548
+ right: 0;
549
+ background: linear-gradient(0deg, rgba(0,0,0,0.9), transparent);
550
+ padding: 20px;
551
+ text-align: center;
552
+ }
553
+
554
+ .collect-button {
555
+ width: 100%;
556
+ background: linear-gradient(45deg, #ff6b35, #f7931e);
557
+ border: none;
558
+ color: #000;
559
+ padding: 15px 20px;
560
+ border-radius: 25px;
561
+ font-family: 'Orbitron', monospace;
562
+ font-size: 1rem;
563
+ font-weight: 700;
564
+ text-transform: uppercase;
565
+ letter-spacing: 2px;
566
+ cursor: pointer;
567
+ transition: all 0.3s ease;
568
+ box-shadow: 0 0 30px rgba(255, 107, 53, 0.4);
569
+ position: relative;
570
+ overflow: hidden;
571
+ }
572
+
573
+ .collect-button:hover {
574
+ transform: translateY(-3px);
575
+ box-shadow: 0 0 50px rgba(255, 107, 53, 0.8);
576
+ }
577
+
578
+ .edition-number {
579
+ position: absolute;
580
+ bottom: 15px;
581
+ left: 20px;
582
+ font-size: 0.6rem;
583
+ color: rgba(255, 255, 255, 0.5);
584
+ font-weight: 400;
585
+ }
586
+
587
+ .hologram-effect {
588
+ position: absolute;
589
+ top: 0; left: 0; right: 0; bottom: 0;
590
+ background: linear-gradient(45deg,
591
+ hsla(${state.hue}, 80%, 50%, 0.1),
592
+ hsla(${(state.hue + 120) % 360}, 80%, 50%, 0.1),
593
+ hsla(${(state.hue + 240) % 360}, 80%, 50%, 0.1));
594
+ background-size: 300% 300%;
595
+ animation: hologramShift 6s ease-in-out infinite;
596
+ pointer-events: none;
597
+ border-radius: 20px;
598
+ }
599
+
600
+ @keyframes hologramShift {
601
+ 0%, 100% {
602
+ background-position: 0% 50%;
603
+ opacity: 0.3;
604
+ }
605
+ 50% {
606
+ background-position: 100% 50%;
607
+ opacity: 0.6;
608
+ }
609
+ }
610
+
611
+ @media (max-width: 480px) {
612
+ .trading-card {
613
+ width: 350px;
614
+ height: 550px;
615
+ }
616
+ }
617
+ </style>
618
+ </head>
619
+ <body>
620
+ <div class="trading-card">
621
+ <div class="card-border"></div>
622
+ <div class="hologram-effect"></div>
623
+
624
+ <div class="rarity-badge">${state.rarity}</div>
625
+
626
+ <div class="card-header">
627
+ <h1 class="card-title">${state.name}</h1>
628
+ <p class="card-subtitle">${state.system} System • ${state.dimension}D</p>
629
+ </div>
630
+
631
+ <div class="card-preview" data-preview-container>
632
+ <div class="visualization-container">
633
+ <canvas class="visualizer-canvas" id="vib34dCanvas"></canvas>
634
+ </div>
635
+ </div>
636
+
637
+ <div class="stats-panel">
638
+ <div class="stat-row">
639
+ <span class="stat-label">Dimension</span>
640
+ <span class="stat-value">${state.dimension}D</span>
641
+ </div>
642
+ <div class="stat-row">
643
+ <span class="stat-label">Geometry</span>
644
+ <span class="stat-value">${state.geometry}</span>
645
+ </div>
646
+ <div class="stat-row">
647
+ <span class="stat-label">System</span>
648
+ <span class="stat-value">${state.system.toUpperCase()}</span>
649
+ </div>
650
+ <div class="stat-row">
651
+ <span class="stat-label">Chaos</span>
652
+ <span class="stat-value">${state.chaos}%</span>
653
+ </div>
654
+ <div class="stat-row">
655
+ <span class="stat-label">Speed</span>
656
+ <span class="stat-value">${state.speed}x</span>
657
+ </div>
658
+ <div class="stat-row">
659
+ <span class="stat-label">Rarity</span>
660
+ <span class="stat-value">${state.rarity}</span>
661
+ </div>
662
+ </div>
663
+
664
+ <div class="action-panel">
665
+ <button class="collect-button" onclick="collectFullSystem()">
666
+ <span class="collect-text">🌌 Get VIB34D Collection</span>
667
+ </button>
668
+ </div>
669
+
670
+ <div class="edition-number">Generated ${new Date().toLocaleDateString()}</div>
671
+ </div>
672
+
673
+ <script>
674
+ ${visualizationContent}
675
+
676
+ // Initialize LIVE multi-layer WebGL system
677
+ document.addEventListener('DOMContentLoaded', () => {
678
+ const canvas = document.getElementById('vib34dCanvas');
679
+ if (canvas) {
680
+ console.log('🎴 Initializing LIVE trading card system...');
681
+ new LiveTradingCardSystem();
682
+ }
683
+
684
+ // EXACT MATCH: Add portfolio card mouse tracking behavior
685
+ initializeHolographicCardEffects();
686
+ });
687
+
688
+ // EXACT COPY from gallery.html - Mouse tracking for trading cards
689
+ function initializeHolographicCardEffects() {
690
+ console.log('🌟 Initializing trading card holographic effects...');
691
+
692
+ const card = document.querySelector('.trading-card');
693
+ if (!card) return;
694
+
695
+ let isHovering = false;
696
+
697
+ // Mouse enter - start holographic effect
698
+ card.addEventListener('mouseenter', (e) => {
699
+ isHovering = true;
700
+ card.style.setProperty('--bend-intensity', '0.8');
701
+ console.log('🌌 Trading card holographic effect activated');
702
+ });
703
+
704
+ // Mouse leave - end holographic effect
705
+ card.addEventListener('mouseleave', (e) => {
706
+ isHovering = false;
707
+ card.style.setProperty('--bend-intensity', '0');
708
+ card.style.setProperty('--mouse-x', '50%');
709
+ card.style.setProperty('--mouse-y', '50%');
710
+ console.log('🌌 Trading card holographic effect deactivated');
711
+ });
712
+
713
+ // Mouse move - track position for card bending + visual reactivity
714
+ card.addEventListener('mousemove', (e) => {
715
+ if (!isHovering) return;
716
+
717
+ const rect = card.getBoundingClientRect();
718
+ const cardX = ((e.clientX - rect.left) / rect.width) * 100;
719
+ const cardY = ((e.clientY - rect.top) / rect.height) * 100;
720
+
721
+ // Calculate distance from center for bend intensity
722
+ const centerX = 50;
723
+ const centerY = 50;
724
+ const distanceFromCenter = Math.sqrt(
725
+ Math.pow(cardX - centerX, 2) + Math.pow(cardY - centerY, 2)
726
+ );
727
+
728
+ // Dynamic bend intensity based on mouse position
729
+ const bendIntensity = Math.min(1, (distanceFromCenter / 70) + 0.3);
730
+
731
+ // Update CSS variables for real-time transformation
732
+ card.style.setProperty('--mouse-x', cardX);
733
+ card.style.setProperty('--mouse-y', cardY);
734
+ card.style.setProperty('--bend-intensity', bendIntensity);
735
+ });
736
+
737
+ console.log('✅ Trading card holographic effects initialized');
738
+ }
739
+
740
+ // Collect button action - leads to VIB34D Portal
741
+ function collectFullSystem() {
742
+ const portalUrl = '${state.portalUrl}';
743
+ const confirmed = confirm(
744
+ "🌌 Ready to explore the complete VIB34D Collection?\\n\\n" +
745
+ "✨ 100+ Legendary Variations\\n" +
746
+ "🎮 3 Complete Visualization Systems\\n" +
747
+ "🎯 4D Mathematics & Physics\\n" +
748
+ "💫 Real-time Parameter Control\\n" +
749
+ "🎨 Create Your Own Trading Cards\\n\\n" +
750
+ "Click OK to visit the VIB34D Portal!"
751
+ );
752
+
753
+ if (confirmed) {
754
+ try {
755
+ window.location.href = portalUrl;
756
+ } catch (e) {
757
+ window.open(portalUrl, '_blank');
758
+ }
759
+ }
760
+ }
761
+ </script>
762
+ </body>
763
+ </html>`;
764
+ }
765
+
766
+ /**
767
+ * Generate social media card HTML
768
+ */
769
+ generateSocialCard(state, canvasImage) {
770
+ const visualizationContent = canvasImage ?
771
+ this.generateImageVisualization(canvasImage) :
772
+ this.generateVisualizationCode(state);
773
+
774
+ return `<!DOCTYPE html>
775
+ <html lang="en">
776
+ <head>
777
+ <meta charset="UTF-8">
778
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
779
+ <title>VIB34D - ${state.name}</title>
780
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&display=swap" rel="stylesheet">
781
+ <style>
782
+ * { margin: 0; padding: 0; box-sizing: border-box; }
783
+
784
+ body {
785
+ background: #000;
786
+ color: #fff;
787
+ font-family: 'Orbitron', monospace;
788
+ overflow: hidden;
789
+ height: 100vh;
790
+ display: flex;
791
+ align-items: center;
792
+ justify-content: center;
793
+ background: linear-gradient(135deg, #0a0a0a 0%, #1a1a2e 50%, #16213e 100%);
794
+ }
795
+
796
+ .social-card {
797
+ width: 500px;
798
+ height: 280px;
799
+ background: linear-gradient(145deg, rgba(0,0,0,0.9), rgba(30,30,60,0.9));
800
+ border-radius: 15px;
801
+ border: 2px solid transparent;
802
+ background-clip: padding-box;
803
+ position: relative;
804
+ overflow: hidden;
805
+ display: flex;
806
+ box-shadow: 0 0 40px hsla(${state.hue}, 80%, 50%, 0.3);
807
+ animation: cardPulse 4s ease-in-out infinite alternate;
808
+ }
809
+
810
+ @keyframes cardPulse {
811
+ 0% { box-shadow: 0 0 40px hsla(${state.hue}, 80%, 50%, 0.3); }
812
+ 100% { box-shadow: 0 0 60px hsla(${(state.hue + 60) % 360}, 80%, 50%, 0.4); }
813
+ }
814
+
815
+ .card-visual {
816
+ flex: 1;
817
+ position: relative;
818
+ background: radial-gradient(ellipse at center, hsla(${state.hue}, 80%, 50%, 0.1), rgba(0, 0, 0, 0.8));
819
+ }
820
+
821
+ .visualizer-canvas {
822
+ width: 100%;
823
+ height: 100%;
824
+ display: block;
825
+ border-radius: 10px;
826
+ }
827
+
828
+ .visualizer-container img {
829
+ width: 100%;
830
+ height: 100%;
831
+ object-fit: cover;
832
+ border-radius: 10px;
833
+ }
834
+
835
+ .card-info {
836
+ flex: 1;
837
+ padding: 25px;
838
+ display: flex;
839
+ flex-direction: column;
840
+ justify-content: space-between;
841
+ background: linear-gradient(90deg, transparent, rgba(0,0,0,0.7));
842
+ }
843
+
844
+ .card-title {
845
+ font-size: 1.6rem;
846
+ font-weight: 900;
847
+ color: hsl(${state.hue}, 80%, 60%);
848
+ text-shadow: 0 0 20px hsla(${state.hue}, 80%, 60%, 0.8);
849
+ margin-bottom: 8px;
850
+ letter-spacing: 1px;
851
+ line-height: 1.2;
852
+ }
853
+
854
+ .card-subtitle {
855
+ font-size: 0.9rem;
856
+ color: rgba(255, 255, 255, 0.8);
857
+ margin-bottom: 20px;
858
+ letter-spacing: 1px;
859
+ }
860
+
861
+ .feature-list {
862
+ margin-bottom: 20px;
863
+ }
864
+
865
+ .feature-item {
866
+ font-size: 0.7rem;
867
+ color: rgba(255, 255, 255, 0.7);
868
+ margin-bottom: 5px;
869
+ }
870
+
871
+ .cta-button {
872
+ background: linear-gradient(45deg, #ff6b35, #f7931e);
873
+ border: none;
874
+ color: #000;
875
+ padding: 12px 20px;
876
+ border-radius: 20px;
877
+ font-family: 'Orbitron', monospace;
878
+ font-size: 0.8rem;
879
+ font-weight: 700;
880
+ text-transform: uppercase;
881
+ letter-spacing: 1px;
882
+ cursor: pointer;
883
+ transition: all 0.3s ease;
884
+ box-shadow: 0 0 20px rgba(255, 107, 53, 0.4);
885
+ }
886
+
887
+ .cta-button:hover {
888
+ transform: translateY(-2px);
889
+ box-shadow: 0 0 30px rgba(255, 107, 53, 0.7);
890
+ }
891
+
892
+ .rarity-badge {
893
+ position: absolute;
894
+ top: 10px;
895
+ right: 10px;
896
+ background: ${state.rarity === 'MYTHIC' ? 'linear-gradient(45deg, #ff00ff, #00ffff)' :
897
+ state.rarity === 'LEGENDARY' ? 'linear-gradient(45deg, #ff6b35, #f7931e)' :
898
+ state.rarity === 'EPIC' ? 'linear-gradient(45deg, #9b59b6, #e74c3c)' :
899
+ state.rarity === 'RARE' ? 'linear-gradient(45deg, #3498db, #2ecc71)' :
900
+ 'linear-gradient(45deg, #95a5a6, #7f8c8d)'};
901
+ color: ${state.rarity === 'COMMON' ? '#fff' : '#000'};
902
+ padding: 4px 12px;
903
+ border-radius: 10px;
904
+ font-size: 0.6rem;
905
+ font-weight: 700;
906
+ text-transform: uppercase;
907
+ letter-spacing: 1px;
908
+ box-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
909
+ }
910
+ </style>
911
+ </head>
912
+ <body>
913
+ <div class="social-card">
914
+ <div class="rarity-badge">${state.rarity}</div>
915
+
916
+ <div class="card-visual">
917
+ ${canvasImage ?
918
+ `<img src="${canvasImage}" class="visualizer-canvas" alt="${state.name}" style="width: 100%; height: 100%; object-fit: cover;" />` :
919
+ `<canvas class="visualizer-canvas" id="vib34dCanvas"></canvas>`
920
+ }
921
+ </div>
922
+
923
+ <div class="card-info">
924
+ <div>
925
+ <h1 class="card-title">VIB34D<br>${state.geometry}</h1>
926
+ <p class="card-subtitle">${state.system} • ${state.dimension}D</p>
927
+
928
+ <div class="feature-list">
929
+ <div class="feature-item">🌌 Dimension: ${state.dimension}D</div>
930
+ <div class="feature-item">⚡ Speed: ${state.speed}x</div>
931
+ <div class="feature-item">🎮 Chaos: ${state.chaos}%</div>
932
+ <div class="feature-item">✨ Rarity: ${state.rarity}</div>
933
+ </div>
934
+ </div>
935
+
936
+ <button class="cta-button" onclick="exploreCollection()">
937
+ 🚀 Get Collection
938
+ </button>
939
+ </div>
940
+ </div>
941
+
942
+ <script>
943
+ ${visualizationContent}
944
+
945
+ document.addEventListener('DOMContentLoaded', () => {
946
+ const canvas = document.getElementById('vib34dCanvas');
947
+ if (canvas) {
948
+ ${canvasImage ? '// Using captured image, no animation needed' : 'new TradingCardVisualizer(canvas);'}
949
+ }
950
+ });
951
+
952
+ function exploreCollection() {
953
+ const portalUrl = '${state.portalUrl}';
954
+ if (confirm("🌌 Visit the VIB34D Portal to collect more variations?")) {
955
+ try {
956
+ window.location.href = portalUrl;
957
+ } catch (e) {
958
+ window.open(portalUrl, '_blank');
959
+ }
960
+ }
961
+ }
962
+ </script>
963
+ </body>
964
+ </html>`;
965
+ }
966
+
967
+ /**
968
+ * Generate LIVE multi-layer WebGL visualization code for the trading card
969
+ * REFACTORED: Now uses modular system architecture
970
+ */
971
+ generateVisualizationCode(state) {
972
+ console.log(`🎯 Generating ${this.currentSystem} system using modular architecture`);
973
+
974
+ if (this.currentSystem === 'faceted') {
975
+ return TradingCardSystemFaceted.generateLiveSystem(state);
976
+ } else if (this.currentSystem === 'quantum') {
977
+ return TradingCardSystemQuantum.generateLiveSystem(state);
978
+ } else if (this.currentSystem === 'holographic') {
979
+ return TradingCardSystemHolographic.generateLiveSystem(state);
980
+ } else if (this.currentSystem === 'polychora') {
981
+ // Use faceted as fallback for polychora (placeholder system)
982
+ console.log('🔮 Polychora system using faceted fallback');
983
+ return TradingCardSystemFaceted.generateLiveSystem(state);
984
+ } else {
985
+ console.warn(`⚠️ Unknown system: ${this.currentSystem}, using faceted fallback`);
986
+ return TradingCardSystemFaceted.generateLiveSystem(state);
987
+ }
988
+ }
989
+
990
+ /**
991
+ * Generate LIVE 5-layer Faceted system with actual Engine code
992
+ */
993
+ generateLiveFacetedSystem(state) {
994
+ return `
995
+ // LIVE VIB34D Faceted System - 5 Layer WebGL Rendering
996
+ class LiveTradingCardSystem {
997
+ constructor() {
998
+ this.layers = ['background', 'shadow', 'content', 'highlight', 'accent'];
999
+ this.visualizers = [];
1000
+ this.params = ${JSON.stringify(state.parameters)};
1001
+ this.startTime = Date.now();
1002
+
1003
+ this.initializeAllLayers();
1004
+ this.startRenderLoop();
1005
+ }
1006
+
1007
+ initializeAllLayers() {
1008
+ // Create 5 canvases dynamically
1009
+ this.layers.forEach((role, index) => {
1010
+ const canvas = document.createElement('canvas');
1011
+ canvas.id = 'card-' + role + '-canvas';
1012
+ canvas.style.position = 'absolute';
1013
+ canvas.style.top = '0';
1014
+ canvas.style.left = '0';
1015
+ canvas.style.width = '100%';
1016
+ canvas.style.height = '100%';
1017
+ canvas.style.zIndex = index;
1018
+
1019
+ // Set layer-specific blend modes and opacity
1020
+ if (role === 'background') {
1021
+ canvas.style.opacity = '0.4';
1022
+ } else if (role === 'shadow') {
1023
+ canvas.style.mixBlendMode = 'multiply';
1024
+ canvas.style.opacity = '0.6';
1025
+ } else if (role === 'content') {
1026
+ canvas.style.opacity = '1.0';
1027
+ } else if (role === 'highlight') {
1028
+ canvas.style.mixBlendMode = 'screen';
1029
+ } else if (role === 'accent') {
1030
+ canvas.style.mixBlendMode = 'overlay';
1031
+ canvas.style.opacity = '0.8';
1032
+ }
1033
+
1034
+ document.getElementById('vib34dCanvas').parentElement.appendChild(canvas);
1035
+
1036
+ // Create WebGL visualizer for this layer
1037
+ const visualizer = new LayerVisualizer(canvas, role, this.params);
1038
+ this.visualizers.push(visualizer);
1039
+ });
1040
+
1041
+ // Hide the original canvas
1042
+ document.getElementById('vib34dCanvas').style.display = 'none';
1043
+ }
1044
+
1045
+ startRenderLoop() {
1046
+ const render = () => {
1047
+ const time = Date.now() - this.startTime;
1048
+ this.visualizers.forEach(visualizer => {
1049
+ visualizer.render(time);
1050
+ });
1051
+ requestAnimationFrame(render);
1052
+ };
1053
+ render();
1054
+ }
1055
+ }
1056
+
1057
+ class LayerVisualizer {
1058
+ constructor(canvas, role, params) {
1059
+ this.canvas = canvas;
1060
+ this.role = role;
1061
+ this.params = params;
1062
+ this.gl = canvas.getContext('webgl');
1063
+
1064
+ const roleIntensities = {
1065
+ 'background': 0.3, 'shadow': 0.5, 'content': 0.8,
1066
+ 'highlight': 1.0, 'accent': 1.2
1067
+ };
1068
+ this.roleIntensity = roleIntensities[role] || 1.0;
1069
+
1070
+ this.initShaders();
1071
+ this.initBuffers();
1072
+ this.resize();
1073
+ }
1074
+
1075
+ resize() {
1076
+ this.canvas.width = this.canvas.clientWidth;
1077
+ this.canvas.height = this.canvas.clientHeight;
1078
+ this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
1079
+ }
1080
+
1081
+ initShaders() {
1082
+ const vertexShaderSource = \`attribute vec2 a_position;
1083
+ void main() {
1084
+ gl_Position = vec4(a_position, 0.0, 1.0);
1085
+ }\`;
1086
+
1087
+ // EXACT FRAGMENT SHADER FROM FACETED SYSTEM
1088
+ const fragmentShaderSource = \`precision highp float;
1089
+ uniform vec2 u_resolution;
1090
+ uniform float u_time;
1091
+ uniform vec2 u_mouse;
1092
+ uniform float u_geometry;
1093
+ uniform float u_gridDensity;
1094
+ uniform float u_morphFactor;
1095
+ uniform float u_chaos;
1096
+ uniform float u_speed;
1097
+ uniform float u_hue;
1098
+ uniform float u_intensity;
1099
+ uniform float u_saturation;
1100
+ uniform float u_dimension;
1101
+ uniform float u_rot4dXW;
1102
+ uniform float u_rot4dYW;
1103
+ uniform float u_rot4dZW;
1104
+ uniform float u_mouseIntensity;
1105
+ uniform float u_clickIntensity;
1106
+ uniform float u_roleIntensity;
1107
+
1108
+ // 4D rotation matrices
1109
+ mat4 rotateXW(float theta) {
1110
+ float c = cos(theta);
1111
+ float s = sin(theta);
1112
+ return mat4(c, 0.0, 0.0, -s, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, s, 0.0, 0.0, c);
1113
+ }
1114
+ mat4 rotateYW(float theta) {
1115
+ float c = cos(theta);
1116
+ float s = sin(theta);
1117
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, c, 0.0, -s, 0.0, 0.0, 1.0, 0.0, 0.0, s, 0.0, c);
1118
+ }
1119
+ mat4 rotateZW(float theta) {
1120
+ float c = cos(theta);
1121
+ float s = sin(theta);
1122
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, c, -s, 0.0, 0.0, s, c);
1123
+ }
1124
+ vec3 project4Dto3D(vec4 p) {
1125
+ float w = 2.5 / (2.5 + p.w);
1126
+ return vec3(p.x * w, p.y * w, p.z * w);
1127
+ }
1128
+
1129
+ float geometryFunction(vec4 p) {
1130
+ int geomType = int(u_geometry);
1131
+
1132
+ if (geomType == 0) {
1133
+ vec4 pos = fract(p * u_gridDensity * 0.08);
1134
+ vec4 dist = min(pos, 1.0 - pos);
1135
+ return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u_morphFactor;
1136
+ }
1137
+ else if (geomType == 1) {
1138
+ vec4 pos = fract(p * u_gridDensity * 0.08);
1139
+ vec4 dist = min(pos, 1.0 - pos);
1140
+ float minDist = min(min(dist.x, dist.y), min(dist.z, dist.w));
1141
+ return minDist * u_morphFactor;
1142
+ }
1143
+ else if (geomType == 2) {
1144
+ float r = length(p);
1145
+ float density = u_gridDensity * 0.08;
1146
+ float spheres = abs(fract(r * density) - 0.5) * 2.0;
1147
+ float theta = atan(p.y, p.x);
1148
+ float harmonics = sin(theta * 3.0) * 0.2;
1149
+ return (spheres + harmonics) * u_morphFactor;
1150
+ }
1151
+ else if (geomType == 3) {
1152
+ float r1 = length(p.xy) - 2.0;
1153
+ float torus = length(vec2(r1, p.z)) - 0.8;
1154
+ float lattice = sin(p.x * u_gridDensity * 0.08) * sin(p.y * u_gridDensity * 0.08);
1155
+ return (torus + lattice * 0.3) * u_morphFactor;
1156
+ }
1157
+ else if (geomType == 4) {
1158
+ float u = atan(p.y, p.x);
1159
+ float v = atan(p.w, p.z);
1160
+ float dist = length(p) - 2.0;
1161
+ float lattice = sin(u * u_gridDensity * 0.08) * sin(v * u_gridDensity * 0.08);
1162
+ return (dist + lattice * 0.4) * u_morphFactor;
1163
+ }
1164
+ else if (geomType == 5) {
1165
+ vec4 pos = fract(p * u_gridDensity * 0.08);
1166
+ pos = abs(pos * 2.0 - 1.0);
1167
+ float dist = length(max(abs(pos) - 1.0, 0.0));
1168
+ return dist * u_morphFactor;
1169
+ }
1170
+ else if (geomType == 6) {
1171
+ float freq = u_gridDensity * 0.08;
1172
+ float time = u_time * 0.001 * u_speed;
1173
+ float wave1 = sin(p.x * freq + time);
1174
+ float wave2 = sin(p.y * freq + time * 1.3);
1175
+ float wave3 = sin(p.z * freq * 0.8 + time * 0.7);
1176
+ float interference = wave1 * wave2 * wave3;
1177
+ return interference * u_morphFactor;
1178
+ }
1179
+ else if (geomType == 7) {
1180
+ vec4 pos = fract(p * u_gridDensity * 0.08) - 0.5;
1181
+ float cube = max(max(abs(pos.x), abs(pos.y)), max(abs(pos.z), abs(pos.w)));
1182
+ return cube * u_morphFactor;
1183
+ }
1184
+ else {
1185
+ vec4 pos = fract(p * u_gridDensity * 0.08);
1186
+ vec4 dist = min(pos, 1.0 - pos);
1187
+ return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u_morphFactor;
1188
+ }
1189
+ }
1190
+
1191
+ void main() {
1192
+ vec2 uv = (gl_FragCoord.xy - u_resolution.xy * 0.5) / min(u_resolution.x, u_resolution.y);
1193
+
1194
+ float timeSpeed = u_time * 0.0001 * u_speed;
1195
+ vec4 pos = vec4(uv * 3.0, sin(timeSpeed * 3.0), cos(timeSpeed * 2.0));
1196
+ pos.xy += (u_mouse - 0.5) * u_mouseIntensity * 2.0;
1197
+
1198
+ pos = rotateXW(u_rot4dXW) * pos;
1199
+ pos = rotateYW(u_rot4dYW) * pos;
1200
+ pos = rotateZW(u_rot4dZW) * pos;
1201
+
1202
+ float value = geometryFunction(pos);
1203
+
1204
+ float noise = sin(pos.x * 7.0) * cos(pos.y * 11.0) * sin(pos.z * 13.0);
1205
+ value += noise * u_chaos;
1206
+
1207
+ float geometryIntensity = 1.0 - clamp(abs(value), 0.0, 1.0);
1208
+ geometryIntensity += u_clickIntensity * 0.3;
1209
+
1210
+ float finalIntensity = geometryIntensity * u_intensity;
1211
+
1212
+ float hue = u_hue / 360.0 + value * 0.1;
1213
+
1214
+ vec3 baseColor = vec3(
1215
+ sin(hue * 6.28318 + 0.0) * 0.5 + 0.5,
1216
+ sin(hue * 6.28318 + 2.0943) * 0.5 + 0.5,
1217
+ sin(hue * 6.28318 + 4.1887) * 0.5 + 0.5
1218
+ );
1219
+
1220
+ float gray = (baseColor.r + baseColor.g + baseColor.b) / 3.0;
1221
+ vec3 color = mix(vec3(gray), baseColor, u_saturation) * finalIntensity;
1222
+
1223
+ gl_FragColor = vec4(color, finalIntensity * u_roleIntensity);
1224
+ }\`;
1225
+
1226
+ this.program = this.createProgram(vertexShaderSource, fragmentShaderSource);
1227
+ this.uniforms = {
1228
+ resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),
1229
+ time: this.gl.getUniformLocation(this.program, 'u_time'),
1230
+ mouse: this.gl.getUniformLocation(this.program, 'u_mouse'),
1231
+ geometry: this.gl.getUniformLocation(this.program, 'u_geometry'),
1232
+ gridDensity: this.gl.getUniformLocation(this.program, 'u_gridDensity'),
1233
+ morphFactor: this.gl.getUniformLocation(this.program, 'u_morphFactor'),
1234
+ chaos: this.gl.getUniformLocation(this.program, 'u_chaos'),
1235
+ speed: this.gl.getUniformLocation(this.program, 'u_speed'),
1236
+ hue: this.gl.getUniformLocation(this.program, 'u_hue'),
1237
+ intensity: this.gl.getUniformLocation(this.program, 'u_intensity'),
1238
+ saturation: this.gl.getUniformLocation(this.program, 'u_saturation'),
1239
+ dimension: this.gl.getUniformLocation(this.program, 'u_dimension'),
1240
+ rot4dXW: this.gl.getUniformLocation(this.program, 'u_rot4dXW'),
1241
+ rot4dYW: this.gl.getUniformLocation(this.program, 'u_rot4dYW'),
1242
+ rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW'),
1243
+ mouseIntensity: this.gl.getUniformLocation(this.program, 'u_mouseIntensity'),
1244
+ clickIntensity: this.gl.getUniformLocation(this.program, 'u_clickIntensity'),
1245
+ roleIntensity: this.gl.getUniformLocation(this.program, 'u_roleIntensity')
1246
+ };
1247
+ }
1248
+
1249
+ createProgram(vertexSource, fragmentSource) {
1250
+ const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexSource);
1251
+ const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentSource);
1252
+
1253
+ const program = this.gl.createProgram();
1254
+ this.gl.attachShader(program, vertexShader);
1255
+ this.gl.attachShader(program, fragmentShader);
1256
+ this.gl.linkProgram(program);
1257
+
1258
+ if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
1259
+ console.error('Program linking failed:', this.gl.getProgramInfoLog(program));
1260
+ return null;
1261
+ }
1262
+
1263
+ return program;
1264
+ }
1265
+
1266
+ createShader(type, source) {
1267
+ const shader = this.gl.createShader(type);
1268
+ this.gl.shaderSource(shader, source);
1269
+ this.gl.compileShader(shader);
1270
+
1271
+ if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
1272
+ console.error('Shader compilation failed:', this.gl.getShaderInfoLog(shader));
1273
+ return null;
1274
+ }
1275
+
1276
+ return shader;
1277
+ }
1278
+
1279
+ initBuffers() {
1280
+ const positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
1281
+
1282
+ this.buffer = this.gl.createBuffer();
1283
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
1284
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
1285
+
1286
+ const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
1287
+ this.gl.enableVertexAttribArray(positionLocation);
1288
+ this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
1289
+ }
1290
+
1291
+ render(time) {
1292
+ if (!this.program) return;
1293
+
1294
+ this.resize();
1295
+ this.gl.useProgram(this.program);
1296
+
1297
+ this.gl.uniform2f(this.uniforms.resolution, this.canvas.width, this.canvas.height);
1298
+ this.gl.uniform1f(this.uniforms.time, time);
1299
+ this.gl.uniform2f(this.uniforms.mouse, 0.5, 0.5);
1300
+ this.gl.uniform1f(this.uniforms.geometry, this.params.geometry || 0);
1301
+ this.gl.uniform1f(this.uniforms.gridDensity, this.params.gridDensity || 15);
1302
+ this.gl.uniform1f(this.uniforms.morphFactor, this.params.morphFactor || 1.0);
1303
+ this.gl.uniform1f(this.uniforms.chaos, this.params.chaos || 0.2);
1304
+ this.gl.uniform1f(this.uniforms.speed, this.params.speed || 1.0);
1305
+ this.gl.uniform1f(this.uniforms.hue, this.params.hue || 200);
1306
+ this.gl.uniform1f(this.uniforms.intensity, this.params.intensity || 0.5);
1307
+ this.gl.uniform1f(this.uniforms.saturation, this.params.saturation || 0.8);
1308
+ this.gl.uniform1f(this.uniforms.dimension, this.params.dimension || 3.8);
1309
+ this.gl.uniform1f(this.uniforms.rot4dXW, this.params.rot4dXW || 0.0);
1310
+ this.gl.uniform1f(this.uniforms.rot4dYW, this.params.rot4dYW || 0.0);
1311
+ this.gl.uniform1f(this.uniforms.rot4dZW, this.params.rot4dZW || 0.0);
1312
+ this.gl.uniform1f(this.uniforms.mouseIntensity, this.mouseIntensity || 0.0);
1313
+ this.gl.uniform1f(this.uniforms.clickIntensity, this.clickIntensity || 0.0);
1314
+ this.gl.uniform1f(this.uniforms.roleIntensity, this.roleIntensity);
1315
+
1316
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
1317
+ }
1318
+ }
1319
+
1320
+ // Enhanced interactivity system - FIXED CANVAS SCOPE
1321
+ const canvas = document.getElementById('vib34dCanvas');
1322
+ if (!canvas) {
1323
+ console.error('Canvas not found for interactivity');
1324
+ return;
1325
+ }
1326
+
1327
+ let mouseX = 0.5, mouseY = 0.5, mouseIntensity = 0.0;
1328
+ let clickIntensity = 0.0;
1329
+ let currentTouch = null;
1330
+
1331
+ // Mouse interactions
1332
+ canvas.addEventListener('mousemove', (e) => {
1333
+ const rect = canvas.getBoundingClientRect();
1334
+ mouseX = (e.clientX - rect.left) / rect.width;
1335
+ mouseY = 1.0 - (e.clientY - rect.top) / rect.height;
1336
+ mouseIntensity = Math.min(1.0, Math.sqrt(e.movementX*e.movementX + e.movementY*e.movementY) / 40);
1337
+
1338
+ // Update all layer visualizers
1339
+ layers.forEach(layer => {
1340
+ if (layer.visualizer) {
1341
+ layer.visualizer.mouseX = mouseX;
1342
+ layer.visualizer.mouseY = mouseY;
1343
+ layer.visualizer.mouseIntensity = mouseIntensity;
1344
+ }
1345
+ });
1346
+ });
1347
+
1348
+ canvas.addEventListener('click', (e) => {
1349
+ clickIntensity = 1.0;
1350
+ layers.forEach(layer => {
1351
+ if (layer.visualizer) {
1352
+ layer.visualizer.clickIntensity = clickIntensity;
1353
+ }
1354
+ });
1355
+ setTimeout(() => {
1356
+ clickIntensity = 0.0;
1357
+ layers.forEach(layer => {
1358
+ if (layer.visualizer) {
1359
+ layer.visualizer.clickIntensity = 0.0;
1360
+ }
1361
+ });
1362
+ }, 500);
1363
+ });
1364
+
1365
+ // Touch interactions
1366
+ canvas.addEventListener('touchstart', (e) => {
1367
+ e.preventDefault();
1368
+ if (e.touches.length > 0) {
1369
+ currentTouch = e.touches[0];
1370
+ const rect = canvas.getBoundingClientRect();
1371
+ mouseX = (currentTouch.clientX - rect.left) / rect.width;
1372
+ mouseY = 1.0 - (currentTouch.clientY - rect.top) / rect.height;
1373
+ clickIntensity = 1.0;
1374
+
1375
+ layers.forEach(layer => {
1376
+ if (layer.visualizer) {
1377
+ layer.visualizer.mouseX = mouseX;
1378
+ layer.visualizer.mouseY = mouseY;
1379
+ layer.visualizer.clickIntensity = clickIntensity;
1380
+ }
1381
+ });
1382
+ }
1383
+ }, { passive: false });
1384
+
1385
+ canvas.addEventListener('touchmove', (e) => {
1386
+ e.preventDefault();
1387
+ if (e.touches.length > 0) {
1388
+ const touch = e.touches[0];
1389
+ const rect = canvas.getBoundingClientRect();
1390
+ mouseX = (touch.clientX - rect.left) / rect.width;
1391
+ mouseY = 1.0 - (touch.clientY - rect.top) / rect.height;
1392
+ mouseIntensity = 0.8;
1393
+ currentTouch = touch;
1394
+
1395
+ layers.forEach(layer => {
1396
+ if (layer.visualizer) {
1397
+ layer.visualizer.mouseX = mouseX;
1398
+ layer.visualizer.mouseY = mouseY;
1399
+ layer.visualizer.mouseIntensity = mouseIntensity;
1400
+ }
1401
+ });
1402
+ }
1403
+ }, { passive: false });
1404
+
1405
+ canvas.addEventListener('touchend', (e) => {
1406
+ clickIntensity = 0.0;
1407
+ mouseIntensity = 0.0;
1408
+ currentTouch = null;
1409
+
1410
+ layers.forEach(layer => {
1411
+ if (layer.visualizer) {
1412
+ layer.visualizer.clickIntensity = 0.0;
1413
+ layer.visualizer.mouseIntensity = 0.0;
1414
+ }
1415
+ });
1416
+ }, { passive: false });
1417
+
1418
+ // Scroll interactions
1419
+ canvas.addEventListener('wheel', (e) => {
1420
+ e.preventDefault();
1421
+ clickIntensity = Math.min(1.0, Math.abs(e.deltaY) / 100);
1422
+
1423
+ layers.forEach(layer => {
1424
+ if (layer.visualizer) {
1425
+ layer.visualizer.clickIntensity = clickIntensity;
1426
+ }
1427
+ });
1428
+
1429
+ setTimeout(() => {
1430
+ clickIntensity = 0.0;
1431
+ layers.forEach(layer => {
1432
+ if (layer.visualizer) {
1433
+ layer.visualizer.clickIntensity = 0.0;
1434
+ }
1435
+ });
1436
+ }, 300);
1437
+ }, { passive: false });`;
1438
+ }
1439
+
1440
+ /**
1441
+ * Generate LIVE Quantum system with enhanced holographic effects
1442
+ */
1443
+ generateLiveQuantumSystem(state) {
1444
+ return `
1445
+ // LIVE VIB34D Quantum System - Enhanced 5 Layer WebGL Rendering
1446
+ class LiveQuantumTradingCardSystem {
1447
+ constructor(canvas) {
1448
+ this.canvas = canvas;
1449
+ this.layers = [];
1450
+ this.params = ${JSON.stringify(state.parameters)};
1451
+ this.startTime = Date.now();
1452
+
1453
+ console.log('🌌 Initializing LIVE Quantum Trading Card System');
1454
+ this.initializeLayers();
1455
+ this.startRenderLoop();
1456
+ }
1457
+
1458
+ initializeLayers() {
1459
+ const layerConfigs = [
1460
+ { id: 'quantum-bg', role: 'background', blend: 'multiply', opacity: 0.4, intensity: 0.4, densityMult: 0.8, speedMult: 0.6 },
1461
+ { id: 'quantum-shadow', role: 'shadow', blend: 'multiply', opacity: 0.6, intensity: 0.6, densityMult: 0.9, speedMult: 0.8 },
1462
+ { id: 'quantum-content', role: 'content', blend: 'normal', opacity: 1.0, intensity: 1.0, densityMult: 1.0, speedMult: 1.0 },
1463
+ { id: 'quantum-highlight', role: 'highlight', blend: 'screen', opacity: 0.8, intensity: 1.3, densityMult: 1.1, speedMult: 1.2 },
1464
+ { id: 'quantum-accent', role: 'accent', blend: 'color-dodge', opacity: 0.7, intensity: 1.6, densityMult: 1.2, speedMult: 1.4 }
1465
+ ];
1466
+
1467
+ layerConfigs.forEach(config => {
1468
+ const layerCanvas = document.createElement('canvas');
1469
+ layerCanvas.id = config.id;
1470
+ layerCanvas.width = this.canvas.width;
1471
+ layerCanvas.height = this.canvas.height;
1472
+ layerCanvas.style.position = 'absolute';
1473
+ layerCanvas.style.top = '0';
1474
+ layerCanvas.style.left = '0';
1475
+ layerCanvas.style.width = '100%';
1476
+ layerCanvas.style.height = '100%';
1477
+ layerCanvas.style.mixBlendMode = config.blend;
1478
+ layerCanvas.style.opacity = config.opacity;
1479
+ layerCanvas.style.pointerEvents = 'none';
1480
+
1481
+ this.canvas.parentNode.appendChild(layerCanvas);
1482
+
1483
+ const visualizer = new QuantumLayerVisualizer(layerCanvas, config);
1484
+ this.layers.push({ visualizer, config });
1485
+ console.log(\`🌌 Created quantum layer: \${config.role}\`);
1486
+ });
1487
+ }
1488
+
1489
+ startRenderLoop() {
1490
+ const render = () => {
1491
+ this.layers.forEach(({ visualizer }) => {
1492
+ if (visualizer && visualizer.render) {
1493
+ visualizer.render(Date.now());
1494
+ }
1495
+ });
1496
+ requestAnimationFrame(render);
1497
+ };
1498
+ render();
1499
+ }
1500
+ }
1501
+
1502
+ // Enhanced Quantum Layer Visualizer with complex 3D lattice shaders
1503
+ class QuantumLayerVisualizer {
1504
+ constructor(canvas, roleConfig) {
1505
+ this.canvas = canvas;
1506
+ this.roleConfig = roleConfig;
1507
+ this.gl = canvas.getContext('webgl');
1508
+ this.params = ${JSON.stringify(state.parameters)};
1509
+ this.mouseX = 0.5;
1510
+ this.mouseY = 0.5;
1511
+ this.mouseIntensity = 0.0;
1512
+ this.clickIntensity = 0.0;
1513
+ this.startTime = Date.now();
1514
+
1515
+ if (!this.gl) {
1516
+ console.error(\`WebGL not supported for quantum layer \${roleConfig.role}\`);
1517
+ return;
1518
+ }
1519
+
1520
+ this.initShaders();
1521
+ this.initBuffers();
1522
+ }
1523
+
1524
+ initShaders() {
1525
+ const vertexShader = \`
1526
+ attribute vec2 a_position;
1527
+ void main() {
1528
+ gl_Position = vec4(a_position, 0.0, 1.0);
1529
+ }\`;
1530
+
1531
+ const fragmentShader = \`
1532
+ precision highp float;
1533
+ uniform vec2 u_resolution;
1534
+ uniform float u_time;
1535
+ uniform vec2 u_mouse;
1536
+ uniform float u_geometry;
1537
+ uniform float u_gridDensity;
1538
+ uniform float u_morphFactor;
1539
+ uniform float u_chaos;
1540
+ uniform float u_speed;
1541
+ uniform float u_hue;
1542
+ uniform float u_intensity;
1543
+ uniform float u_saturation;
1544
+ uniform float u_rot4dXW;
1545
+ uniform float u_rot4dYW;
1546
+ uniform float u_rot4dZW;
1547
+ uniform float u_mouseIntensity;
1548
+ uniform float u_clickIntensity;
1549
+ uniform float u_roleIntensity;
1550
+
1551
+ // 4D rotation matrices
1552
+ mat4 rotateXW(float theta) {
1553
+ float c = cos(theta);
1554
+ float s = sin(theta);
1555
+ return mat4(c, 0.0, 0.0, -s, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, s, 0.0, 0.0, c);
1556
+ }
1557
+
1558
+ mat4 rotateYW(float theta) {
1559
+ float c = cos(theta);
1560
+ float s = sin(theta);
1561
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, c, 0.0, -s, 0.0, 0.0, 1.0, 0.0, 0.0, s, 0.0, c);
1562
+ }
1563
+
1564
+ mat4 rotateZW(float theta) {
1565
+ float c = cos(theta);
1566
+ float s = sin(theta);
1567
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, c, -s, 0.0, 0.0, s, c);
1568
+ }
1569
+
1570
+ vec3 project4Dto3D(vec4 p) {
1571
+ float w = 2.5 / (2.5 + p.w);
1572
+ return vec3(p.x * w, p.y * w, p.z * w);
1573
+ }
1574
+
1575
+ // COMPLEX 3D LATTICE FUNCTIONS - QUANTUM ENHANCED
1576
+ float tetrahedronLattice(vec3 p, float gridSize) {
1577
+ vec3 q = fract(p * gridSize) - 0.5;
1578
+ float d1 = length(q);
1579
+ float d2 = length(q - vec3(0.4, 0.0, 0.0));
1580
+ float d3 = length(q - vec3(0.0, 0.4, 0.0));
1581
+ float d4 = length(q - vec3(0.0, 0.0, 0.4));
1582
+ float vertices = 1.0 - smoothstep(0.0, 0.04, min(min(d1, d2), min(d3, d4)));
1583
+ float edges = 0.0;
1584
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.xy) - 0.2)));
1585
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.yz) - 0.2)));
1586
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.xz) - 0.2)));
1587
+ return max(vertices, edges * 0.5);
1588
+ }
1589
+
1590
+ float hypercubeLattice(vec3 p, float gridSize) {
1591
+ vec3 grid = fract(p * gridSize);
1592
+ vec3 edges = min(grid, 1.0 - grid);
1593
+ float minEdge = min(min(edges.x, edges.y), edges.z);
1594
+ float lattice = 1.0 - smoothstep(0.0, 0.03, minEdge);
1595
+
1596
+ vec3 centers = abs(grid - 0.5);
1597
+ float maxCenter = max(max(centers.x, centers.y), centers.z);
1598
+ float vertices = 1.0 - smoothstep(0.45, 0.5, maxCenter);
1599
+
1600
+ return max(lattice * 0.7, vertices);
1601
+ }
1602
+
1603
+ // ENHANCED GEOMETRY FUNCTION WITH QUANTUM EFFECTS
1604
+ float quantumGeometry(vec4 p) {
1605
+ int geomType = int(u_geometry);
1606
+ vec3 p3d = project4Dto3D(p);
1607
+ float gridSize = u_gridDensity * 0.08;
1608
+
1609
+ if (geomType == 0) {
1610
+ return tetrahedronLattice(p3d, gridSize) * u_morphFactor;
1611
+ } else if (geomType == 1) {
1612
+ return hypercubeLattice(p3d, gridSize) * u_morphFactor;
1613
+ } else {
1614
+ return hypercubeLattice(p3d, gridSize) * u_morphFactor;
1615
+ }
1616
+ }
1617
+
1618
+ // HSV to RGB conversion
1619
+ vec3 hsv2rgb(vec3 c) {
1620
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
1621
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
1622
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
1623
+ }
1624
+
1625
+ // RGB Glitch effect
1626
+ vec3 rgbGlitch(vec3 color, vec2 uv, float intensity) {
1627
+ float r = color.r + sin(uv.y * 30.0 + u_time * 0.001) * intensity * 0.06;
1628
+ float g = color.g + sin(uv.y * 28.0 + u_time * 0.0012) * intensity * 0.06;
1629
+ float b = color.b + sin(uv.y * 32.0 + u_time * 0.0008) * intensity * 0.06;
1630
+ return vec3(r, g, b);
1631
+ }
1632
+
1633
+ void main() {
1634
+ vec2 uv = (gl_FragCoord.xy - u_resolution.xy * 0.5) / min(u_resolution.x, u_resolution.y);
1635
+
1636
+ // Enhanced 4D position with quantum effects
1637
+ float timeSpeed = u_time * 0.0001 * u_speed;
1638
+ vec4 pos = vec4(uv * 3.0, sin(timeSpeed * 3.0), cos(timeSpeed * 2.0));
1639
+ pos.xy += (u_mouse - 0.5) * u_mouseIntensity * 2.0;
1640
+
1641
+ // Apply 4D rotations
1642
+ pos = rotateXW(u_rot4dXW) * pos;
1643
+ pos = rotateYW(u_rot4dYW) * pos;
1644
+ pos = rotateZW(u_rot4dZW) * pos;
1645
+
1646
+ // Calculate quantum geometry value
1647
+ float value = quantumGeometry(pos);
1648
+
1649
+ // Enhanced chaos with quantum noise
1650
+ float noise = sin(pos.x * 7.0) * cos(pos.y * 11.0) * sin(pos.z * 13.0);
1651
+ value += noise * u_chaos;
1652
+
1653
+ // Quantum intensity calculation with holographic glow
1654
+ float geometryIntensity = 1.0 - clamp(abs(value * 0.8), 0.0, 1.0);
1655
+ geometryIntensity = pow(geometryIntensity, 1.5);
1656
+ geometryIntensity += u_clickIntensity * 0.3;
1657
+
1658
+ // Quantum shimmer effect
1659
+ float shimmer = sin(uv.x * 20.0 + timeSpeed * 5.0) * cos(uv.y * 15.0 + timeSpeed * 3.0) * 0.1;
1660
+ geometryIntensity += shimmer * geometryIntensity;
1661
+
1662
+ float finalIntensity = geometryIntensity * u_intensity;
1663
+
1664
+ // Enhanced quantum color system
1665
+ float baseHue = u_hue / 360.0;
1666
+ float hueShift = value * 0.2 + timeSpeed * 0.1;
1667
+ float finalHue = baseHue + hueShift;
1668
+
1669
+ vec3 hsvColor = vec3(finalHue, u_saturation, finalIntensity);
1670
+ vec3 baseColor = hsv2rgb(hsvColor);
1671
+
1672
+ // Add quantum particles
1673
+ float particles = 0.0;
1674
+ vec2 particleUV = uv * 8.0;
1675
+ vec2 particleID = floor(particleUV);
1676
+ vec2 particlePos = fract(particleUV) - 0.5;
1677
+ float particleDist = length(particlePos);
1678
+
1679
+ float particleTime = timeSpeed + dot(particleID, vec2(127.1, 311.7));
1680
+ float particleAlpha = sin(particleTime) * 0.5 + 0.5;
1681
+ particles = (1.0 - smoothstep(0.1, 0.3, particleDist)) * particleAlpha * 0.3;
1682
+
1683
+ vec3 glitchedColor = rgbGlitch(baseColor, uv, finalIntensity * 0.5);
1684
+ vec3 finalColor = glitchedColor + particles * vec3(1.0, 0.8, 1.0);
1685
+
1686
+ gl_FragColor = vec4(finalColor, finalIntensity * u_roleIntensity);
1687
+ }\`;
1688
+
1689
+ this.program = this.createProgram(vertexShader, fragmentShader);
1690
+ if (this.program) {
1691
+ this.uniforms = {
1692
+ resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),
1693
+ time: this.gl.getUniformLocation(this.program, 'u_time'),
1694
+ mouse: this.gl.getUniformLocation(this.program, 'u_mouse'),
1695
+ geometry: this.gl.getUniformLocation(this.program, 'u_geometry'),
1696
+ gridDensity: this.gl.getUniformLocation(this.program, 'u_gridDensity'),
1697
+ morphFactor: this.gl.getUniformLocation(this.program, 'u_morphFactor'),
1698
+ chaos: this.gl.getUniformLocation(this.program, 'u_chaos'),
1699
+ speed: this.gl.getUniformLocation(this.program, 'u_speed'),
1700
+ hue: this.gl.getUniformLocation(this.program, 'u_hue'),
1701
+ intensity: this.gl.getUniformLocation(this.program, 'u_intensity'),
1702
+ saturation: this.gl.getUniformLocation(this.program, 'u_saturation'),
1703
+ rot4dXW: this.gl.getUniformLocation(this.program, 'u_rot4dXW'),
1704
+ rot4dYW: this.gl.getUniformLocation(this.program, 'u_rot4dYW'),
1705
+ rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW'),
1706
+ mouseIntensity: this.gl.getUniformLocation(this.program, 'u_mouseIntensity'),
1707
+ clickIntensity: this.gl.getUniformLocation(this.program, 'u_clickIntensity'),
1708
+ roleIntensity: this.gl.getUniformLocation(this.program, 'u_roleIntensity')
1709
+ };
1710
+ }
1711
+ }
1712
+
1713
+ createProgram(vertexSource, fragmentSource) {
1714
+ const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexSource);
1715
+ const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentSource);
1716
+
1717
+ if (!vertexShader || !fragmentShader) return null;
1718
+
1719
+ const program = this.gl.createProgram();
1720
+ this.gl.attachShader(program, vertexShader);
1721
+ this.gl.attachShader(program, fragmentShader);
1722
+ this.gl.linkProgram(program);
1723
+
1724
+ if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
1725
+ console.error('Quantum program linking failed:', this.gl.getProgramInfoLog(program));
1726
+ return null;
1727
+ }
1728
+
1729
+ return program;
1730
+ }
1731
+
1732
+ createShader(type, source) {
1733
+ const shader = this.gl.createShader(type);
1734
+ this.gl.shaderSource(shader, source);
1735
+ this.gl.compileShader(shader);
1736
+
1737
+ if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
1738
+ console.error('Quantum shader compilation failed:', this.gl.getShaderInfoLog(shader));
1739
+ return null;
1740
+ }
1741
+
1742
+ return shader;
1743
+ }
1744
+
1745
+ initBuffers() {
1746
+ const positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
1747
+ this.buffer = this.gl.createBuffer();
1748
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
1749
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
1750
+
1751
+ const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
1752
+ this.gl.enableVertexAttribArray(positionLocation);
1753
+ this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
1754
+ }
1755
+
1756
+ render(time) {
1757
+ if (!this.program) return;
1758
+
1759
+ this.canvas.width = this.canvas.clientWidth;
1760
+ this.canvas.height = this.canvas.clientHeight;
1761
+ this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
1762
+ this.gl.useProgram(this.program);
1763
+
1764
+ this.gl.uniform2f(this.uniforms.resolution, this.canvas.width, this.canvas.height);
1765
+ this.gl.uniform1f(this.uniforms.time, time);
1766
+ this.gl.uniform2f(this.uniforms.mouse, this.mouseX || 0.5, this.mouseY || 0.5);
1767
+ this.gl.uniform1f(this.uniforms.geometry, this.params.geometry || 0);
1768
+ this.gl.uniform1f(this.uniforms.gridDensity, (this.params.gridDensity || 15) * this.roleConfig.densityMult);
1769
+ this.gl.uniform1f(this.uniforms.morphFactor, this.params.morphFactor || 1.0);
1770
+ this.gl.uniform1f(this.uniforms.chaos, this.params.chaos || 0.2);
1771
+ this.gl.uniform1f(this.uniforms.speed, (this.params.speed || 1.0) * this.roleConfig.speedMult);
1772
+ this.gl.uniform1f(this.uniforms.hue, this.params.hue || 280); // Quantum purple-blue
1773
+ this.gl.uniform1f(this.uniforms.intensity, (this.params.intensity || 0.7) * this.roleConfig.intensity);
1774
+ this.gl.uniform1f(this.uniforms.saturation, this.params.saturation || 0.9);
1775
+ this.gl.uniform1f(this.uniforms.rot4dXW, this.params.rot4dXW || 0.0);
1776
+ this.gl.uniform1f(this.uniforms.rot4dYW, this.params.rot4dYW || 0.0);
1777
+ this.gl.uniform1f(this.uniforms.rot4dZW, this.params.rot4dZW || 0.0);
1778
+ this.gl.uniform1f(this.uniforms.mouseIntensity, this.mouseIntensity || 0.0);
1779
+ this.gl.uniform1f(this.uniforms.clickIntensity, this.clickIntensity || 0.0);
1780
+ this.gl.uniform1f(this.uniforms.roleIntensity, this.roleConfig.intensity);
1781
+
1782
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
1783
+ }
1784
+ }
1785
+
1786
+ // Enhanced interactivity system for Quantum cards - FIXED CANVAS SCOPE
1787
+ const canvas = document.getElementById('vib34dCanvas');
1788
+ if (!canvas) {
1789
+ console.error('Canvas not found for quantum interactivity');
1790
+ return;
1791
+ }
1792
+
1793
+ let mouseX = 0.5, mouseY = 0.5, mouseIntensity = 0.0;
1794
+ let clickIntensity = 0.0;
1795
+
1796
+ canvas.addEventListener('mousemove', (e) => {
1797
+ const rect = canvas.getBoundingClientRect();
1798
+ mouseX = (e.clientX - rect.left) / rect.width;
1799
+ mouseY = 1.0 - (e.clientY - rect.top) / rect.height;
1800
+ mouseIntensity = Math.min(1.0, Math.sqrt(e.movementX*e.movementX + e.movementY*e.movementY) / 40);
1801
+
1802
+ layers.forEach(layer => {
1803
+ if (layer.visualizer) {
1804
+ layer.visualizer.mouseX = mouseX;
1805
+ layer.visualizer.mouseY = mouseY;
1806
+ layer.visualizer.mouseIntensity = mouseIntensity;
1807
+ }
1808
+ });
1809
+ });
1810
+
1811
+ canvas.addEventListener('dblclick', async () => {
1812
+ console.log('🌌 Quantum card audio reactivity - Coming soon!');
1813
+ canvas.style.border = '2px solid #ff00ff';
1814
+ setTimeout(() => { canvas.style.border = ''; }, 2000);
1815
+ });`;
1816
+ }
1817
+
1818
+ /**
1819
+ * Generate LIVE 5-layer Holographic system with actual shader code
1820
+ */
1821
+ generateLiveHolographicSystem(state) {
1822
+ return `
1823
+ // LIVE Active Holographic System - 5 Layer WebGL with Audio Reactivity
1824
+ class LiveTradingCardSystem {
1825
+ constructor() {
1826
+ this.layers = ['background', 'shadow', 'content', 'highlight', 'accent'];
1827
+ this.visualizers = [];
1828
+ this.params = ${JSON.stringify(state.parameters)};
1829
+ this.startTime = Date.now();
1830
+
1831
+ this.initializeAllLayers();
1832
+ this.startRenderLoop();
1833
+ }
1834
+
1835
+ initializeAllLayers() {
1836
+ // Create 5 canvases with holographic blend modes
1837
+ this.layers.forEach((role, index) => {
1838
+ const canvas = document.createElement('canvas');
1839
+ canvas.id = 'card-' + role + '-canvas';
1840
+ canvas.style.position = 'absolute';
1841
+ canvas.style.top = '0';
1842
+ canvas.style.left = '0';
1843
+ canvas.style.width = '100%';
1844
+ canvas.style.height = '100%';
1845
+ canvas.style.zIndex = index;
1846
+
1847
+ // Holographic layer blend modes for rich effects
1848
+ if (role === 'background') {
1849
+ canvas.style.opacity = '0.3';
1850
+ canvas.style.mixBlendMode = 'normal';
1851
+ } else if (role === 'shadow') {
1852
+ canvas.style.opacity = '0.7';
1853
+ canvas.style.mixBlendMode = 'multiply';
1854
+ } else if (role === 'content') {
1855
+ canvas.style.opacity = '1.0';
1856
+ canvas.style.mixBlendMode = 'normal';
1857
+ } else if (role === 'highlight') {
1858
+ canvas.style.opacity = '0.9';
1859
+ canvas.style.mixBlendMode = 'screen';
1860
+ } else if (role === 'accent') {
1861
+ canvas.style.opacity = '0.6';
1862
+ canvas.style.mixBlendMode = 'color-dodge';
1863
+ }
1864
+
1865
+ document.getElementById('vib34dCanvas').parentElement.appendChild(canvas);
1866
+
1867
+ // Create holographic visualizer for this layer
1868
+ const visualizer = new HolographicLayerVisualizer(canvas, role, this.params);
1869
+ this.visualizers.push(visualizer);
1870
+ });
1871
+
1872
+ // Hide the original canvas
1873
+ document.getElementById('vib34dCanvas').style.display = 'none';
1874
+ }
1875
+
1876
+ startRenderLoop() {
1877
+ const render = () => {
1878
+ const time = Date.now() - this.startTime;
1879
+ this.visualizers.forEach(visualizer => {
1880
+ visualizer.render(time);
1881
+ });
1882
+ requestAnimationFrame(render);
1883
+ };
1884
+ render();
1885
+ }
1886
+ }
1887
+
1888
+ class HolographicLayerVisualizer {
1889
+ constructor(canvas, role, params) {
1890
+ this.canvas = canvas;
1891
+ this.role = role;
1892
+ this.params = params;
1893
+ this.gl = canvas.getContext('webgl');
1894
+
1895
+ const roleParams = {
1896
+ 'background': { densityMult: 0.4, speedMult: 0.2, intensity: 0.2 },
1897
+ 'shadow': { densityMult: 0.8, speedMult: 0.3, intensity: 0.4 },
1898
+ 'content': { densityMult: 1.0, speedMult: 0.5, intensity: 0.8 },
1899
+ 'highlight': { densityMult: 1.5, speedMult: 0.8, intensity: 1.0 },
1900
+ 'accent': { densityMult: 2.0, speedMult: 0.4, intensity: 0.6 }
1901
+ };
1902
+ this.roleConfig = roleParams[role] || roleParams['content'];
1903
+
1904
+ this.initShaders();
1905
+ this.initBuffers();
1906
+ this.resize();
1907
+ }
1908
+
1909
+ resize() {
1910
+ this.canvas.width = this.canvas.clientWidth;
1911
+ this.canvas.height = this.canvas.clientHeight;
1912
+ this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
1913
+ }
1914
+
1915
+ initShaders() {
1916
+ const vertexShaderSource = \`
1917
+ attribute vec2 a_position;
1918
+ void main() {
1919
+ gl_Position = vec4(a_position, 0.0, 1.0);
1920
+ }
1921
+ \`;
1922
+
1923
+ // EXACT HOLOGRAPHIC FRAGMENT SHADER WITH ALL EFFECTS
1924
+ const fragmentShaderSource = \`
1925
+ precision highp float;
1926
+
1927
+ uniform vec2 u_resolution;
1928
+ uniform float u_time;
1929
+ uniform vec2 u_mouse;
1930
+ uniform float u_geometry;
1931
+ uniform float u_density;
1932
+ uniform float u_speed;
1933
+ uniform vec3 u_color;
1934
+ uniform float u_intensity;
1935
+ uniform float u_roleDensity;
1936
+ uniform float u_roleSpeed;
1937
+ uniform float u_geometryType;
1938
+ uniform float u_chaos;
1939
+ uniform float u_morph;
1940
+ uniform float u_rot4dXW;
1941
+ uniform float u_rot4dYW;
1942
+ uniform float u_rot4dZW;
1943
+
1944
+ // 4D rotation matrices
1945
+ mat4 rotateXW(float theta) {
1946
+ float c = cos(theta);
1947
+ float s = sin(theta);
1948
+ return mat4(c, 0, 0, -s, 0, 1, 0, 0, 0, 0, 1, 0, s, 0, 0, c);
1949
+ }
1950
+
1951
+ mat4 rotateYW(float theta) {
1952
+ float c = cos(theta);
1953
+ float s = sin(theta);
1954
+ return mat4(1, 0, 0, 0, 0, c, 0, -s, 0, 0, 1, 0, 0, s, 0, c);
1955
+ }
1956
+
1957
+ mat4 rotateZW(float theta) {
1958
+ float c = cos(theta);
1959
+ float s = sin(theta);
1960
+ return mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, c, -s, 0, 0, s, c);
1961
+ }
1962
+
1963
+ vec3 project4Dto3D(vec4 p) {
1964
+ float w = 2.5 / (2.5 + p.w);
1965
+ return vec3(p.x * w, p.y * w, p.z * w);
1966
+ }
1967
+
1968
+ // Complete VIB3 Geometry Library
1969
+ float tetrahedronLattice(vec3 p, float gridSize) {
1970
+ vec3 q = fract(p * gridSize) - 0.5;
1971
+ float d1 = length(q);
1972
+ float d2 = length(q - vec3(0.4, 0.0, 0.0));
1973
+ float d3 = length(q - vec3(0.0, 0.4, 0.0));
1974
+ float d4 = length(q - vec3(0.0, 0.0, 0.4));
1975
+ float vertices = 1.0 - smoothstep(0.0, 0.04, min(min(d1, d2), min(d3, d4)));
1976
+ float edges = 0.0;
1977
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.xy) - 0.2)));
1978
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.yz) - 0.2)));
1979
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.xz) - 0.2)));
1980
+ return max(vertices, edges * 0.5);
1981
+ }
1982
+
1983
+ float hypercubeLattice(vec3 p, float gridSize) {
1984
+ vec3 grid = fract(p * gridSize);
1985
+ vec3 edges = 1.0 - smoothstep(0.0, 0.03, abs(grid - 0.5));
1986
+ return max(max(edges.x, edges.y), edges.z);
1987
+ }
1988
+
1989
+ float sphereLattice(vec3 p, float gridSize) {
1990
+ vec3 q = fract(p * gridSize) - 0.5;
1991
+ float r = length(q);
1992
+ return 1.0 - smoothstep(0.2, 0.5, r);
1993
+ }
1994
+
1995
+ float torusLattice(vec3 p, float gridSize) {
1996
+ vec3 q = fract(p * gridSize) - 0.5;
1997
+ float r1 = sqrt(q.x*q.x + q.y*q.y);
1998
+ float r2 = sqrt((r1 - 0.3)*(r1 - 0.3) + q.z*q.z);
1999
+ return 1.0 - smoothstep(0.0, 0.1, r2);
2000
+ }
2001
+
2002
+ float kleinLattice(vec3 p, float gridSize) {
2003
+ vec3 q = fract(p * gridSize);
2004
+ float u = q.x * 2.0 * 3.14159;
2005
+ float v = q.y * 2.0 * 3.14159;
2006
+ float x = cos(u) * (3.0 + cos(u/2.0) * sin(v) - sin(u/2.0) * sin(2.0*v));
2007
+ float klein = length(vec2(x, q.z)) - 0.1;
2008
+ return 1.0 - smoothstep(0.0, 0.05, abs(klein));
2009
+ }
2010
+
2011
+ float fractalLattice(vec3 p, float gridSize) {
2012
+ vec3 q = p * gridSize;
2013
+ float scale = 1.0;
2014
+ float fractal = 0.0;
2015
+ for(int i = 0; i < 4; i++) {
2016
+ q = fract(q) - 0.5;
2017
+ fractal += abs(length(q)) / scale;
2018
+ scale *= 2.0;
2019
+ q *= 2.0;
2020
+ }
2021
+ return 1.0 - smoothstep(0.0, 1.0, fractal);
2022
+ }
2023
+
2024
+ float waveLattice(vec3 p, float gridSize) {
2025
+ vec3 q = p * gridSize;
2026
+ float wave = sin(q.x * 2.0) * sin(q.y * 2.0) * sin(q.z * 2.0 + u_time);
2027
+ return smoothstep(-0.5, 0.5, wave);
2028
+ }
2029
+
2030
+ float crystalLattice(vec3 p, float gridSize) {
2031
+ vec3 q = fract(p * gridSize) - 0.5;
2032
+ float d = max(max(abs(q.x), abs(q.y)), abs(q.z));
2033
+ return 1.0 - smoothstep(0.3, 0.5, d);
2034
+ }
2035
+
2036
+ float getDynamicGeometry(vec3 p, float gridSize, float geometryType) {
2037
+ int baseGeom = int(mod(geometryType, 8.0));
2038
+ float variation = floor(geometryType / 8.0) / 4.0;
2039
+ float variedGridSize = gridSize * (0.5 + variation * 1.5);
2040
+
2041
+ if (baseGeom == 0) return tetrahedronLattice(p, variedGridSize);
2042
+ else if (baseGeom == 1) return hypercubeLattice(p, variedGridSize);
2043
+ else if (baseGeom == 2) return sphereLattice(p, variedGridSize);
2044
+ else if (baseGeom == 3) return torusLattice(p, variedGridSize);
2045
+ else if (baseGeom == 4) return kleinLattice(p, variedGridSize);
2046
+ else if (baseGeom == 5) return fractalLattice(p, variedGridSize);
2047
+ else if (baseGeom == 6) return waveLattice(p, variedGridSize);
2048
+ else return crystalLattice(p, variedGridSize);
2049
+ }
2050
+
2051
+ vec3 rgbGlitch(vec3 color, vec2 uv, float intensity) {
2052
+ vec2 offset = vec2(intensity * 0.005, 0.0);
2053
+ float r = color.r + sin(uv.y * 30.0 + u_time * 0.001) * intensity * 0.06;
2054
+ float g = color.g + sin(uv.y * 28.0 + u_time * 0.0012) * intensity * 0.06;
2055
+ float b = color.b + sin(uv.y * 32.0 + u_time * 0.0008) * intensity * 0.06;
2056
+ return vec3(r, g, b);
2057
+ }
2058
+
2059
+ float moirePattern(vec2 uv, float intensity) {
2060
+ float freq1 = 12.0 + intensity * 6.0;
2061
+ float freq2 = 14.0 + intensity * 8.0;
2062
+ float pattern1 = sin(uv.x * freq1) * sin(uv.y * freq1);
2063
+ float pattern2 = sin(uv.x * freq2) * sin(uv.y * freq2);
2064
+ return (pattern1 * pattern2) * intensity * 0.15;
2065
+ }
2066
+
2067
+ void main() {
2068
+ vec2 uv = gl_FragCoord.xy / u_resolution.xy;
2069
+ float aspectRatio = u_resolution.x / u_resolution.y;
2070
+ uv.x *= aspectRatio;
2071
+ uv -= 0.5;
2072
+
2073
+ float time = u_time * 0.0004 * u_speed * u_roleSpeed;
2074
+
2075
+ vec4 p4d = vec4(uv * 3.0, sin(time * 0.1) * 0.15, cos(time * 0.08) * 0.15);
2076
+
2077
+ p4d = rotateXW(u_rot4dXW + time * 0.2) * p4d;
2078
+ p4d = rotateYW(u_rot4dYW + time * 0.15) * p4d;
2079
+ p4d = rotateZW(u_rot4dZW + time * 0.25) * p4d;
2080
+
2081
+ vec3 p = project4Dto3D(p4d);
2082
+
2083
+ float roleDensity = u_density * u_roleDensity;
2084
+ float morphedGeometry = u_geometryType + u_morph * 3.0;
2085
+ float lattice = getDynamicGeometry(p, roleDensity, morphedGeometry);
2086
+
2087
+ vec3 baseColor = u_color;
2088
+ float latticeIntensity = lattice * u_intensity;
2089
+
2090
+ vec3 color = baseColor * (0.3 + latticeIntensity * 0.7);
2091
+ color += vec3(lattice * 0.4) * baseColor;
2092
+
2093
+ // Add holographic effects
2094
+ color += vec3(moirePattern(uv, u_chaos));
2095
+ color = rgbGlitch(color, uv, u_chaos);
2096
+
2097
+ gl_FragColor = vec4(color, 0.95);
2098
+ }
2099
+ \`;
2100
+
2101
+ this.program = this.createProgram(vertexShaderSource, fragmentShaderSource);
2102
+ this.uniforms = {
2103
+ resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),
2104
+ time: this.gl.getUniformLocation(this.program, 'u_time'),
2105
+ mouse: this.gl.getUniformLocation(this.program, 'u_mouse'),
2106
+ geometry: this.gl.getUniformLocation(this.program, 'u_geometry'),
2107
+ density: this.gl.getUniformLocation(this.program, 'u_density'),
2108
+ speed: this.gl.getUniformLocation(this.program, 'u_speed'),
2109
+ color: this.gl.getUniformLocation(this.program, 'u_color'),
2110
+ intensity: this.gl.getUniformLocation(this.program, 'u_intensity'),
2111
+ roleDensity: this.gl.getUniformLocation(this.program, 'u_roleDensity'),
2112
+ roleSpeed: this.gl.getUniformLocation(this.program, 'u_roleSpeed'),
2113
+ geometryType: this.gl.getUniformLocation(this.program, 'u_geometryType'),
2114
+ chaos: this.gl.getUniformLocation(this.program, 'u_chaos'),
2115
+ morph: this.gl.getUniformLocation(this.program, 'u_morph'),
2116
+ rot4dXW: this.gl.getUniformLocation(this.program, 'u_rot4dXW'),
2117
+ rot4dYW: this.gl.getUniformLocation(this.program, 'u_rot4dYW'),
2118
+ rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW')
2119
+ };
2120
+ }
2121
+
2122
+ createProgram(vertexSource, fragmentSource) {
2123
+ const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexSource);
2124
+ const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentSource);
2125
+
2126
+ const program = this.gl.createProgram();
2127
+ this.gl.attachShader(program, vertexShader);
2128
+ this.gl.attachShader(program, fragmentShader);
2129
+ this.gl.linkProgram(program);
2130
+
2131
+ if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
2132
+ console.error('Program linking failed:', this.gl.getProgramInfoLog(program));
2133
+ return null;
2134
+ }
2135
+
2136
+ return program;
2137
+ }
2138
+
2139
+ createShader(type, source) {
2140
+ const shader = this.gl.createShader(type);
2141
+ this.gl.shaderSource(shader, source);
2142
+ this.gl.compileShader(shader);
2143
+
2144
+ if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
2145
+ console.error('Shader compilation failed:', this.gl.getShaderInfoLog(shader));
2146
+ return null;
2147
+ }
2148
+
2149
+ return shader;
2150
+ }
2151
+
2152
+ initBuffers() {
2153
+ const positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
2154
+
2155
+ this.buffer = this.gl.createBuffer();
2156
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
2157
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
2158
+
2159
+ const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
2160
+ this.gl.enableVertexAttribArray(positionLocation);
2161
+ this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
2162
+ }
2163
+
2164
+ render(time) {
2165
+ if (!this.program) return;
2166
+
2167
+ this.resize();
2168
+ this.gl.useProgram(this.program);
2169
+
2170
+ const hue = (this.params.hue || 200) / 360;
2171
+ const saturation = this.params.saturation || 0.8;
2172
+ const lightness = this.params.intensity || 0.5;
2173
+
2174
+ // HSL to RGB conversion
2175
+ const hslToRgb = (h, s, l) => {
2176
+ let r, g, b;
2177
+ if (s === 0) {
2178
+ r = g = b = l;
2179
+ } else {
2180
+ const hue2rgb = (p, q, t) => {
2181
+ if (t < 0) t += 1;
2182
+ if (t > 1) t -= 1;
2183
+ if (t < 1/6) return p + (q - p) * 6 * t;
2184
+ if (t < 1/2) return q;
2185
+ if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
2186
+ return p;
2187
+ };
2188
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
2189
+ const p = 2 * l - q;
2190
+ r = hue2rgb(p, q, h + 1/3);
2191
+ g = hue2rgb(p, q, h);
2192
+ b = hue2rgb(p, q, h - 1/3);
2193
+ }
2194
+ return [r, g, b];
2195
+ };
2196
+
2197
+ const rgbColor = hslToRgb(hue, saturation, lightness);
2198
+
2199
+ this.gl.uniform2f(this.uniforms.resolution, this.canvas.width, this.canvas.height);
2200
+ this.gl.uniform1f(this.uniforms.time, time);
2201
+ this.gl.uniform2f(this.uniforms.mouse, 0.5, 0.5);
2202
+ this.gl.uniform1f(this.uniforms.geometryType, this.params.geometryType || 0);
2203
+ this.gl.uniform1f(this.uniforms.density, (this.params.density || 1.0) * this.roleConfig.densityMult);
2204
+ this.gl.uniform1f(this.uniforms.speed, (this.params.speed || 0.5) * this.roleConfig.speedMult);
2205
+ this.gl.uniform3fv(this.uniforms.color, new Float32Array(rgbColor));
2206
+ this.gl.uniform1f(this.uniforms.intensity, (this.params.intensity || 0.5) * this.roleConfig.intensity);
2207
+ this.gl.uniform1f(this.uniforms.roleDensity, this.roleConfig.densityMult);
2208
+ this.gl.uniform1f(this.uniforms.roleSpeed, this.roleConfig.speedMult);
2209
+ this.gl.uniform1f(this.uniforms.chaos, this.params.chaos || 0.0);
2210
+ this.gl.uniform1f(this.uniforms.morph, this.params.morph || 0.0);
2211
+ this.gl.uniform1f(this.uniforms.rot4dXW, this.params.rot4dXW || 0.0);
2212
+ this.gl.uniform1f(this.uniforms.rot4dYW, this.params.rot4dYW || 0.0);
2213
+ this.gl.uniform1f(this.uniforms.rot4dZW, this.params.rot4dZW || 0.0);
2214
+
2215
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
2216
+ }
2217
+ }
2218
+
2219
+ // Enhanced interactivity system for Holographic cards - FIXED CANVAS SCOPE
2220
+ const canvas = document.getElementById('vib34dCanvas');
2221
+ if (!canvas) {
2222
+ console.error('Canvas not found for holographic interactivity');
2223
+ return;
2224
+ }
2225
+
2226
+ let mouseX = 0.5, mouseY = 0.5, mouseIntensity = 0.0;
2227
+ let clickIntensity = 0.0;
2228
+ let currentTouch = null;
2229
+
2230
+ // Mouse interactions
2231
+ canvas.addEventListener('mousemove', (e) => {
2232
+ const rect = canvas.getBoundingClientRect();
2233
+ mouseX = (e.clientX - rect.left) / rect.width;
2234
+ mouseY = 1.0 - (e.clientY - rect.top) / rect.height;
2235
+ mouseIntensity = Math.min(1.0, Math.sqrt(e.movementX*e.movementX + e.movementY*e.movementY) / 40);
2236
+
2237
+ // Update all layer visualizers
2238
+ layers.forEach(layer => {
2239
+ if (layer.visualizer) {
2240
+ layer.visualizer.mouseX = mouseX;
2241
+ layer.visualizer.mouseY = mouseY;
2242
+ layer.visualizer.mouseIntensity = mouseIntensity;
2243
+ }
2244
+ });
2245
+ });
2246
+
2247
+ // Audio reactivity (double-click to enable)
2248
+ let audioEnabled = false;
2249
+ let audioContext = null;
2250
+ let analyser = null;
2251
+ let frequencyData = null;
2252
+
2253
+ canvas.addEventListener('dblclick', async () => {
2254
+ if (!audioEnabled) {
2255
+ try {
2256
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
2257
+ analyser = audioContext.createAnalyser();
2258
+ analyser.fftSize = 256;
2259
+ frequencyData = new Uint8Array(analyser.frequencyBinCount);
2260
+
2261
+ const stream = await navigator.mediaDevices.getUserMedia({
2262
+ audio: { echoCancellation: false, noiseSuppression: false }
2263
+ });
2264
+
2265
+ const source = audioContext.createMediaStreamSource(stream);
2266
+ source.connect(analyser);
2267
+ audioEnabled = true;
2268
+
2269
+ console.log('🎵 Trading card audio reactivity ENABLED');
2270
+ canvas.style.border = '2px solid #00ff00';
2271
+ setTimeout(() => { canvas.style.border = ''; }, 2000);
2272
+ } catch (error) {
2273
+ console.error('Audio failed:', error);
2274
+ }
2275
+ }
2276
+ });`;
2277
+ }
2278
+
2279
+ /**
2280
+ * Generate LIVE Polychora system (placeholder for now)
2281
+ */
2282
+ generateLivePolychoraSystem(state) {
2283
+ // For now, use faceted system as base - will be enhanced later
2284
+ return this.generateLiveFacetedSystem(state);
2285
+ }
2286
+
2287
+ /**
2288
+ * Generate WebGL code for Faceted system with EXACT shader from Visualizer.js
2289
+ */
2290
+ generateFacetedVisualizationCode(state) {
2291
+ return `
2292
+ // VIB34D Faceted System Trading Card - ${state.name}
2293
+ // EXACT SHADER CODE FROM src/core/Visualizer.js IntegratedHolographicVisualizer
2294
+ class TradingCardVisualizer {
2295
+ constructor(canvas) {
2296
+ this.canvas = canvas;
2297
+ this.gl = canvas.getContext('webgl');
2298
+ this.params = ${JSON.stringify(state.parameters)};
2299
+ this.startTime = Date.now();
2300
+
2301
+ if (!this.gl) {
2302
+ console.error('WebGL not supported');
2303
+ return;
2304
+ }
2305
+
2306
+ this.initShaders();
2307
+ this.initBuffers();
2308
+ this.resize();
2309
+ this.animate();
2310
+ }
2311
+
2312
+ resize() {
2313
+ this.canvas.width = this.canvas.clientWidth;
2314
+ this.canvas.height = this.canvas.clientHeight;
2315
+ this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
2316
+ }
2317
+
2318
+ initShaders() {
2319
+ const vertexShaderSource = \`attribute vec2 a_position;
2320
+ void main() {
2321
+ gl_Position = vec4(a_position, 0.0, 1.0);
2322
+ }\`;
2323
+
2324
+ // EXACT FRAGMENT SHADER FROM FACETED SYSTEM
2325
+ const fragmentShaderSource = \`precision highp float;
2326
+ uniform vec2 u_resolution;
2327
+ uniform float u_time;
2328
+ uniform vec2 u_mouse;
2329
+ uniform float u_geometry;
2330
+ uniform float u_gridDensity;
2331
+ uniform float u_morphFactor;
2332
+ uniform float u_chaos;
2333
+ uniform float u_speed;
2334
+ uniform float u_hue;
2335
+ uniform float u_intensity;
2336
+ uniform float u_saturation;
2337
+ uniform float u_dimension;
2338
+ uniform float u_rot4dXW;
2339
+ uniform float u_rot4dYW;
2340
+ uniform float u_rot4dZW;
2341
+ uniform float u_mouseIntensity;
2342
+ uniform float u_clickIntensity;
2343
+ uniform float u_roleIntensity;
2344
+ // 4D rotation matrices
2345
+ mat4 rotateXW(float theta) {
2346
+ float c = cos(theta);
2347
+ float s = sin(theta);
2348
+ return mat4(c, 0.0, 0.0, -s, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, s, 0.0, 0.0, c);
2349
+ }
2350
+ mat4 rotateYW(float theta) {
2351
+ float c = cos(theta);
2352
+ float s = sin(theta);
2353
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, c, 0.0, -s, 0.0, 0.0, 1.0, 0.0, 0.0, s, 0.0, c);
2354
+ }
2355
+ mat4 rotateZW(float theta) {
2356
+ float c = cos(theta);
2357
+ float s = sin(theta);
2358
+ return mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, c, -s, 0.0, 0.0, s, c);
2359
+ }
2360
+ vec3 project4Dto3D(vec4 p) {
2361
+ float w = 2.5 / (2.5 + p.w);
2362
+ return vec3(p.x * w, p.y * w, p.z * w);
2363
+ }
2364
+ // Simplified geometry functions for WebGL 1.0 compatibility
2365
+ float geometryFunction(vec4 p) {
2366
+ int geomType = int(u_geometry);
2367
+
2368
+ if (geomType == 0) {
2369
+ // Tetrahedron lattice - UNIFORM GRID DENSITY
2370
+ vec4 pos = fract(p * u_gridDensity * 0.08);
2371
+ vec4 dist = min(pos, 1.0 - pos);
2372
+ return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u_morphFactor;
2373
+ }
2374
+ else if (geomType == 1) {
2375
+ // Hypercube lattice - UNIFORM GRID DENSITY
2376
+ vec4 pos = fract(p * u_gridDensity * 0.08);
2377
+ vec4 dist = min(pos, 1.0 - pos);
2378
+ float minDist = min(min(dist.x, dist.y), min(dist.z, dist.w));
2379
+ return minDist * u_morphFactor;
2380
+ }
2381
+ else if (geomType == 2) {
2382
+ // Sphere lattice - UNIFORM GRID DENSITY
2383
+ float r = length(p);
2384
+ float density = u_gridDensity * 0.08;
2385
+ float spheres = abs(fract(r * density) - 0.5) * 2.0;
2386
+ float theta = atan(p.y, p.x);
2387
+ float harmonics = sin(theta * 3.0) * 0.2;
2388
+ return (spheres + harmonics) * u_morphFactor;
2389
+ }
2390
+ else if (geomType == 3) {
2391
+ // Torus lattice - UNIFORM GRID DENSITY
2392
+ float r1 = length(p.xy) - 2.0;
2393
+ float torus = length(vec2(r1, p.z)) - 0.8;
2394
+ float lattice = sin(p.x * u_gridDensity * 0.08) * sin(p.y * u_gridDensity * 0.08);
2395
+ return (torus + lattice * 0.3) * u_morphFactor;
2396
+ }
2397
+ else if (geomType == 4) {
2398
+ // Klein bottle lattice - UNIFORM GRID DENSITY
2399
+ float u = atan(p.y, p.x);
2400
+ float v = atan(p.w, p.z);
2401
+ float dist = length(p) - 2.0;
2402
+ float lattice = sin(u * u_gridDensity * 0.08) * sin(v * u_gridDensity * 0.08);
2403
+ return (dist + lattice * 0.4) * u_morphFactor;
2404
+ }
2405
+ else if (geomType == 5) {
2406
+ // Fractal lattice - NOW WITH UNIFORM GRID DENSITY
2407
+ vec4 pos = fract(p * u_gridDensity * 0.08);
2408
+ pos = abs(pos * 2.0 - 1.0);
2409
+ float dist = length(max(abs(pos) - 1.0, 0.0));
2410
+ return dist * u_morphFactor;
2411
+ }
2412
+ else if (geomType == 6) {
2413
+ // Wave lattice - UNIFORM GRID DENSITY
2414
+ float freq = u_gridDensity * 0.08;
2415
+ float time = u_time * 0.001 * u_speed;
2416
+ float wave1 = sin(p.x * freq + time);
2417
+ float wave2 = sin(p.y * freq + time * 1.3);
2418
+ float wave3 = sin(p.z * freq * 0.8 + time * 0.7); // Add Z-dimension waves
2419
+ float interference = wave1 * wave2 * wave3;
2420
+ return interference * u_morphFactor;
2421
+ }
2422
+ else if (geomType == 7) {
2423
+ // Crystal lattice - UNIFORM GRID DENSITY
2424
+ vec4 pos = fract(p * u_gridDensity * 0.08) - 0.5;
2425
+ float cube = max(max(abs(pos.x), abs(pos.y)), max(abs(pos.z), abs(pos.w)));
2426
+ return cube * u_morphFactor;
2427
+ }
2428
+ else {
2429
+ // Default hypercube - UNIFORM GRID DENSITY
2430
+ vec4 pos = fract(p * u_gridDensity * 0.08);
2431
+ vec4 dist = min(pos, 1.0 - pos);
2432
+ return min(min(dist.x, dist.y), min(dist.z, dist.w)) * u_morphFactor;
2433
+ }
2434
+ }
2435
+ void main() {
2436
+ vec2 uv = (gl_FragCoord.xy - u_resolution.xy * 0.5) / min(u_resolution.x, u_resolution.y);
2437
+
2438
+ // 4D position with mouse interaction - NOW USING SPEED PARAMETER
2439
+ float timeSpeed = u_time * 0.0001 * u_speed;
2440
+ vec4 pos = vec4(uv * 3.0, sin(timeSpeed * 3.0), cos(timeSpeed * 2.0));
2441
+ pos.xy += (u_mouse - 0.5) * u_mouseIntensity * 2.0;
2442
+
2443
+ // Apply 4D rotations
2444
+ pos = rotateXW(u_rot4dXW) * pos;
2445
+ pos = rotateYW(u_rot4dYW) * pos;
2446
+ pos = rotateZW(u_rot4dZW) * pos;
2447
+
2448
+ // Calculate geometry value
2449
+ float value = geometryFunction(pos);
2450
+
2451
+ // Apply chaos
2452
+ float noise = sin(pos.x * 7.0) * cos(pos.y * 11.0) * sin(pos.z * 13.0);
2453
+ value += noise * u_chaos;
2454
+
2455
+ // Color based on geometry value and hue with user-controlled intensity/saturation
2456
+ float geometryIntensity = 1.0 - clamp(abs(value), 0.0, 1.0);
2457
+ geometryIntensity += u_clickIntensity * 0.3;
2458
+
2459
+ // Apply user intensity control
2460
+ float finalIntensity = geometryIntensity * u_intensity;
2461
+
2462
+ float hue = u_hue / 360.0 + value * 0.1;
2463
+
2464
+ // Create color with saturation control
2465
+ vec3 baseColor = vec3(
2466
+ sin(hue * 6.28318 + 0.0) * 0.5 + 0.5,
2467
+ sin(hue * 6.28318 + 2.0943) * 0.5 + 0.5,
2468
+ sin(hue * 6.28318 + 4.1887) * 0.5 + 0.5
2469
+ );
2470
+
2471
+ // Apply saturation (mix with grayscale)
2472
+ float gray = (baseColor.r + baseColor.g + baseColor.b) / 3.0;
2473
+ vec3 color = mix(vec3(gray), baseColor, u_saturation) * finalIntensity;
2474
+
2475
+ gl_FragColor = vec4(color, finalIntensity * u_roleIntensity);
2476
+ }\`;
2477
+
2478
+ this.program = this.createProgram(vertexShaderSource, fragmentShaderSource);
2479
+ this.uniforms = {
2480
+ resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),
2481
+ time: this.gl.getUniformLocation(this.program, 'u_time'),
2482
+ mouse: this.gl.getUniformLocation(this.program, 'u_mouse'),
2483
+ geometry: this.gl.getUniformLocation(this.program, 'u_geometry'),
2484
+ gridDensity: this.gl.getUniformLocation(this.program, 'u_gridDensity'),
2485
+ morphFactor: this.gl.getUniformLocation(this.program, 'u_morphFactor'),
2486
+ chaos: this.gl.getUniformLocation(this.program, 'u_chaos'),
2487
+ speed: this.gl.getUniformLocation(this.program, 'u_speed'),
2488
+ hue: this.gl.getUniformLocation(this.program, 'u_hue'),
2489
+ intensity: this.gl.getUniformLocation(this.program, 'u_intensity'),
2490
+ saturation: this.gl.getUniformLocation(this.program, 'u_saturation'),
2491
+ dimension: this.gl.getUniformLocation(this.program, 'u_dimension'),
2492
+ rot4dXW: this.gl.getUniformLocation(this.program, 'u_rot4dXW'),
2493
+ rot4dYW: this.gl.getUniformLocation(this.program, 'u_rot4dYW'),
2494
+ rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW'),
2495
+ mouseIntensity: this.gl.getUniformLocation(this.program, 'u_mouseIntensity'),
2496
+ clickIntensity: this.gl.getUniformLocation(this.program, 'u_clickIntensity'),
2497
+ roleIntensity: this.gl.getUniformLocation(this.program, 'u_roleIntensity')
2498
+ };
2499
+ }
2500
+
2501
+ createProgram(vertexSource, fragmentSource) {
2502
+ const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexSource);
2503
+ const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentSource);
2504
+
2505
+ const program = this.gl.createProgram();
2506
+ this.gl.attachShader(program, vertexShader);
2507
+ this.gl.attachShader(program, fragmentShader);
2508
+ this.gl.linkProgram(program);
2509
+
2510
+ if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
2511
+ console.error('Program linking failed:', this.gl.getProgramInfoLog(program));
2512
+ return null;
2513
+ }
2514
+
2515
+ return program;
2516
+ }
2517
+
2518
+ createShader(type, source) {
2519
+ const shader = this.gl.createShader(type);
2520
+ this.gl.shaderSource(shader, source);
2521
+ this.gl.compileShader(shader);
2522
+
2523
+ if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
2524
+ console.error('Shader compilation failed:', this.gl.getShaderInfoLog(shader));
2525
+ return null;
2526
+ }
2527
+
2528
+ return shader;
2529
+ }
2530
+
2531
+ initBuffers() {
2532
+ const positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
2533
+
2534
+ this.buffer = this.gl.createBuffer();
2535
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
2536
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
2537
+
2538
+ const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
2539
+ this.gl.enableVertexAttribArray(positionLocation);
2540
+ this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
2541
+ }
2542
+
2543
+ animate() {
2544
+ this.render();
2545
+ requestAnimationFrame(() => this.animate());
2546
+ }
2547
+
2548
+ render() {
2549
+ if (!this.program) return;
2550
+
2551
+ this.resize();
2552
+ this.gl.useProgram(this.program);
2553
+
2554
+ const time = Date.now() - this.startTime;
2555
+
2556
+ this.gl.uniform2f(this.uniforms.resolution, this.canvas.width, this.canvas.height);
2557
+ this.gl.uniform1f(this.uniforms.time, time);
2558
+ this.gl.uniform2f(this.uniforms.mouse, 0.5, 0.5);
2559
+ this.gl.uniform1f(this.uniforms.geometry, this.params.geometry || 0);
2560
+ this.gl.uniform1f(this.uniforms.gridDensity, this.params.gridDensity || 15);
2561
+ this.gl.uniform1f(this.uniforms.morphFactor, this.params.morphFactor || 1.0);
2562
+ this.gl.uniform1f(this.uniforms.chaos, this.params.chaos || 0.2);
2563
+ this.gl.uniform1f(this.uniforms.speed, this.params.speed || 1.0);
2564
+ this.gl.uniform1f(this.uniforms.hue, this.params.hue || 200);
2565
+ this.gl.uniform1f(this.uniforms.intensity, this.params.intensity || 0.5);
2566
+ this.gl.uniform1f(this.uniforms.saturation, this.params.saturation || 0.8);
2567
+ this.gl.uniform1f(this.uniforms.dimension, this.params.dimension || 3.8);
2568
+ this.gl.uniform1f(this.uniforms.rot4dXW, this.params.rot4dXW || 0.0);
2569
+ this.gl.uniform1f(this.uniforms.rot4dYW, this.params.rot4dYW || 0.0);
2570
+ this.gl.uniform1f(this.uniforms.rot4dZW, this.params.rot4dZW || 0.0);
2571
+ this.gl.uniform1f(this.uniforms.mouseIntensity, 0.0);
2572
+ this.gl.uniform1f(this.uniforms.clickIntensity, 0.0);
2573
+ this.gl.uniform1f(this.uniforms.roleIntensity, 1.0);
2574
+
2575
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
2576
+ }
2577
+ }`;
2578
+ }
2579
+
2580
+ /**
2581
+ * Generate WebGL code for Holographic system with EXACT shader from HolographicVisualizer.js
2582
+ */
2583
+ generateHolographicVisualizationCode(state) {
2584
+ return `
2585
+ // VIB34D Holographic System Trading Card - ${state.name}
2586
+ // EXACT SHADER CODE FROM src/holograms/HolographicVisualizer.js
2587
+ class TradingCardVisualizer {
2588
+ constructor(canvas) {
2589
+ this.canvas = canvas;
2590
+ this.gl = canvas.getContext('webgl');
2591
+ this.params = ${JSON.stringify(state.parameters)};
2592
+ this.startTime = Date.now();
2593
+
2594
+ if (!this.gl) {
2595
+ console.error('WebGL not supported');
2596
+ return;
2597
+ }
2598
+
2599
+ this.initHolographicShaders();
2600
+ this.initBuffers();
2601
+ this.resize();
2602
+ this.animate();
2603
+ }
2604
+
2605
+ initHolographicShaders() {
2606
+ const vertexShaderSource = \`
2607
+ attribute vec2 a_position;
2608
+ void main() {
2609
+ gl_Position = vec4(a_position, 0.0, 1.0);
2610
+ }
2611
+ \`;
2612
+
2613
+ // EXACT FRAGMENT SHADER FROM HOLOGRAPHIC SYSTEM
2614
+ const fragmentShaderSource = \`
2615
+ precision highp float;
2616
+
2617
+ uniform vec2 u_resolution;
2618
+ uniform float u_time;
2619
+ uniform vec2 u_mouse;
2620
+ uniform float u_geometry;
2621
+ uniform float u_density;
2622
+ uniform float u_speed;
2623
+ uniform vec3 u_color;
2624
+ uniform float u_intensity;
2625
+ uniform float u_roleDensity;
2626
+ uniform float u_roleSpeed;
2627
+ uniform float u_colorShift;
2628
+ uniform float u_chaosIntensity;
2629
+ uniform float u_mouseIntensity;
2630
+ uniform float u_clickIntensity;
2631
+ uniform float u_densityVariation;
2632
+ uniform float u_geometryType;
2633
+ uniform float u_chaos;
2634
+ uniform float u_morph;
2635
+ uniform float u_touchMorph;
2636
+ uniform float u_touchChaos;
2637
+ uniform float u_scrollParallax;
2638
+ uniform float u_gridDensityShift;
2639
+ uniform float u_colorScrollShift;
2640
+ uniform float u_audioDensityBoost;
2641
+ uniform float u_audioMorphBoost;
2642
+ uniform float u_audioSpeedBoost;
2643
+ uniform float u_audioChaosBoost;
2644
+ uniform float u_audioColorShift;
2645
+ uniform float u_rot4dXW;
2646
+ uniform float u_rot4dYW;
2647
+ uniform float u_rot4dZW;
2648
+
2649
+ // 4D rotation matrices
2650
+ mat4 rotateXW(float theta) {
2651
+ float c = cos(theta);
2652
+ float s = sin(theta);
2653
+ return mat4(c, 0, 0, -s, 0, 1, 0, 0, 0, 0, 1, 0, s, 0, 0, c);
2654
+ }
2655
+
2656
+ mat4 rotateYW(float theta) {
2657
+ float c = cos(theta);
2658
+ float s = sin(theta);
2659
+ return mat4(1, 0, 0, 0, 0, c, 0, -s, 0, 0, 1, 0, 0, s, 0, c);
2660
+ }
2661
+
2662
+ mat4 rotateZW(float theta) {
2663
+ float c = cos(theta);
2664
+ float s = sin(theta);
2665
+ return mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, c, -s, 0, 0, s, c);
2666
+ }
2667
+
2668
+ // 4D to 3D projection
2669
+ vec3 project4Dto3D(vec4 p) {
2670
+ float w = 2.5 / (2.5 + p.w);
2671
+ return vec3(p.x * w, p.y * w, p.z * w);
2672
+ }
2673
+
2674
+ // VIB3 Geometry Library
2675
+ float tetrahedronLattice(vec3 p, float gridSize) {
2676
+ vec3 q = fract(p * gridSize) - 0.5;
2677
+ float d1 = length(q);
2678
+ float d2 = length(q - vec3(0.4, 0.0, 0.0));
2679
+ float d3 = length(q - vec3(0.0, 0.4, 0.0));
2680
+ float d4 = length(q - vec3(0.0, 0.0, 0.4));
2681
+ float vertices = 1.0 - smoothstep(0.0, 0.04, min(min(d1, d2), min(d3, d4)));
2682
+ float edges = 0.0;
2683
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.xy) - 0.2)));
2684
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.yz) - 0.2)));
2685
+ edges = max(edges, 1.0 - smoothstep(0.0, 0.02, abs(length(q.xz) - 0.2)));
2686
+ return max(vertices, edges * 0.5);
2687
+ }
2688
+
2689
+ float hypercubeLattice(vec3 p, float gridSize) {
2690
+ vec3 grid = fract(p * gridSize);
2691
+ vec3 edges = 1.0 - smoothstep(0.0, 0.03, abs(grid - 0.5));
2692
+ return max(max(edges.x, edges.y), edges.z);
2693
+ }
2694
+
2695
+ float sphereLattice(vec3 p, float gridSize) {
2696
+ vec3 q = fract(p * gridSize) - 0.5;
2697
+ float r = length(q);
2698
+ return 1.0 - smoothstep(0.2, 0.5, r);
2699
+ }
2700
+
2701
+ float torusLattice(vec3 p, float gridSize) {
2702
+ vec3 q = fract(p * gridSize) - 0.5;
2703
+ float r1 = sqrt(q.x*q.x + q.y*q.y);
2704
+ float r2 = sqrt((r1 - 0.3)*(r1 - 0.3) + q.z*q.z);
2705
+ return 1.0 - smoothstep(0.0, 0.1, r2);
2706
+ }
2707
+
2708
+ float kleinLattice(vec3 p, float gridSize) {
2709
+ vec3 q = fract(p * gridSize);
2710
+ float u = q.x * 2.0 * 3.14159;
2711
+ float v = q.y * 2.0 * 3.14159;
2712
+ float x = cos(u) * (3.0 + cos(u/2.0) * sin(v) - sin(u/2.0) * sin(2.0*v));
2713
+ float klein = length(vec2(x, q.z)) - 0.1;
2714
+ return 1.0 - smoothstep(0.0, 0.05, abs(klein));
2715
+ }
2716
+
2717
+ float fractalLattice(vec3 p, float gridSize) {
2718
+ vec3 q = p * gridSize;
2719
+ float scale = 1.0;
2720
+ float fractal = 0.0;
2721
+ for(int i = 0; i < 4; i++) {
2722
+ q = fract(q) - 0.5;
2723
+ fractal += abs(length(q)) / scale;
2724
+ scale *= 2.0;
2725
+ q *= 2.0;
2726
+ }
2727
+ return 1.0 - smoothstep(0.0, 1.0, fractal);
2728
+ }
2729
+
2730
+ float waveLattice(vec3 p, float gridSize) {
2731
+ vec3 q = p * gridSize;
2732
+ float wave = sin(q.x * 2.0) * sin(q.y * 2.0) * sin(q.z * 2.0 + u_time);
2733
+ return smoothstep(-0.5, 0.5, wave);
2734
+ }
2735
+
2736
+ float crystalLattice(vec3 p, float gridSize) {
2737
+ vec3 q = fract(p * gridSize) - 0.5;
2738
+ float d = max(max(abs(q.x), abs(q.y)), abs(q.z));
2739
+ return 1.0 - smoothstep(0.3, 0.5, d);
2740
+ }
2741
+
2742
+ float getDynamicGeometry(vec3 p, float gridSize, float geometryType) {
2743
+ int baseGeom = int(mod(geometryType, 8.0));
2744
+ float variation = floor(geometryType / 8.0) / 4.0;
2745
+ float variedGridSize = gridSize * (0.5 + variation * 1.5);
2746
+
2747
+ if (baseGeom == 0) return tetrahedronLattice(p, variedGridSize);
2748
+ else if (baseGeom == 1) return hypercubeLattice(p, variedGridSize);
2749
+ else if (baseGeom == 2) return sphereLattice(p, variedGridSize);
2750
+ else if (baseGeom == 3) return torusLattice(p, variedGridSize);
2751
+ else if (baseGeom == 4) return kleinLattice(p, variedGridSize);
2752
+ else if (baseGeom == 5) return fractalLattice(p, variedGridSize);
2753
+ else if (baseGeom == 6) return waveLattice(p, variedGridSize);
2754
+ else return crystalLattice(p, variedGridSize);
2755
+ }
2756
+
2757
+ vec3 hsv2rgb(vec3 c) {
2758
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
2759
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
2760
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
2761
+ }
2762
+
2763
+ vec3 rgbGlitch(vec3 color, vec2 uv, float intensity) {
2764
+ vec2 offset = vec2(intensity * 0.005, 0.0);
2765
+ float r = color.r + sin(uv.y * 30.0 + u_time * 0.001) * intensity * 0.06;
2766
+ float g = color.g + sin(uv.y * 28.0 + u_time * 0.0012) * intensity * 0.06;
2767
+ float b = color.b + sin(uv.y * 32.0 + u_time * 0.0008) * intensity * 0.06;
2768
+ return vec3(r, g, b);
2769
+ }
2770
+
2771
+ float moirePattern(vec2 uv, float intensity) {
2772
+ float freq1 = 12.0 + intensity * 6.0 + u_densityVariation * 3.0;
2773
+ float freq2 = 14.0 + intensity * 8.0 + u_densityVariation * 4.0;
2774
+ float pattern1 = sin(uv.x * freq1) * sin(uv.y * freq1);
2775
+ float pattern2 = sin(uv.x * freq2) * sin(uv.y * freq2);
2776
+ return (pattern1 * pattern2) * intensity * 0.15;
2777
+ }
2778
+
2779
+ float gridOverlay(vec2 uv, float intensity) {
2780
+ vec2 grid = fract(uv * (8.0 + u_densityVariation * 4.0));
2781
+ float lines = 0.0;
2782
+ lines = max(lines, 1.0 - smoothstep(0.0, 0.02, abs(grid.x - 0.5)));
2783
+ lines = max(lines, 1.0 - smoothstep(0.0, 0.02, abs(grid.y - 0.5)));
2784
+ return lines * intensity * 0.1;
2785
+ }
2786
+
2787
+ void main() {
2788
+ vec2 uv = gl_FragCoord.xy / u_resolution.xy;
2789
+ float aspectRatio = u_resolution.x / u_resolution.y;
2790
+ uv.x *= aspectRatio;
2791
+ uv -= 0.5;
2792
+
2793
+ float time = u_time * 0.0004 * u_speed * u_roleSpeed;
2794
+
2795
+ float mouseInfluence = u_mouseIntensity * 0.5;
2796
+ vec2 mouseOffset = (u_mouse - 0.5) * mouseInfluence;
2797
+
2798
+ float parallaxOffset = u_scrollParallax * 0.2;
2799
+ vec2 scrollOffset = vec2(parallaxOffset * 0.1, parallaxOffset * 0.05);
2800
+
2801
+ float morphOffset = u_touchMorph * 0.3;
2802
+
2803
+ vec4 p4d = vec4(uv + mouseOffset * 0.1 + scrollOffset,
2804
+ sin(time * 0.1 + morphOffset) * 0.15,
2805
+ cos(time * 0.08 + morphOffset * 0.5) * 0.15);
2806
+
2807
+ float scrollRotation = u_scrollParallax * 0.1;
2808
+ float touchRotation = u_touchMorph * 0.2;
2809
+
2810
+ // Combine manual rotation with automatic/interactive rotation
2811
+ p4d = rotateXW(u_rot4dXW + time * 0.2 + mouseOffset.y * 0.5 + scrollRotation) * p4d;
2812
+ p4d = rotateYW(u_rot4dYW + time * 0.15 + mouseOffset.x * 0.5 + touchRotation) * p4d;
2813
+ p4d = rotateZW(u_rot4dZW + time * 0.25 + u_clickIntensity * 0.3 + u_touchChaos * 0.4) * p4d;
2814
+
2815
+ vec3 p = project4Dto3D(p4d);
2816
+
2817
+ float scrollDensityMod = 1.0 + u_gridDensityShift * 0.3;
2818
+ float audioDensityMod = 1.0 + u_audioDensityBoost * 0.5;
2819
+ float roleDensity = ((u_density + u_densityVariation) * u_roleDensity) * scrollDensityMod * audioDensityMod;
2820
+
2821
+ float morphedGeometry = u_geometryType + u_morph * 3.0 + u_touchMorph * 2.0 + u_audioMorphBoost * 1.5;
2822
+ float lattice = getDynamicGeometry(p, roleDensity, morphedGeometry);
2823
+
2824
+ // Use the passed RGB as base color and modulate with lattice patterns
2825
+ vec3 baseColor = u_color;
2826
+ float latticeIntensity = lattice * u_intensity;
2827
+
2828
+ vec3 color = baseColor * (0.3 + latticeIntensity * 0.7);
2829
+
2830
+ // Add lattice-based brightness variations
2831
+ color += vec3(lattice * 0.4) * baseColor;
2832
+
2833
+ float enhancedChaos = u_chaos + u_chaosIntensity + u_touchChaos * 0.3 + u_audioChaosBoost * 0.4;
2834
+ color += vec3(moirePattern(uv + scrollOffset, enhancedChaos));
2835
+ color += vec3(gridOverlay(uv, u_mouseIntensity + u_scrollParallax * 0.1));
2836
+ color = rgbGlitch(color, uv, enhancedChaos);
2837
+
2838
+ // Apply morph distortion to position
2839
+ vec2 morphDistortion = vec2(sin(uv.y * 10.0 + u_time * 0.001) * u_morph * 0.1,
2840
+ cos(uv.x * 10.0 + u_time * 0.001) * u_morph * 0.1);
2841
+ color = mix(color, color * (1.0 + length(morphDistortion)), u_morph * 0.5);
2842
+
2843
+ float mouseDist = length(uv - (u_mouse - 0.5) * vec2(aspectRatio, 1.0));
2844
+ float mouseGlow = exp(-mouseDist * 1.5) * u_mouseIntensity * 0.2;
2845
+ color += vec3(mouseGlow) * baseColor * 0.6;
2846
+
2847
+ float clickPulse = u_clickIntensity * exp(-mouseDist * 2.0) * 0.3;
2848
+ color += vec3(clickPulse, clickPulse * 0.5, clickPulse * 1.5);
2849
+
2850
+ gl_FragColor = vec4(color, 0.95);
2851
+ }
2852
+ \`;
2853
+
2854
+ this.program = this.createProgram(vertexShaderSource, fragmentShaderSource);
2855
+ this.uniforms = {
2856
+ resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),
2857
+ time: this.gl.getUniformLocation(this.program, 'u_time'),
2858
+ mouse: this.gl.getUniformLocation(this.program, 'u_mouse'),
2859
+ geometry: this.gl.getUniformLocation(this.program, 'u_geometry'),
2860
+ density: this.gl.getUniformLocation(this.program, 'u_density'),
2861
+ speed: this.gl.getUniformLocation(this.program, 'u_speed'),
2862
+ color: this.gl.getUniformLocation(this.program, 'u_color'),
2863
+ intensity: this.gl.getUniformLocation(this.program, 'u_intensity'),
2864
+ roleDensity: this.gl.getUniformLocation(this.program, 'u_roleDensity'),
2865
+ roleSpeed: this.gl.getUniformLocation(this.program, 'u_roleSpeed'),
2866
+ colorShift: this.gl.getUniformLocation(this.program, 'u_colorShift'),
2867
+ chaosIntensity: this.gl.getUniformLocation(this.program, 'u_chaosIntensity'),
2868
+ mouseIntensity: this.gl.getUniformLocation(this.program, 'u_mouseIntensity'),
2869
+ clickIntensity: this.gl.getUniformLocation(this.program, 'u_clickIntensity'),
2870
+ densityVariation: this.gl.getUniformLocation(this.program, 'u_densityVariation'),
2871
+ geometryType: this.gl.getUniformLocation(this.program, 'u_geometryType'),
2872
+ chaos: this.gl.getUniformLocation(this.program, 'u_chaos'),
2873
+ morph: this.gl.getUniformLocation(this.program, 'u_morph'),
2874
+ touchMorph: this.gl.getUniformLocation(this.program, 'u_touchMorph'),
2875
+ touchChaos: this.gl.getUniformLocation(this.program, 'u_touchChaos'),
2876
+ scrollParallax: this.gl.getUniformLocation(this.program, 'u_scrollParallax'),
2877
+ gridDensityShift: this.gl.getUniformLocation(this.program, 'u_gridDensityShift'),
2878
+ colorScrollShift: this.gl.getUniformLocation(this.program, 'u_colorScrollShift'),
2879
+ audioDensityBoost: this.gl.getUniformLocation(this.program, 'u_audioDensityBoost'),
2880
+ audioMorphBoost: this.gl.getUniformLocation(this.program, 'u_audioMorphBoost'),
2881
+ audioSpeedBoost: this.gl.getUniformLocation(this.program, 'u_audioSpeedBoost'),
2882
+ audioChaosBoost: this.gl.getUniformLocation(this.program, 'u_audioChaosBoost'),
2883
+ audioColorShift: this.gl.getUniformLocation(this.program, 'u_audioColorShift'),
2884
+ rot4dXW: this.gl.getUniformLocation(this.program, 'u_rot4dXW'),
2885
+ rot4dYW: this.gl.getUniformLocation(this.program, 'u_rot4dYW'),
2886
+ rot4dZW: this.gl.getUniformLocation(this.program, 'u_rot4dZW')
2887
+ };
2888
+ }
2889
+
2890
+ createProgram(vertexSource, fragmentSource) {
2891
+ const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexSource);
2892
+ const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentSource);
2893
+
2894
+ const program = this.gl.createProgram();
2895
+ this.gl.attachShader(program, vertexShader);
2896
+ this.gl.attachShader(program, fragmentShader);
2897
+ this.gl.linkProgram(program);
2898
+
2899
+ if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
2900
+ console.error('Program linking failed:', this.gl.getProgramInfoLog(program));
2901
+ return null;
2902
+ }
2903
+
2904
+ return program;
2905
+ }
2906
+
2907
+ createShader(type, source) {
2908
+ const shader = this.gl.createShader(type);
2909
+ this.gl.shaderSource(shader, source);
2910
+ this.gl.compileShader(shader);
2911
+
2912
+ if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
2913
+ console.error('Shader compilation failed:', this.gl.getShaderInfoLog(shader));
2914
+ return null;
2915
+ }
2916
+
2917
+ return shader;
2918
+ }
2919
+
2920
+ initBuffers() {
2921
+ const positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
2922
+
2923
+ this.buffer = this.gl.createBuffer();
2924
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
2925
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
2926
+
2927
+ const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
2928
+ this.gl.enableVertexAttribArray(positionLocation);
2929
+ this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
2930
+ }
2931
+
2932
+ resize() {
2933
+ this.canvas.width = this.canvas.clientWidth;
2934
+ this.canvas.height = this.canvas.clientHeight;
2935
+ this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
2936
+ }
2937
+
2938
+ animate() {
2939
+ this.render();
2940
+ requestAnimationFrame(() => this.animate());
2941
+ }
2942
+
2943
+ render() {
2944
+ if (!this.program) return;
2945
+
2946
+ this.resize();
2947
+ this.gl.useProgram(this.program);
2948
+
2949
+ const time = Date.now() - this.startTime;
2950
+ const hue = (this.params.hue || 200) / 360;
2951
+
2952
+ // Convert hue to RGB
2953
+ const hslToRgb = (h, s, l) => {
2954
+ let r, g, b;
2955
+ if (s === 0) {
2956
+ r = g = b = l;
2957
+ } else {
2958
+ const hue2rgb = (p, q, t) => {
2959
+ if (t < 0) t += 1;
2960
+ if (t > 1) t -= 1;
2961
+ if (t < 1/6) return p + (q - p) * 6 * t;
2962
+ if (t < 1/2) return q;
2963
+ if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
2964
+ return p;
2965
+ };
2966
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
2967
+ const p = 2 * l - q;
2968
+ r = hue2rgb(p, q, h + 1/3);
2969
+ g = hue2rgb(p, q, h);
2970
+ b = hue2rgb(p, q, h - 1/3);
2971
+ }
2972
+ return [r, g, b];
2973
+ };
2974
+
2975
+ const rgbColor = hslToRgb(hue, this.params.saturation || 0.8, this.params.intensity || 0.5);
2976
+
2977
+ this.gl.uniform2f(this.uniforms.resolution, this.canvas.width, this.canvas.height);
2978
+ this.gl.uniform1f(this.uniforms.time, time);
2979
+ this.gl.uniform2f(this.uniforms.mouse, 0.5, 0.5);
2980
+ this.gl.uniform1f(this.uniforms.geometryType, this.params.geometryType || 0);
2981
+ this.gl.uniform1f(this.uniforms.density, this.params.density || 1.0);
2982
+ this.gl.uniform1f(this.uniforms.speed, this.params.speed || 0.5);
2983
+ this.gl.uniform3fv(this.uniforms.color, new Float32Array(rgbColor));
2984
+ this.gl.uniform1f(this.uniforms.intensity, this.params.intensity || 0.5);
2985
+ this.gl.uniform1f(this.uniforms.roleDensity, 1.0);
2986
+ this.gl.uniform1f(this.uniforms.roleSpeed, 1.0);
2987
+ this.gl.uniform1f(this.uniforms.colorShift, 0.0);
2988
+ this.gl.uniform1f(this.uniforms.chaosIntensity, this.params.chaos || 0.0);
2989
+ this.gl.uniform1f(this.uniforms.mouseIntensity, 0.0);
2990
+ this.gl.uniform1f(this.uniforms.clickIntensity, 0.0);
2991
+ this.gl.uniform1f(this.uniforms.densityVariation, 0.0);
2992
+ this.gl.uniform1f(this.uniforms.chaos, this.params.chaos || 0.0);
2993
+ this.gl.uniform1f(this.uniforms.morph, this.params.morph || 0.0);
2994
+ this.gl.uniform1f(this.uniforms.touchMorph, 0.0);
2995
+ this.gl.uniform1f(this.uniforms.touchChaos, 0.0);
2996
+ this.gl.uniform1f(this.uniforms.scrollParallax, 0.0);
2997
+ this.gl.uniform1f(this.uniforms.gridDensityShift, 0.0);
2998
+ this.gl.uniform1f(this.uniforms.colorScrollShift, 0.0);
2999
+ this.gl.uniform1f(this.uniforms.audioDensityBoost, 0.0);
3000
+ this.gl.uniform1f(this.uniforms.audioMorphBoost, 0.0);
3001
+ this.gl.uniform1f(this.uniforms.audioSpeedBoost, 0.0);
3002
+ this.gl.uniform1f(this.uniforms.audioChaosBoost, 0.0);
3003
+ this.gl.uniform1f(this.uniforms.audioColorShift, 0.0);
3004
+ this.gl.uniform1f(this.uniforms.rot4dXW, this.params.rot4dXW || 0.0);
3005
+ this.gl.uniform1f(this.uniforms.rot4dYW, this.params.rot4dYW || 0.0);
3006
+ this.gl.uniform1f(this.uniforms.rot4dZW, this.params.rot4dZW || 0.0);
3007
+
3008
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
3009
+ }
3010
+ }`;
3011
+ }
3012
+
3013
+ /**
3014
+ * Generate fallback visualization code
3015
+ */
3016
+ generateFallbackVisualizationCode(state) {
3017
+ return `
3018
+ // VIB34D Trading Card - Fallback Canvas Renderer
3019
+ class TradingCardVisualizer {
3020
+ constructor(canvas) {
3021
+ console.log('🎴 Trading card using fallback 2D renderer');
3022
+ // Simple 2D fallback if WebGL fails
3023
+ this.canvas = canvas;
3024
+ this.ctx = canvas.getContext('2d');
3025
+ this.animate();
3026
+ }
3027
+
3028
+ animate() {
3029
+ if (this.ctx) {
3030
+ this.ctx.fillStyle = '#000';
3031
+ this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
3032
+ this.ctx.fillStyle = '#00ffff';
3033
+ this.ctx.font = '20px Orbitron';
3034
+ this.ctx.textAlign = 'center';
3035
+ this.ctx.fillText('VIB34D', this.canvas.width/2, this.canvas.height/2);
3036
+ }
3037
+ requestAnimationFrame(() => this.animate());
3038
+ }
3039
+ }`;
3040
+ }
3041
+
3042
+ /**
3043
+ * Generate simple image display code for captured canvas
3044
+ */
3045
+ generateImageVisualization(imageData) {
3046
+ return `
3047
+ // VIB34D Trading Card - Captured Visualization
3048
+ // This card contains the exact visual state from when it was created
3049
+ console.log('🎴 Trading card using captured visualization');
3050
+
3051
+ // The visualization is embedded as an image
3052
+ // Original state preserved perfectly
3053
+ `;
3054
+ }
3055
+ }