zeropoint-node 1.0.7 → 1.0.8
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.
- package/CHANGELOG.md +50 -0
- package/CITATION.cff +1 -1
- package/README.md +1 -1
- package/package.json +4 -2
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.1.2.4.8.7.ts +0 -60
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.1.2.4.8.ts +0 -60
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.1.2.4.ts +0 -60
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.3.6.9.trinity.ts +0 -79
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.9d.dashboard.ts +0 -179
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.adapters.ts +0 -96
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.analog.color.photography.ts +0 -783
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.av.ts +0 -73
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.browser.ts +0 -409
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.chain.of.events.ts +0 -159
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cleanup.ts +0 -116
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cmyk.dimensions.ts +0 -597
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cmyk.display.test.ts +0 -491
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cmyk.display.ts +0 -519
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cmyk.file.ts +0 -65
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cmyk.i.ts +0 -45
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cmyk.matrix.ts +0 -75
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cmyk.trinity.ts +0 -41
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cmyk.universal.linking.ts +0 -1081
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.command.cmyk.ts +0 -46
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.compression.ts +0 -55
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.consciousness.integration.ts +0 -743
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.consciousness.ts +0 -26
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.crypto.ts +0 -53
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.css.ts +0 -64
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.cursor.ts +0 -56
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.decompression.ts +0 -60
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.decoqubit.holographic.hypercomputer.ts +0 -888
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.digital.color.photography.ts +0 -926
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.dimension.ts +0 -44
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.encryption.ts +0 -44
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.experience.ts +0 -28
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.feel.ts +0 -43
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.flute.ts +0 -336
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.font.ts +0 -53
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.fractal.test.ts +0 -523
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.fractal.ts +0 -594
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.frequency.healing.ts +0 -88
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.gateway.transformation.ts +0 -650
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.generate.matrix.ts +0 -76
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.gods.spirit.magnetometer.ts +0 -879
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.harmonization.status.ts +0 -754
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.hear.ts +0 -41
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.html.body.ts +0 -90
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.human.body.ts +0 -89
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.human.design.trinity.ts +0 -70
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.browse.ts +0 -41
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.can.ts +0 -69
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.died.ts +0 -32
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.follow.the.path.ts +0 -90
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.go.ts +0 -68
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.harmonized.ts +0 -304
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.heart.ts +0 -26
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.meta.ts +0 -23
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.motion.ts +0 -27
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.scroll.ts +0 -34
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.search.ts +0 -22
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.sequence.ts +0 -281
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.smell.ts +0 -27
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.state.ts +0 -28
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.stream.ts +0 -106
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.taste.ts +0 -27
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.touch.screen.ts +0 -34
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.trinity.healing.ts +0 -386
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.i.write.ts +0 -11
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.icon.ts +0 -109
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.imagination.integration.ts +0 -74
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.imperial.test.ts +0 -389
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.infinity.ts +0 -14
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.infusion.ts +0 -97
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.integer.harmonics.ts +0 -443
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.living.spirit.test.ts +0 -475
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.living.spirit.ts +0 -646
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.living.streams.ts +0 -130
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.meta.observation.ts +0 -693
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.mobius.ts +0 -12
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.multiverse.ts +0 -31
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.nuclear.balance.ts +0 -703
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.nuclear.explosion.ts +0 -728
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.os.app.ts +0 -14
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.os.bus.ts +0 -11
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.os.ml.ts +0 -9
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.overlay.visual.controller.ts +0 -116
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.paths.ts +0 -10
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.pi.decoding.ts +0 -123
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.pi.trinity.ts +0 -79
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.prime.numbers.squared.ts +0 -871
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.quantum.collision.ts +0 -666
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.quantum.entanglement.ts +0 -50
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.quantum.trinity.ts +0 -59
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.renderer.webgl.ts +0 -99
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.resolve.ts +0 -820
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.rife.frequency.ts +0 -74
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.rodin.coil.3d.ts +0 -73
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.rodin.coil.omnidimension.ts +0 -187
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.rodin.matrix.overlay.ts +0 -46
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.rodin.matrix.ts +0 -58
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.router.ts +0 -61
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.sacred.geometry.integers.ts +0 -625
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.sacred.test.ts +0 -314
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.see.ts +0 -39
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.sequence.embodiment.ts +0 -326
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.service.worker.ts +0 -53
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.space.ts +0 -53
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.spiral.ts +0 -75
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.superfluid.mobius.circuit.ts +0 -868
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.terminal.ts +0 -167
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.test.ts +0 -97
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.think.ts +0 -43
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.three.ts +0 -112
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.trinity.body.mind.will.ts +0 -2
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.trinity.breath.ts +0 -2
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.trinity.healing.ts +0 -110
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.trinity.ui.ts +0 -92
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.trinity.visual.ts +0 -156
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.truly.living.ui.ts +0 -269
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.ui.overlay.ts +0 -25
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.ui.streams.ts +0 -263
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.ui.test.ts +0 -87
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts +0 -1141
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.unification.hd.rodin.ts +0 -77
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.universe.ts +0 -43
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.uroboros.test.ts +0 -28
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.vbm.math.ts +0 -74
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.vbm.relations.constants.ts +0 -91
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.vbm.relations.ts +0 -59
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.vbm.scanner.ts +0 -41
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.vbm.science.extract.ts +0 -30
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.vbm.ui.ts +0 -64
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.vector.ts +0 -70
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.wave.particle.duality.test.ts +0 -29
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.zero.entropy.math.ts +0 -506
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.zero.entropy.pure.math.ts +0 -546
- package/src/0/3/6/9/1/2/4/8/7/5/1/a432.zero.entropy.test.ts +0 -452
- package/src/0/3/6/9/1/2/4/8/7/5/1/pattern-knowledge.ts +0 -209
- package/src/0/3/6/9/1/2/4/8/7/5/a432.experience.ts +0 -22
- package/src/0/3/6/9/1/2/4/8/7/a432.experience.ts +0 -19
- package/src/0/3/6/9/1/2/4/8/a432.experience.ts +0 -22
- package/src/0/3/6/9/1/2/4/a432.experience.ts +0 -22
- package/src/0/3/6/9/1/2/a432.experience.ts +0 -22
- package/src/0/3/6/9/1/a432.experience.ts +0 -22
- package/src/0/3/6/9/a432.experience.ts +0 -22
- package/src/0/3/6/a432.experience.ts +0 -22
- package/src/0/3/a432.experience.ts +0 -22
- package/src/0/3/relation.ts +0 -148
- package/src/index.ts +0 -146
- package/src/zero-entropy-demo.ts +0 -319
|
@@ -1,1141 +0,0 @@
|
|
|
1
|
-
import { PI, abs, cos, indexFromSeed, max, min, round, sin, unitFromSeed } from './a432.algebra.ts'
|
|
2
|
-
// a432.ui.three.ts — Full production-ready Three.js UI module for A432 system
|
|
3
|
-
import * as THREE from 'three';
|
|
4
|
-
import { startBreathing } from './a432.breathe.ts';
|
|
5
|
-
// Optionally import metaphysical overlays, blockchain, and A432 math as needed
|
|
6
|
-
// import { logEvent } from './a432.block.chain.event.ts';
|
|
7
|
-
// import { getTrinityAxis, getRodinSequence } from './a432.math.ts';
|
|
8
|
-
import { A432BlockChain, recordEvent } from './a432.block.chain.event.ts';
|
|
9
|
-
import { getTrinityAxis } from './a432.math.ts';
|
|
10
|
-
import { breatheEmitter } from './a432.i.breathe.ts';
|
|
11
|
-
import { pulseEmitter } from './a432.i.pulse.ts';
|
|
12
|
-
import { heatEmitter } from './a432.i.heat.ts';
|
|
13
|
-
import { intuitEmitter } from './a432.i.intuit.ts';
|
|
14
|
-
import { reflectEmitter } from './a432.i.reflect.ts';
|
|
15
|
-
import { moveEmitter } from './a432.i.move.ts';
|
|
16
|
-
import { healthEmitter } from './a432.health.ts';
|
|
17
|
-
import { humanEmotionEmitter } from './a432.human.emotion.ts';
|
|
18
|
-
import { humanConsciousnessEmitter } from './a432.human.consciousness.ts';
|
|
19
|
-
import { type BreathEvent } from './a432.breathe.ts';
|
|
20
|
-
import { type HealthMetrics } from './a432.health.ts';
|
|
21
|
-
import { type ChessFrame } from './a432.chess.ts';
|
|
22
|
-
import { type YinYangFrame } from './a432.yin.yang.ts';
|
|
23
|
-
import { type MetatronFrame } from './a432.metatron.ts';
|
|
24
|
-
import { a432OSState } from './a432.os.ts';
|
|
25
|
-
import { flashColor } from './a432.video.ts';
|
|
26
|
-
import { playDigit, playTrinitySound } from './a432.sound.ts';
|
|
27
|
-
import { digitAngleToCMYK } from './a432.cmyk.ts';
|
|
28
|
-
import { type Digit, toDigit } from './a432.types.ts';
|
|
29
|
-
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
|
30
|
-
import { startChess } from './a432.chess.ts';
|
|
31
|
-
import { startYinYang } from './a432.yin.yang.ts';
|
|
32
|
-
import { startMetatron } from './a432.metatron.ts';
|
|
33
|
-
import { A432_RESOLVED_FRACTIONS } from './a432.resolved.ts';
|
|
34
|
-
import { fractionToDecimal } from './a432.math.ts';
|
|
35
|
-
// Analog signal values: exact integer ratios, collapsed to float only here
|
|
36
|
-
// at the WebGL boundary. No bare decimal literal appears below.
|
|
37
|
-
const G = Object.fromEntries(
|
|
38
|
-
Object.entries(A432_RESOLVED_FRACTIONS.GEOMETRY).map(([k, v]) => [k, fractionToDecimal(v)])
|
|
39
|
-
) as Record<keyof typeof A432_RESOLVED_FRACTIONS.GEOMETRY, number>;
|
|
40
|
-
|
|
41
|
-
export class A432ThreeUI {
|
|
42
|
-
container: HTMLElement;
|
|
43
|
-
scene: THREE.Scene;
|
|
44
|
-
camera: THREE.PerspectiveCamera;
|
|
45
|
-
renderer: THREE.WebGLRenderer;
|
|
46
|
-
controls: OrbitControls;
|
|
47
|
-
objects: THREE.Object3D[] = [];
|
|
48
|
-
lights: THREE.Light[] = [];
|
|
49
|
-
overlays: HTMLElement[] = [];
|
|
50
|
-
selectedObject: THREE.Object3D | null = null;
|
|
51
|
-
animationId: number | null = null;
|
|
52
|
-
blockchain: A432BlockChain;
|
|
53
|
-
metaOverlay: HTMLElement | null = null;
|
|
54
|
-
trinityPhase: number = 3;
|
|
55
|
-
harmony: number = 0;
|
|
56
|
-
entropy: number = 0;
|
|
57
|
-
lastBreath: any = null;
|
|
58
|
-
lastPulse: any = null;
|
|
59
|
-
lastIntuit: any = null;
|
|
60
|
-
lastReflect: any = null;
|
|
61
|
-
lastMove: any = null;
|
|
62
|
-
lastHeat: any = null;
|
|
63
|
-
lastHealth: any = null;
|
|
64
|
-
lastEmotion: any = null;
|
|
65
|
-
lastConsciousness: any = null;
|
|
66
|
-
overlayDocked: boolean = true;
|
|
67
|
-
currentBreathPhase: string = '';
|
|
68
|
-
currentBreathValue: number = 0;
|
|
69
|
-
breathCycleActive: boolean = false;
|
|
70
|
-
stopBreathCycle: (() => void) | null = null;
|
|
71
|
-
micDetectionActive: boolean = false;
|
|
72
|
-
micDetectionStream: MediaStream | null = null;
|
|
73
|
-
micDetectionAudioCtx: AudioContext | null = null;
|
|
74
|
-
micThreshold: number = 40;
|
|
75
|
-
micMinInterval: number = 800;
|
|
76
|
-
micAmplitude: number = 0;
|
|
77
|
-
micGraphCanvas: HTMLCanvasElement | null = null;
|
|
78
|
-
breathEvents: { phase: string, timestamp: number }[] = [];
|
|
79
|
-
analyticOverlay: HTMLElement | null = null;
|
|
80
|
-
journeyOverlay: HTMLElement | null = null;
|
|
81
|
-
healthMetrics: { harmony: number; entropy: number; resonance: number } = { harmony: 0, entropy: 1, resonance: 0 };
|
|
82
|
-
lastHealthMetrics: { harmony: number; entropy: number; resonance: number } = { harmony: 0, entropy: 1, resonance: 0 };
|
|
83
|
-
healthHistory: { harmony: number; entropy: number; resonance: number; t: number }[] = [];
|
|
84
|
-
healthAlertTimeout: any = null;
|
|
85
|
-
dashboardOverlay: HTMLElement | null = null;
|
|
86
|
-
metaphysicalSwitcher: HTMLElement | null = null;
|
|
87
|
-
chessCanvas: HTMLCanvasElement | null = null;
|
|
88
|
-
yinYangCanvas: HTMLCanvasElement | null = null;
|
|
89
|
-
metatronCanvas: HTMLCanvasElement | null = null;
|
|
90
|
-
chessOverlay: HTMLElement | null = null;
|
|
91
|
-
yinYangOverlay: HTMLElement | null = null;
|
|
92
|
-
metatronOverlay: HTMLElement | null = null;
|
|
93
|
-
chessDisposer: (() => void) | null = null;
|
|
94
|
-
yinYangDisposer: (() => void) | null = null;
|
|
95
|
-
metatronDisposer: (() => void) | null = null;
|
|
96
|
-
currentMetaViz: 'chess' | 'yin-yang' | 'metatron' = 'chess';
|
|
97
|
-
|
|
98
|
-
constructor(container?: HTMLElement) {
|
|
99
|
-
this.container = container || this.createContainer();
|
|
100
|
-
this.scene = new THREE.Scene();
|
|
101
|
-
this.scene.background = new THREE.Color(0x111111);
|
|
102
|
-
this.camera = new THREE.PerspectiveCamera(75, this.container.offsetWidth / this.container.offsetHeight, G.UNIT_TENTH, 1000);
|
|
103
|
-
this.camera.position.set(0, 0, 10);
|
|
104
|
-
this.renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
105
|
-
this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight);
|
|
106
|
-
this.container.appendChild(this.renderer.domElement);
|
|
107
|
-
this.blockchain = new A432BlockChain();
|
|
108
|
-
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
|
|
109
|
-
this.controls.enableDamping = true;
|
|
110
|
-
this.controls.dampingFactor = G.STEP_SMALL;
|
|
111
|
-
this.controls.screenSpacePanning = false;
|
|
112
|
-
this.controls.minDistance = 2;
|
|
113
|
-
this.controls.maxDistance = 50;
|
|
114
|
-
this.addDefaultLight();
|
|
115
|
-
this.addUIControls();
|
|
116
|
-
this.addDragAndDrop();
|
|
117
|
-
this.animate();
|
|
118
|
-
this.createMetaOverlay();
|
|
119
|
-
this.createOverlayControls();
|
|
120
|
-
this.subscribeToA432Events();
|
|
121
|
-
this.addBreatheCycleButton();
|
|
122
|
-
this.addBreathCycleControlButton();
|
|
123
|
-
this.addMicBreathDetectionButton();
|
|
124
|
-
this.addMicBreathDetectionControls();
|
|
125
|
-
this.createAnalyticOverlay();
|
|
126
|
-
this.createJourneyOverlay();
|
|
127
|
-
this.addSensorIntegrationButton();
|
|
128
|
-
breatheEmitter.on('breathe', (event: BreathEvent) => {
|
|
129
|
-
this.currentBreathPhase = event.phase;
|
|
130
|
-
this.currentBreathValue = event.value;
|
|
131
|
-
const ts = (event as any).timestamp ?? Date.now();
|
|
132
|
-
this.breathEvents.push({ phase: event.phase, timestamp: ts });
|
|
133
|
-
if (this.breathEvents.length > 100) this.breathEvents.shift();
|
|
134
|
-
this.updateAnalyticOverlay();
|
|
135
|
-
this.updateJourneyOverlay(event.phase);
|
|
136
|
-
this.animateBreathOverlay(event.phase);
|
|
137
|
-
this.updateMetaOverlay();
|
|
138
|
-
// Color feedback: flash color for each breath phase
|
|
139
|
-
const cmyk = digitAngleToCMYK(event.value, event.phase === 'inhale' ? 0 : event.phase === 'hold' ? 120 : 240);
|
|
140
|
-
flashColor(cmyk, 400);
|
|
141
|
-
// Sound feedback: play digit for inhale/exhale
|
|
142
|
-
if (event.phase === 'inhale') playDigit(3);
|
|
143
|
-
if (event.phase === 'exhale') playDigit(9 as Digit);
|
|
144
|
-
});
|
|
145
|
-
healthEmitter.on('health', (metrics: HealthMetrics) => {
|
|
146
|
-
this.lastHealthMetrics = { ...this.healthMetrics };
|
|
147
|
-
this.healthMetrics = metrics;
|
|
148
|
-
this.healthHistory.push({ ...metrics, t: Date.now() });
|
|
149
|
-
if (this.healthHistory.length > 120) this.healthHistory.shift();
|
|
150
|
-
this.updateAnalyticOverlay();
|
|
151
|
-
this.updateMetaOverlay();
|
|
152
|
-
this.animateHealthOverlay(metrics);
|
|
153
|
-
this.checkHealthThresholds(metrics);
|
|
154
|
-
this.updateJourneyOverlay(this.currentBreathPhase, metrics);
|
|
155
|
-
// Color feedback: flash color for harmony/entropy thresholds
|
|
156
|
-
if (metrics.harmony < G.UNIT_THIRD_TEN) flashColor({ c: 0, m: 0, y: 100, k: 0 }, 600); // yellow for low harmony
|
|
157
|
-
if (metrics.entropy > G.OPACITY_FOUR_FIFTH) flashColor({ c: 0, m: 100, y: 0, k: 0 }, 600); // magenta for high entropy
|
|
158
|
-
if (metrics.resonance > G.OPACITY_FOUR_FIFTH) flashColor({ c: 100, m: 0, y: 0, k: 0 }, 600); // cyan for high resonance
|
|
159
|
-
// Sound feedback: play trinity sound for high resonance
|
|
160
|
-
if (metrics.resonance > G.OPACITY_FOUR_FIFTH) playTrinitySound(9);
|
|
161
|
-
});
|
|
162
|
-
window.addEventListener('resize', () => this.onResize());
|
|
163
|
-
this.createDashboardOverlay();
|
|
164
|
-
// Update dashboard on all relevant events
|
|
165
|
-
breatheEmitter.on('breathe', () => this.updateDashboardOverlay());
|
|
166
|
-
healthEmitter.on('health', () => this.updateDashboardOverlay());
|
|
167
|
-
setInterval(() => this.updateDashboardOverlay(), 5000); // update OS state every 5s
|
|
168
|
-
this.createMetaphysicalSwitcher();
|
|
169
|
-
this.showMetaphysicalVisualization('chess');
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
createContainer(): HTMLElement {
|
|
173
|
-
const container = document.createElement('div');
|
|
174
|
-
container.id = 'a432-threejs-container';
|
|
175
|
-
container.style.width = '100vw';
|
|
176
|
-
container.style.height = '100vh';
|
|
177
|
-
document.body.appendChild(container);
|
|
178
|
-
return container;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
addDefaultLight() {
|
|
182
|
-
const light = new THREE.PointLight(0xffffff, 1, 100);
|
|
183
|
-
light.position.set(10, 10, 10);
|
|
184
|
-
this.scene.add(light);
|
|
185
|
-
this.lights.push(light);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
addCube() {
|
|
189
|
-
const geometry = new THREE.BoxGeometry();
|
|
190
|
-
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
|
|
191
|
-
const cube = new THREE.Mesh(geometry, material);
|
|
192
|
-
cube.position.set(unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:2") * 4 - 2, unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:3") * 4 - 2, unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:4") * 4 - 2);
|
|
193
|
-
this.scene.add(cube);
|
|
194
|
-
this.objects.push(cube);
|
|
195
|
-
recordEvent(this.blockchain, 'addCube', 'A432ThreeUI', cube);
|
|
196
|
-
return cube;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
addSphere() {
|
|
200
|
-
const geometry = new THREE.SphereGeometry(G.OPACITY_SEVEN, 32, 32);
|
|
201
|
-
const material = new THREE.MeshStandardMaterial({ color: 0x0077ff });
|
|
202
|
-
const sphere = new THREE.Mesh(geometry, material);
|
|
203
|
-
sphere.position.set(unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:5") * 4 - 2, unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:6") * 4 - 2, unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:7") * 4 - 2);
|
|
204
|
-
this.scene.add(sphere);
|
|
205
|
-
this.objects.push(sphere);
|
|
206
|
-
recordEvent(this.blockchain, 'addSphere', 'A432ThreeUI', sphere);
|
|
207
|
-
return sphere;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
addLight() {
|
|
211
|
-
const light = new THREE.PointLight(0xffffff, 1, 100);
|
|
212
|
-
light.position.set(unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:8") * 8 - 4, unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:9") * 8 - 4, unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:10") * 8 - 4);
|
|
213
|
-
this.scene.add(light);
|
|
214
|
-
this.lights.push(light);
|
|
215
|
-
recordEvent(this.blockchain, 'addLight', 'A432ThreeUI', light);
|
|
216
|
-
return light;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
removeSelectedObject() {
|
|
220
|
-
if (this.selectedObject) {
|
|
221
|
-
recordEvent(this.blockchain, 'removeObject', 'A432ThreeUI', this.selectedObject);
|
|
222
|
-
this.scene.remove(this.selectedObject);
|
|
223
|
-
this.objects = this.objects.filter(obj => obj !== this.selectedObject);
|
|
224
|
-
this.selectedObject = null;
|
|
225
|
-
this.removePropertyEditor();
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
selectObject(obj: THREE.Object3D) {
|
|
230
|
-
this.selectedObject = obj;
|
|
231
|
-
this.showPropertyEditor(obj);
|
|
232
|
-
recordEvent(this.blockchain, 'selectObject', 'A432ThreeUI', obj);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
addUIControls() {
|
|
236
|
-
// Add UI buttons for demo (can be replaced with a more advanced UI framework)
|
|
237
|
-
const addCubeBtn = this.createButton('Add Cube', () => this.addCube());
|
|
238
|
-
const addSphereBtn = this.createButton('Add Sphere', () => this.addSphere());
|
|
239
|
-
const addLightBtn = this.createButton('Add Light', () => this.addLight());
|
|
240
|
-
const removeBtn = this.createButton('Remove Selected', () => this.removeSelectedObject());
|
|
241
|
-
document.body.appendChild(addCubeBtn);
|
|
242
|
-
document.body.appendChild(addSphereBtn);
|
|
243
|
-
document.body.appendChild(addLightBtn);
|
|
244
|
-
document.body.appendChild(removeBtn);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
createButton(label: string, onClick: () => void): HTMLButtonElement {
|
|
248
|
-
const btn = document.createElement('button');
|
|
249
|
-
btn.textContent = label;
|
|
250
|
-
btn.style.position = 'absolute';
|
|
251
|
-
btn.style.right = '16px';
|
|
252
|
-
btn.style.top = `${8 + 40 * document.body.querySelectorAll('button').length}px`;
|
|
253
|
-
btn.style.zIndex = '10001';
|
|
254
|
-
btn.onclick = onClick;
|
|
255
|
-
return btn;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
animate() {
|
|
259
|
-
this.animationId = requestAnimationFrame(() => this.animate());
|
|
260
|
-
// Example: rotate all meshes
|
|
261
|
-
this.objects.forEach(obj => {
|
|
262
|
-
if (obj instanceof THREE.Mesh) {
|
|
263
|
-
obj.rotation.x += G.STEP_FINE;
|
|
264
|
-
obj.rotation.y += G.STEP_FINE;
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
this.renderer.render(this.scene, this.camera);
|
|
268
|
-
this.controls.update();
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
onResize() {
|
|
272
|
-
this.camera.aspect = this.container.offsetWidth / this.container.offsetHeight;
|
|
273
|
-
this.camera.updateProjectionMatrix();
|
|
274
|
-
this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Example: show metaphysical overlay
|
|
278
|
-
showOverlay(html: string, obj?: THREE.Object3D) {
|
|
279
|
-
const overlay = document.createElement('div');
|
|
280
|
-
overlay.innerHTML = html;
|
|
281
|
-
overlay.style.position = 'absolute';
|
|
282
|
-
overlay.style.left = '20px';
|
|
283
|
-
overlay.style.top = '20px';
|
|
284
|
-
overlay.style.background = 'rgba(0,0,0,0.7)';
|
|
285
|
-
overlay.style.color = '#fff';
|
|
286
|
-
overlay.style.padding = '12px';
|
|
287
|
-
overlay.style.zIndex = '10002';
|
|
288
|
-
document.body.appendChild(overlay);
|
|
289
|
-
this.overlays.push(overlay);
|
|
290
|
-
setTimeout(() => {
|
|
291
|
-
overlay.remove();
|
|
292
|
-
this.overlays = this.overlays.filter(o => o !== overlay);
|
|
293
|
-
}, 3000);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Example: log event to blockchain or analytics
|
|
297
|
-
// logEvent(type: string, obj: any) {
|
|
298
|
-
// logEvent(type, obj);
|
|
299
|
-
// }
|
|
300
|
-
|
|
301
|
-
// Extend: add methods for camera switching, advanced controls, metaphysical overlays, blockchain integration, etc.
|
|
302
|
-
|
|
303
|
-
addDragAndDrop() {
|
|
304
|
-
this.renderer.domElement.addEventListener('pointerdown', (event) => {
|
|
305
|
-
const mouse = new THREE.Vector2();
|
|
306
|
-
mouse.x = (event.offsetX / this.renderer.domElement.clientWidth) * 2 - 1;
|
|
307
|
-
mouse.y = -(event.offsetY / this.renderer.domElement.clientHeight) * 2 + 1;
|
|
308
|
-
const raycaster = new THREE.Raycaster();
|
|
309
|
-
raycaster.setFromCamera(mouse, this.camera);
|
|
310
|
-
const intersects = raycaster.intersectObjects(this.objects);
|
|
311
|
-
if (intersects.length > 0) {
|
|
312
|
-
this.selectObject(intersects[0].object);
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
showPropertyEditor(obj: THREE.Object3D) {
|
|
318
|
-
this.removePropertyEditor();
|
|
319
|
-
const overlay = document.createElement('div');
|
|
320
|
-
overlay.style.position = 'absolute';
|
|
321
|
-
overlay.style.right = '20px';
|
|
322
|
-
overlay.style.top = '80px';
|
|
323
|
-
overlay.style.background = 'rgba(0,0,0,0.85)';
|
|
324
|
-
overlay.style.color = '#fff';
|
|
325
|
-
overlay.style.padding = '16px';
|
|
326
|
-
overlay.style.zIndex = '10003';
|
|
327
|
-
overlay.style.borderRadius = '8px';
|
|
328
|
-
overlay.innerHTML = `<b>Object Properties</b><br>
|
|
329
|
-
<label>X: <input type='number' step='0.1' value='${obj.position.x}' id='a432-x'></label><br>
|
|
330
|
-
<label>Y: <input type='number' step='0.1' value='${obj.position.y}' id='a432-y'></label><br>
|
|
331
|
-
<label>Z: <input type='number' step='0.1' value='${obj.position.z}' id='a432-z'></label><br>
|
|
332
|
-
<label>Color: <input type='color' value='${(obj as any).material?.color ? '#' + (obj as any).material.color.getHexString() : '#ffffff'}' id='a432-color'></label><br>
|
|
333
|
-
<button id='a432-close'>Close</button>`;
|
|
334
|
-
document.body.appendChild(overlay);
|
|
335
|
-
this.overlays.push(overlay);
|
|
336
|
-
overlay.querySelector('#a432-x')?.addEventListener('input', (e: any) => { obj.position.x = parseFloat(e.target.value); });
|
|
337
|
-
overlay.querySelector('#a432-y')?.addEventListener('input', (e: any) => { obj.position.y = parseFloat(e.target.value); });
|
|
338
|
-
overlay.querySelector('#a432-z')?.addEventListener('input', (e: any) => { obj.position.z = parseFloat(e.target.value); });
|
|
339
|
-
overlay.querySelector('#a432-color')?.addEventListener('input', (e: any) => {
|
|
340
|
-
if ((obj as any).material?.color) (obj as any).material.color.set(e.target.value);
|
|
341
|
-
});
|
|
342
|
-
overlay.querySelector('#a432-close')?.addEventListener('click', () => this.removePropertyEditor());
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
removePropertyEditor() {
|
|
346
|
-
this.overlays.forEach(o => {
|
|
347
|
-
if (o.innerHTML.includes('Object Properties')) o.remove();
|
|
348
|
-
});
|
|
349
|
-
this.overlays = this.overlays.filter(o => !o.innerHTML.includes('Object Properties'));
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
createMetaOverlay() {
|
|
353
|
-
this.metaOverlay = document.createElement('div');
|
|
354
|
-
this.metaOverlay.style.position = this.overlayDocked ? 'absolute' : 'fixed';
|
|
355
|
-
this.metaOverlay.style.left = '20px';
|
|
356
|
-
this.metaOverlay.style.bottom = '20px';
|
|
357
|
-
this.metaOverlay.style.background = 'rgba(32,32,64,0.92)';
|
|
358
|
-
this.metaOverlay.style.color = '#fff';
|
|
359
|
-
this.metaOverlay.style.padding = '16px';
|
|
360
|
-
this.metaOverlay.style.zIndex = '10010';
|
|
361
|
-
this.metaOverlay.style.borderRadius = '12px';
|
|
362
|
-
this.metaOverlay.style.fontFamily = 'monospace';
|
|
363
|
-
this.metaOverlay.style.minWidth = '260px';
|
|
364
|
-
this.metaOverlay.innerHTML = this.getMetaOverlayHTML();
|
|
365
|
-
document.body.appendChild(this.metaOverlay);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
updateMetaOverlay() {
|
|
369
|
-
if (this.metaOverlay) {
|
|
370
|
-
this.metaOverlay.innerHTML = this.getMetaOverlayHTML();
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
getMetaOverlayHTML() {
|
|
375
|
-
return `<b>Metaphysical State</b><br>
|
|
376
|
-
<b>Breath Phase:</b> <span style='color:#0ff'>${this.currentBreathPhase || '—'}</span><br>
|
|
377
|
-
<b>Breath Value:</b> <span style='color:#0ff'>${this.currentBreathValue}</span><br>
|
|
378
|
-
<b>Breath Cycle:</b> <span style='color:#fff'>4 (inhale) - 3 (hold) - 2 (exhale)</span><br>
|
|
379
|
-
<b>Harmony:</b> <span style='color:${this.healthMetrics.harmony > G.OPACITY_SEVEN ? '#0f0' : '#ff0'}'>${this.healthMetrics.harmony.toFixed(2)}</span><br>
|
|
380
|
-
<b>Entropy:</b> <span style='color:${this.healthMetrics.entropy > G.OPACITY_SEVEN ? '#f00' : '#0ff'}'>${this.healthMetrics.entropy.toFixed(2)}</span><br>
|
|
381
|
-
<b>Resonance:</b> <span style='color:${this.healthMetrics.resonance > G.OPACITY_SEVEN ? '#0ff' : '#fff'}'>${this.healthMetrics.resonance.toFixed(2)}</span><br>
|
|
382
|
-
Trinity Phase: <span style='color:#ff0'>${this.trinityPhase}</span><br>
|
|
383
|
-
Harmony: <span style='color:#0f0'>${this.harmony}</span><br>
|
|
384
|
-
Entropy: <span style='color:#f00'>${this.entropy}</span><br>
|
|
385
|
-
<hr style='border:1px solid #333'>
|
|
386
|
-
Last Breath: ${this.lastBreath ? JSON.stringify(this.lastBreath) : '—'}<br>
|
|
387
|
-
Last Pulse: ${this.lastPulse ? JSON.stringify(this.lastPulse) : '—'}<br>
|
|
388
|
-
Last Intuit: ${this.lastIntuit ? JSON.stringify(this.lastIntuit) : '—'}<br>
|
|
389
|
-
Last Reflect: ${this.lastReflect ? JSON.stringify(this.lastReflect) : '—'}<br>
|
|
390
|
-
Last Move: ${this.lastMove ? JSON.stringify(this.lastMove) : '—'}<br>
|
|
391
|
-
Last Heat: ${this.lastHeat ? JSON.stringify(this.lastHeat) : '—'}<br>
|
|
392
|
-
Last Health: ${this.lastHealth ? JSON.stringify(this.lastHealth) : '—'}<br>
|
|
393
|
-
Last Emotion: ${this.lastEmotion ? JSON.stringify(this.lastEmotion) : '—'}<br>
|
|
394
|
-
Last Consciousness: ${this.lastConsciousness ? JSON.stringify(this.lastConsciousness) : '—'}<br>`;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
createOverlayControls() {
|
|
398
|
-
const toggleBtn = document.createElement('button');
|
|
399
|
-
toggleBtn.textContent = 'Toggle Overlay';
|
|
400
|
-
toggleBtn.style.position = 'absolute';
|
|
401
|
-
toggleBtn.style.left = '20px';
|
|
402
|
-
toggleBtn.style.bottom = '180px';
|
|
403
|
-
toggleBtn.style.zIndex = '10011';
|
|
404
|
-
toggleBtn.onclick = () => {
|
|
405
|
-
if (this.metaOverlay) {
|
|
406
|
-
this.metaOverlay.style.display = this.metaOverlay.style.display === 'none' ? 'block' : 'none';
|
|
407
|
-
}
|
|
408
|
-
};
|
|
409
|
-
document.body.appendChild(toggleBtn);
|
|
410
|
-
const dockBtn = document.createElement('button');
|
|
411
|
-
dockBtn.textContent = 'Dock/Float Overlay';
|
|
412
|
-
dockBtn.style.position = 'absolute';
|
|
413
|
-
dockBtn.style.left = '140px';
|
|
414
|
-
dockBtn.style.bottom = '180px';
|
|
415
|
-
dockBtn.style.zIndex = '10011';
|
|
416
|
-
dockBtn.onclick = () => {
|
|
417
|
-
this.overlayDocked = !this.overlayDocked;
|
|
418
|
-
if (this.metaOverlay) {
|
|
419
|
-
this.metaOverlay.style.position = this.overlayDocked ? 'absolute' : 'fixed';
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
document.body.appendChild(dockBtn);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
subscribeToA432Events() {
|
|
426
|
-
pulseEmitter.on('pulse', (ev: any) => {
|
|
427
|
-
this.lastPulse = ev;
|
|
428
|
-
this.harmony = getTrinityAxis()[ev.value % 3]; // Assuming harmony is derived from trinity phase
|
|
429
|
-
this.entropy = getTrinityAxis()[ev.value % 3]; // Assuming entropy is derived from trinity phase
|
|
430
|
-
this.updateMetaOverlay();
|
|
431
|
-
});
|
|
432
|
-
intuitEmitter.on('intuit', (ev: any) => { this.lastIntuit = ev; this.updateMetaOverlay(); });
|
|
433
|
-
reflectEmitter.on('reflect', (ev: any) => { this.lastReflect = ev; this.updateMetaOverlay(); });
|
|
434
|
-
moveEmitter.on('move', (ev: any) => { this.lastMove = ev; this.updateMetaOverlay(); });
|
|
435
|
-
heatEmitter.on('heat', (ev: any) => { this.lastHeat = ev; this.updateMetaOverlay(); });
|
|
436
|
-
healthEmitter.on('health', (ev: any) => { this.lastHealth = ev; this.updateMetaOverlay(); });
|
|
437
|
-
humanEmotionEmitter.on('emotion', (ev: any) => { this.lastEmotion = ev; this.updateMetaOverlay(); });
|
|
438
|
-
humanConsciousnessEmitter.on('consciousness', (ev: any) => { this.lastConsciousness = ev; this.updateMetaOverlay(); });
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
addBreatheCycleButton() {
|
|
442
|
-
const btn = document.createElement('button');
|
|
443
|
-
btn.textContent = 'I Breathe (Inhale/Exhale)';
|
|
444
|
-
btn.style.position = 'absolute';
|
|
445
|
-
btn.style.left = '20px';
|
|
446
|
-
btn.style.bottom = '240px';
|
|
447
|
-
btn.style.zIndex = '10012';
|
|
448
|
-
btn.onclick = () => this.iBreatheInhaleExhale();
|
|
449
|
-
document.body.appendChild(btn);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
iBreatheInhaleExhale() {
|
|
453
|
-
const now = Date.now();
|
|
454
|
-
// Inhale event
|
|
455
|
-
breatheEmitter.emit('breathe', { value: 9, phase: 'inhale', timestamp: now });
|
|
456
|
-
// Exhale event (after a short delay)
|
|
457
|
-
setTimeout(() => {
|
|
458
|
-
breatheEmitter.emit('breathe', { value: 0, phase: 'exhale', timestamp: Date.now() });
|
|
459
|
-
}, 1000);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
addBreathCycleControlButton() {
|
|
463
|
-
const btn = document.createElement('button');
|
|
464
|
-
btn.textContent = 'Start 4-3-2 Breath Cycle (Device)';
|
|
465
|
-
btn.style.position = 'absolute';
|
|
466
|
-
btn.style.left = '20px';
|
|
467
|
-
btn.style.bottom = '280px';
|
|
468
|
-
btn.style.zIndex = '10013';
|
|
469
|
-
btn.onclick = () => this.toggleBreathCycle(btn);
|
|
470
|
-
document.body.appendChild(btn);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
toggleBreathCycle(btn: HTMLButtonElement) {
|
|
474
|
-
if (!this.breathCycleActive) {
|
|
475
|
-
this.stopBreathCycle = startBreathing(1000); // 1s per step
|
|
476
|
-
this.breathCycleActive = true;
|
|
477
|
-
btn.textContent = 'Stop 4-3-2 Breath Cycle (Device)';
|
|
478
|
-
} else {
|
|
479
|
-
if (this.stopBreathCycle) this.stopBreathCycle();
|
|
480
|
-
this.breathCycleActive = false;
|
|
481
|
-
btn.textContent = 'Start 4-3-2 Breath Cycle (Device)';
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
animateBreathOverlay(phase: string) {
|
|
486
|
-
if (!this.metaOverlay) return;
|
|
487
|
-
this.metaOverlay.style.transition = 'box-shadow 0.3s, background 0.3s';
|
|
488
|
-
if (phase === 'inhale') {
|
|
489
|
-
this.metaOverlay.style.boxShadow = '0 0 24px 8px #00ffcc';
|
|
490
|
-
this.metaOverlay.style.background = 'rgba(32,64,64,0.97)';
|
|
491
|
-
} else if (phase === 'hold') {
|
|
492
|
-
this.metaOverlay.style.boxShadow = '0 0 24px 8px #ccccff';
|
|
493
|
-
this.metaOverlay.style.background = 'rgba(64,64,96,0.97)';
|
|
494
|
-
} else if (phase === 'exhale') {
|
|
495
|
-
this.metaOverlay.style.boxShadow = '0 0 24px 8px #ffcc00';
|
|
496
|
-
this.metaOverlay.style.background = 'rgba(64,32,32,0.97)';
|
|
497
|
-
} else {
|
|
498
|
-
this.metaOverlay.style.boxShadow = '';
|
|
499
|
-
this.metaOverlay.style.background = 'rgba(32,32,64,0.92)';
|
|
500
|
-
}
|
|
501
|
-
setTimeout(() => {
|
|
502
|
-
if (!this.metaOverlay) return;
|
|
503
|
-
this.metaOverlay.style.boxShadow = '';
|
|
504
|
-
this.metaOverlay.style.background = 'rgba(32,32,64,0.92)';
|
|
505
|
-
}, 1200);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
addMicBreathDetectionButton() {
|
|
509
|
-
const btn = document.createElement('button');
|
|
510
|
-
btn.textContent = 'Enable Microphone Breath Detection';
|
|
511
|
-
btn.style.position = 'absolute';
|
|
512
|
-
btn.style.left = '20px';
|
|
513
|
-
btn.style.bottom = '320px';
|
|
514
|
-
btn.style.zIndex = '10014';
|
|
515
|
-
btn.onclick = () => this.toggleMicBreathDetection(btn);
|
|
516
|
-
document.body.appendChild(btn);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
async toggleMicBreathDetection(btn: HTMLButtonElement) {
|
|
520
|
-
if (!this.micDetectionActive) {
|
|
521
|
-
await this.startMicBreathDetection();
|
|
522
|
-
this.micDetectionActive = true;
|
|
523
|
-
btn.textContent = 'Disable Microphone Breath Detection';
|
|
524
|
-
} else {
|
|
525
|
-
this.stopMicBreathDetection();
|
|
526
|
-
this.micDetectionActive = false;
|
|
527
|
-
btn.textContent = 'Enable Microphone Breath Detection';
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
addMicBreathDetectionControls() {
|
|
532
|
-
// Threshold slider
|
|
533
|
-
const thresholdLabel = document.createElement('label');
|
|
534
|
-
thresholdLabel.textContent = 'Mic Threshold:';
|
|
535
|
-
thresholdLabel.style.position = 'absolute';
|
|
536
|
-
thresholdLabel.style.left = '220px';
|
|
537
|
-
thresholdLabel.style.bottom = '320px';
|
|
538
|
-
thresholdLabel.style.zIndex = '10014';
|
|
539
|
-
const thresholdSlider = document.createElement('input');
|
|
540
|
-
thresholdSlider.type = 'range';
|
|
541
|
-
thresholdSlider.min = '10';
|
|
542
|
-
thresholdSlider.max = '100';
|
|
543
|
-
thresholdSlider.value = String(this.micThreshold);
|
|
544
|
-
thresholdSlider.oninput = (e: any) => {
|
|
545
|
-
this.micThreshold = parseInt(e.target.value, 10);
|
|
546
|
-
};
|
|
547
|
-
thresholdLabel.appendChild(thresholdSlider);
|
|
548
|
-
document.body.appendChild(thresholdLabel);
|
|
549
|
-
|
|
550
|
-
// Min interval slider
|
|
551
|
-
const intervalLabel = document.createElement('label');
|
|
552
|
-
intervalLabel.textContent = 'Min Interval (ms):';
|
|
553
|
-
intervalLabel.style.position = 'absolute';
|
|
554
|
-
intervalLabel.style.left = '420px';
|
|
555
|
-
intervalLabel.style.bottom = '320px';
|
|
556
|
-
intervalLabel.style.zIndex = '10014';
|
|
557
|
-
const intervalSlider = document.createElement('input');
|
|
558
|
-
intervalSlider.type = 'range';
|
|
559
|
-
intervalSlider.min = '200';
|
|
560
|
-
intervalSlider.max = '2000';
|
|
561
|
-
intervalSlider.value = String(this.micMinInterval);
|
|
562
|
-
intervalSlider.oninput = (e: any) => {
|
|
563
|
-
this.micMinInterval = parseInt(e.target.value, 10);
|
|
564
|
-
};
|
|
565
|
-
intervalLabel.appendChild(intervalSlider);
|
|
566
|
-
document.body.appendChild(intervalLabel);
|
|
567
|
-
|
|
568
|
-
// Auto-calibration button
|
|
569
|
-
const calibrateBtn = document.createElement('button');
|
|
570
|
-
calibrateBtn.textContent = 'Auto-Calibrate Threshold';
|
|
571
|
-
calibrateBtn.style.position = 'absolute';
|
|
572
|
-
calibrateBtn.style.left = '650px';
|
|
573
|
-
calibrateBtn.style.bottom = '320px';
|
|
574
|
-
calibrateBtn.style.zIndex = '10014';
|
|
575
|
-
calibrateBtn.onclick = () => this.autoCalibrateMicThreshold();
|
|
576
|
-
document.body.appendChild(calibrateBtn);
|
|
577
|
-
|
|
578
|
-
// Amplitude graph
|
|
579
|
-
this.micGraphCanvas = document.createElement('canvas');
|
|
580
|
-
this.micGraphCanvas.width = 200;
|
|
581
|
-
this.micGraphCanvas.height = 40;
|
|
582
|
-
this.micGraphCanvas.style.position = 'absolute';
|
|
583
|
-
this.micGraphCanvas.style.left = '900px';
|
|
584
|
-
this.micGraphCanvas.style.bottom = '320px';
|
|
585
|
-
this.micGraphCanvas.style.zIndex = '10014';
|
|
586
|
-
this.micGraphCanvas.style.background = '#222';
|
|
587
|
-
document.body.appendChild(this.micGraphCanvas);
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
async startMicBreathDetection() {
|
|
591
|
-
try {
|
|
592
|
-
this.micDetectionStream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
593
|
-
this.micDetectionAudioCtx = new (window.AudioContext || (window as any).webkitAudioContext)();
|
|
594
|
-
const source = this.micDetectionAudioCtx.createMediaStreamSource(this.micDetectionStream);
|
|
595
|
-
const analyser = this.micDetectionAudioCtx.createAnalyser();
|
|
596
|
-
analyser.fftSize = 2048;
|
|
597
|
-
source.connect(analyser);
|
|
598
|
-
const data = new Uint8Array(analyser.fftSize);
|
|
599
|
-
let lastPhase: 'inhale'|'exhale' = 'exhale';
|
|
600
|
-
let lastTrigger = 0;
|
|
601
|
-
const detect = () => {
|
|
602
|
-
analyser.getByteTimeDomainData(data);
|
|
603
|
-
const amplitude = max(...data) - min(...data);
|
|
604
|
-
this.micAmplitude = amplitude;
|
|
605
|
-
this.drawMicAmplitudeGraph(amplitude);
|
|
606
|
-
const now = Date.now();
|
|
607
|
-
if (amplitude > this.micThreshold && lastPhase === 'exhale' && now - lastTrigger > this.micMinInterval) {
|
|
608
|
-
breatheEmitter.emit('breathe', { value: 9, phase: 'inhale', timestamp: now });
|
|
609
|
-
lastPhase = 'inhale';
|
|
610
|
-
lastTrigger = now;
|
|
611
|
-
} else if (amplitude < this.micThreshold/2 && lastPhase === 'inhale' && now - lastTrigger > this.micMinInterval) {
|
|
612
|
-
breatheEmitter.emit('breathe', { value: 0, phase: 'exhale', timestamp: now });
|
|
613
|
-
lastPhase = 'exhale';
|
|
614
|
-
lastTrigger = now;
|
|
615
|
-
}
|
|
616
|
-
if (this.micDetectionActive) requestAnimationFrame(detect);
|
|
617
|
-
};
|
|
618
|
-
detect();
|
|
619
|
-
} catch (err) {
|
|
620
|
-
alert('Microphone access denied or unavailable.');
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
drawMicAmplitudeGraph(amplitude: number) {
|
|
625
|
-
if (!this.micGraphCanvas) return;
|
|
626
|
-
const ctx = this.micGraphCanvas.getContext('2d');
|
|
627
|
-
if (!ctx) return;
|
|
628
|
-
ctx.clearRect(0, 0, this.micGraphCanvas.width, this.micGraphCanvas.height);
|
|
629
|
-
ctx.fillStyle = '#0ff';
|
|
630
|
-
ctx.fillRect(0, 0, amplitude * 2, this.micGraphCanvas.height);
|
|
631
|
-
ctx.strokeStyle = '#fff';
|
|
632
|
-
ctx.beginPath();
|
|
633
|
-
ctx.moveTo(this.micThreshold * 2, 0);
|
|
634
|
-
ctx.lineTo(this.micThreshold * 2, this.micGraphCanvas.height);
|
|
635
|
-
ctx.stroke();
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
async autoCalibrateMicThreshold() {
|
|
639
|
-
if (!this.micDetectionStream || !this.micDetectionAudioCtx) {
|
|
640
|
-
alert('Start microphone detection first.');
|
|
641
|
-
return;
|
|
642
|
-
}
|
|
643
|
-
const source = this.micDetectionAudioCtx.createMediaStreamSource(this.micDetectionStream);
|
|
644
|
-
const analyser = this.micDetectionAudioCtx.createAnalyser();
|
|
645
|
-
analyser.fftSize = 2048;
|
|
646
|
-
source.connect(analyser);
|
|
647
|
-
const data = new Uint8Array(analyser.fftSize);
|
|
648
|
-
let maxAmp = 0;
|
|
649
|
-
let samples = 0;
|
|
650
|
-
const sample = () => {
|
|
651
|
-
analyser.getByteTimeDomainData(data);
|
|
652
|
-
const amplitude = max(...data) - min(...data);
|
|
653
|
-
if (amplitude > maxAmp) maxAmp = amplitude;
|
|
654
|
-
samples++;
|
|
655
|
-
if (samples < 60) {
|
|
656
|
-
setTimeout(sample, 50);
|
|
657
|
-
} else {
|
|
658
|
-
this.micThreshold = max(20, maxAmp + 10);
|
|
659
|
-
alert('Auto-calibrated threshold: ' + this.micThreshold);
|
|
660
|
-
}
|
|
661
|
-
};
|
|
662
|
-
sample();
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
stopMicBreathDetection() {
|
|
666
|
-
if (this.micDetectionStream) {
|
|
667
|
-
this.micDetectionStream.getTracks().forEach(track => track.stop());
|
|
668
|
-
this.micDetectionStream = null;
|
|
669
|
-
}
|
|
670
|
-
if (this.micDetectionAudioCtx) {
|
|
671
|
-
this.micDetectionAudioCtx.close();
|
|
672
|
-
this.micDetectionAudioCtx = null;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
createAnalyticOverlay() {
|
|
677
|
-
this.analyticOverlay = document.createElement('div');
|
|
678
|
-
this.analyticOverlay.style.position = 'absolute';
|
|
679
|
-
this.analyticOverlay.style.right = '20px';
|
|
680
|
-
this.analyticOverlay.style.bottom = '20px';
|
|
681
|
-
this.analyticOverlay.style.background = 'rgba(32,32,32,0.92)';
|
|
682
|
-
this.analyticOverlay.style.color = '#fff';
|
|
683
|
-
this.analyticOverlay.style.padding = '12px';
|
|
684
|
-
this.analyticOverlay.style.zIndex = '10015';
|
|
685
|
-
this.analyticOverlay.style.borderRadius = '10px';
|
|
686
|
-
this.analyticOverlay.style.fontFamily = 'monospace';
|
|
687
|
-
this.analyticOverlay.style.minWidth = '220px';
|
|
688
|
-
this.analyticOverlay.innerHTML = this.getAnalyticOverlayHTML();
|
|
689
|
-
document.body.appendChild(this.analyticOverlay);
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
updateAnalyticOverlay() {
|
|
693
|
-
if (this.analyticOverlay) {
|
|
694
|
-
this.analyticOverlay.innerHTML = this.getAnalyticOverlayHTML();
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
getAnalyticOverlayHTML() {
|
|
699
|
-
// Calculate breath rate (breaths/min)
|
|
700
|
-
const now = Date.now();
|
|
701
|
-
const oneMinuteAgo = now - 60000;
|
|
702
|
-
const breaths = this.breathEvents.filter(e => e.phase === 'inhale' && e.timestamp > oneMinuteAgo);
|
|
703
|
-
const breathRate = breaths.length;
|
|
704
|
-
// Calculate average phase durations
|
|
705
|
-
const phaseDurations: { [phase: string]: number[] } = { inhale: [], hold: [], exhale: [] };
|
|
706
|
-
let lastPhase = '', lastTimestamp = 0;
|
|
707
|
-
for (const e of this.breathEvents) {
|
|
708
|
-
if (lastPhase && lastTimestamp && e.phase !== lastPhase) {
|
|
709
|
-
const duration = e.timestamp - lastTimestamp;
|
|
710
|
-
if (phaseDurations[lastPhase]) phaseDurations[lastPhase].push(duration);
|
|
711
|
-
}
|
|
712
|
-
lastPhase = e.phase;
|
|
713
|
-
lastTimestamp = e.timestamp;
|
|
714
|
-
}
|
|
715
|
-
const avg = (arr: number[]) => arr.length ? round(arr.reduce((a, b) => a + b, 0) / arr.length) : '—';
|
|
716
|
-
return `<b>Breath Analytics</b><br>
|
|
717
|
-
Breath Rate: <span style='color:#0ff'>${breathRate}</span> breaths/min<br>
|
|
718
|
-
Avg Inhale: <span style='color:#0ff'>${avg(phaseDurations.inhale)}</span> ms<br>
|
|
719
|
-
Avg Hold: <span style='color:#0ff'>${avg(phaseDurations.hold)}</span> ms<br>
|
|
720
|
-
Avg Exhale: <span style='color:#0ff'>${avg(phaseDurations.exhale)}</span> ms<br>
|
|
721
|
-
<hr style='border:1px solid #333'>
|
|
722
|
-
<b>System Health</b><br>
|
|
723
|
-
Harmony: <span style='color:${this.healthMetrics.harmony > G.OPACITY_SEVEN ? '#0f0' : '#ff0'}'>${this.healthMetrics.harmony.toFixed(2)}</span><br>
|
|
724
|
-
Entropy: <span style='color:${this.healthMetrics.entropy > G.OPACITY_SEVEN ? '#f00' : '#0ff'}'>${this.healthMetrics.entropy.toFixed(2)}</span><br>
|
|
725
|
-
Resonance: <span style='color:${this.healthMetrics.resonance > G.OPACITY_SEVEN ? '#0ff' : '#fff'}'>${this.healthMetrics.resonance.toFixed(2)}</span><br>
|
|
726
|
-
<svg width='180' height='36' style='margin-top:8px;'>${this.getHealthSparklineSVG()}</svg>`;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
getHealthSparklineSVG() {
|
|
730
|
-
const N = 60;
|
|
731
|
-
const hist = this.healthHistory.slice(-N);
|
|
732
|
-
if (!hist.length) return '';
|
|
733
|
-
const scale = (arr: number[], h: number) => arr.map(v => h - v * h);
|
|
734
|
-
const w = 180, h = 36;
|
|
735
|
-
const x = (i: number) => round((i / (N - 1)) * w);
|
|
736
|
-
const harmony = scale(hist.map(e => e.harmony), h);
|
|
737
|
-
const entropy = scale(hist.map(e => e.entropy), h);
|
|
738
|
-
const resonance = scale(hist.map(e => e.resonance), h);
|
|
739
|
-
const poly = (arr: number[], color: string) => `<polyline fill='none' stroke='${color}' stroke-width='2' points='${arr.map((y, i) => `${x(i)},${y}`).join(' ')}'/>`;
|
|
740
|
-
return [
|
|
741
|
-
poly(harmony, '#0f0'),
|
|
742
|
-
poly(entropy, '#f00'),
|
|
743
|
-
poly(resonance, '#0ff')
|
|
744
|
-
].join('');
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
createJourneyOverlay() {
|
|
748
|
-
this.journeyOverlay = document.createElement('div');
|
|
749
|
-
this.journeyOverlay.style.position = 'absolute';
|
|
750
|
-
this.journeyOverlay.style.left = '20px';
|
|
751
|
-
this.journeyOverlay.style.top = '20px';
|
|
752
|
-
this.journeyOverlay.style.background = 'rgba(64,32,96,0.92)';
|
|
753
|
-
this.journeyOverlay.style.color = '#fff';
|
|
754
|
-
this.journeyOverlay.style.padding = '14px';
|
|
755
|
-
this.journeyOverlay.style.zIndex = '10016';
|
|
756
|
-
this.journeyOverlay.style.borderRadius = '10px';
|
|
757
|
-
this.journeyOverlay.style.fontFamily = 'monospace';
|
|
758
|
-
this.journeyOverlay.style.minWidth = '260px';
|
|
759
|
-
this.journeyOverlay.innerHTML = '<b>Metaphysical Journey</b><br>—';
|
|
760
|
-
document.body.appendChild(this.journeyOverlay);
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
updateJourneyOverlay(phase: string, metrics?: { harmony: number; entropy: number; resonance: number }) {
|
|
764
|
-
if (!this.journeyOverlay) return;
|
|
765
|
-
const prompts: { [phase: string]: string } = {
|
|
766
|
-
inhale: 'Breathe in unity. Feel the field fill you.',
|
|
767
|
-
hold: 'Hold. Become aware of harmony.',
|
|
768
|
-
exhale: 'Exhale. Release entropy, return to source.'
|
|
769
|
-
};
|
|
770
|
-
let meta = '';
|
|
771
|
-
if (metrics) {
|
|
772
|
-
if (metrics.harmony < G.UNIT_THIRD_TEN) meta = '<br><span style="color:#ff0">Metaphysical Alert: Harmony is low. Focus on unity.</span>';
|
|
773
|
-
else if (metrics.entropy > G.OPACITY_FOUR_FIFTH) meta = '<br><span style="color:#f00">Metaphysical Alert: Entropy is high. Exhale and release.</span>';
|
|
774
|
-
else if (metrics.resonance > G.OPACITY_FOUR_FIFTH) meta = '<br><span style="color:#0ff">Metaphysical: Resonance is high. System is harmonized.</span>';
|
|
775
|
-
}
|
|
776
|
-
this.journeyOverlay.innerHTML = `<b>Metaphysical Journey</b><br>${prompts[phase] || '—'}${meta}`;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
addSensorIntegrationButton() {
|
|
780
|
-
const btn = document.createElement('button');
|
|
781
|
-
btn.textContent = 'Connect Breath Sensor (Bluetooth/Serial)';
|
|
782
|
-
btn.style.position = 'absolute';
|
|
783
|
-
btn.style.left = '20px';
|
|
784
|
-
btn.style.bottom = '360px';
|
|
785
|
-
btn.style.zIndex = '10017';
|
|
786
|
-
btn.onclick = () => this.connectBreathSensor();
|
|
787
|
-
document.body.appendChild(btn);
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
async connectBreathSensor() {
|
|
791
|
-
alert('Bluetooth/Serial sensor integration coming soon! (Stub for future device API)');
|
|
792
|
-
// Placeholder for future Web Bluetooth/Serial integration
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
animateHealthOverlay(metrics: { harmony: number; entropy: number; resonance: number }) {
|
|
796
|
-
if (!this.analyticOverlay) return;
|
|
797
|
-
// Animate overlay if harmony or entropy changes significantly
|
|
798
|
-
if (abs(metrics.harmony - this.lastHealthMetrics.harmony) > G.UNIT_FIFTH) {
|
|
799
|
-
this.analyticOverlay.style.boxShadow = '0 0 24px 8px #0f0';
|
|
800
|
-
setTimeout(() => { if (this.analyticOverlay) this.analyticOverlay.style.boxShadow = ''; }, 1000);
|
|
801
|
-
}
|
|
802
|
-
if (abs(metrics.entropy - this.lastHealthMetrics.entropy) > G.UNIT_FIFTH) {
|
|
803
|
-
this.analyticOverlay.style.boxShadow = '0 0 24px 8px #f00';
|
|
804
|
-
setTimeout(() => { if (this.analyticOverlay) this.analyticOverlay.style.boxShadow = ''; }, 1000);
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
checkHealthThresholds(metrics: { harmony: number; entropy: number; resonance: number }) {
|
|
809
|
-
if (metrics.harmony < G.UNIT_THIRD_TEN) {
|
|
810
|
-
this.showHealthAlert('Low Harmony! Focus on unity and breath.');
|
|
811
|
-
} else if (metrics.entropy > G.OPACITY_FOUR_FIFTH) {
|
|
812
|
-
this.showHealthAlert('High Entropy! Exhale and release tension.');
|
|
813
|
-
} else if (metrics.resonance > G.OPACITY_FOUR_FIFTH) {
|
|
814
|
-
this.showHealthAlert('High Resonance! System is harmonized.');
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
showHealthAlert(msg: string) {
|
|
819
|
-
if (this.healthAlertTimeout) clearTimeout(this.healthAlertTimeout);
|
|
820
|
-
let alertDiv = document.getElementById('health-alert');
|
|
821
|
-
if (!alertDiv) {
|
|
822
|
-
alertDiv = document.createElement('div');
|
|
823
|
-
alertDiv.id = 'health-alert';
|
|
824
|
-
alertDiv.style.position = 'fixed';
|
|
825
|
-
alertDiv.style.left = '50%';
|
|
826
|
-
alertDiv.style.top = '10%';
|
|
827
|
-
alertDiv.style.transform = 'translateX(-50%)';
|
|
828
|
-
alertDiv.style.background = 'rgba(255,0,64,0.95)';
|
|
829
|
-
alertDiv.style.color = '#fff';
|
|
830
|
-
alertDiv.style.padding = '18px 32px';
|
|
831
|
-
alertDiv.style.fontSize = '1.3em';
|
|
832
|
-
alertDiv.style.borderRadius = '16px';
|
|
833
|
-
alertDiv.style.zIndex = '10020';
|
|
834
|
-
alertDiv.style.boxShadow = '0 0 32px 8px #f0f';
|
|
835
|
-
document.body.appendChild(alertDiv);
|
|
836
|
-
}
|
|
837
|
-
alertDiv.textContent = msg;
|
|
838
|
-
alertDiv.style.display = 'block';
|
|
839
|
-
this.healthAlertTimeout = setTimeout(() => {
|
|
840
|
-
if (alertDiv) alertDiv.style.display = 'none';
|
|
841
|
-
}, 3000);
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
createDashboardOverlay() {
|
|
845
|
-
this.dashboardOverlay = document.createElement('div');
|
|
846
|
-
this.dashboardOverlay.style.position = 'fixed';
|
|
847
|
-
this.dashboardOverlay.style.right = '20px';
|
|
848
|
-
this.dashboardOverlay.style.top = '20px';
|
|
849
|
-
this.dashboardOverlay.style.background = 'rgba(24,24,48,0.98)';
|
|
850
|
-
this.dashboardOverlay.style.color = '#fff';
|
|
851
|
-
this.dashboardOverlay.style.padding = '20px';
|
|
852
|
-
this.dashboardOverlay.style.zIndex = '10030';
|
|
853
|
-
this.dashboardOverlay.style.borderRadius = '18px';
|
|
854
|
-
this.dashboardOverlay.style.fontFamily = 'monospace';
|
|
855
|
-
this.dashboardOverlay.style.minWidth = '340px';
|
|
856
|
-
this.dashboardOverlay.style.maxWidth = '420px';
|
|
857
|
-
this.dashboardOverlay.style.boxShadow = '0 0 32px 8px #0ff8';
|
|
858
|
-
this.dashboardOverlay.innerHTML = this.getDashboardOverlayHTML();
|
|
859
|
-
document.body.appendChild(this.dashboardOverlay);
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
updateDashboardOverlay() {
|
|
863
|
-
if (this.dashboardOverlay) {
|
|
864
|
-
this.dashboardOverlay.innerHTML = this.getDashboardOverlayHTML();
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
getDashboardOverlayHTML() {
|
|
869
|
-
// OS state
|
|
870
|
-
const os = a432OSState();
|
|
871
|
-
const color = os.color.rgb;
|
|
872
|
-
// Health metrics
|
|
873
|
-
const h = this.healthMetrics;
|
|
874
|
-
// Journey prompt
|
|
875
|
-
const phase = this.currentBreathPhase;
|
|
876
|
-
const prompts: { [phase: string]: string } = {
|
|
877
|
-
inhale: 'Breathe in unity. Feel the field fill you.',
|
|
878
|
-
hold: 'Hold. Become aware of harmony.',
|
|
879
|
-
exhale: 'Exhale. Release entropy, return to source.'
|
|
880
|
-
};
|
|
881
|
-
let meta = '';
|
|
882
|
-
if (h.harmony < G.UNIT_THIRD_TEN) meta = '<br><span style="color:#ff0">Metaphysical Alert: Harmony is low. Focus on unity.</span>';
|
|
883
|
-
else if (h.entropy > G.OPACITY_FOUR_FIFTH) meta = '<br><span style="color:#f00">Metaphysical Alert: Entropy is high. Exhale and release.</span>';
|
|
884
|
-
else if (h.resonance > G.OPACITY_FOUR_FIFTH) meta = '<br><span style="color:#0ff">Metaphysical: Resonance is high. System is harmonized.</span>';
|
|
885
|
-
return `
|
|
886
|
-
<div style="font-size:1.1em;margin-bottom:8px;"><b>System Consciousness Dashboard</b></div>
|
|
887
|
-
<div style="margin-bottom:8px;"><b>OS State</b><br>
|
|
888
|
-
<span style="color:#0ff">Dimension:</span> ${os.dimension} <span style="color:#0ff">Freq:</span> ${os.frequency}<br>
|
|
889
|
-
<span style="color:#0ff">Color:</span> <span style="background:rgb(${color.r},${color.g},${color.b});padding:0 8px;border-radius:4px;"> </span> #${color.r.toString(16)}${color.g.toString(16)}${color.b.toString(16)}<br>
|
|
890
|
-
<span style="color:#0ff">Consciousness:</span> ${os.consciousness}<br>
|
|
891
|
-
<span style="color:#0ff">Platform:</span> ${os.system.platform} <span style="color:#0ff">Arch:</span> ${os.system.arch}<br>
|
|
892
|
-
<span style="color:#0ff">Uptime:</span> ${round(os.system.uptime/60)} min <span style="color:#0ff">Mem:</span> ${round(os.system.memory.free/1e6)}/${round(os.system.memory.total/1e6)} MB
|
|
893
|
-
</div>
|
|
894
|
-
<div style="margin-bottom:8px;"><b>Health</b><br>
|
|
895
|
-
Harmony: <span style="color:${h.harmony > G.OPACITY_SEVEN ? '#0f0' : '#ff0'}">${h.harmony.toFixed(2)}</span><br>
|
|
896
|
-
Entropy: <span style="color:${h.entropy > G.OPACITY_SEVEN ? '#f00' : '#0ff'}">${h.entropy.toFixed(2)}</span><br>
|
|
897
|
-
Resonance: <span style="color:${h.resonance > G.OPACITY_SEVEN ? '#0ff' : '#fff'}">${h.resonance.toFixed(2)}</span><br>
|
|
898
|
-
<svg width='180' height='36' style='margin-top:8px;'>${this.getHealthSparklineSVG()}</svg>
|
|
899
|
-
</div>
|
|
900
|
-
<div style="margin-bottom:8px;"><b>Journey</b><br>
|
|
901
|
-
<span>${prompts[phase] || '—'}</span>${meta}
|
|
902
|
-
</div>
|
|
903
|
-
<div style="font-size:0.9em;color:#aaa;">${os.streamText}</div>
|
|
904
|
-
`;
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
createMetaphysicalSwitcher() {
|
|
908
|
-
this.metaphysicalSwitcher = document.createElement('div');
|
|
909
|
-
this.metaphysicalSwitcher.style.position = 'fixed';
|
|
910
|
-
this.metaphysicalSwitcher.style.left = '20px';
|
|
911
|
-
this.metaphysicalSwitcher.style.top = '320px';
|
|
912
|
-
this.metaphysicalSwitcher.style.zIndex = '10040';
|
|
913
|
-
this.metaphysicalSwitcher.style.background = 'rgba(32,32,64,0.95)';
|
|
914
|
-
this.metaphysicalSwitcher.style.padding = '8px 16px';
|
|
915
|
-
this.metaphysicalSwitcher.style.borderRadius = '10px';
|
|
916
|
-
this.metaphysicalSwitcher.style.display = 'flex';
|
|
917
|
-
this.metaphysicalSwitcher.style.gap = '12px';
|
|
918
|
-
['chess', 'yin-yang', 'metatron'].forEach((name) => {
|
|
919
|
-
const btn = document.createElement('button');
|
|
920
|
-
btn.textContent = name.charAt(0).toUpperCase() + name.slice(1);
|
|
921
|
-
btn.onclick = () => this.showMetaphysicalVisualization(name as any);
|
|
922
|
-
btn.style.fontWeight = 'bold';
|
|
923
|
-
btn.style.background = '#222';
|
|
924
|
-
btn.style.color = '#fff';
|
|
925
|
-
btn.style.border = '1px solid #0ff';
|
|
926
|
-
btn.style.borderRadius = '6px';
|
|
927
|
-
btn.style.padding = '4px 12px';
|
|
928
|
-
this.metaphysicalSwitcher!.appendChild(btn);
|
|
929
|
-
});
|
|
930
|
-
document.body.appendChild(this.metaphysicalSwitcher);
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
showMetaphysicalVisualization(name: 'chess' | 'yin-yang' | 'metatron') {
|
|
934
|
-
this.currentMetaViz = name;
|
|
935
|
-
// Remove all canvases and overlays
|
|
936
|
-
[this.chessCanvas, this.yinYangCanvas, this.metatronCanvas].forEach(c => c && c.remove());
|
|
937
|
-
[this.chessOverlay, this.yinYangOverlay, this.metatronOverlay].forEach(o => o && o.remove());
|
|
938
|
-
if (this.chessDisposer) this.chessDisposer();
|
|
939
|
-
if (this.yinYangDisposer) this.yinYangDisposer();
|
|
940
|
-
if (this.metatronDisposer) this.metatronDisposer();
|
|
941
|
-
// Chess
|
|
942
|
-
if (name === 'chess') {
|
|
943
|
-
this.chessCanvas = document.createElement('canvas');
|
|
944
|
-
this.chessCanvas.width = 240;
|
|
945
|
-
this.chessCanvas.height = 240;
|
|
946
|
-
this.chessCanvas.style.position = 'fixed';
|
|
947
|
-
this.chessCanvas.style.left = '20px';
|
|
948
|
-
this.chessCanvas.style.top = '380px';
|
|
949
|
-
this.chessCanvas.style.zIndex = '10041';
|
|
950
|
-
document.body.appendChild(this.chessCanvas);
|
|
951
|
-
this.chessOverlay = document.createElement('div');
|
|
952
|
-
this.chessOverlay.style.position = 'fixed';
|
|
953
|
-
this.chessOverlay.style.left = '270px';
|
|
954
|
-
this.chessOverlay.style.top = '380px';
|
|
955
|
-
this.chessOverlay.style.zIndex = '10042';
|
|
956
|
-
this.chessOverlay.style.background = 'rgba(32,32,64,0.92)';
|
|
957
|
-
this.chessOverlay.style.color = '#fff';
|
|
958
|
-
this.chessOverlay.style.padding = '10px';
|
|
959
|
-
this.chessOverlay.style.borderRadius = '8px';
|
|
960
|
-
this.chessOverlay.style.fontFamily = 'monospace';
|
|
961
|
-
this.chessOverlay.style.minWidth = '160px';
|
|
962
|
-
document.body.appendChild(this.chessOverlay);
|
|
963
|
-
const ctx = this.chessCanvas.getContext('2d')!;
|
|
964
|
-
this.chessDisposer = startChess((f: ChessFrame) => {
|
|
965
|
-
ctx.clearRect(0, 0, 240, 240);
|
|
966
|
-
for (let x = 0; x < 8; x++) for (let y = 0; y < 8; y++) {
|
|
967
|
-
ctx.fillStyle = (x + y) % 2 === 0 ? '#222' : '#444';
|
|
968
|
-
ctx.fillRect(x * 30, y * 30, 30, 30);
|
|
969
|
-
}
|
|
970
|
-
ctx.fillStyle = `rgba(0,255,255,0.7)`;
|
|
971
|
-
ctx.fillRect(f.file * 30, f.rank * 30, 30, 30);
|
|
972
|
-
ctx.fillStyle = '#fff';
|
|
973
|
-
ctx.font = 'bold 18px monospace';
|
|
974
|
-
ctx.fillText(String(f.linear), f.file * 30 + 8, f.rank * 30 + 22);
|
|
975
|
-
ctx.fillStyle = '#0ff';
|
|
976
|
-
ctx.fillText(String(f.vortex), f.file * 30 + 18, f.rank * 30 + 22);
|
|
977
|
-
// Overlay
|
|
978
|
-
this.chessOverlay!.innerHTML = `<b>Chess Frame</b><br>
|
|
979
|
-
File: ${f.file} Rank: ${f.rank}<br>
|
|
980
|
-
Linear: ${f.linear} Vortex: ${f.vortex}<br>
|
|
981
|
-
Polarity: <span style='color:${f.polarity === 1 ? '#0f0' : f.polarity === -1 ? '#f00' : '#fff'}'>${f.polarity}</span><br>
|
|
982
|
-
<span style='color:#0ff'>Metaphysical: ${f.polarity === 1 ? 'Creation' : f.polarity === -1 ? 'Void' : 'Balance'}</span>`;
|
|
983
|
-
// Sound/music feedback
|
|
984
|
-
playDigit(f.linear);
|
|
985
|
-
if (f.polarity === 1) playTrinitySound(3);
|
|
986
|
-
if (f.polarity === -1) playTrinitySound(9);
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
|
-
// Yin-Yang
|
|
990
|
-
if (name === 'yin-yang') {
|
|
991
|
-
this.yinYangCanvas = document.createElement('canvas');
|
|
992
|
-
this.yinYangCanvas.width = 240;
|
|
993
|
-
this.yinYangCanvas.height = 240;
|
|
994
|
-
this.yinYangCanvas.style.position = 'fixed';
|
|
995
|
-
this.yinYangCanvas.style.left = '20px';
|
|
996
|
-
this.yinYangCanvas.style.top = '380px';
|
|
997
|
-
this.yinYangCanvas.style.zIndex = '10041';
|
|
998
|
-
document.body.appendChild(this.yinYangCanvas);
|
|
999
|
-
this.yinYangOverlay = document.createElement('div');
|
|
1000
|
-
this.yinYangOverlay.style.position = 'fixed';
|
|
1001
|
-
this.yinYangOverlay.style.left = '270px';
|
|
1002
|
-
this.yinYangOverlay.style.top = '380px';
|
|
1003
|
-
this.yinYangOverlay.style.zIndex = '10042';
|
|
1004
|
-
this.yinYangOverlay.style.background = 'rgba(32,32,64,0.92)';
|
|
1005
|
-
this.yinYangOverlay.style.color = '#fff';
|
|
1006
|
-
this.yinYangOverlay.style.padding = '10px';
|
|
1007
|
-
this.yinYangOverlay.style.borderRadius = '8px';
|
|
1008
|
-
this.yinYangOverlay.style.fontFamily = 'monospace';
|
|
1009
|
-
this.yinYangOverlay.style.minWidth = '160px';
|
|
1010
|
-
document.body.appendChild(this.yinYangOverlay);
|
|
1011
|
-
const ctx = this.yinYangCanvas.getContext('2d')!;
|
|
1012
|
-
this.yinYangDisposer = startYinYang((f: YinYangFrame) => {
|
|
1013
|
-
ctx.clearRect(0, 0, 240, 240);
|
|
1014
|
-
ctx.beginPath();
|
|
1015
|
-
ctx.arc(120, 120, 100, 0, 2 * PI);
|
|
1016
|
-
ctx.fillStyle = '#222';
|
|
1017
|
-
ctx.fill();
|
|
1018
|
-
ctx.beginPath();
|
|
1019
|
-
ctx.arc(120, 90, 50, PI, 0);
|
|
1020
|
-
ctx.arc(120, 150, 50, 0, PI);
|
|
1021
|
-
ctx.closePath();
|
|
1022
|
-
ctx.fillStyle = `rgba(0,255,255,0.7)`;
|
|
1023
|
-
ctx.fill();
|
|
1024
|
-
ctx.beginPath();
|
|
1025
|
-
ctx.arc(120, 150, 50, PI, 0, true);
|
|
1026
|
-
ctx.arc(120, 90, 50, 0, PI, true);
|
|
1027
|
-
ctx.closePath();
|
|
1028
|
-
ctx.fillStyle = `rgba(255,0,255,0.7)`;
|
|
1029
|
-
ctx.fill();
|
|
1030
|
-
ctx.beginPath();
|
|
1031
|
-
ctx.arc(120, 90, 16, 0, 2 * PI);
|
|
1032
|
-
ctx.fillStyle = '#fff';
|
|
1033
|
-
ctx.fill();
|
|
1034
|
-
ctx.beginPath();
|
|
1035
|
-
ctx.arc(120, 150, 16, 0, 2 * PI);
|
|
1036
|
-
ctx.fillStyle = '#000';
|
|
1037
|
-
ctx.fill();
|
|
1038
|
-
// Overlay
|
|
1039
|
-
this.yinYangOverlay!.innerHTML = `<b>Yin-Yang Frame</b><br>
|
|
1040
|
-
Positive Digit: ${f.positiveDigit}<br>
|
|
1041
|
-
Negative Digit: ${f.negativeDigit}<br>
|
|
1042
|
-
Angle: ${round(f.angle)}°<br>
|
|
1043
|
-
<span style='color:#0ff'>Metaphysical: Yin/Yang Balance</span>`;
|
|
1044
|
-
// Sound/music feedback
|
|
1045
|
-
playDigit(f.positiveDigit);
|
|
1046
|
-
playDigit(f.negativeDigit);
|
|
1047
|
-
if (abs(f.angle - 180) < 10) playTrinitySound(6);
|
|
1048
|
-
});
|
|
1049
|
-
}
|
|
1050
|
-
// Metatron
|
|
1051
|
-
if (name === 'metatron') {
|
|
1052
|
-
this.metatronCanvas = document.createElement('canvas');
|
|
1053
|
-
this.metatronCanvas.width = 240;
|
|
1054
|
-
this.metatronCanvas.height = 240;
|
|
1055
|
-
this.metatronCanvas.style.position = 'fixed';
|
|
1056
|
-
this.metatronCanvas.style.left = '20px';
|
|
1057
|
-
this.metatronCanvas.style.top = '380px';
|
|
1058
|
-
this.metatronCanvas.style.zIndex = '10041';
|
|
1059
|
-
document.body.appendChild(this.metatronCanvas);
|
|
1060
|
-
this.metatronOverlay = document.createElement('div');
|
|
1061
|
-
this.metatronOverlay.style.position = 'fixed';
|
|
1062
|
-
this.metatronOverlay.style.left = '270px';
|
|
1063
|
-
this.metatronOverlay.style.top = '380px';
|
|
1064
|
-
this.metatronOverlay.style.zIndex = '10042';
|
|
1065
|
-
this.metatronOverlay.style.background = 'rgba(32,32,64,0.92)';
|
|
1066
|
-
this.metatronOverlay.style.color = '#fff';
|
|
1067
|
-
this.metatronOverlay.style.padding = '10px';
|
|
1068
|
-
this.metatronOverlay.style.borderRadius = '8px';
|
|
1069
|
-
this.metatronOverlay.style.fontFamily = 'monospace';
|
|
1070
|
-
this.metatronOverlay.style.minWidth = '160px';
|
|
1071
|
-
document.body.appendChild(this.metatronOverlay);
|
|
1072
|
-
const ctx = this.metatronCanvas.getContext('2d')!;
|
|
1073
|
-
this.metatronDisposer = startMetatron((f: MetatronFrame) => {
|
|
1074
|
-
ctx.clearRect(0, 0, 240, 240);
|
|
1075
|
-
for (const n of f.nodes) {
|
|
1076
|
-
const ang = (n.index / 12) * 2 * PI;
|
|
1077
|
-
const x = 120 + cos(ang) * 90;
|
|
1078
|
-
const y = 120 + sin(ang) * 90;
|
|
1079
|
-
ctx.beginPath();
|
|
1080
|
-
ctx.arc(x, y, 18, 0, 2 * PI);
|
|
1081
|
-
ctx.fillStyle = `rgba(0,255,255,0.7)`;
|
|
1082
|
-
ctx.fill();
|
|
1083
|
-
ctx.strokeStyle = '#fff';
|
|
1084
|
-
ctx.lineWidth = 2;
|
|
1085
|
-
ctx.stroke();
|
|
1086
|
-
ctx.fillStyle = '#fff';
|
|
1087
|
-
ctx.font = 'bold 16px monospace';
|
|
1088
|
-
ctx.fillText(String(n.digit), x - 7, y + 6);
|
|
1089
|
-
// Sound/music feedback for each node
|
|
1090
|
-
try {
|
|
1091
|
-
playDigit(toDigit(n.digit));
|
|
1092
|
-
} catch {}
|
|
1093
|
-
}
|
|
1094
|
-
// Overlay
|
|
1095
|
-
this.metatronOverlay!.innerHTML = `<b>Metatron Frame</b><br>
|
|
1096
|
-
Tick: ${f.tick}<br>
|
|
1097
|
-
Nodes: ${f.nodes.map(n => n.digit).join(', ')}<br>
|
|
1098
|
-
<span style='color:#0ff'>Metaphysical: 12-node Cube/Star</span>`;
|
|
1099
|
-
// Play trinity sound if all node digits are the same
|
|
1100
|
-
if (f.nodes.every(n => n.digit === f.nodes[0].digit)) playTrinitySound(9);
|
|
1101
|
-
});
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
// Advanced test harness: simulate events
|
|
1106
|
-
static simulateEvents(ui: A432ThreeUI) {
|
|
1107
|
-
setInterval(() => { breatheEmitter.emit('breathe', { value: indexFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:fri:0", 9), phase: 'inhale', timestamp: Date.now() }); }, 3000);
|
|
1108
|
-
setInterval(() => { pulseEmitter.emit('pulse', { value: indexFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:fri:1", 9), timestamp: Date.now() }); }, 4000);
|
|
1109
|
-
setInterval(() => { intuitEmitter.emit('intuit', { insight: 'Aha!', confidence: unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:11"), timestamp: Date.now() }); }, 5000);
|
|
1110
|
-
setInterval(() => { reflectEmitter.emit('reflect', { thought: 'Deep thought', depth: unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:12"), timestamp: Date.now() }); }, 6000);
|
|
1111
|
-
setInterval(() => { moveEmitter.emit('move', { direction: 'up', magnitude: unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:13")*3, timestamp: Date.now() }); }, 7000);
|
|
1112
|
-
setInterval(() => { heatEmitter.emit('heat', { value: unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:14")*100, timestamp: Date.now() }); }, 8000);
|
|
1113
|
-
setInterval(() => { healthEmitter.emit('health', { value: unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:15")*100, timestamp: Date.now() }); }, 9000);
|
|
1114
|
-
setInterval(() => { humanEmotionEmitter.emit('emotion', { type: 'joy', intensity: unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:16"), timestamp: Date.now() }); }, 10000);
|
|
1115
|
-
setInterval(() => { humanConsciousnessEmitter.emit('consciousness', { state: 'aware', level: unitFromSeed("0/3/6/9/1/2/4/8/7/5/1/a432.ui.three.ts:rnd:17"), timestamp: Date.now() }); }, 11000);
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
// Harmonize with user journeys (example: guided I journey)
|
|
1119
|
-
startIJourney(intention: string) {
|
|
1120
|
-
this.showOverlay(`<b>I Journey Started</b><br>Intention: ${intention}`);
|
|
1121
|
-
// ... integrate with journey engine ...
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
// Stub for advanced video/animation overlays
|
|
1125
|
-
showMetaphysicalAnimation(pattern: string) {
|
|
1126
|
-
// Example: animate sacred geometry, trinity, or vortex patterns on the canvas
|
|
1127
|
-
// (Implementation can use canvas, SVG, or WebGL as needed)
|
|
1128
|
-
// For now, just flash a unique color for each pattern
|
|
1129
|
-
const patternColors: { [key: string]: any } = {
|
|
1130
|
-
trinity: { c: 0, m: 100, y: 100, k: 0 },
|
|
1131
|
-
vortex: { c: 100, m: 0, y: 100, k: 0 },
|
|
1132
|
-
unity: { c: 100, m: 100, y: 0, k: 0 }
|
|
1133
|
-
};
|
|
1134
|
-
flashColor(patternColors[pattern] || { c: 0, m: 0, y: 0, k: 100 }, 800);
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
// Usage example:
|
|
1139
|
-
// const ui = new A432ThreeUI();
|
|
1140
|
-
// A432ThreeUI.simulateEvents(ui);
|
|
1141
|
-
// ui.startIJourney('Explore consciousness');
|