@testgorilla/tgo-ui 5.0.0 → 5.0.2
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/components/ai-audio-circle/ai-audio-circle.component.d.ts +59 -0
- package/components/ai-audio-circle/ai-audio-circle.module.d.ts +8 -0
- package/components/ai-audio-circle/index.d.ts +5 -0
- package/components/ai-audio-circle/public-api.d.ts +2 -0
- package/fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs +418 -0
- package/fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs.map +1 -0
- package/fesm2022/testgorilla-tgo-ui.mjs +1 -0
- package/fesm2022/testgorilla-tgo-ui.mjs.map +1 -1
- package/package.json +12 -9
- package/public-api.d.ts +1 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { OnDestroy, WritableSignal, ElementRef, AfterViewInit } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare enum InterviewState {
|
|
4
|
+
CandidateSpeaking = "candidate-speaking",
|
|
5
|
+
AiListening = "ai-listening",
|
|
6
|
+
AiSpeaking = "ai-speaking"
|
|
7
|
+
}
|
|
8
|
+
export declare class AiAudioCircleComponent implements OnDestroy, AfterViewInit {
|
|
9
|
+
pulseCanvasRef?: ElementRef<HTMLCanvasElement>;
|
|
10
|
+
audioTrack: import("@angular/core").InputSignal<MediaStreamTrack | undefined>;
|
|
11
|
+
candidateAudioTrack: import("@angular/core").InputSignal<MediaStreamTrack | undefined>;
|
|
12
|
+
state: import("@angular/core").ModelSignal<InterviewState>;
|
|
13
|
+
canvasSize: import("@angular/core").InputSignal<number>;
|
|
14
|
+
isSpeaking: WritableSignal<boolean>;
|
|
15
|
+
scaleValue: WritableSignal<number>;
|
|
16
|
+
audioContext?: AudioContext;
|
|
17
|
+
analyser?: AnalyserNode;
|
|
18
|
+
candidateAnalyser?: AnalyserNode;
|
|
19
|
+
dataArray?: Uint8Array<ArrayBuffer>;
|
|
20
|
+
candidateDataArray?: Uint8Array<ArrayBuffer>;
|
|
21
|
+
animationFrameId?: number;
|
|
22
|
+
source?: MediaStreamAudioSourceNode;
|
|
23
|
+
candidateSource?: MediaStreamAudioSourceNode;
|
|
24
|
+
pulseCtx?: CanvasRenderingContext2D;
|
|
25
|
+
currentAmp: number;
|
|
26
|
+
simTime: number;
|
|
27
|
+
baseRadius: import("@angular/core").Signal<number>;
|
|
28
|
+
readonly AI_SPEAKING_THRESHOLD = 0.02;
|
|
29
|
+
readonly CANDIDATE_SPEAKING_THRESHOLD = 0.5;
|
|
30
|
+
readonly SHADOW_COLOR_RGB: string;
|
|
31
|
+
pulseTime: number;
|
|
32
|
+
pulseScale: number;
|
|
33
|
+
pulseTargetScale: number;
|
|
34
|
+
pulseAnimationId?: number;
|
|
35
|
+
blobs: Array<{
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
vx: number;
|
|
39
|
+
vy: number;
|
|
40
|
+
radius: number;
|
|
41
|
+
color: string;
|
|
42
|
+
opacity: number;
|
|
43
|
+
}>;
|
|
44
|
+
constructor();
|
|
45
|
+
ngAfterViewInit(): void;
|
|
46
|
+
private initializeCanvas;
|
|
47
|
+
private initializeBlobs;
|
|
48
|
+
private setupAudioAnalysis;
|
|
49
|
+
private setupCandidateAudioAnalysis;
|
|
50
|
+
private analyzeAudio;
|
|
51
|
+
private startAnimations;
|
|
52
|
+
private mainLoop;
|
|
53
|
+
private animatePulse;
|
|
54
|
+
private hexToRgb;
|
|
55
|
+
private cleanup;
|
|
56
|
+
ngOnDestroy(): void;
|
|
57
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AiAudioCircleComponent, never>;
|
|
58
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AiAudioCircleComponent, "ui-ai-audio-circle", never, { "audioTrack": { "alias": "audioTrack"; "required": false; "isSignal": true; }; "candidateAudioTrack": { "alias": "candidateAudioTrack"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "canvasSize": { "alias": "canvasSize"; "required": false; "isSignal": true; }; }, { "state": "stateChange"; }, never, never, false, never>;
|
|
59
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import * as i1 from "./ai-audio-circle.component";
|
|
3
|
+
import * as i2 from "@angular/common";
|
|
4
|
+
export declare class AiAudioCircleModule {
|
|
5
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AiAudioCircleModule, never>;
|
|
6
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<AiAudioCircleModule, [typeof i1.AiAudioCircleComponent], [typeof i2.CommonModule], [typeof i1.AiAudioCircleComponent]>;
|
|
7
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<AiAudioCircleModule>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, model, signal, computed, effect, ViewChild, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
|
|
3
|
+
import { Color } from '@testgorilla/tgo-ui/components/core';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
|
|
6
|
+
var InterviewState;
|
|
7
|
+
(function (InterviewState) {
|
|
8
|
+
InterviewState["CandidateSpeaking"] = "candidate-speaking";
|
|
9
|
+
InterviewState["AiListening"] = "ai-listening";
|
|
10
|
+
InterviewState["AiSpeaking"] = "ai-speaking";
|
|
11
|
+
})(InterviewState || (InterviewState = {}));
|
|
12
|
+
class AiAudioCircleComponent {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.audioTrack = input();
|
|
15
|
+
this.candidateAudioTrack = input();
|
|
16
|
+
this.state = model(InterviewState.AiListening);
|
|
17
|
+
this.canvasSize = input(280);
|
|
18
|
+
this.isSpeaking = signal(false);
|
|
19
|
+
this.scaleValue = signal(1);
|
|
20
|
+
this.currentAmp = 0.02;
|
|
21
|
+
this.simTime = 0;
|
|
22
|
+
this.baseRadius = computed(() => this.canvasSize() * 0.38);
|
|
23
|
+
// Audio detection thresholds
|
|
24
|
+
this.AI_SPEAKING_THRESHOLD = 0.02;
|
|
25
|
+
this.CANDIDATE_SPEAKING_THRESHOLD = 0.5;
|
|
26
|
+
this.SHADOW_COLOR_RGB = this.hexToRgb(Color.BRAND_50);
|
|
27
|
+
this.pulseTime = 0;
|
|
28
|
+
this.pulseScale = 1;
|
|
29
|
+
this.pulseTargetScale = 1;
|
|
30
|
+
this.blobs = [];
|
|
31
|
+
effect(() => {
|
|
32
|
+
const audioTrack = this.audioTrack();
|
|
33
|
+
if (audioTrack) {
|
|
34
|
+
this.setupAudioAnalysis();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
effect(() => {
|
|
38
|
+
const candidateAudioTrack = this.candidateAudioTrack();
|
|
39
|
+
if (candidateAudioTrack) {
|
|
40
|
+
this.setupCandidateAudioAnalysis();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
ngAfterViewInit() {
|
|
45
|
+
this.initializeCanvas();
|
|
46
|
+
this.initializeBlobs();
|
|
47
|
+
this.startAnimations();
|
|
48
|
+
}
|
|
49
|
+
initializeCanvas() {
|
|
50
|
+
if (!this.pulseCanvasRef) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const pulseCanvas = this.pulseCanvasRef.nativeElement;
|
|
54
|
+
const dpr = window.devicePixelRatio || 1;
|
|
55
|
+
// Setup pulse canvas
|
|
56
|
+
const size = this.canvasSize();
|
|
57
|
+
pulseCanvas.width = size * dpr;
|
|
58
|
+
pulseCanvas.height = size * dpr;
|
|
59
|
+
pulseCanvas.style.width = `${size}px`;
|
|
60
|
+
pulseCanvas.style.height = `${size}px`;
|
|
61
|
+
const ctx = pulseCanvas.getContext('2d');
|
|
62
|
+
if (!ctx) {
|
|
63
|
+
console.error('[AI_AUDIO_CIRCLE] Failed to get 2d context');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.pulseCtx = ctx;
|
|
67
|
+
this.pulseCtx.scale(dpr, dpr);
|
|
68
|
+
}
|
|
69
|
+
initializeBlobs() {
|
|
70
|
+
const size = this.canvasSize();
|
|
71
|
+
const centerX = size / 2;
|
|
72
|
+
const centerY = size / 2;
|
|
73
|
+
const baseRadius = this.baseRadius();
|
|
74
|
+
const colors = [
|
|
75
|
+
{ color: Color.INFORMATIVE_30, opacity: 0.8 },
|
|
76
|
+
{ color: Color.INFORMATIVE_20, opacity: 0.7 },
|
|
77
|
+
{ color: Color.BRAND_50, opacity: 0.75 },
|
|
78
|
+
{ color: Color.BRAND_20, opacity: 0.6 },
|
|
79
|
+
{ color: Color.INFORMATIVE_30, opacity: 0.65 },
|
|
80
|
+
];
|
|
81
|
+
this.blobs = colors.map((c, i) => {
|
|
82
|
+
const angle = (i / colors.length) * Math.PI * 2;
|
|
83
|
+
const dist = baseRadius * 0.25;
|
|
84
|
+
return {
|
|
85
|
+
x: centerX + Math.cos(angle) * dist,
|
|
86
|
+
y: centerY + Math.sin(angle) * dist,
|
|
87
|
+
vx: (Math.random() - 0.5) * 0.4,
|
|
88
|
+
vy: (Math.random() - 0.5) * 0.4,
|
|
89
|
+
radius: baseRadius * (0.6 + Math.random() * 0.4),
|
|
90
|
+
color: c.color,
|
|
91
|
+
opacity: c.opacity,
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
setupAudioAnalysis() {
|
|
96
|
+
const audioTrack = this.audioTrack();
|
|
97
|
+
if (!audioTrack) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
if (!this.audioContext) {
|
|
102
|
+
this.audioContext = new AudioContext();
|
|
103
|
+
}
|
|
104
|
+
this.analyser = this.audioContext.createAnalyser();
|
|
105
|
+
this.analyser.fftSize = 256;
|
|
106
|
+
this.analyser.smoothingTimeConstant = 0.8;
|
|
107
|
+
const bufferLength = this.analyser.frequencyBinCount;
|
|
108
|
+
this.dataArray = new Uint8Array(bufferLength);
|
|
109
|
+
const stream = new MediaStream([audioTrack]);
|
|
110
|
+
this.source = this.audioContext.createMediaStreamSource(stream);
|
|
111
|
+
this.source.connect(this.analyser);
|
|
112
|
+
this.analyzeAudio();
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
console.error('[AI_AUDIO_CIRCLE] Error setting up audio analysis:', error);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
setupCandidateAudioAnalysis() {
|
|
119
|
+
const candidateAudioTrack = this.candidateAudioTrack();
|
|
120
|
+
if (!candidateAudioTrack) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
if (!this.audioContext) {
|
|
125
|
+
this.audioContext = new AudioContext();
|
|
126
|
+
}
|
|
127
|
+
this.candidateAnalyser = this.audioContext.createAnalyser();
|
|
128
|
+
this.candidateAnalyser.fftSize = 256;
|
|
129
|
+
this.candidateAnalyser.smoothingTimeConstant = 0.8;
|
|
130
|
+
const bufferLength = this.candidateAnalyser.frequencyBinCount;
|
|
131
|
+
this.candidateDataArray = new Uint8Array(bufferLength);
|
|
132
|
+
const stream = new MediaStream([candidateAudioTrack]);
|
|
133
|
+
this.candidateSource = this.audioContext.createMediaStreamSource(stream);
|
|
134
|
+
this.candidateSource.connect(this.candidateAnalyser);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error('[AI_AUDIO_CIRCLE] Error setting up candidate audio analysis:', error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
analyzeAudio() {
|
|
141
|
+
if (!this.analyser || !this.dataArray) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const analyze = () => {
|
|
145
|
+
if (!this.analyser || !this.dataArray) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
// Analyze AI audio
|
|
149
|
+
this.analyser.getByteFrequencyData(this.dataArray);
|
|
150
|
+
const sum = Array.from(this.dataArray).reduce((a, b) => a + b, 0);
|
|
151
|
+
const aiVolume = sum / this.dataArray.length / 255;
|
|
152
|
+
// Analyze candidate audio if available
|
|
153
|
+
let candidateVolume = 0;
|
|
154
|
+
if (this.candidateAnalyser && this.candidateDataArray) {
|
|
155
|
+
this.candidateAnalyser.getByteFrequencyData(this.candidateDataArray);
|
|
156
|
+
const candidateSum = Array.from(this.candidateDataArray).reduce((a, b) => a + b, 0);
|
|
157
|
+
candidateVolume = candidateSum / this.candidateDataArray.length / 255;
|
|
158
|
+
}
|
|
159
|
+
const aiSpeaking = aiVolume > this.AI_SPEAKING_THRESHOLD;
|
|
160
|
+
const candidateSpeaking = candidateVolume > this.CANDIDATE_SPEAKING_THRESHOLD;
|
|
161
|
+
if (candidateSpeaking) {
|
|
162
|
+
this.state.set(InterviewState.CandidateSpeaking);
|
|
163
|
+
}
|
|
164
|
+
else if (aiSpeaking) {
|
|
165
|
+
this.state.set(InterviewState.AiSpeaking);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
this.state.set(InterviewState.AiListening);
|
|
169
|
+
}
|
|
170
|
+
this.isSpeaking.set(aiSpeaking);
|
|
171
|
+
// Update amplitude for animations
|
|
172
|
+
const currentStateValue = this.state();
|
|
173
|
+
if (currentStateValue === InterviewState.AiSpeaking && aiSpeaking) {
|
|
174
|
+
const target = Math.pow(aiVolume, 0.8) * 1.3;
|
|
175
|
+
this.currentAmp += (target - this.currentAmp) * 0.4;
|
|
176
|
+
}
|
|
177
|
+
else if (currentStateValue === InterviewState.CandidateSpeaking) {
|
|
178
|
+
const target = 0.55;
|
|
179
|
+
this.currentAmp += (target - this.currentAmp) * 0.1;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
const fixedBase = 0.2;
|
|
183
|
+
this.currentAmp += (fixedBase - this.currentAmp) * 0.05;
|
|
184
|
+
}
|
|
185
|
+
this.animationFrameId = requestAnimationFrame(analyze);
|
|
186
|
+
};
|
|
187
|
+
this.animationFrameId = requestAnimationFrame(analyze);
|
|
188
|
+
}
|
|
189
|
+
startAnimations() {
|
|
190
|
+
this.animatePulse();
|
|
191
|
+
this.mainLoop();
|
|
192
|
+
}
|
|
193
|
+
mainLoop() {
|
|
194
|
+
this.simTime += 0.05;
|
|
195
|
+
const currentStateValue = this.state();
|
|
196
|
+
if (currentStateValue === InterviewState.AiSpeaking) {
|
|
197
|
+
if (this.analyser && this.dataArray) {
|
|
198
|
+
// Use real audio amplitude (already handled in analyzeAudio)
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// Simulated speaking
|
|
202
|
+
const rhythm = Math.sin(this.simTime * 0.8) * 0.5 + 0.5;
|
|
203
|
+
const spikes = Math.random() * 0.6;
|
|
204
|
+
const target = rhythm * spikes;
|
|
205
|
+
this.currentAmp += (target - this.currentAmp) * 0.2;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
else if (currentStateValue === InterviewState.CandidateSpeaking) {
|
|
209
|
+
const target = 0.55;
|
|
210
|
+
this.currentAmp += (target - this.currentAmp) * 0.1;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
const fixedBase = 0.2;
|
|
214
|
+
this.currentAmp += (fixedBase - this.currentAmp) * 0.05;
|
|
215
|
+
}
|
|
216
|
+
requestAnimationFrame(this.mainLoop);
|
|
217
|
+
}
|
|
218
|
+
animatePulse() {
|
|
219
|
+
if (!this.pulseCtx) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const ctx = this.pulseCtx;
|
|
223
|
+
this.pulseTime += 0.016;
|
|
224
|
+
const size = this.canvasSize();
|
|
225
|
+
const centerX = size / 2;
|
|
226
|
+
const centerY = size / 2;
|
|
227
|
+
const baseRadius = this.baseRadius();
|
|
228
|
+
ctx.clearRect(0, 0, size, size);
|
|
229
|
+
const currentStateValue = this.state();
|
|
230
|
+
const effectiveAmp = this.currentAmp;
|
|
231
|
+
const isListening = currentStateValue === InterviewState.AiListening;
|
|
232
|
+
const isCandidate = currentStateValue === InterviewState.CandidateSpeaking;
|
|
233
|
+
// Scale logic
|
|
234
|
+
if (isCandidate) {
|
|
235
|
+
// Candidate speaking: Fixed enlarged scale (115%), no breathing effect
|
|
236
|
+
this.pulseTargetScale = 1.15;
|
|
237
|
+
const breathing = 0;
|
|
238
|
+
this.pulseScale += (this.pulseTargetScale + breathing - this.pulseScale) * 0.05;
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// AI speaking/listening: Scale reacts to audio amplitude, with optional breathing
|
|
242
|
+
// When AI is speaking: effectiveAmp is high, scale grows with voice
|
|
243
|
+
// When AI is listening: effectiveAmp is low (~0.2), scale stays near 1.0 with breathing effect
|
|
244
|
+
this.pulseTargetScale = 1 + effectiveAmp * 0.3;
|
|
245
|
+
const breathing = isListening ? Math.sin(this.pulseTime * 1.5) * 0.035 : 0;
|
|
246
|
+
this.pulseScale += (this.pulseTargetScale + breathing - this.pulseScale) * 0.05;
|
|
247
|
+
}
|
|
248
|
+
const currentRadius = baseRadius * this.pulseScale;
|
|
249
|
+
// Draw shadows
|
|
250
|
+
for (let i = 3; i >= 1; i--) {
|
|
251
|
+
const shadowRadius = currentRadius + i * 6;
|
|
252
|
+
const shadowOpacity = 0.24 - i * 0.04;
|
|
253
|
+
const shadowGradient = ctx.createRadialGradient(centerX, centerY, currentRadius * 0.98, centerX, centerY, shadowRadius);
|
|
254
|
+
shadowGradient.addColorStop(0, `rgba(${this.SHADOW_COLOR_RGB}, ${shadowOpacity})`);
|
|
255
|
+
shadowGradient.addColorStop(0.6, `rgba(${this.SHADOW_COLOR_RGB}, ${shadowOpacity * 0.4})`);
|
|
256
|
+
shadowGradient.addColorStop(1, `rgba(${this.SHADOW_COLOR_RGB}, 0)`);
|
|
257
|
+
ctx.beginPath();
|
|
258
|
+
ctx.arc(centerX, centerY, shadowRadius, 0, Math.PI * 2);
|
|
259
|
+
ctx.fillStyle = shadowGradient;
|
|
260
|
+
ctx.fill();
|
|
261
|
+
}
|
|
262
|
+
// Clip to circle
|
|
263
|
+
ctx.save();
|
|
264
|
+
ctx.beginPath();
|
|
265
|
+
ctx.arc(centerX, centerY, currentRadius, 0, Math.PI * 2);
|
|
266
|
+
ctx.clip();
|
|
267
|
+
// Background gradient
|
|
268
|
+
const bgGradient = ctx.createLinearGradient(centerX - currentRadius, centerY - currentRadius, centerX + currentRadius, centerY + currentRadius);
|
|
269
|
+
bgGradient.addColorStop(0, Color.BRAND_50);
|
|
270
|
+
bgGradient.addColorStop(0.5, Color.INFORMATIVE_20);
|
|
271
|
+
bgGradient.addColorStop(1, Color.INFORMATIVE_30);
|
|
272
|
+
ctx.beginPath();
|
|
273
|
+
ctx.arc(centerX, centerY, currentRadius, 0, Math.PI * 2);
|
|
274
|
+
ctx.fillStyle = bgGradient;
|
|
275
|
+
ctx.fill();
|
|
276
|
+
// Animate blobs
|
|
277
|
+
let speedMultiplier;
|
|
278
|
+
if (isCandidate) {
|
|
279
|
+
speedMultiplier = 2.0;
|
|
280
|
+
}
|
|
281
|
+
else if (isListening) {
|
|
282
|
+
speedMultiplier = 1.2;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
speedMultiplier = 0.8 + effectiveAmp * 1.5;
|
|
286
|
+
}
|
|
287
|
+
this.blobs.forEach((blob, index) => {
|
|
288
|
+
// Chaos forces
|
|
289
|
+
const chaos1 = Math.sin(this.pulseTime * 0.6 + index * 2.5 + blob.x * 0.02) * 0.15;
|
|
290
|
+
const chaos2 = Math.cos(this.pulseTime * 0.4 + index * 1.8 + blob.y * 0.015) * 0.12;
|
|
291
|
+
const chaos3 = Math.sin(this.pulseTime * 1.0 + index * 0.7) * 0.08;
|
|
292
|
+
// Apply forces
|
|
293
|
+
blob.vx += (chaos1 + chaos3 * Math.cos(this.pulseTime * 1.5 + index)) * 0.025 * speedMultiplier;
|
|
294
|
+
blob.vy += (chaos2 + chaos3 * Math.sin(this.pulseTime * 1.2 + index)) * 0.025 * speedMultiplier;
|
|
295
|
+
// Friction
|
|
296
|
+
blob.vx *= 0.98;
|
|
297
|
+
blob.vy *= 0.98;
|
|
298
|
+
// Max velocity
|
|
299
|
+
const maxVel = (isListening ? 1.5 : 2.2) * speedMultiplier;
|
|
300
|
+
const vel = Math.sqrt(blob.vx * blob.vx + blob.vy * blob.vy);
|
|
301
|
+
if (vel > maxVel) {
|
|
302
|
+
blob.vx = (blob.vx / vel) * maxVel;
|
|
303
|
+
blob.vy = (blob.vy / vel) * maxVel;
|
|
304
|
+
}
|
|
305
|
+
// Update position
|
|
306
|
+
blob.x += blob.vx;
|
|
307
|
+
blob.y += blob.vy;
|
|
308
|
+
// Keep within bounds
|
|
309
|
+
const dx = blob.x - centerX;
|
|
310
|
+
const dy = blob.y - centerY;
|
|
311
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
312
|
+
const maxDist = currentRadius * 0.55;
|
|
313
|
+
if (dist > maxDist) {
|
|
314
|
+
const angle = Math.atan2(dy, dx);
|
|
315
|
+
blob.x = centerX + Math.cos(angle) * maxDist;
|
|
316
|
+
blob.y = centerY + Math.sin(angle) * maxDist;
|
|
317
|
+
blob.vx -= dx * 0.065;
|
|
318
|
+
blob.vy -= dy * 0.065;
|
|
319
|
+
}
|
|
320
|
+
// Parse color to RGB
|
|
321
|
+
const rgb = this.hexToRgb(blob.color);
|
|
322
|
+
// Draw blob with glow
|
|
323
|
+
const blurRadius = blob.radius * 1.3;
|
|
324
|
+
const outerGlow = ctx.createRadialGradient(blob.x, blob.y, 0, blob.x, blob.y, blurRadius);
|
|
325
|
+
outerGlow.addColorStop(0, `rgba(${rgb}, ${blob.opacity * 0.9})`);
|
|
326
|
+
outerGlow.addColorStop(0.2, `rgba(${rgb}, ${blob.opacity * 0.7})`);
|
|
327
|
+
outerGlow.addColorStop(0.4, `rgba(${rgb}, ${blob.opacity * 0.5})`);
|
|
328
|
+
outerGlow.addColorStop(0.6, `rgba(${rgb}, ${blob.opacity * 0.3})`);
|
|
329
|
+
outerGlow.addColorStop(0.8, `rgba(${rgb}, ${blob.opacity * 0.1})`);
|
|
330
|
+
outerGlow.addColorStop(1, `rgba(${rgb}, 0)`);
|
|
331
|
+
ctx.beginPath();
|
|
332
|
+
ctx.arc(blob.x, blob.y, blurRadius, 0, Math.PI * 2);
|
|
333
|
+
ctx.fillStyle = outerGlow;
|
|
334
|
+
ctx.fill();
|
|
335
|
+
});
|
|
336
|
+
// Highlight
|
|
337
|
+
const highlightGradient = ctx.createRadialGradient(centerX - currentRadius * 0.3, centerY - currentRadius * 0.3, 0, centerX - currentRadius * 0.3, centerY - currentRadius * 0.3, currentRadius * 0.6);
|
|
338
|
+
highlightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.12)');
|
|
339
|
+
highlightGradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.03)');
|
|
340
|
+
highlightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
|
|
341
|
+
ctx.beginPath();
|
|
342
|
+
ctx.arc(centerX, centerY, currentRadius, 0, Math.PI * 2);
|
|
343
|
+
ctx.fillStyle = highlightGradient;
|
|
344
|
+
ctx.fill();
|
|
345
|
+
ctx.restore();
|
|
346
|
+
this.pulseAnimationId = requestAnimationFrame(this.animatePulse);
|
|
347
|
+
}
|
|
348
|
+
;
|
|
349
|
+
hexToRgb(hex) {
|
|
350
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
351
|
+
if (!result) {
|
|
352
|
+
return '0, 0, 0';
|
|
353
|
+
}
|
|
354
|
+
const r = parseInt(result[1], 16);
|
|
355
|
+
const g = parseInt(result[2], 16);
|
|
356
|
+
const b = parseInt(result[3], 16);
|
|
357
|
+
return `${r}, ${g}, ${b}`;
|
|
358
|
+
}
|
|
359
|
+
cleanup() {
|
|
360
|
+
if (this.animationFrameId) {
|
|
361
|
+
cancelAnimationFrame(this.animationFrameId);
|
|
362
|
+
this.animationFrameId = undefined;
|
|
363
|
+
}
|
|
364
|
+
if (this.pulseAnimationId) {
|
|
365
|
+
cancelAnimationFrame(this.pulseAnimationId);
|
|
366
|
+
this.pulseAnimationId = undefined;
|
|
367
|
+
}
|
|
368
|
+
if (this.source) {
|
|
369
|
+
this.source.disconnect();
|
|
370
|
+
this.source = undefined;
|
|
371
|
+
}
|
|
372
|
+
if (this.candidateSource) {
|
|
373
|
+
this.candidateSource.disconnect();
|
|
374
|
+
this.candidateSource = undefined;
|
|
375
|
+
}
|
|
376
|
+
if (this.audioContext && this.audioContext.state !== 'closed') {
|
|
377
|
+
void this.audioContext.close();
|
|
378
|
+
this.audioContext = undefined;
|
|
379
|
+
}
|
|
380
|
+
this.analyser = undefined;
|
|
381
|
+
this.candidateAnalyser = undefined;
|
|
382
|
+
this.dataArray = undefined;
|
|
383
|
+
this.candidateDataArray = undefined;
|
|
384
|
+
}
|
|
385
|
+
ngOnDestroy() {
|
|
386
|
+
this.cleanup();
|
|
387
|
+
}
|
|
388
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: AiAudioCircleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
389
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.18", type: AiAudioCircleComponent, isStandalone: false, selector: "ui-ai-audio-circle", inputs: { audioTrack: { classPropertyName: "audioTrack", publicName: "audioTrack", isSignal: true, isRequired: false, transformFunction: null }, candidateAudioTrack: { classPropertyName: "candidateAudioTrack", publicName: "candidateAudioTrack", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { state: "stateChange" }, viewQueries: [{ propertyName: "pulseCanvasRef", first: true, predicate: ["pulseCanvas"], descendants: true }], ngImport: i0, template: "<div class=\"ai-audio-visualizer\">\n <div class=\"canvas-container\">\n <canvas #pulseCanvas></canvas>\n </div>\n</div>\n", styles: [".ai-audio-visualizer{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%}.canvas-container{position:relative;display:flex;flex-direction:column;justify-content:center;align-items:center}canvas{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
390
|
+
}
|
|
391
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: AiAudioCircleComponent, decorators: [{
|
|
392
|
+
type: Component,
|
|
393
|
+
args: [{ selector: 'ui-ai-audio-circle', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div class=\"ai-audio-visualizer\">\n <div class=\"canvas-container\">\n <canvas #pulseCanvas></canvas>\n </div>\n</div>\n", styles: [".ai-audio-visualizer{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%}.canvas-container{position:relative;display:flex;flex-direction:column;justify-content:center;align-items:center}canvas{display:block}\n"] }]
|
|
394
|
+
}], ctorParameters: () => [], propDecorators: { pulseCanvasRef: [{
|
|
395
|
+
type: ViewChild,
|
|
396
|
+
args: ['pulseCanvas', { static: false }]
|
|
397
|
+
}] } });
|
|
398
|
+
|
|
399
|
+
class AiAudioCircleModule {
|
|
400
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: AiAudioCircleModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
401
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.18", ngImport: i0, type: AiAudioCircleModule, declarations: [AiAudioCircleComponent], imports: [CommonModule], exports: [AiAudioCircleComponent] }); }
|
|
402
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: AiAudioCircleModule, imports: [CommonModule] }); }
|
|
403
|
+
}
|
|
404
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: AiAudioCircleModule, decorators: [{
|
|
405
|
+
type: NgModule,
|
|
406
|
+
args: [{
|
|
407
|
+
declarations: [AiAudioCircleComponent],
|
|
408
|
+
imports: [CommonModule],
|
|
409
|
+
exports: [AiAudioCircleComponent],
|
|
410
|
+
}]
|
|
411
|
+
}] });
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Generated bundle index. Do not edit.
|
|
415
|
+
*/
|
|
416
|
+
|
|
417
|
+
export { AiAudioCircleComponent, AiAudioCircleModule, InterviewState };
|
|
418
|
+
//# sourceMappingURL=testgorilla-tgo-ui-components-ai-audio-circle.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testgorilla-tgo-ui-components-ai-audio-circle.mjs","sources":["../../../components/ai-audio-circle/ai-audio-circle.component.ts","../../../components/ai-audio-circle/ai-audio-circle.component.html","../../../components/ai-audio-circle/ai-audio-circle.module.ts","../../../components/ai-audio-circle/testgorilla-tgo-ui-components-ai-audio-circle.ts"],"sourcesContent":["import {\n Component,\n input,\n model,\n OnDestroy,\n ChangeDetectionStrategy,\n WritableSignal,\n signal,\n ElementRef,\n ViewChild,\n AfterViewInit,\n effect,\n computed,\n} from '@angular/core';\nimport { Color } from '@testgorilla/tgo-ui/components/core';\n\nexport enum InterviewState {\n CandidateSpeaking = 'candidate-speaking',\n AiListening = 'ai-listening',\n AiSpeaking = 'ai-speaking',\n}\n\n@Component({\n selector: 'ui-ai-audio-circle',\n templateUrl: './ai-audio-circle.component.html',\n styleUrls: ['./ai-audio-circle.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false,\n})\nexport class AiAudioCircleComponent implements OnDestroy, AfterViewInit {\n @ViewChild('pulseCanvas', { static: false }) pulseCanvasRef?: ElementRef<HTMLCanvasElement>;\n\n audioTrack = input<MediaStreamTrack>();\n candidateAudioTrack = input<MediaStreamTrack>();\n state = model<InterviewState>(InterviewState.AiListening);\n canvasSize = input<number>(280);\n\n isSpeaking: WritableSignal<boolean> = signal(false);\n scaleValue: WritableSignal<number> = signal(1);\n\n audioContext?: AudioContext;\n analyser?: AnalyserNode;\n candidateAnalyser?: AnalyserNode;\n dataArray?: Uint8Array<ArrayBuffer>;\n candidateDataArray?: Uint8Array<ArrayBuffer>;\n animationFrameId?: number;\n source?: MediaStreamAudioSourceNode;\n candidateSource?: MediaStreamAudioSourceNode;\n\n pulseCtx?: CanvasRenderingContext2D;\n currentAmp = 0.02;\n simTime = 0;\n baseRadius = computed(() => this.canvasSize() * 0.38);\n\n // Audio detection thresholds\n readonly AI_SPEAKING_THRESHOLD = 0.02;\n readonly CANDIDATE_SPEAKING_THRESHOLD = 0.5;\n\n readonly SHADOW_COLOR_RGB = this.hexToRgb(Color.BRAND_50);\n\n pulseTime = 0;\n pulseScale = 1;\n pulseTargetScale = 1;\n pulseAnimationId?: number;\n blobs: Array<{\n x: number;\n y: number;\n vx: number;\n vy: number;\n radius: number;\n color: string;\n opacity: number;\n }> = [];\n\n constructor() {\n effect(() => {\n const audioTrack = this.audioTrack();\n if (audioTrack) {\n this.setupAudioAnalysis();\n }\n });\n\n effect(() => {\n const candidateAudioTrack = this.candidateAudioTrack();\n if (candidateAudioTrack) {\n this.setupCandidateAudioAnalysis();\n }\n });\n }\n\n ngAfterViewInit(): void {\n this.initializeCanvas();\n this.initializeBlobs();\n this.startAnimations();\n }\n\n private initializeCanvas(): void {\n if (!this.pulseCanvasRef) {\n return;\n }\n\n const pulseCanvas = this.pulseCanvasRef.nativeElement;\n\n const dpr = window.devicePixelRatio || 1;\n\n // Setup pulse canvas\n const size = this.canvasSize();\n pulseCanvas.width = size * dpr;\n pulseCanvas.height = size * dpr;\n pulseCanvas.style.width = `${size}px`;\n pulseCanvas.style.height = `${size}px`;\n const ctx = pulseCanvas.getContext('2d');\n if (!ctx) {\n console.error('[AI_AUDIO_CIRCLE] Failed to get 2d context');\n return;\n }\n this.pulseCtx = ctx;\n this.pulseCtx.scale(dpr, dpr);\n }\n\n private initializeBlobs(): void {\n const size = this.canvasSize();\n const centerX = size / 2;\n const centerY = size / 2;\n const baseRadius = this.baseRadius();\n\n const colors = [\n { color: Color.INFORMATIVE_30, opacity: 0.8 },\n { color: Color.INFORMATIVE_20, opacity: 0.7 },\n { color: Color.BRAND_50, opacity: 0.75 },\n { color: Color.BRAND_20, opacity: 0.6 },\n { color: Color.INFORMATIVE_30, opacity: 0.65 },\n ];\n\n this.blobs = colors.map((c, i) => {\n const angle = (i / colors.length) * Math.PI * 2;\n const dist = baseRadius * 0.25;\n return {\n x: centerX + Math.cos(angle) * dist,\n y: centerY + Math.sin(angle) * dist,\n vx: (Math.random() - 0.5) * 0.4,\n vy: (Math.random() - 0.5) * 0.4,\n radius: baseRadius * (0.6 + Math.random() * 0.4),\n color: c.color,\n opacity: c.opacity,\n };\n });\n }\n\n private setupAudioAnalysis(): void {\n const audioTrack = this.audioTrack();\n if (!audioTrack) {\n return;\n }\n\n try {\n if (!this.audioContext) {\n this.audioContext = new AudioContext();\n }\n\n this.analyser = this.audioContext.createAnalyser();\n this.analyser.fftSize = 256;\n this.analyser.smoothingTimeConstant = 0.8;\n\n const bufferLength = this.analyser.frequencyBinCount;\n this.dataArray = new Uint8Array(bufferLength);\n\n const stream = new MediaStream([audioTrack]);\n this.source = this.audioContext.createMediaStreamSource(stream);\n this.source.connect(this.analyser);\n\n this.analyzeAudio();\n } catch (error) {\n console.error('[AI_AUDIO_CIRCLE] Error setting up audio analysis:', error);\n }\n }\n\n private setupCandidateAudioAnalysis(): void {\n const candidateAudioTrack = this.candidateAudioTrack();\n if (!candidateAudioTrack) {\n return;\n }\n\n try {\n if (!this.audioContext) {\n this.audioContext = new AudioContext();\n }\n\n this.candidateAnalyser = this.audioContext.createAnalyser();\n this.candidateAnalyser.fftSize = 256;\n this.candidateAnalyser.smoothingTimeConstant = 0.8;\n\n const bufferLength = this.candidateAnalyser.frequencyBinCount;\n this.candidateDataArray = new Uint8Array(bufferLength);\n\n const stream = new MediaStream([candidateAudioTrack]);\n this.candidateSource = this.audioContext.createMediaStreamSource(stream);\n this.candidateSource.connect(this.candidateAnalyser);\n } catch (error) {\n console.error('[AI_AUDIO_CIRCLE] Error setting up candidate audio analysis:', error);\n }\n }\n\n private analyzeAudio(): void {\n if (!this.analyser || !this.dataArray) {\n return;\n }\n\n const analyze = () => {\n if (!this.analyser || !this.dataArray) {\n return;\n }\n\n // Analyze AI audio\n this.analyser.getByteFrequencyData(this.dataArray);\n const sum = Array.from(this.dataArray).reduce((a, b) => a + b, 0);\n const aiVolume = sum / this.dataArray.length / 255;\n\n // Analyze candidate audio if available\n let candidateVolume = 0;\n if (this.candidateAnalyser && this.candidateDataArray) {\n this.candidateAnalyser.getByteFrequencyData(this.candidateDataArray);\n const candidateSum = Array.from(this.candidateDataArray).reduce((a, b) => a + b, 0);\n candidateVolume = candidateSum / this.candidateDataArray.length / 255;\n }\n\n const aiSpeaking = aiVolume > this.AI_SPEAKING_THRESHOLD;\n const candidateSpeaking = candidateVolume > this.CANDIDATE_SPEAKING_THRESHOLD;\n\n if (candidateSpeaking) {\n this.state.set(InterviewState.CandidateSpeaking);\n } else if (aiSpeaking) {\n this.state.set(InterviewState.AiSpeaking);\n } else {\n this.state.set(InterviewState.AiListening);\n }\n\n this.isSpeaking.set(aiSpeaking);\n\n // Update amplitude for animations\n const currentStateValue = this.state();\n if (currentStateValue === InterviewState.AiSpeaking && aiSpeaking) {\n const target = Math.pow(aiVolume, 0.8) * 1.3;\n this.currentAmp += (target - this.currentAmp) * 0.4;\n } else if (currentStateValue === InterviewState.CandidateSpeaking) {\n const target = 0.55;\n this.currentAmp += (target - this.currentAmp) * 0.1;\n } else {\n const fixedBase = 0.2;\n this.currentAmp += (fixedBase - this.currentAmp) * 0.05;\n }\n\n this.animationFrameId = requestAnimationFrame(analyze);\n };\n\n this.animationFrameId = requestAnimationFrame(analyze);\n }\n\n private startAnimations(): void {\n this.animatePulse();\n this.mainLoop();\n }\n\n private mainLoop(): void {\n this.simTime += 0.05;\n\n const currentStateValue = this.state();\n\n if (currentStateValue === InterviewState.AiSpeaking) {\n if (this.analyser && this.dataArray) {\n // Use real audio amplitude (already handled in analyzeAudio)\n } else {\n // Simulated speaking\n const rhythm = Math.sin(this.simTime * 0.8) * 0.5 + 0.5;\n const spikes = Math.random() * 0.6;\n const target = rhythm * spikes;\n this.currentAmp += (target - this.currentAmp) * 0.2;\n }\n } else if (currentStateValue === InterviewState.CandidateSpeaking) {\n const target = 0.55;\n this.currentAmp += (target - this.currentAmp) * 0.1;\n } else {\n const fixedBase = 0.2;\n this.currentAmp += (fixedBase - this.currentAmp) * 0.05;\n }\n\n requestAnimationFrame(this.mainLoop);\n }\n\n private animatePulse(): void {\n if (!this.pulseCtx) {\n return;\n }\n\n const ctx = this.pulseCtx;\n this.pulseTime += 0.016;\n const size = this.canvasSize();\n const centerX = size / 2;\n const centerY = size / 2;\n const baseRadius = this.baseRadius();\n\n ctx.clearRect(0, 0, size, size);\n\n const currentStateValue = this.state();\n const effectiveAmp = this.currentAmp;\n const isListening = currentStateValue === InterviewState.AiListening;\n const isCandidate = currentStateValue === InterviewState.CandidateSpeaking;\n\n // Scale logic\n if (isCandidate) {\n // Candidate speaking: Fixed enlarged scale (115%), no breathing effect\n this.pulseTargetScale = 1.15;\n const breathing = 0;\n this.pulseScale += (this.pulseTargetScale + breathing - this.pulseScale) * 0.05;\n } else {\n // AI speaking/listening: Scale reacts to audio amplitude, with optional breathing\n // When AI is speaking: effectiveAmp is high, scale grows with voice\n // When AI is listening: effectiveAmp is low (~0.2), scale stays near 1.0 with breathing effect\n this.pulseTargetScale = 1 + effectiveAmp * 0.3;\n const breathing = isListening ? Math.sin(this.pulseTime * 1.5) * 0.035 : 0;\n this.pulseScale += (this.pulseTargetScale + breathing - this.pulseScale) * 0.05;\n }\n\n const currentRadius = baseRadius * this.pulseScale;\n\n // Draw shadows\n for (let i = 3; i >= 1; i--) {\n const shadowRadius = currentRadius + i * 6;\n const shadowOpacity = 0.24 - i * 0.04;\n const shadowGradient = ctx.createRadialGradient(\n centerX,\n centerY,\n currentRadius * 0.98,\n centerX,\n centerY,\n shadowRadius\n );\n shadowGradient.addColorStop(0, `rgba(${this.SHADOW_COLOR_RGB}, ${shadowOpacity})`);\n shadowGradient.addColorStop(0.6, `rgba(${this.SHADOW_COLOR_RGB}, ${shadowOpacity * 0.4})`);\n shadowGradient.addColorStop(1, `rgba(${this.SHADOW_COLOR_RGB}, 0)`);\n ctx.beginPath();\n ctx.arc(centerX, centerY, shadowRadius, 0, Math.PI * 2);\n ctx.fillStyle = shadowGradient;\n ctx.fill();\n }\n\n // Clip to circle\n ctx.save();\n ctx.beginPath();\n ctx.arc(centerX, centerY, currentRadius, 0, Math.PI * 2);\n ctx.clip();\n\n // Background gradient\n const bgGradient = ctx.createLinearGradient(\n centerX - currentRadius,\n centerY - currentRadius,\n centerX + currentRadius,\n centerY + currentRadius\n );\n bgGradient.addColorStop(0, Color.BRAND_50);\n bgGradient.addColorStop(0.5, Color.INFORMATIVE_20);\n bgGradient.addColorStop(1, Color.INFORMATIVE_30);\n ctx.beginPath();\n ctx.arc(centerX, centerY, currentRadius, 0, Math.PI * 2);\n ctx.fillStyle = bgGradient;\n ctx.fill();\n\n // Animate blobs\n let speedMultiplier;\n if (isCandidate) {\n speedMultiplier = 2.0;\n } else if (isListening) {\n speedMultiplier = 1.2;\n } else {\n speedMultiplier = 0.8 + effectiveAmp * 1.5;\n }\n\n this.blobs.forEach((blob, index) => {\n // Chaos forces\n const chaos1 = Math.sin(this.pulseTime * 0.6 + index * 2.5 + blob.x * 0.02) * 0.15;\n const chaos2 = Math.cos(this.pulseTime * 0.4 + index * 1.8 + blob.y * 0.015) * 0.12;\n const chaos3 = Math.sin(this.pulseTime * 1.0 + index * 0.7) * 0.08;\n\n // Apply forces\n blob.vx += (chaos1 + chaos3 * Math.cos(this.pulseTime * 1.5 + index)) * 0.025 * speedMultiplier;\n blob.vy += (chaos2 + chaos3 * Math.sin(this.pulseTime * 1.2 + index)) * 0.025 * speedMultiplier;\n\n // Friction\n blob.vx *= 0.98;\n blob.vy *= 0.98;\n\n // Max velocity\n const maxVel = (isListening ? 1.5 : 2.2) * speedMultiplier;\n const vel = Math.sqrt(blob.vx * blob.vx + blob.vy * blob.vy);\n if (vel > maxVel) {\n blob.vx = (blob.vx / vel) * maxVel;\n blob.vy = (blob.vy / vel) * maxVel;\n }\n\n // Update position\n blob.x += blob.vx;\n blob.y += blob.vy;\n\n // Keep within bounds\n const dx = blob.x - centerX;\n const dy = blob.y - centerY;\n const dist = Math.sqrt(dx * dx + dy * dy);\n const maxDist = currentRadius * 0.55;\n if (dist > maxDist) {\n const angle = Math.atan2(dy, dx);\n blob.x = centerX + Math.cos(angle) * maxDist;\n blob.y = centerY + Math.sin(angle) * maxDist;\n blob.vx -= dx * 0.065;\n blob.vy -= dy * 0.065;\n }\n\n // Parse color to RGB\n const rgb = this.hexToRgb(blob.color);\n\n // Draw blob with glow\n const blurRadius = blob.radius * 1.3;\n const outerGlow = ctx.createRadialGradient(blob.x, blob.y, 0, blob.x, blob.y, blurRadius);\n outerGlow.addColorStop(0, `rgba(${rgb}, ${blob.opacity * 0.9})`);\n outerGlow.addColorStop(0.2, `rgba(${rgb}, ${blob.opacity * 0.7})`);\n outerGlow.addColorStop(0.4, `rgba(${rgb}, ${blob.opacity * 0.5})`);\n outerGlow.addColorStop(0.6, `rgba(${rgb}, ${blob.opacity * 0.3})`);\n outerGlow.addColorStop(0.8, `rgba(${rgb}, ${blob.opacity * 0.1})`);\n outerGlow.addColorStop(1, `rgba(${rgb}, 0)`);\n ctx.beginPath();\n ctx.arc(blob.x, blob.y, blurRadius, 0, Math.PI * 2);\n ctx.fillStyle = outerGlow;\n ctx.fill();\n });\n\n // Highlight\n const highlightGradient = ctx.createRadialGradient(\n centerX - currentRadius * 0.3,\n centerY - currentRadius * 0.3,\n 0,\n centerX - currentRadius * 0.3,\n centerY - currentRadius * 0.3,\n currentRadius * 0.6\n );\n highlightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.12)');\n highlightGradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.03)');\n highlightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');\n ctx.beginPath();\n ctx.arc(centerX, centerY, currentRadius, 0, Math.PI * 2);\n ctx.fillStyle = highlightGradient;\n ctx.fill();\n\n ctx.restore();\n\n this.pulseAnimationId = requestAnimationFrame(this.animatePulse);\n };\n\n private hexToRgb(hex: string): string {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n if (!result) {\n return '0, 0, 0';\n }\n const r = parseInt(result[1], 16);\n const g = parseInt(result[2], 16);\n const b = parseInt(result[3], 16);\n return `${r}, ${g}, ${b}`;\n }\n\n private cleanup(): void {\n if (this.animationFrameId) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = undefined;\n }\n if (this.pulseAnimationId) {\n cancelAnimationFrame(this.pulseAnimationId);\n this.pulseAnimationId = undefined;\n }\n if (this.source) {\n this.source.disconnect();\n this.source = undefined;\n }\n if (this.candidateSource) {\n this.candidateSource.disconnect();\n this.candidateSource = undefined;\n }\n if (this.audioContext && this.audioContext.state !== 'closed') {\n void this.audioContext.close();\n this.audioContext = undefined;\n }\n this.analyser = undefined;\n this.candidateAnalyser = undefined;\n this.dataArray = undefined;\n this.candidateDataArray = undefined;\n }\n\n ngOnDestroy(): void {\n this.cleanup();\n }\n}\n","<div class=\"ai-audio-visualizer\">\n <div class=\"canvas-container\">\n <canvas #pulseCanvas></canvas>\n </div>\n</div>\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { AiAudioCircleComponent } from './ai-audio-circle.component';\n\n@NgModule({\n declarations: [AiAudioCircleComponent],\n imports: [CommonModule],\n exports: [AiAudioCircleComponent],\n})\nexport class AiAudioCircleModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -128,6 +128,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
128
128
|
* - @testgorilla/tgo-ui/components/side-sheet
|
|
129
129
|
* - @testgorilla/tgo-ui/components/table
|
|
130
130
|
* - @testgorilla/tgo-ui/components/datepicker
|
|
131
|
+
* - @testgorilla/tgo-ui/components/ai-audio-circle
|
|
131
132
|
* - @testgorilla/tgo-ui/components/ai-feedback
|
|
132
133
|
* - @testgorilla/tgo-ui/components/checklist
|
|
133
134
|
* - @testgorilla/tgo-ui/components/file-upload
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testgorilla-tgo-ui.mjs","sources":["../../../projects/tgo-canopy-ui/components/deprecated-paginator/deprecated-paginator.component.ts","../../../projects/tgo-canopy-ui/components/deprecated-paginator/deprecated-paginator.component.html","../../../projects/tgo-canopy-ui/components/deprecated-paginator/deprecated-paginator.component.module.ts","../../../projects/tgo-canopy-ui/public-api.ts","../../../projects/tgo-canopy-ui/testgorilla-tgo-ui.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { PageEvent } from '@angular/material/paginator';\n\n@Component({\n selector: 'ui-paginator',\n templateUrl: './deprecated-paginator.component.html',\n styleUrls: ['./deprecated-paginator.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false\n})\nexport class DeprecatedPaginatorComponent implements OnInit {\n // TODO: Some properties and methods are ignored on purpose because of a current issue with compodoc and angular 13\n // https://github.com/StoryFnbookjs/StoryFnbook/issues/16865\n // https://github.com/StoryFnbookjs/StoryFnbook/issues/17004\n\n /**\n * Paginator size options\n *\n * @type {number[]}\n * @memberof PaginatorComponent\n */\n readonly pageSizeOptions = [10, 25, 50];\n\n /**\n * Data length\n *\n * @type {number}\n * @memberof PaginatorComponent\n */\n @Input() length = 0;\n\n /**\n * Default page size\n *\n * @type {number}\n * @memberof PaginatorComponent\n */\n @Input() defaultPageSize = 25;\n\n /**\n * @ignore\n */\n @Output() paginatorChangedEvent: EventEmitter<PageEvent> = new EventEmitter<PageEvent>();\n\n /**\n * @ignore\n */\n ngOnInit(): void {}\n\n constructor() {}\n\n paginatorChanged(paginator: PageEvent) {\n this.paginatorChangedEvent.emit(paginator);\n }\n}\n","<mat-paginator [length]=\"length\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n (page)=\"paginatorChanged($event)\">\n</mat-paginator>","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { MatPaginatorModule } from '@angular/material/paginator';\nimport { DeprecatedPaginatorComponent } from './deprecated-paginator.component';\n\n@NgModule({\n declarations: [DeprecatedPaginatorComponent],\n imports: [CommonModule, MatPaginatorModule],\n exports: [DeprecatedPaginatorComponent],\n providers: [],\n})\nexport class DeprecatedPaginatorComponentModule {}\n","/* eslint-disable */\n/**\n * @testgorilla/tgo-ui Public API\n *\n * IMPORTANT: For optimal tree-shaking, import directly from entry points:\n *\n * @example\n * import { ButtonComponent } from '@testgorilla/tgo-ui/components/button';\n * import { IconComponent } from '@testgorilla/tgo-ui/components/icon';\n * import { DialogService } from '@testgorilla/tgo-ui/components/dialog';\n *\n * Available entry points:\n * - @testgorilla/tgo-ui/components/core (shared utilities, pipes, directives)\n * - @testgorilla/tgo-ui/components/icon\n * - @testgorilla/tgo-ui/components/badge\n * - @testgorilla/tgo-ui/components/button\n * - @testgorilla/tgo-ui/components/card\n * - @testgorilla/tgo-ui/components/checkbox\n * - @testgorilla/tgo-ui/components/dropdown\n * - @testgorilla/tgo-ui/components/field\n * - @testgorilla/tgo-ui/components/inline-field\n * - @testgorilla/tgo-ui/components/toggle\n * - @testgorilla/tgo-ui/components/radio-button\n * - @testgorilla/tgo-ui/components/slider\n * - @testgorilla/tgo-ui/components/rating\n * - @testgorilla/tgo-ui/components/scale\n * - @testgorilla/tgo-ui/components/autocomplete\n * - @testgorilla/tgo-ui/components/divider\n * - @testgorilla/tgo-ui/components/skeleton\n * - @testgorilla/tgo-ui/components/elevation-shadow\n * - @testgorilla/tgo-ui/components/tooltip\n * - @testgorilla/tgo-ui/components/spinner\n * - @testgorilla/tgo-ui/components/progress-bar\n * - @testgorilla/tgo-ui/components/radial-progress\n * - @testgorilla/tgo-ui/components/tag\n * - @testgorilla/tgo-ui/components/avatar\n * - @testgorilla/tgo-ui/components/logo\n * - @testgorilla/tgo-ui/components/empty-state\n * - @testgorilla/tgo-ui/components/filter-button\n * - @testgorilla/tgo-ui/components/segmented-button\n * - @testgorilla/tgo-ui/components/segmented-bar\n * - @testgorilla/tgo-ui/components/paginator\n * - @testgorilla/tgo-ui/components/validation-error\n * - @testgorilla/tgo-ui/components/accordion\n * - @testgorilla/tgo-ui/components/alert-banner\n * - @testgorilla/tgo-ui/components/breadcrumb\n * - @testgorilla/tgo-ui/components/navbar\n * - @testgorilla/tgo-ui/components/page-header\n * - @testgorilla/tgo-ui/components/tabs\n * - @testgorilla/tgo-ui/components/stepper\n * - @testgorilla/tgo-ui/components/dialog\n * - @testgorilla/tgo-ui/components/snackbar\n * - @testgorilla/tgo-ui/components/side-panel\n * - @testgorilla/tgo-ui/components/side-sheet\n * - @testgorilla/tgo-ui/components/table\n * - @testgorilla/tgo-ui/components/datepicker\n * - @testgorilla/tgo-ui/components/ai-feedback\n * - @testgorilla/tgo-ui/components/checklist\n * - @testgorilla/tgo-ui/components/file-upload\n * - @testgorilla/tgo-ui/components/multi-input\n * - @testgorilla/tgo-ui/components/overflow-menu\n * - @testgorilla/tgo-ui/components/password-criteria\n * - @testgorilla/tgo-ui/components/password-strength\n * - @testgorilla/tgo-ui/components/phone-input\n * - @testgorilla/tgo-ui/components/prompt\n * - @testgorilla/tgo-ui/components/scale-table\n * - @testgorilla/tgo-ui/components/icon-label\n * - @testgorilla/tgo-ui/components/media-card\n * - @testgorilla/tgo-ui/components/media-dialog\n * - @testgorilla/tgo-ui/components/selectable-card\n * - @testgorilla/tgo-ui/components/donut-chart\n * - @testgorilla/tgo-ui/components/gaussian-chart\n * - @testgorilla/tgo-ui/components/spider-chart\n * - @testgorilla/tgo-ui/components/universal-skills\n */\n\n// Core utilities (re-exported for backward compatibility)\nexport * from '@testgorilla/tgo-ui/components/core';\n\n// Legacy: Deprecated Paginator (not an entry point)\nexport * from './components/deprecated-paginator/deprecated-paginator.component';\nexport * from './components/deprecated-paginator/deprecated-paginator.component.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;MAUa,4BAA4B,CAAA;AAkCvC;;AAEG;AACH,IAAA,QAAQ;AAER,IAAA,WAAA,GAAA;;;;AAlCA;;;;;AAKG;QACM,IAAe,CAAA,eAAA,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAEvC;;;;;AAKG;QACM,IAAM,CAAA,MAAA,GAAG,CAAC;AAEnB;;;;;AAKG;QACM,IAAe,CAAA,eAAA,GAAG,EAAE;AAE7B;;AAEG;AACO,QAAA,IAAA,CAAA,qBAAqB,GAA4B,IAAI,YAAY,EAAa;;AASxF,IAAA,gBAAgB,CAAC,SAAoB,EAAA;AACnC,QAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC;;+GA1CjC,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA5B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,4BAA4B,wMCVzC,6MAIgB,EAAA,MAAA,EAAA,CAAA,2yFAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,WAAA,EAAA,QAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,cAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,MAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FDMH,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBAPxC,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,EAGP,eAAA,EAAA,uBAAuB,CAAC,MAAM,cACnC,KAAK,EAAA,QAAA,EAAA,6MAAA,EAAA,MAAA,EAAA,CAAA,2yFAAA,CAAA,EAAA;wDAqBV,MAAM,EAAA,CAAA;sBAAd;gBAQQ,eAAe,EAAA,CAAA;sBAAvB;gBAKS,qBAAqB,EAAA,CAAA;sBAA9B;;;ME/BU,kCAAkC,CAAA;+GAAlC,kCAAkC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAlC,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kCAAkC,iBAL9B,4BAA4B,CAAA,EAAA,OAAA,EAAA,CACjC,YAAY,EAAE,kBAAkB,aAChC,4BAA4B,CAAA,EAAA,CAAA,CAAA;gHAG3B,kCAAkC,EAAA,OAAA,EAAA,CAJnC,YAAY,EAAE,kBAAkB,CAAA,EAAA,CAAA,CAAA;;4FAI/B,kCAAkC,EAAA,UAAA,EAAA,CAAA;kBAN9C,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;oBACR,YAAY,EAAE,CAAC,4BAA4B,CAAC;AAC5C,oBAAA,OAAO,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC;oBAC3C,OAAO,EAAE,CAAC,4BAA4B,CAAC;AACvC,oBAAA,SAAS,EAAE,EAAE;AACd,iBAAA;;;ACVD;AACA
|
|
1
|
+
{"version":3,"file":"testgorilla-tgo-ui.mjs","sources":["../../../projects/tgo-canopy-ui/components/deprecated-paginator/deprecated-paginator.component.ts","../../../projects/tgo-canopy-ui/components/deprecated-paginator/deprecated-paginator.component.html","../../../projects/tgo-canopy-ui/components/deprecated-paginator/deprecated-paginator.component.module.ts","../../../projects/tgo-canopy-ui/public-api.ts","../../../projects/tgo-canopy-ui/testgorilla-tgo-ui.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { PageEvent } from '@angular/material/paginator';\n\n@Component({\n selector: 'ui-paginator',\n templateUrl: './deprecated-paginator.component.html',\n styleUrls: ['./deprecated-paginator.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false\n})\nexport class DeprecatedPaginatorComponent implements OnInit {\n // TODO: Some properties and methods are ignored on purpose because of a current issue with compodoc and angular 13\n // https://github.com/StoryFnbookjs/StoryFnbook/issues/16865\n // https://github.com/StoryFnbookjs/StoryFnbook/issues/17004\n\n /**\n * Paginator size options\n *\n * @type {number[]}\n * @memberof PaginatorComponent\n */\n readonly pageSizeOptions = [10, 25, 50];\n\n /**\n * Data length\n *\n * @type {number}\n * @memberof PaginatorComponent\n */\n @Input() length = 0;\n\n /**\n * Default page size\n *\n * @type {number}\n * @memberof PaginatorComponent\n */\n @Input() defaultPageSize = 25;\n\n /**\n * @ignore\n */\n @Output() paginatorChangedEvent: EventEmitter<PageEvent> = new EventEmitter<PageEvent>();\n\n /**\n * @ignore\n */\n ngOnInit(): void {}\n\n constructor() {}\n\n paginatorChanged(paginator: PageEvent) {\n this.paginatorChangedEvent.emit(paginator);\n }\n}\n","<mat-paginator [length]=\"length\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n (page)=\"paginatorChanged($event)\">\n</mat-paginator>","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { MatPaginatorModule } from '@angular/material/paginator';\nimport { DeprecatedPaginatorComponent } from './deprecated-paginator.component';\n\n@NgModule({\n declarations: [DeprecatedPaginatorComponent],\n imports: [CommonModule, MatPaginatorModule],\n exports: [DeprecatedPaginatorComponent],\n providers: [],\n})\nexport class DeprecatedPaginatorComponentModule {}\n","/* eslint-disable */\n/**\n * @testgorilla/tgo-ui Public API\n *\n * IMPORTANT: For optimal tree-shaking, import directly from entry points:\n *\n * @example\n * import { ButtonComponent } from '@testgorilla/tgo-ui/components/button';\n * import { IconComponent } from '@testgorilla/tgo-ui/components/icon';\n * import { DialogService } from '@testgorilla/tgo-ui/components/dialog';\n *\n * Available entry points:\n * - @testgorilla/tgo-ui/components/core (shared utilities, pipes, directives)\n * - @testgorilla/tgo-ui/components/icon\n * - @testgorilla/tgo-ui/components/badge\n * - @testgorilla/tgo-ui/components/button\n * - @testgorilla/tgo-ui/components/card\n * - @testgorilla/tgo-ui/components/checkbox\n * - @testgorilla/tgo-ui/components/dropdown\n * - @testgorilla/tgo-ui/components/field\n * - @testgorilla/tgo-ui/components/inline-field\n * - @testgorilla/tgo-ui/components/toggle\n * - @testgorilla/tgo-ui/components/radio-button\n * - @testgorilla/tgo-ui/components/slider\n * - @testgorilla/tgo-ui/components/rating\n * - @testgorilla/tgo-ui/components/scale\n * - @testgorilla/tgo-ui/components/autocomplete\n * - @testgorilla/tgo-ui/components/divider\n * - @testgorilla/tgo-ui/components/skeleton\n * - @testgorilla/tgo-ui/components/elevation-shadow\n * - @testgorilla/tgo-ui/components/tooltip\n * - @testgorilla/tgo-ui/components/spinner\n * - @testgorilla/tgo-ui/components/progress-bar\n * - @testgorilla/tgo-ui/components/radial-progress\n * - @testgorilla/tgo-ui/components/tag\n * - @testgorilla/tgo-ui/components/avatar\n * - @testgorilla/tgo-ui/components/logo\n * - @testgorilla/tgo-ui/components/empty-state\n * - @testgorilla/tgo-ui/components/filter-button\n * - @testgorilla/tgo-ui/components/segmented-button\n * - @testgorilla/tgo-ui/components/segmented-bar\n * - @testgorilla/tgo-ui/components/paginator\n * - @testgorilla/tgo-ui/components/validation-error\n * - @testgorilla/tgo-ui/components/accordion\n * - @testgorilla/tgo-ui/components/alert-banner\n * - @testgorilla/tgo-ui/components/breadcrumb\n * - @testgorilla/tgo-ui/components/navbar\n * - @testgorilla/tgo-ui/components/page-header\n * - @testgorilla/tgo-ui/components/tabs\n * - @testgorilla/tgo-ui/components/stepper\n * - @testgorilla/tgo-ui/components/dialog\n * - @testgorilla/tgo-ui/components/snackbar\n * - @testgorilla/tgo-ui/components/side-panel\n * - @testgorilla/tgo-ui/components/side-sheet\n * - @testgorilla/tgo-ui/components/table\n * - @testgorilla/tgo-ui/components/datepicker\n * - @testgorilla/tgo-ui/components/ai-audio-circle\n * - @testgorilla/tgo-ui/components/ai-feedback\n * - @testgorilla/tgo-ui/components/checklist\n * - @testgorilla/tgo-ui/components/file-upload\n * - @testgorilla/tgo-ui/components/multi-input\n * - @testgorilla/tgo-ui/components/overflow-menu\n * - @testgorilla/tgo-ui/components/password-criteria\n * - @testgorilla/tgo-ui/components/password-strength\n * - @testgorilla/tgo-ui/components/phone-input\n * - @testgorilla/tgo-ui/components/prompt\n * - @testgorilla/tgo-ui/components/scale-table\n * - @testgorilla/tgo-ui/components/icon-label\n * - @testgorilla/tgo-ui/components/media-card\n * - @testgorilla/tgo-ui/components/media-dialog\n * - @testgorilla/tgo-ui/components/selectable-card\n * - @testgorilla/tgo-ui/components/donut-chart\n * - @testgorilla/tgo-ui/components/gaussian-chart\n * - @testgorilla/tgo-ui/components/spider-chart\n * - @testgorilla/tgo-ui/components/universal-skills\n */\n\n// Core utilities (re-exported for backward compatibility)\nexport * from '@testgorilla/tgo-ui/components/core';\n\n// Legacy: Deprecated Paginator (not an entry point)\nexport * from './components/deprecated-paginator/deprecated-paginator.component';\nexport * from './components/deprecated-paginator/deprecated-paginator.component.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;MAUa,4BAA4B,CAAA;AAkCvC;;AAEG;AACH,IAAA,QAAQ;AAER,IAAA,WAAA,GAAA;;;;AAlCA;;;;;AAKG;QACM,IAAe,CAAA,eAAA,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAEvC;;;;;AAKG;QACM,IAAM,CAAA,MAAA,GAAG,CAAC;AAEnB;;;;;AAKG;QACM,IAAe,CAAA,eAAA,GAAG,EAAE;AAE7B;;AAEG;AACO,QAAA,IAAA,CAAA,qBAAqB,GAA4B,IAAI,YAAY,EAAa;;AASxF,IAAA,gBAAgB,CAAC,SAAoB,EAAA;AACnC,QAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC;;+GA1CjC,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA5B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,4BAA4B,wMCVzC,6MAIgB,EAAA,MAAA,EAAA,CAAA,2yFAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,WAAA,EAAA,QAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,cAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,MAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FDMH,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBAPxC,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,EAGP,eAAA,EAAA,uBAAuB,CAAC,MAAM,cACnC,KAAK,EAAA,QAAA,EAAA,6MAAA,EAAA,MAAA,EAAA,CAAA,2yFAAA,CAAA,EAAA;wDAqBV,MAAM,EAAA,CAAA;sBAAd;gBAQQ,eAAe,EAAA,CAAA;sBAAvB;gBAKS,qBAAqB,EAAA,CAAA;sBAA9B;;;ME/BU,kCAAkC,CAAA;+GAAlC,kCAAkC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAlC,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kCAAkC,iBAL9B,4BAA4B,CAAA,EAAA,OAAA,EAAA,CACjC,YAAY,EAAE,kBAAkB,aAChC,4BAA4B,CAAA,EAAA,CAAA,CAAA;gHAG3B,kCAAkC,EAAA,OAAA,EAAA,CAJnC,YAAY,EAAE,kBAAkB,CAAA,EAAA,CAAA,CAAA;;4FAI/B,kCAAkC,EAAA,UAAA,EAAA,CAAA;kBAN9C,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;oBACR,YAAY,EAAE,CAAC,4BAA4B,CAAC;AAC5C,oBAAA,OAAO,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC;oBAC3C,OAAO,EAAE,CAAC,4BAA4B,CAAC;AACvC,oBAAA,SAAS,EAAE,EAAE;AACd,iBAAA;;;ACVD;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EG;AAEH;;AC7EA;;AAEG;;;;"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testgorilla/tgo-ui",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"license": "proprietary-license",
|
|
5
5
|
"lint-staged": {
|
|
6
|
-
"
|
|
6
|
+
"{projects,components}/**/*.ts": [
|
|
7
7
|
"eslint --fix",
|
|
8
|
-
"prettier --write"
|
|
9
|
-
"git add"
|
|
8
|
+
"prettier --write"
|
|
10
9
|
],
|
|
11
|
-
"
|
|
10
|
+
"{projects,components}/**/*.scss": [
|
|
12
11
|
"stylelint"
|
|
13
12
|
]
|
|
14
13
|
},
|
|
@@ -72,6 +71,10 @@
|
|
|
72
71
|
"types": "./components/alert-banner/index.d.ts",
|
|
73
72
|
"default": "./fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs"
|
|
74
73
|
},
|
|
74
|
+
"./components/ai-audio-circle": {
|
|
75
|
+
"types": "./components/ai-audio-circle/index.d.ts",
|
|
76
|
+
"default": "./fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs"
|
|
77
|
+
},
|
|
75
78
|
"./components/autocomplete": {
|
|
76
79
|
"types": "./components/autocomplete/index.d.ts",
|
|
77
80
|
"default": "./fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs"
|
|
@@ -108,14 +111,14 @@
|
|
|
108
111
|
"types": "./components/core/index.d.ts",
|
|
109
112
|
"default": "./fesm2022/testgorilla-tgo-ui-components-core.mjs"
|
|
110
113
|
},
|
|
111
|
-
"./components/datepicker": {
|
|
112
|
-
"types": "./components/datepicker/index.d.ts",
|
|
113
|
-
"default": "./fesm2022/testgorilla-tgo-ui-components-datepicker.mjs"
|
|
114
|
-
},
|
|
115
114
|
"./components/dialog": {
|
|
116
115
|
"types": "./components/dialog/index.d.ts",
|
|
117
116
|
"default": "./fesm2022/testgorilla-tgo-ui-components-dialog.mjs"
|
|
118
117
|
},
|
|
118
|
+
"./components/datepicker": {
|
|
119
|
+
"types": "./components/datepicker/index.d.ts",
|
|
120
|
+
"default": "./fesm2022/testgorilla-tgo-ui-components-datepicker.mjs"
|
|
121
|
+
},
|
|
119
122
|
"./components/divider": {
|
|
120
123
|
"types": "./components/divider/index.d.ts",
|
|
121
124
|
"default": "./fesm2022/testgorilla-tgo-ui-components-divider.mjs"
|
package/public-api.d.ts
CHANGED
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
* - @testgorilla/tgo-ui/components/side-sheet
|
|
54
54
|
* - @testgorilla/tgo-ui/components/table
|
|
55
55
|
* - @testgorilla/tgo-ui/components/datepicker
|
|
56
|
+
* - @testgorilla/tgo-ui/components/ai-audio-circle
|
|
56
57
|
* - @testgorilla/tgo-ui/components/ai-feedback
|
|
57
58
|
* - @testgorilla/tgo-ui/components/checklist
|
|
58
59
|
* - @testgorilla/tgo-ui/components/file-upload
|