@medc-com-br/ngx-jaimes-scribe 0.1.6 → 0.1.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.
|
@@ -970,23 +970,23 @@ class RecorderComponent {
|
|
|
970
970
|
} @else if (sessionData()) {
|
|
971
971
|
<!-- Audio Player -->
|
|
972
972
|
<div class="scribe-player">
|
|
973
|
-
<
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
<
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
<
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
973
|
+
<div class="scribe-player-row">
|
|
974
|
+
<button
|
|
975
|
+
class="scribe-btn scribe-btn--play"
|
|
976
|
+
(click)="togglePlayback()"
|
|
977
|
+
[attr.aria-label]="isPlaying() ? 'Pausar' : 'Reproduzir'"
|
|
978
|
+
>
|
|
979
|
+
@if (isPlaying()) {
|
|
980
|
+
<svg class="scribe-icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
|
|
981
|
+
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
|
|
982
|
+
</svg>
|
|
983
|
+
} @else {
|
|
984
|
+
<svg class="scribe-icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
|
|
985
|
+
<path d="M8 5v14l11-7z"/>
|
|
986
|
+
</svg>
|
|
987
|
+
}
|
|
988
|
+
</button>
|
|
988
989
|
|
|
989
|
-
<div class="scribe-timeline">
|
|
990
990
|
<input
|
|
991
991
|
type="range"
|
|
992
992
|
class="scribe-timeline-slider"
|
|
@@ -997,24 +997,24 @@ class RecorderComponent {
|
|
|
997
997
|
(input)="seekTo($event)"
|
|
998
998
|
aria-label="Posição do áudio"
|
|
999
999
|
/>
|
|
1000
|
-
<div class="scribe-time">
|
|
1001
|
-
{{ formatTimeDisplay(audioCurrentTime()) }} / {{ formatTimeDisplay(audioDuration()) }}
|
|
1002
|
-
</div>
|
|
1003
|
-
</div>
|
|
1004
1000
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1001
|
+
<select
|
|
1002
|
+
class="scribe-speed"
|
|
1003
|
+
[value]="playbackRate()"
|
|
1004
|
+
(change)="setPlaybackRate($event)"
|
|
1005
|
+
aria-label="Velocidade de reprodução"
|
|
1006
|
+
>
|
|
1007
|
+
<option value="0.5">0.5x</option>
|
|
1008
|
+
<option value="0.75">0.75x</option>
|
|
1009
|
+
<option value="1">1x</option>
|
|
1010
|
+
<option value="1.25">1.25x</option>
|
|
1011
|
+
<option value="1.5">1.5x</option>
|
|
1012
|
+
<option value="2">2x</option>
|
|
1013
|
+
</select>
|
|
1014
|
+
</div>
|
|
1015
|
+
<div class="scribe-time">
|
|
1016
|
+
{{ formatTimeDisplay(audioCurrentTime()) }} / {{ formatTimeDisplay(audioDuration()) }}
|
|
1017
|
+
</div>
|
|
1018
1018
|
</div>
|
|
1019
1019
|
|
|
1020
1020
|
<!-- Transcription with Highlight -->
|
|
@@ -1197,7 +1197,7 @@ class RecorderComponent {
|
|
|
1197
1197
|
}
|
|
1198
1198
|
}
|
|
1199
1199
|
</div>
|
|
1200
|
-
`, isInline: true, styles: [":host{--scribe-primary: #4caf50;--scribe-primary-dark: #388e3c;--scribe-primary-light: #81c784;--scribe-danger: #f44336;--scribe-danger-dark: #d32f2f;--scribe-text-color: #212121;--scribe-text-partial: #9e9e9e;--scribe-font-family: inherit;--scribe-font-size: 1rem;--scribe-bg: #ffffff;--scribe-bg-transcript: #f5f5f5;--scribe-border-radius: 8px;--scribe-border-color: #e0e0e0;--scribe-level-bg: #e0e0e0;--scribe-level-fill: #4caf50;--scribe-speaker-0: #2196f3;--scribe-speaker-1: #9c27b0;--scribe-speaker-2: #ff9800;--scribe-speaker-3: #009688;display:block;font-family:var(--scribe-font-family);font-size:var(--scribe-font-size)}.scribe-recorder{background:var(--scribe-bg);border-radius:var(--scribe-border-radius)}.scribe-controls{display:flex;align-items:center;gap:1rem;padding:1rem}.scribe-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.75rem;border:none;border-radius:var(--scribe-border-radius);font-family:var(--scribe-font-family);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.scribe-btn:disabled{opacity:.5;cursor:not-allowed}.scribe-btn--mic{width:48px;height:48px;border-radius:50%;background:var(--scribe-bg-transcript);color:var(--scribe-text-color)}.scribe-btn--mic:hover:not(:disabled){background:var(--scribe-border-color)}.scribe-btn--mic.scribe-btn--active{background:var(--scribe-danger);color:#fff;animation:pulse-recording 1.5s ease-in-out infinite}.scribe-btn--mic.scribe-btn--paused{background:var(--scribe-primary);color:#fff}.scribe-btn--mic.scribe-btn--paused:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-btn--mic.scribe-btn--connecting{background:var(--scribe-primary-light);color:#fff}.scribe-btn--finish{padding:.75rem 1.25rem;background:var(--scribe-primary);color:#fff}.scribe-btn--finish:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-icon{flex-shrink:0}.scribe-icon--spinner{animation:spin 1s linear infinite}.scribe-level{flex:1;height:8px;background:var(--scribe-level-bg);border-radius:4px;overflow:hidden;opacity:.5;transition:opacity .2s ease}.scribe-level--active{opacity:1}.scribe-level__fill{height:100%;background:var(--scribe-level-fill);border-radius:4px;transition:width .05s ease-out}.scribe-transcript{min-height:120px;max-height:400px;overflow-y:auto;padding:1rem;margin:0 1rem 1rem;background:var(--scribe-bg-transcript);border-radius:var(--scribe-border-radius);line-height:1.6}.scribe-transcript--empty{display:flex;align-items:center;justify-content:center}.scribe-placeholder{color:var(--scribe-text-partial);font-style:italic}.scribe-speaker-block{margin-bottom:.75rem;padding-left:.5rem;border-left:3px solid var(--scribe-border-color)}.scribe-speaker-block--partial{opacity:.7}.scribe-speaker-block[data-speaker=\"0\"]{border-left-color:var(--scribe-speaker-0)}.scribe-speaker-block[data-speaker=\"1\"]{border-left-color:var(--scribe-speaker-1)}.scribe-speaker-block[data-speaker=\"2\"]{border-left-color:var(--scribe-speaker-2)}.scribe-speaker-block[data-speaker=\"3\"]{border-left-color:var(--scribe-speaker-3)}.scribe-speaker-label{display:inline-block;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;padding:.125rem .5rem;border-radius:4px;margin-bottom:.25rem;color:#fff;background:var(--scribe-border-color)}.scribe-speaker--0{background:var(--scribe-speaker-0)}.scribe-speaker--1{background:var(--scribe-speaker-1)}.scribe-speaker--2{background:var(--scribe-speaker-2)}.scribe-speaker--3{background:var(--scribe-speaker-3)}.scribe-speaker-text{margin-top:.25rem}.scribe-text{word-wrap:break-word}.scribe-text--final{color:var(--scribe-text-color)}.scribe-text--partial{color:var(--scribe-text-partial);font-style:italic}.scribe-generate-container{position:relative;margin-left:.5rem}.scribe-btn--generate{display:flex;align-items:center;gap:.5rem;padding:.75rem 1.25rem;background:var(--scribe-primary);color:#fff;border:none;border-radius:var(--scribe-border-radius);font-family:var(--scribe-font-family);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.scribe-btn--generate:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-btn--generate:disabled{opacity:.7;cursor:not-allowed}.scribe-template-menu{position:absolute;top:100%;left:0;margin-top:.25rem;min-width:220px;background:var(--scribe-bg);border:1px solid var(--scribe-border-color);border-radius:var(--scribe-border-radius);box-shadow:0 4px 12px #00000026;z-index:100;overflow:hidden}.scribe-template-item{display:flex;flex-direction:column;align-items:flex-start;width:100%;padding:.75rem 1rem;border:none;background:transparent;cursor:pointer;text-align:left;transition:background .15s ease}.scribe-template-item:hover{background:var(--scribe-bg-transcript)}.scribe-template-item:not(:last-child){border-bottom:1px solid var(--scribe-border-color)}.scribe-template-name{font-weight:500;color:var(--scribe-text-color)}.scribe-template-desc{font-size:.75rem;color:var(--scribe-text-partial);margin-top:.25rem}@keyframes pulse-recording{0%,to{box-shadow:0 0 #f4433666}50%{box-shadow:0 0 0 8px #f4433600}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.scribe-playback{padding:1rem}.scribe-loading,.scribe-error{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:2rem;color:var(--scribe-text-partial)}.scribe-player{display:flex;
|
|
1200
|
+
`, isInline: true, styles: [":host{--scribe-primary: #4caf50;--scribe-primary-dark: #388e3c;--scribe-primary-light: #81c784;--scribe-danger: #f44336;--scribe-danger-dark: #d32f2f;--scribe-text-color: #212121;--scribe-text-partial: #9e9e9e;--scribe-font-family: inherit;--scribe-font-size: 1rem;--scribe-bg: #ffffff;--scribe-bg-transcript: #f5f5f5;--scribe-border-radius: 8px;--scribe-border-color: #e0e0e0;--scribe-level-bg: #e0e0e0;--scribe-level-fill: #4caf50;--scribe-speaker-0: #2196f3;--scribe-speaker-1: #9c27b0;--scribe-speaker-2: #ff9800;--scribe-speaker-3: #009688;display:block;font-family:var(--scribe-font-family);font-size:var(--scribe-font-size)}.scribe-recorder{background:var(--scribe-bg);border-radius:var(--scribe-border-radius)}.scribe-controls{display:flex;align-items:center;gap:1rem;padding:1rem}.scribe-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.75rem;border:none;border-radius:var(--scribe-border-radius);font-family:var(--scribe-font-family);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.scribe-btn:disabled{opacity:.5;cursor:not-allowed}.scribe-btn--mic{width:48px;height:48px;border-radius:50%;background:var(--scribe-bg-transcript);color:var(--scribe-text-color)}.scribe-btn--mic:hover:not(:disabled){background:var(--scribe-border-color)}.scribe-btn--mic.scribe-btn--active{background:var(--scribe-danger);color:#fff;animation:pulse-recording 1.5s ease-in-out infinite}.scribe-btn--mic.scribe-btn--paused{background:var(--scribe-primary);color:#fff}.scribe-btn--mic.scribe-btn--paused:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-btn--mic.scribe-btn--connecting{background:var(--scribe-primary-light);color:#fff}.scribe-btn--finish{padding:.75rem 1.25rem;background:var(--scribe-primary);color:#fff}.scribe-btn--finish:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-icon{flex-shrink:0}.scribe-icon--spinner{animation:spin 1s linear infinite}.scribe-level{flex:1;height:8px;background:var(--scribe-level-bg);border-radius:4px;overflow:hidden;opacity:.5;transition:opacity .2s ease}.scribe-level--active{opacity:1}.scribe-level__fill{height:100%;background:var(--scribe-level-fill);border-radius:4px;transition:width .05s ease-out}.scribe-transcript{min-height:120px;max-height:400px;overflow-y:auto;padding:1rem;margin:0 1rem 1rem;background:var(--scribe-bg-transcript);border-radius:var(--scribe-border-radius);line-height:1.6}.scribe-transcript--empty{display:flex;align-items:center;justify-content:center}.scribe-placeholder{color:var(--scribe-text-partial);font-style:italic}.scribe-speaker-block{margin-bottom:.75rem;padding-left:.5rem;border-left:3px solid var(--scribe-border-color)}.scribe-speaker-block--partial{opacity:.7}.scribe-speaker-block[data-speaker=\"0\"]{border-left-color:var(--scribe-speaker-0)}.scribe-speaker-block[data-speaker=\"1\"]{border-left-color:var(--scribe-speaker-1)}.scribe-speaker-block[data-speaker=\"2\"]{border-left-color:var(--scribe-speaker-2)}.scribe-speaker-block[data-speaker=\"3\"]{border-left-color:var(--scribe-speaker-3)}.scribe-speaker-label{display:inline-block;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;padding:.125rem .5rem;border-radius:4px;margin-bottom:.25rem;color:#fff;background:var(--scribe-border-color)}.scribe-speaker--0{background:var(--scribe-speaker-0)}.scribe-speaker--1{background:var(--scribe-speaker-1)}.scribe-speaker--2{background:var(--scribe-speaker-2)}.scribe-speaker--3{background:var(--scribe-speaker-3)}.scribe-speaker-text{margin-top:.25rem}.scribe-text{word-wrap:break-word}.scribe-text--final{color:var(--scribe-text-color)}.scribe-text--partial{color:var(--scribe-text-partial);font-style:italic}.scribe-generate-container{position:relative;margin-left:.5rem}.scribe-btn--generate{display:flex;align-items:center;gap:.5rem;padding:.75rem 1.25rem;background:var(--scribe-primary);color:#fff;border:none;border-radius:var(--scribe-border-radius);font-family:var(--scribe-font-family);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.scribe-btn--generate:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-btn--generate:disabled{opacity:.7;cursor:not-allowed}.scribe-template-menu{position:absolute;top:100%;left:0;margin-top:.25rem;min-width:220px;background:var(--scribe-bg);border:1px solid var(--scribe-border-color);border-radius:var(--scribe-border-radius);box-shadow:0 4px 12px #00000026;z-index:100;overflow:hidden}.scribe-template-item{display:flex;flex-direction:column;align-items:flex-start;width:100%;padding:.75rem 1rem;border:none;background:transparent;cursor:pointer;text-align:left;transition:background .15s ease}.scribe-template-item:hover{background:var(--scribe-bg-transcript)}.scribe-template-item:not(:last-child){border-bottom:1px solid var(--scribe-border-color)}.scribe-template-name{font-weight:500;color:var(--scribe-text-color)}.scribe-template-desc{font-size:.75rem;color:var(--scribe-text-partial);margin-top:.25rem}@keyframes pulse-recording{0%,to{box-shadow:0 0 #f4433666}50%{box-shadow:0 0 0 8px #f4433600}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.scribe-playback{padding:1rem}.scribe-loading,.scribe-error{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:2rem;color:var(--scribe-text-partial)}.scribe-player{display:flex;flex-direction:column;gap:.5rem;padding:1rem;background:var(--scribe-bg-transcript);border-radius:var(--scribe-border-radius);margin-bottom:1rem}.scribe-player-row{display:flex;align-items:center;gap:1rem}.scribe-btn--play{width:48px;height:48px;border-radius:50%;background:var(--scribe-primary);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .2s ease;flex-shrink:0}.scribe-btn--play:hover{background:var(--scribe-primary-dark)}.scribe-timeline-slider{flex:1;cursor:pointer;height:6px;-webkit-appearance:none;appearance:none;background:var(--scribe-level-bg);border-radius:3px;outline:none}.scribe-timeline-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;background:var(--scribe-primary);border-radius:50%;cursor:pointer}.scribe-timeline-slider::-moz-range-thumb{width:14px;height:14px;background:var(--scribe-primary);border-radius:50%;cursor:pointer;border:none}.scribe-time{font-size:.75rem;color:var(--scribe-text-partial);text-align:center}.scribe-speed{padding:.375rem .5rem;border-radius:4px;border:1px solid var(--scribe-border-color);background:var(--scribe-bg);font-size:.875rem;cursor:pointer}.scribe-transcript-playback{max-height:400px;overflow-y:auto;scroll-behavior:smooth;padding:.5rem}.scribe-segment{padding:.75rem 1rem;margin-bottom:.5rem;border-left:3px solid var(--speaker-color, var(--scribe-border-color));background:var(--scribe-bg);border-radius:0 var(--scribe-border-radius) var(--scribe-border-radius) 0;cursor:pointer;transition:background .2s ease}.scribe-segment:hover{background:var(--scribe-bg-transcript)}.scribe-segment--active{background:#4caf501a;border-left-color:var(--scribe-primary)}.scribe-segment-text{margin:.25rem 0 0;line-height:1.6}.scribe-word{transition:background .15s ease,color .15s ease;padding:0 1px;border-radius:2px}.scribe-word:hover{background:#0000000d;cursor:pointer}.scribe-word--active{background:var(--scribe-primary);color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
1201
1201
|
}
|
|
1202
1202
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: RecorderComponent, decorators: [{
|
|
1203
1203
|
type: Component,
|
|
@@ -1216,23 +1216,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
1216
1216
|
} @else if (sessionData()) {
|
|
1217
1217
|
<!-- Audio Player -->
|
|
1218
1218
|
<div class="scribe-player">
|
|
1219
|
-
<
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
<
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
<
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1219
|
+
<div class="scribe-player-row">
|
|
1220
|
+
<button
|
|
1221
|
+
class="scribe-btn scribe-btn--play"
|
|
1222
|
+
(click)="togglePlayback()"
|
|
1223
|
+
[attr.aria-label]="isPlaying() ? 'Pausar' : 'Reproduzir'"
|
|
1224
|
+
>
|
|
1225
|
+
@if (isPlaying()) {
|
|
1226
|
+
<svg class="scribe-icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
|
|
1227
|
+
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
|
|
1228
|
+
</svg>
|
|
1229
|
+
} @else {
|
|
1230
|
+
<svg class="scribe-icon" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
|
|
1231
|
+
<path d="M8 5v14l11-7z"/>
|
|
1232
|
+
</svg>
|
|
1233
|
+
}
|
|
1234
|
+
</button>
|
|
1234
1235
|
|
|
1235
|
-
<div class="scribe-timeline">
|
|
1236
1236
|
<input
|
|
1237
1237
|
type="range"
|
|
1238
1238
|
class="scribe-timeline-slider"
|
|
@@ -1243,24 +1243,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
1243
1243
|
(input)="seekTo($event)"
|
|
1244
1244
|
aria-label="Posição do áudio"
|
|
1245
1245
|
/>
|
|
1246
|
-
<div class="scribe-time">
|
|
1247
|
-
{{ formatTimeDisplay(audioCurrentTime()) }} / {{ formatTimeDisplay(audioDuration()) }}
|
|
1248
|
-
</div>
|
|
1249
|
-
</div>
|
|
1250
1246
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1247
|
+
<select
|
|
1248
|
+
class="scribe-speed"
|
|
1249
|
+
[value]="playbackRate()"
|
|
1250
|
+
(change)="setPlaybackRate($event)"
|
|
1251
|
+
aria-label="Velocidade de reprodução"
|
|
1252
|
+
>
|
|
1253
|
+
<option value="0.5">0.5x</option>
|
|
1254
|
+
<option value="0.75">0.75x</option>
|
|
1255
|
+
<option value="1">1x</option>
|
|
1256
|
+
<option value="1.25">1.25x</option>
|
|
1257
|
+
<option value="1.5">1.5x</option>
|
|
1258
|
+
<option value="2">2x</option>
|
|
1259
|
+
</select>
|
|
1260
|
+
</div>
|
|
1261
|
+
<div class="scribe-time">
|
|
1262
|
+
{{ formatTimeDisplay(audioCurrentTime()) }} / {{ formatTimeDisplay(audioDuration()) }}
|
|
1263
|
+
</div>
|
|
1264
1264
|
</div>
|
|
1265
1265
|
|
|
1266
1266
|
<!-- Transcription with Highlight -->
|
|
@@ -1443,7 +1443,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
1443
1443
|
}
|
|
1444
1444
|
}
|
|
1445
1445
|
</div>
|
|
1446
|
-
`, styles: [":host{--scribe-primary: #4caf50;--scribe-primary-dark: #388e3c;--scribe-primary-light: #81c784;--scribe-danger: #f44336;--scribe-danger-dark: #d32f2f;--scribe-text-color: #212121;--scribe-text-partial: #9e9e9e;--scribe-font-family: inherit;--scribe-font-size: 1rem;--scribe-bg: #ffffff;--scribe-bg-transcript: #f5f5f5;--scribe-border-radius: 8px;--scribe-border-color: #e0e0e0;--scribe-level-bg: #e0e0e0;--scribe-level-fill: #4caf50;--scribe-speaker-0: #2196f3;--scribe-speaker-1: #9c27b0;--scribe-speaker-2: #ff9800;--scribe-speaker-3: #009688;display:block;font-family:var(--scribe-font-family);font-size:var(--scribe-font-size)}.scribe-recorder{background:var(--scribe-bg);border-radius:var(--scribe-border-radius)}.scribe-controls{display:flex;align-items:center;gap:1rem;padding:1rem}.scribe-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.75rem;border:none;border-radius:var(--scribe-border-radius);font-family:var(--scribe-font-family);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.scribe-btn:disabled{opacity:.5;cursor:not-allowed}.scribe-btn--mic{width:48px;height:48px;border-radius:50%;background:var(--scribe-bg-transcript);color:var(--scribe-text-color)}.scribe-btn--mic:hover:not(:disabled){background:var(--scribe-border-color)}.scribe-btn--mic.scribe-btn--active{background:var(--scribe-danger);color:#fff;animation:pulse-recording 1.5s ease-in-out infinite}.scribe-btn--mic.scribe-btn--paused{background:var(--scribe-primary);color:#fff}.scribe-btn--mic.scribe-btn--paused:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-btn--mic.scribe-btn--connecting{background:var(--scribe-primary-light);color:#fff}.scribe-btn--finish{padding:.75rem 1.25rem;background:var(--scribe-primary);color:#fff}.scribe-btn--finish:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-icon{flex-shrink:0}.scribe-icon--spinner{animation:spin 1s linear infinite}.scribe-level{flex:1;height:8px;background:var(--scribe-level-bg);border-radius:4px;overflow:hidden;opacity:.5;transition:opacity .2s ease}.scribe-level--active{opacity:1}.scribe-level__fill{height:100%;background:var(--scribe-level-fill);border-radius:4px;transition:width .05s ease-out}.scribe-transcript{min-height:120px;max-height:400px;overflow-y:auto;padding:1rem;margin:0 1rem 1rem;background:var(--scribe-bg-transcript);border-radius:var(--scribe-border-radius);line-height:1.6}.scribe-transcript--empty{display:flex;align-items:center;justify-content:center}.scribe-placeholder{color:var(--scribe-text-partial);font-style:italic}.scribe-speaker-block{margin-bottom:.75rem;padding-left:.5rem;border-left:3px solid var(--scribe-border-color)}.scribe-speaker-block--partial{opacity:.7}.scribe-speaker-block[data-speaker=\"0\"]{border-left-color:var(--scribe-speaker-0)}.scribe-speaker-block[data-speaker=\"1\"]{border-left-color:var(--scribe-speaker-1)}.scribe-speaker-block[data-speaker=\"2\"]{border-left-color:var(--scribe-speaker-2)}.scribe-speaker-block[data-speaker=\"3\"]{border-left-color:var(--scribe-speaker-3)}.scribe-speaker-label{display:inline-block;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;padding:.125rem .5rem;border-radius:4px;margin-bottom:.25rem;color:#fff;background:var(--scribe-border-color)}.scribe-speaker--0{background:var(--scribe-speaker-0)}.scribe-speaker--1{background:var(--scribe-speaker-1)}.scribe-speaker--2{background:var(--scribe-speaker-2)}.scribe-speaker--3{background:var(--scribe-speaker-3)}.scribe-speaker-text{margin-top:.25rem}.scribe-text{word-wrap:break-word}.scribe-text--final{color:var(--scribe-text-color)}.scribe-text--partial{color:var(--scribe-text-partial);font-style:italic}.scribe-generate-container{position:relative;margin-left:.5rem}.scribe-btn--generate{display:flex;align-items:center;gap:.5rem;padding:.75rem 1.25rem;background:var(--scribe-primary);color:#fff;border:none;border-radius:var(--scribe-border-radius);font-family:var(--scribe-font-family);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.scribe-btn--generate:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-btn--generate:disabled{opacity:.7;cursor:not-allowed}.scribe-template-menu{position:absolute;top:100%;left:0;margin-top:.25rem;min-width:220px;background:var(--scribe-bg);border:1px solid var(--scribe-border-color);border-radius:var(--scribe-border-radius);box-shadow:0 4px 12px #00000026;z-index:100;overflow:hidden}.scribe-template-item{display:flex;flex-direction:column;align-items:flex-start;width:100%;padding:.75rem 1rem;border:none;background:transparent;cursor:pointer;text-align:left;transition:background .15s ease}.scribe-template-item:hover{background:var(--scribe-bg-transcript)}.scribe-template-item:not(:last-child){border-bottom:1px solid var(--scribe-border-color)}.scribe-template-name{font-weight:500;color:var(--scribe-text-color)}.scribe-template-desc{font-size:.75rem;color:var(--scribe-text-partial);margin-top:.25rem}@keyframes pulse-recording{0%,to{box-shadow:0 0 #f4433666}50%{box-shadow:0 0 0 8px #f4433600}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.scribe-playback{padding:1rem}.scribe-loading,.scribe-error{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:2rem;color:var(--scribe-text-partial)}.scribe-player{display:flex;
|
|
1446
|
+
`, styles: [":host{--scribe-primary: #4caf50;--scribe-primary-dark: #388e3c;--scribe-primary-light: #81c784;--scribe-danger: #f44336;--scribe-danger-dark: #d32f2f;--scribe-text-color: #212121;--scribe-text-partial: #9e9e9e;--scribe-font-family: inherit;--scribe-font-size: 1rem;--scribe-bg: #ffffff;--scribe-bg-transcript: #f5f5f5;--scribe-border-radius: 8px;--scribe-border-color: #e0e0e0;--scribe-level-bg: #e0e0e0;--scribe-level-fill: #4caf50;--scribe-speaker-0: #2196f3;--scribe-speaker-1: #9c27b0;--scribe-speaker-2: #ff9800;--scribe-speaker-3: #009688;display:block;font-family:var(--scribe-font-family);font-size:var(--scribe-font-size)}.scribe-recorder{background:var(--scribe-bg);border-radius:var(--scribe-border-radius)}.scribe-controls{display:flex;align-items:center;gap:1rem;padding:1rem}.scribe-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.75rem;border:none;border-radius:var(--scribe-border-radius);font-family:var(--scribe-font-family);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.scribe-btn:disabled{opacity:.5;cursor:not-allowed}.scribe-btn--mic{width:48px;height:48px;border-radius:50%;background:var(--scribe-bg-transcript);color:var(--scribe-text-color)}.scribe-btn--mic:hover:not(:disabled){background:var(--scribe-border-color)}.scribe-btn--mic.scribe-btn--active{background:var(--scribe-danger);color:#fff;animation:pulse-recording 1.5s ease-in-out infinite}.scribe-btn--mic.scribe-btn--paused{background:var(--scribe-primary);color:#fff}.scribe-btn--mic.scribe-btn--paused:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-btn--mic.scribe-btn--connecting{background:var(--scribe-primary-light);color:#fff}.scribe-btn--finish{padding:.75rem 1.25rem;background:var(--scribe-primary);color:#fff}.scribe-btn--finish:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-icon{flex-shrink:0}.scribe-icon--spinner{animation:spin 1s linear infinite}.scribe-level{flex:1;height:8px;background:var(--scribe-level-bg);border-radius:4px;overflow:hidden;opacity:.5;transition:opacity .2s ease}.scribe-level--active{opacity:1}.scribe-level__fill{height:100%;background:var(--scribe-level-fill);border-radius:4px;transition:width .05s ease-out}.scribe-transcript{min-height:120px;max-height:400px;overflow-y:auto;padding:1rem;margin:0 1rem 1rem;background:var(--scribe-bg-transcript);border-radius:var(--scribe-border-radius);line-height:1.6}.scribe-transcript--empty{display:flex;align-items:center;justify-content:center}.scribe-placeholder{color:var(--scribe-text-partial);font-style:italic}.scribe-speaker-block{margin-bottom:.75rem;padding-left:.5rem;border-left:3px solid var(--scribe-border-color)}.scribe-speaker-block--partial{opacity:.7}.scribe-speaker-block[data-speaker=\"0\"]{border-left-color:var(--scribe-speaker-0)}.scribe-speaker-block[data-speaker=\"1\"]{border-left-color:var(--scribe-speaker-1)}.scribe-speaker-block[data-speaker=\"2\"]{border-left-color:var(--scribe-speaker-2)}.scribe-speaker-block[data-speaker=\"3\"]{border-left-color:var(--scribe-speaker-3)}.scribe-speaker-label{display:inline-block;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;padding:.125rem .5rem;border-radius:4px;margin-bottom:.25rem;color:#fff;background:var(--scribe-border-color)}.scribe-speaker--0{background:var(--scribe-speaker-0)}.scribe-speaker--1{background:var(--scribe-speaker-1)}.scribe-speaker--2{background:var(--scribe-speaker-2)}.scribe-speaker--3{background:var(--scribe-speaker-3)}.scribe-speaker-text{margin-top:.25rem}.scribe-text{word-wrap:break-word}.scribe-text--final{color:var(--scribe-text-color)}.scribe-text--partial{color:var(--scribe-text-partial);font-style:italic}.scribe-generate-container{position:relative;margin-left:.5rem}.scribe-btn--generate{display:flex;align-items:center;gap:.5rem;padding:.75rem 1.25rem;background:var(--scribe-primary);color:#fff;border:none;border-radius:var(--scribe-border-radius);font-family:var(--scribe-font-family);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}.scribe-btn--generate:hover:not(:disabled){background:var(--scribe-primary-dark)}.scribe-btn--generate:disabled{opacity:.7;cursor:not-allowed}.scribe-template-menu{position:absolute;top:100%;left:0;margin-top:.25rem;min-width:220px;background:var(--scribe-bg);border:1px solid var(--scribe-border-color);border-radius:var(--scribe-border-radius);box-shadow:0 4px 12px #00000026;z-index:100;overflow:hidden}.scribe-template-item{display:flex;flex-direction:column;align-items:flex-start;width:100%;padding:.75rem 1rem;border:none;background:transparent;cursor:pointer;text-align:left;transition:background .15s ease}.scribe-template-item:hover{background:var(--scribe-bg-transcript)}.scribe-template-item:not(:last-child){border-bottom:1px solid var(--scribe-border-color)}.scribe-template-name{font-weight:500;color:var(--scribe-text-color)}.scribe-template-desc{font-size:.75rem;color:var(--scribe-text-partial);margin-top:.25rem}@keyframes pulse-recording{0%,to{box-shadow:0 0 #f4433666}50%{box-shadow:0 0 0 8px #f4433600}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.scribe-playback{padding:1rem}.scribe-loading,.scribe-error{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:2rem;color:var(--scribe-text-partial)}.scribe-player{display:flex;flex-direction:column;gap:.5rem;padding:1rem;background:var(--scribe-bg-transcript);border-radius:var(--scribe-border-radius);margin-bottom:1rem}.scribe-player-row{display:flex;align-items:center;gap:1rem}.scribe-btn--play{width:48px;height:48px;border-radius:50%;background:var(--scribe-primary);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .2s ease;flex-shrink:0}.scribe-btn--play:hover{background:var(--scribe-primary-dark)}.scribe-timeline-slider{flex:1;cursor:pointer;height:6px;-webkit-appearance:none;appearance:none;background:var(--scribe-level-bg);border-radius:3px;outline:none}.scribe-timeline-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;background:var(--scribe-primary);border-radius:50%;cursor:pointer}.scribe-timeline-slider::-moz-range-thumb{width:14px;height:14px;background:var(--scribe-primary);border-radius:50%;cursor:pointer;border:none}.scribe-time{font-size:.75rem;color:var(--scribe-text-partial);text-align:center}.scribe-speed{padding:.375rem .5rem;border-radius:4px;border:1px solid var(--scribe-border-color);background:var(--scribe-bg);font-size:.875rem;cursor:pointer}.scribe-transcript-playback{max-height:400px;overflow-y:auto;scroll-behavior:smooth;padding:.5rem}.scribe-segment{padding:.75rem 1rem;margin-bottom:.5rem;border-left:3px solid var(--speaker-color, var(--scribe-border-color));background:var(--scribe-bg);border-radius:0 var(--scribe-border-radius) var(--scribe-border-radius) 0;cursor:pointer;transition:background .2s ease}.scribe-segment:hover{background:var(--scribe-bg-transcript)}.scribe-segment--active{background:#4caf501a;border-left-color:var(--scribe-primary)}.scribe-segment-text{margin:.25rem 0 0;line-height:1.6}.scribe-word{transition:background .15s ease,color .15s ease;padding:0 1px;border-radius:2px}.scribe-word:hover{background:#0000000d;cursor:pointer}.scribe-word--active{background:var(--scribe-primary);color:#fff}\n"] }]
|
|
1447
1447
|
}], ctorParameters: () => [], propDecorators: { onDocumentClick: [{
|
|
1448
1448
|
type: HostListener,
|
|
1449
1449
|
args: ['document:click', ['$event']]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"medc-com-br-ngx-jaimes-scribe.mjs","sources":["../../../libs/ngx-jaimes-scribe/src/lib/services/vad.service.ts","../../../libs/ngx-jaimes-scribe/src/lib/services/audio-capture.service.ts","../../../libs/ngx-jaimes-scribe/src/lib/services/scribe-socket.service.ts","../../../libs/ngx-jaimes-scribe/src/lib/utils/pcm-to-wav.ts","../../../libs/ngx-jaimes-scribe/src/lib/components/recorder/recorder.component.ts","../../../libs/ngx-jaimes-scribe/src/medc-com-br-ngx-jaimes-scribe.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\nexport type VadState = 'idle' | 'speech' | 'silence_pending' | 'silence';\n\nexport interface VadConfig {\n speechThreshold: number;\n silenceThreshold: number;\n silenceDebounceMs: number;\n}\n\nconst DEFAULT_CONFIG: VadConfig = {\n speechThreshold: 8,\n silenceThreshold: 3,\n silenceDebounceMs: 1500,\n};\n\n@Injectable({ providedIn: 'root' })\nexport class VadService {\n private state: VadState = 'idle';\n private silenceStartTime: number | null = null;\n private config = { ...DEFAULT_CONFIG };\n\n readonly state$ = new BehaviorSubject<VadState>('idle');\n\n analyzeLevel(level: number): { isSilence: boolean } {\n const now = Date.now();\n\n if (level >= this.config.speechThreshold) {\n this.state = 'speech';\n this.silenceStartTime = null;\n this.state$.next('speech');\n return { isSilence: false };\n }\n\n if (level < this.config.silenceThreshold) {\n if (this.state === 'speech') {\n this.silenceStartTime = now;\n this.state = 'silence_pending';\n } else if (this.state === 'silence_pending' && this.silenceStartTime) {\n if (now - this.silenceStartTime >= this.config.silenceDebounceMs) {\n this.state = 'silence';\n this.state$.next('silence');\n }\n }\n } else {\n if (this.state === 'silence_pending') {\n this.state = 'speech';\n this.silenceStartTime = null;\n }\n }\n\n return { isSilence: this.state === 'silence' };\n }\n\n reset(): void {\n this.state = 'idle';\n this.silenceStartTime = null;\n this.state$.next('idle');\n }\n\n getState(): VadState {\n return this.state;\n }\n}\n","import { Injectable, InjectionToken, inject, NgZone } from '@angular/core';\nimport { Subject, Observable, BehaviorSubject } from 'rxjs';\nimport { VadService } from './vad.service';\n\nexport interface AudioCaptureConfig {\n workletUrl: string;\n levelUpdateInterval: number;\n}\n\nexport const AUDIO_CAPTURE_CONFIG = new InjectionToken<AudioCaptureConfig>('AUDIO_CAPTURE_CONFIG');\n\nconst DEFAULT_CONFIG: AudioCaptureConfig = {\n workletUrl: '/assets/pcm-processor.js',\n levelUpdateInterval: 50,\n};\n\nexport interface AudioChunk {\n data: ArrayBuffer;\n isSilence: boolean;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class AudioCaptureService {\n private config: AudioCaptureConfig;\n private ngZone: NgZone;\n private vadService: VadService;\n private audioContext: AudioContext | null = null;\n private workletNode: AudioWorkletNode | null = null;\n private analyserNode: AnalyserNode | null = null;\n private source: MediaStreamAudioSourceNode | null = null;\n private stream: MediaStream | null = null;\n private workletRegistered = false;\n private levelInterval: ReturnType<typeof setInterval> | null = null;\n private paused = false;\n\n private audioChunkSubject = new Subject<AudioChunk>();\n private audioLevelSubject = new BehaviorSubject<number>(0);\n private errorSubject = new Subject<Error>();\n\n audioChunk$: Observable<AudioChunk> = this.audioChunkSubject.asObservable();\n audioLevel$: Observable<number> = this.audioLevelSubject.asObservable();\n error$: Observable<Error> = this.errorSubject.asObservable();\n\n constructor() {\n const injectedConfig = inject(AUDIO_CAPTURE_CONFIG, { optional: true });\n this.config = injectedConfig ?? DEFAULT_CONFIG;\n this.ngZone = inject(NgZone);\n this.vadService = inject(VadService);\n }\n\n async startCapture(): Promise<void> {\n try {\n this.stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n channelCount: 1,\n echoCancellation: true,\n noiseSuppression: true,\n },\n });\n\n this.audioContext = new AudioContext();\n\n if (!this.workletRegistered) {\n await this.audioContext.audioWorklet.addModule(this.config.workletUrl);\n this.workletRegistered = true;\n }\n\n this.workletNode = new AudioWorkletNode(this.audioContext, 'pcm-processor', {\n processorOptions: {\n inputSampleRate: this.audioContext.sampleRate,\n },\n });\n\n this.workletNode.port.onmessage = (event: MessageEvent<ArrayBuffer>) => {\n if (!this.paused) {\n const level = this.getAudioLevel();\n const { isSilence } = this.vadService.analyzeLevel(level);\n this.audioChunkSubject.next({ data: event.data, isSilence });\n }\n };\n\n this.analyserNode = this.audioContext.createAnalyser();\n this.analyserNode.fftSize = 256;\n this.analyserNode.smoothingTimeConstant = 0.8;\n\n this.source = this.audioContext.createMediaStreamSource(this.stream);\n this.source.connect(this.analyserNode);\n this.source.connect(this.workletNode);\n\n this.startLevelMonitoring();\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Failed to start audio capture');\n this.errorSubject.next(err);\n throw err;\n }\n }\n\n async stopCapture(): Promise<void> {\n this.stopLevelMonitoring();\n this.paused = false;\n this.vadService.reset();\n\n if (this.workletNode) {\n this.workletNode.port.close();\n this.workletNode.disconnect();\n this.workletNode = null;\n }\n\n if (this.analyserNode) {\n this.analyserNode.disconnect();\n this.analyserNode = null;\n }\n\n if (this.source) {\n this.source.disconnect();\n this.source = null;\n }\n\n if (this.audioContext) {\n await this.audioContext.close();\n this.audioContext = null;\n this.workletRegistered = false;\n }\n\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n\n this.audioLevelSubject.next(0);\n }\n\n pauseCapture(): void {\n if (this.isCapturing() && !this.paused) {\n this.paused = true;\n }\n }\n\n resumeCapture(): void {\n if (this.isCapturing() && this.paused) {\n this.paused = false;\n }\n }\n\n isCapturing(): boolean {\n return this.workletNode !== null && this.stream !== null;\n }\n\n isPaused(): boolean {\n return this.paused;\n }\n\n getSampleRate(): number | null {\n return this.audioContext?.sampleRate ?? null;\n }\n\n private startLevelMonitoring(): void {\n this.stopLevelMonitoring();\n\n this.ngZone.runOutsideAngular(() => {\n this.levelInterval = setInterval(() => {\n const level = this.getAudioLevel();\n this.ngZone.run(() => {\n this.audioLevelSubject.next(level);\n });\n }, this.config.levelUpdateInterval);\n });\n }\n\n private stopLevelMonitoring(): void {\n if (this.levelInterval) {\n clearInterval(this.levelInterval);\n this.levelInterval = null;\n }\n }\n\n private getAudioLevel(): number {\n if (!this.analyserNode) {\n return 0;\n }\n\n const dataArray = new Uint8Array(this.analyserNode.frequencyBinCount);\n this.analyserNode.getByteFrequencyData(dataArray);\n\n const sum = dataArray.reduce((acc, val) => acc + val, 0);\n const average = sum / dataArray.length;\n\n return Math.round((average / 255) * 100);\n }\n}\n","import { Injectable, InjectionToken, inject, NgZone } from '@angular/core';\nimport { BehaviorSubject, Subject, Observable } from 'rxjs';\nimport type { TranscriptionEvent } from '@medc-com-br/jaimes-shared';\n\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';\n\nexport interface ScribeSocketConfig {\n reconnectAttempts: number;\n reconnectBaseDelay: number;\n chunkBufferInterval: number;\n}\n\nexport const SCRIBE_SOCKET_CONFIG = new InjectionToken<ScribeSocketConfig>('SCRIBE_SOCKET_CONFIG');\n\nconst DEFAULT_CONFIG: ScribeSocketConfig = {\n reconnectAttempts: 5,\n reconnectBaseDelay: 1000,\n chunkBufferInterval: 250,\n};\n\n@Injectable({ providedIn: 'root' })\nexport class ScribeSocketService {\n private config: ScribeSocketConfig;\n private ngZone: NgZone;\n private ws: WebSocket | null = null;\n private wsUrl: string | null = null;\n private token: string | null = null;\n private premium = false;\n private reconnectAttempt = 0;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n private intentionalClose = false;\n\n private chunkBuffer: string[] = [];\n private sendInterval: ReturnType<typeof setInterval> | null = null;\n private keepaliveInterval: ReturnType<typeof setInterval> | null = null;\n private currentlyInSilence = false;\n\n private connectionStateSubject = new BehaviorSubject<ConnectionState>('disconnected');\n private transcriptionSubject = new Subject<TranscriptionEvent>();\n private errorSubject = new Subject<Error>();\n private sessionIdSubject = new BehaviorSubject<string | null>(null);\n\n connectionState$: Observable<ConnectionState> = this.connectionStateSubject.asObservable();\n transcription$: Observable<TranscriptionEvent> = this.transcriptionSubject.asObservable();\n error$: Observable<Error> = this.errorSubject.asObservable();\n sessionId$: Observable<string | null> = this.sessionIdSubject.asObservable();\n\n constructor() {\n const injectedConfig = inject(SCRIBE_SOCKET_CONFIG, { optional: true });\n this.config = injectedConfig ?? DEFAULT_CONFIG;\n this.ngZone = inject(NgZone);\n }\n\n async connect(url: string, token: string, premium = false): Promise<void> {\n if (this.connectionStateSubject.getValue() === 'connecting') {\n throw new Error('Connection already in progress');\n }\n\n if (this.isConnected()) {\n this.disconnect();\n }\n\n this.clearReconnectTimeout();\n this.wsUrl = url;\n this.token = token;\n this.premium = premium;\n this.intentionalClose = false;\n this.reconnectAttempt = 0;\n\n return this.createConnection();\n }\n\n disconnect(): void {\n this.intentionalClose = true;\n this.flushAndStopBuffering();\n this.clearReconnectTimeout();\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.close(1000, 'Client disconnect');\n }\n this.ws = null;\n\n this.connectionStateSubject.next('disconnected');\n this.sessionIdSubject.next(null);\n }\n\n sendAudioChunk(chunk: ArrayBuffer, isSilence: boolean): void {\n const message = JSON.stringify({\n type: 'audio',\n isSilence,\n data: this.arrayBufferToBase64(chunk),\n });\n this.chunkBuffer.push(message);\n\n if (isSilence && !this.currentlyInSilence) {\n this.currentlyInSilence = true;\n this.startKeepaliveInterval();\n } else if (!isSilence && this.currentlyInSilence) {\n this.currentlyInSilence = false;\n this.stopKeepaliveInterval();\n }\n }\n\n private startKeepaliveInterval(): void {\n this.stopKeepaliveInterval();\n this.keepaliveInterval = setInterval(() => {\n if (this.isConnected()) {\n this.ws!.send(JSON.stringify({ type: 'keepalive' }));\n }\n }, 3000);\n }\n\n private stopKeepaliveInterval(): void {\n if (this.keepaliveInterval) {\n clearInterval(this.keepaliveInterval);\n this.keepaliveInterval = null;\n }\n }\n\n private arrayBufferToBase64(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n\n isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n getSessionId(): string | null {\n return this.sessionIdSubject.getValue();\n }\n\n private createConnection(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.wsUrl) {\n reject(new Error('WebSocket URL is required'));\n return;\n }\n\n this.connectionStateSubject.next('connecting');\n const params = new URLSearchParams({ premium: String(this.premium) });\n if (this.token) {\n params.set('token', this.token);\n }\n const url = `${this.wsUrl}?${params.toString()}`;\n\n this.ws = new WebSocket(url);\n this.ws.binaryType = 'arraybuffer';\n\n this.ws.onopen = () => {\n this.ngZone.run(() => {\n this.reconnectAttempt = 0;\n this.connectionStateSubject.next('connected');\n this.startBuffering();\n resolve();\n });\n };\n\n this.ws.onerror = () => {\n this.ngZone.run(() => {\n const error = new Error('WebSocket connection error');\n this.errorSubject.next(error);\n if (this.connectionStateSubject.getValue() === 'connecting') {\n reject(error);\n }\n });\n };\n\n this.ws.onmessage = (event) => {\n this.ngZone.run(() => {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'connected' && data.sessionId) {\n this.sessionIdSubject.next(data.sessionId);\n }\n this.transcriptionSubject.next(data as TranscriptionEvent);\n } catch (e) {\n const error = new Error(`Failed to parse WebSocket message: ${e instanceof Error ? e.message : String(e)}`);\n console.error(error.message);\n this.errorSubject.next(error);\n }\n });\n };\n\n this.ws.onclose = (event) => {\n this.ngZone.run(() => {\n this.stopBuffering();\n\n if (!this.intentionalClose && event.code !== 1000) {\n this.attemptReconnect();\n } else {\n this.connectionStateSubject.next('disconnected');\n this.sessionIdSubject.next(null);\n }\n });\n };\n });\n }\n\n private attemptReconnect(): void {\n if (this.reconnectAttempt >= this.config.reconnectAttempts) {\n this.connectionStateSubject.next('disconnected');\n this.errorSubject.next(new Error('Max reconnection attempts reached'));\n return;\n }\n\n this.connectionStateSubject.next('reconnecting');\n const delay = this.config.reconnectBaseDelay * Math.pow(2, this.reconnectAttempt);\n this.reconnectAttempt++;\n\n this.reconnectTimeout = setTimeout(() => {\n this.createConnection().catch(() => {});\n }, delay);\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n }\n\n private startBuffering(): void {\n this.stopBuffering();\n\n this.sendInterval = setInterval(() => {\n if (this.chunkBuffer.length > 0 && this.isConnected()) {\n for (const msg of this.chunkBuffer) {\n this.ws!.send(msg);\n }\n this.chunkBuffer = [];\n }\n }, this.config.chunkBufferInterval);\n }\n\n private flushAndStopBuffering(): void {\n if (this.sendInterval) {\n clearInterval(this.sendInterval);\n this.sendInterval = null;\n }\n\n if (this.chunkBuffer.length > 0 && this.isConnected()) {\n for (const msg of this.chunkBuffer) {\n this.ws!.send(msg);\n }\n }\n this.chunkBuffer = [];\n this.stopKeepaliveInterval();\n this.currentlyInSilence = false;\n }\n\n private stopBuffering(): void {\n if (this.sendInterval) {\n clearInterval(this.sendInterval);\n this.sendInterval = null;\n }\n this.chunkBuffer = [];\n }\n\n}\n","const SAMPLE_RATE = 16000;\nconst NUM_CHANNELS = 1;\nconst BITS_PER_SAMPLE = 16;\n\nfunction writeString(view: DataView, offset: number, str: string): void {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n}\n\nfunction concatBuffers(buffer1: ArrayBuffer, buffer2: ArrayBuffer): ArrayBuffer {\n const combined = new Uint8Array(buffer1.byteLength + buffer2.byteLength);\n combined.set(new Uint8Array(buffer1), 0);\n combined.set(new Uint8Array(buffer2), buffer1.byteLength);\n return combined.buffer;\n}\n\nexport function pcmToWav(pcmData: ArrayBuffer, sampleRate = SAMPLE_RATE): ArrayBuffer {\n const header = new ArrayBuffer(44);\n const view = new DataView(header);\n\n const byteRate = sampleRate * NUM_CHANNELS * (BITS_PER_SAMPLE / 8);\n const blockAlign = NUM_CHANNELS * (BITS_PER_SAMPLE / 8);\n\n // RIFF chunk descriptor\n writeString(view, 0, 'RIFF');\n view.setUint32(4, 36 + pcmData.byteLength, true);\n writeString(view, 8, 'WAVE');\n\n // fmt sub-chunk\n writeString(view, 12, 'fmt ');\n view.setUint32(16, 16, true); // SubChunk1Size (16 for PCM)\n view.setUint16(20, 1, true); // AudioFormat (1 = PCM)\n view.setUint16(22, NUM_CHANNELS, true); // NumChannels\n view.setUint32(24, sampleRate, true); // SampleRate\n view.setUint32(28, byteRate, true); // ByteRate\n view.setUint16(32, blockAlign, true); // BlockAlign\n view.setUint16(34, BITS_PER_SAMPLE, true); // BitsPerSample\n\n // data sub-chunk\n writeString(view, 36, 'data');\n view.setUint32(40, pcmData.byteLength, true);\n\n return concatBuffers(header, pcmData);\n}\n\nexport function createAudioBlobUrl(wavData: ArrayBuffer): string {\n const blob = new Blob([wavData], { type: 'audio/wav' });\n return URL.createObjectURL(blob);\n}\n\nexport function formatTime(seconds: number): string {\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","import { Component, inject, signal, input, output, OnDestroy, computed, HostListener, ElementRef, effect } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs';\nimport { AudioCaptureService } from '../../services/audio-capture.service';\nimport { ScribeSocketService, ConnectionState } from '../../services/scribe-socket.service';\nimport { pcmToWav, createAudioBlobUrl, formatTime } from '../../utils/pcm-to-wav';\nimport type { TranscriptionEvent, TemplateOption, GeneratedDocument, SessionPlaybackData, TranscriptSegment, TranscriptionWord } from '@medc-com-br/jaimes-shared';\n\ninterface TranscriptEntry {\n id: number;\n text: string;\n speaker?: number;\n isFinal: boolean;\n startTime?: number;\n endTime?: number;\n}\n\nexport type RecorderMode = 'recording' | 'playback';\n\ninterface SpeakerGroup {\n speaker?: number;\n entries: TranscriptEntry[];\n}\n\nconst SPEAKER_LABELS: Record<number, string> = {\n 0: 'Pessoa 1',\n 1: 'Pessoa 2',\n 2: 'Pessoa 3',\n 3: 'Pessoa 4',\n};\n\n@Component({\n selector: 'ngx-jaimes-scribe-recorder',\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"scribe-recorder\">\n @if (mode() === 'playback') {\n <!-- Playback Mode -->\n <div class=\"scribe-playback\">\n @if (isLoadingSession()) {\n <div class=\"scribe-loading\">\n <svg class=\"scribe-icon scribe-icon--spinner\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32\" stroke-linecap=\"round\"/>\n </svg>\n <span>Carregando sessão...</span>\n </div>\n } @else if (sessionData()) {\n <!-- Audio Player -->\n <div class=\"scribe-player\">\n <button\n class=\"scribe-btn scribe-btn--play\"\n (click)=\"togglePlayback()\"\n [attr.aria-label]=\"isPlaying() ? 'Pausar' : 'Reproduzir'\"\n >\n @if (isPlaying()) {\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/>\n </svg>\n } @else {\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\"/>\n </svg>\n }\n </button>\n\n <div class=\"scribe-timeline\">\n <input\n type=\"range\"\n class=\"scribe-timeline-slider\"\n [min]=\"0\"\n [max]=\"audioDuration()\"\n [value]=\"audioCurrentTime()\"\n step=\"0.1\"\n (input)=\"seekTo($event)\"\n aria-label=\"Posição do áudio\"\n />\n <div class=\"scribe-time\">\n {{ formatTimeDisplay(audioCurrentTime()) }} / {{ formatTimeDisplay(audioDuration()) }}\n </div>\n </div>\n\n <select\n class=\"scribe-speed\"\n [value]=\"playbackRate()\"\n (change)=\"setPlaybackRate($event)\"\n aria-label=\"Velocidade de reprodução\"\n >\n <option value=\"0.5\">0.5x</option>\n <option value=\"0.75\">0.75x</option>\n <option value=\"1\">1x</option>\n <option value=\"1.25\">1.25x</option>\n <option value=\"1.5\">1.5x</option>\n <option value=\"2\">2x</option>\n </select>\n </div>\n\n <!-- Transcription with Highlight -->\n <div class=\"scribe-transcript-playback\">\n @for (segment of segments(); track segment.id; let idx = $index) {\n <div\n class=\"scribe-segment\"\n [class.scribe-segment--active]=\"activeSegmentId() === segment.id\"\n [style.--speaker-color]=\"getSpeakerColor(segment.speaker)\"\n [attr.data-segment-id]=\"segment.id\"\n (click)=\"seekToSegment(segment)\"\n >\n @if (segment.speaker !== undefined && shouldShowSpeakerLabel(idx)) {\n <span class=\"scribe-speaker-label\" [class]=\"'scribe-speaker--' + segment.speaker\">\n {{ getSpeakerLabel(segment.speaker) }}\n </span>\n }\n\n <p class=\"scribe-segment-text\">\n @if (segment.words?.length) {\n @for (word of segment.words; track $index; let i = $index) {\n <span\n class=\"scribe-word\"\n [class.scribe-word--active]=\"activeSegmentId() === segment.id && activeWordIndex() === i\"\n (click)=\"seekToWord(word, $event)\"\n >{{ word.word }}</span>{{ ' ' }}\n }\n } @else {\n {{ segment.text }}\n }\n </p>\n </div>\n }\n @if (segments().length === 0) {\n <span class=\"scribe-placeholder\">Nenhuma transcrição disponível.</span>\n }\n </div>\n } @else {\n <div class=\"scribe-error\">\n <span>Não foi possível carregar a sessão.</span>\n </div>\n }\n </div>\n } @else {\n <!-- Recording Mode -->\n @if (isLoadingSession()) {\n <div class=\"scribe-loading\">\n <svg class=\"scribe-icon scribe-icon--spinner\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32\" stroke-linecap=\"round\"/>\n </svg>\n <span>Carregando sessão...</span>\n </div>\n } @else {\n <div class=\"scribe-controls\">\n @if (!hasFinishedSession()) {\n <button\n class=\"scribe-btn scribe-btn--mic\"\n [class.scribe-btn--active]=\"isRecording() && !isPaused()\"\n [class.scribe-btn--paused]=\"isPaused()\"\n [class.scribe-btn--connecting]=\"connectionState() === 'connecting'\"\n [disabled]=\"connectionState() === 'connecting'\"\n (click)=\"toggleRecording()\"\n [attr.aria-label]=\"getMicButtonLabel()\"\n >\n @if (connectionState() === 'connecting') {\n <svg class=\"scribe-icon scribe-icon--spinner\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32\" stroke-linecap=\"round\"/>\n </svg>\n } @else if (isPaused()) {\n <!-- Play icon when paused -->\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\"/>\n </svg>\n } @else if (isRecording()) {\n <!-- Pause icon when recording -->\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/>\n </svg>\n } @else {\n <!-- Mic icon when idle -->\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm-1-9c0-.55.45-1 1-1s1 .45 1 1v6c0 .55-.45 1-1 1s-1-.45-1-1V5z\"/>\n <path d=\"M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z\"/>\n </svg>\n }\n </button>\n\n <div class=\"scribe-level\" [class.scribe-level--active]=\"isRecording() && !isPaused()\">\n <div class=\"scribe-level__fill\" [style.width.%]=\"isPaused() ? 0 : audioLevel()\"></div>\n </div>\n\n <button\n class=\"scribe-btn scribe-btn--finish\"\n [disabled]=\"!isRecording() && !isPaused()\"\n (click)=\"finishSession()\"\n aria-label=\"Finalizar gravação\"\n >\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"currentColor\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/>\n </svg>\n <span>Finalizar</span>\n </button>\n }\n\n @if (hasFinishedSession() && templates().length > 0) {\n <div class=\"scribe-generate-container\">\n <button\n class=\"scribe-btn scribe-btn--generate\"\n [disabled]=\"isGenerating()\"\n [attr.aria-expanded]=\"showTemplateMenu()\"\n aria-haspopup=\"menu\"\n (click)=\"toggleTemplateMenu()\"\n aria-label=\"Gerar resumo\"\n >\n @if (isGenerating()) {\n <svg class=\"scribe-icon scribe-icon--spinner\" viewBox=\"0 0 24 24\" width=\"20\" height=\"20\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32\" stroke-linecap=\"round\"/>\n </svg>\n <span>Gerando...</span>\n } @else {\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"currentColor\">\n <path d=\"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11zm-3-7h-2v2h-2v-2H9v-2h2V9h2v2h2v2z\"/>\n </svg>\n <span>Gerar Resumo</span>\n }\n </button>\n\n @if (showTemplateMenu()) {\n <div class=\"scribe-template-menu\" role=\"menu\">\n @for (template of templates(); track template.id) {\n <button\n class=\"scribe-template-item\"\n role=\"menuitem\"\n (click)=\"selectTemplate(template)\"\n >\n <span class=\"scribe-template-name\">{{ template.name }}</span>\n @if (template.description) {\n <span class=\"scribe-template-desc\">{{ template.description }}</span>\n }\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"scribe-transcript\" [class.scribe-transcript--empty]=\"speakerGroups().length === 0 && !partialText()\">\n @if (speakerGroups().length === 0 && !partialText()) {\n <span class=\"scribe-placeholder\">A transcrição aparecerá aqui...</span>\n } @else {\n @for (group of speakerGroups(); track $index) {\n <div class=\"scribe-speaker-block\" [attr.data-speaker]=\"group.speaker\">\n @if (group.speaker !== undefined && group.speaker !== null) {\n <span class=\"scribe-speaker-label\" [class]=\"'scribe-speaker--' + group.speaker\">\n {{ getSpeakerLabel(group.speaker) }}\n </span>\n }\n <div class=\"scribe-speaker-text\">\n @for (entry of group.entries; track entry.id) {\n <span class=\"scribe-text scribe-text--final\">{{ entry.text }} </span>\n }\n </div>\n </div>\n }\n @if (partialText()) {\n <div class=\"scribe-speaker-block scribe-speaker-block--partial\">\n @if (currentSpeaker() !== undefined && currentSpeaker() !== null) {\n <span class=\"scribe-speaker-label\" [class]=\"'scribe-speaker--' + currentSpeaker()\">\n {{ getSpeakerLabel(currentSpeaker()!) }}\n </span>\n }\n <div class=\"scribe-speaker-text\">\n <span class=\"scribe-text scribe-text--partial\">{{ partialText() }}</span>\n </div>\n </div>\n }\n }\n </div>\n }\n }\n </div>\n `,\n styles: [`\n :host {\n --scribe-primary: #4caf50;\n --scribe-primary-dark: #388e3c;\n --scribe-primary-light: #81c784;\n --scribe-danger: #f44336;\n --scribe-danger-dark: #d32f2f;\n --scribe-text-color: #212121;\n --scribe-text-partial: #9e9e9e;\n --scribe-font-family: inherit;\n --scribe-font-size: 1rem;\n --scribe-bg: #ffffff;\n --scribe-bg-transcript: #f5f5f5;\n --scribe-border-radius: 8px;\n --scribe-border-color: #e0e0e0;\n --scribe-level-bg: #e0e0e0;\n --scribe-level-fill: #4caf50;\n\n --scribe-speaker-0: #2196f3;\n --scribe-speaker-1: #9c27b0;\n --scribe-speaker-2: #ff9800;\n --scribe-speaker-3: #009688;\n\n display: block;\n font-family: var(--scribe-font-family);\n font-size: var(--scribe-font-size);\n }\n\n .scribe-recorder {\n background: var(--scribe-bg);\n border-radius: var(--scribe-border-radius);\n }\n\n .scribe-controls {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n }\n\n .scribe-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem;\n border: none;\n border-radius: var(--scribe-border-radius);\n font-family: var(--scribe-font-family);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .scribe-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .scribe-btn--mic {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: var(--scribe-bg-transcript);\n color: var(--scribe-text-color);\n }\n\n .scribe-btn--mic:hover:not(:disabled) {\n background: var(--scribe-border-color);\n }\n\n .scribe-btn--mic.scribe-btn--active {\n background: var(--scribe-danger);\n color: white;\n animation: pulse-recording 1.5s ease-in-out infinite;\n }\n\n .scribe-btn--mic.scribe-btn--paused {\n background: var(--scribe-primary);\n color: white;\n }\n\n .scribe-btn--mic.scribe-btn--paused:hover:not(:disabled) {\n background: var(--scribe-primary-dark);\n }\n\n .scribe-btn--mic.scribe-btn--connecting {\n background: var(--scribe-primary-light);\n color: white;\n }\n\n .scribe-btn--finish {\n padding: 0.75rem 1.25rem;\n background: var(--scribe-primary);\n color: white;\n }\n\n .scribe-btn--finish:hover:not(:disabled) {\n background: var(--scribe-primary-dark);\n }\n\n .scribe-icon {\n flex-shrink: 0;\n }\n\n .scribe-icon--spinner {\n animation: spin 1s linear infinite;\n }\n\n .scribe-level {\n flex: 1;\n height: 8px;\n background: var(--scribe-level-bg);\n border-radius: 4px;\n overflow: hidden;\n opacity: 0.5;\n transition: opacity 0.2s ease;\n }\n\n .scribe-level--active {\n opacity: 1;\n }\n\n .scribe-level__fill {\n height: 100%;\n background: var(--scribe-level-fill);\n border-radius: 4px;\n transition: width 0.05s ease-out;\n }\n\n .scribe-transcript {\n min-height: 120px;\n max-height: 400px;\n overflow-y: auto;\n padding: 1rem;\n margin: 0 1rem 1rem;\n background: var(--scribe-bg-transcript);\n border-radius: var(--scribe-border-radius);\n line-height: 1.6;\n }\n\n .scribe-transcript--empty {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .scribe-placeholder {\n color: var(--scribe-text-partial);\n font-style: italic;\n }\n\n .scribe-speaker-block {\n margin-bottom: 0.75rem;\n padding-left: 0.5rem;\n border-left: 3px solid var(--scribe-border-color);\n }\n\n .scribe-speaker-block--partial {\n opacity: 0.7;\n }\n\n .scribe-speaker-block[data-speaker=\"0\"] {\n border-left-color: var(--scribe-speaker-0);\n }\n\n .scribe-speaker-block[data-speaker=\"1\"] {\n border-left-color: var(--scribe-speaker-1);\n }\n\n .scribe-speaker-block[data-speaker=\"2\"] {\n border-left-color: var(--scribe-speaker-2);\n }\n\n .scribe-speaker-block[data-speaker=\"3\"] {\n border-left-color: var(--scribe-speaker-3);\n }\n\n .scribe-speaker-label {\n display: inline-block;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n padding: 0.125rem 0.5rem;\n border-radius: 4px;\n margin-bottom: 0.25rem;\n color: white;\n background: var(--scribe-border-color);\n }\n\n .scribe-speaker--0 {\n background: var(--scribe-speaker-0);\n }\n\n .scribe-speaker--1 {\n background: var(--scribe-speaker-1);\n }\n\n .scribe-speaker--2 {\n background: var(--scribe-speaker-2);\n }\n\n .scribe-speaker--3 {\n background: var(--scribe-speaker-3);\n }\n\n .scribe-speaker-text {\n margin-top: 0.25rem;\n }\n\n .scribe-text {\n word-wrap: break-word;\n }\n\n .scribe-text--final {\n color: var(--scribe-text-color);\n }\n\n .scribe-text--partial {\n color: var(--scribe-text-partial);\n font-style: italic;\n }\n\n .scribe-generate-container {\n position: relative;\n margin-left: 0.5rem;\n }\n\n .scribe-btn--generate {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n background: var(--scribe-primary);\n color: white;\n border: none;\n border-radius: var(--scribe-border-radius);\n font-family: var(--scribe-font-family);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .scribe-btn--generate:hover:not(:disabled) {\n background: var(--scribe-primary-dark);\n }\n\n .scribe-btn--generate:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n }\n\n .scribe-template-menu {\n position: absolute;\n top: 100%;\n left: 0;\n margin-top: 0.25rem;\n min-width: 220px;\n background: var(--scribe-bg);\n border: 1px solid var(--scribe-border-color);\n border-radius: var(--scribe-border-radius);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n z-index: 100;\n overflow: hidden;\n }\n\n .scribe-template-item {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n padding: 0.75rem 1rem;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.15s ease;\n }\n\n .scribe-template-item:hover {\n background: var(--scribe-bg-transcript);\n }\n\n .scribe-template-item:not(:last-child) {\n border-bottom: 1px solid var(--scribe-border-color);\n }\n\n .scribe-template-name {\n font-weight: 500;\n color: var(--scribe-text-color);\n }\n\n .scribe-template-desc {\n font-size: 0.75rem;\n color: var(--scribe-text-partial);\n margin-top: 0.25rem;\n }\n\n @keyframes pulse-recording {\n 0%, 100% { box-shadow: 0 0 0 0 rgba(244, 67, 54, 0.4); }\n 50% { box-shadow: 0 0 0 8px rgba(244, 67, 54, 0); }\n }\n\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* Playback Mode Styles */\n .scribe-playback {\n padding: 1rem;\n }\n\n .scribe-loading,\n .scribe-error {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 2rem;\n color: var(--scribe-text-partial);\n }\n\n .scribe-player {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n background: var(--scribe-bg-transcript);\n border-radius: var(--scribe-border-radius);\n margin-bottom: 1rem;\n }\n\n .scribe-btn--play {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: var(--scribe-primary);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s ease;\n flex-shrink: 0;\n }\n\n .scribe-btn--play:hover {\n background: var(--scribe-primary-dark);\n }\n\n .scribe-timeline {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n }\n\n .scribe-timeline-slider {\n width: 100%;\n cursor: pointer;\n height: 6px;\n -webkit-appearance: none;\n appearance: none;\n background: var(--scribe-level-bg);\n border-radius: 3px;\n outline: none;\n }\n\n .scribe-timeline-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 14px;\n height: 14px;\n background: var(--scribe-primary);\n border-radius: 50%;\n cursor: pointer;\n }\n\n .scribe-timeline-slider::-moz-range-thumb {\n width: 14px;\n height: 14px;\n background: var(--scribe-primary);\n border-radius: 50%;\n cursor: pointer;\n border: none;\n }\n\n .scribe-time {\n font-size: 0.75rem;\n color: var(--scribe-text-partial);\n text-align: center;\n }\n\n .scribe-speed {\n padding: 0.375rem 0.5rem;\n border-radius: 4px;\n border: 1px solid var(--scribe-border-color);\n background: var(--scribe-bg);\n font-size: 0.875rem;\n cursor: pointer;\n }\n\n .scribe-transcript-playback {\n max-height: 400px;\n overflow-y: auto;\n scroll-behavior: smooth;\n padding: 0.5rem;\n }\n\n .scribe-segment {\n padding: 0.75rem 1rem;\n margin-bottom: 0.5rem;\n border-left: 3px solid var(--speaker-color, var(--scribe-border-color));\n background: var(--scribe-bg);\n border-radius: 0 var(--scribe-border-radius) var(--scribe-border-radius) 0;\n cursor: pointer;\n transition: background 0.2s ease;\n }\n\n .scribe-segment:hover {\n background: var(--scribe-bg-transcript);\n }\n\n .scribe-segment--active {\n background: rgba(76, 175, 80, 0.1);\n border-left-color: var(--scribe-primary);\n }\n\n .scribe-segment-text {\n margin: 0.25rem 0 0 0;\n line-height: 1.6;\n }\n\n .scribe-word {\n transition: background 0.15s ease, color 0.15s ease;\n padding: 0 1px;\n border-radius: 2px;\n }\n\n .scribe-word:hover {\n background: rgba(0, 0, 0, 0.05);\n cursor: pointer;\n }\n\n .scribe-word--active {\n background: var(--scribe-primary);\n color: white;\n }\n `],\n})\nexport class RecorderComponent implements OnDestroy {\n private audioCapture = inject(AudioCaptureService);\n private socket = inject(ScribeSocketService);\n private elementRef = inject(ElementRef);\n private subscriptions: Subscription[] = [];\n private entryIdCounter = 0;\n private generateAbortController: AbortController | null = null;\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (!this.showTemplateMenu()) return;\n const target = event.target as HTMLElement;\n if (!this.elementRef.nativeElement.contains(target)) {\n this.showTemplateMenu.set(false);\n }\n }\n\n wsUrl = input<string>('');\n token = input<string>('');\n speakerLabels = input<Record<number, string>>({});\n premium = input<boolean>(false);\n templates = input<TemplateOption[]>([]);\n lambdaUrl = input<string>('');\n\n sessionId = input<string | undefined>();\n apiUrl = input<string>('');\n resumeSessionId = input<string | undefined>();\n\n sessionStarted = output<string>();\n sessionFinished = output<{ transcript: string; entries: TranscriptEntry[] }>();\n error = output<Error>();\n documentGenerated = output<GeneratedDocument>();\n generationError = output<Error>();\n\n isRecording = signal(false);\n isPaused = signal(false);\n audioLevel = signal(0);\n connectionState = signal<ConnectionState>('disconnected');\n entries = signal<TranscriptEntry[]>([]);\n partialText = signal('');\n currentSpeaker = signal<number | undefined>(undefined);\n showTemplateMenu = signal(false);\n isGenerating = signal(false);\n lastSessionId = signal<string | null>(null);\n\n isPlaying = signal(false);\n isLoadingSession = signal(false);\n audioCurrentTime = signal(0);\n audioDuration = signal(0);\n playbackRate = signal(1);\n sessionData = signal<SessionPlaybackData | null>(null);\n activeSegmentId = signal<string | null>(null);\n activeWordIndex = signal<number | null>(null);\n\n private audioElement: HTMLAudioElement | null = null;\n private audioBlobUrl: string | null = null;\n\n mode = computed<RecorderMode>(() =>\n this.sessionId() ? 'playback' : 'recording'\n );\n\n segments = computed(() =>\n this.sessionData()?.transcription.segments ?? []\n );\n\n hasFinishedSession = computed(() =>\n this.lastSessionId() !== null &&\n !this.isRecording() &&\n !this.isPaused()\n );\n\n speakerGroups = computed<SpeakerGroup[]>(() => {\n const allEntries = this.entries();\n if (allEntries.length === 0) return [];\n\n const groups: SpeakerGroup[] = [];\n let currentGroup: SpeakerGroup | null = null;\n\n for (const entry of allEntries) {\n if (!currentGroup || currentGroup.speaker !== entry.speaker) {\n currentGroup = { speaker: entry.speaker, entries: [] };\n groups.push(currentGroup);\n }\n currentGroup.entries.push(entry);\n }\n\n return groups;\n });\n\n constructor() {\n this.subscriptions.push(\n this.audioCapture.audioLevel$.subscribe((level) => {\n this.audioLevel.set(level);\n }),\n this.socket.connectionState$.subscribe((state) => {\n this.connectionState.set(state);\n }),\n this.socket.transcription$.subscribe((event) => {\n this.handleTranscription(event);\n }),\n this.socket.error$.subscribe((err) => {\n this.error.emit(err);\n }),\n this.audioCapture.error$.subscribe((err) => {\n this.error.emit(err);\n }),\n this.audioCapture.audioChunk$.subscribe(({ data, isSilence }) => {\n this.socket.sendAudioChunk(data, isSilence);\n })\n );\n\n effect(() => {\n const sid = this.sessionId();\n const api = this.apiUrl();\n if (sid && api && this.mode() === 'playback') {\n this.loadSession();\n }\n });\n\n effect(() => {\n const resumeId = this.resumeSessionId();\n const api = this.apiUrl();\n if (resumeId && api && this.mode() === 'recording') {\n this.resumeSession(resumeId);\n }\n });\n }\n\n ngOnDestroy(): void {\n this.subscriptions.forEach((sub) => sub.unsubscribe());\n this.generateAbortController?.abort();\n this.cleanup();\n this.cleanupPlayback();\n }\n\n private audioEventHandlers: {\n loadedmetadata?: () => void;\n timeupdate?: () => void;\n ended?: () => void;\n } = {};\n\n private cleanupPlayback(): void {\n if (this.audioElement) {\n this.audioElement.pause();\n if (this.audioEventHandlers.loadedmetadata) {\n this.audioElement.removeEventListener('loadedmetadata', this.audioEventHandlers.loadedmetadata);\n }\n if (this.audioEventHandlers.timeupdate) {\n this.audioElement.removeEventListener('timeupdate', this.audioEventHandlers.timeupdate);\n }\n if (this.audioEventHandlers.ended) {\n this.audioElement.removeEventListener('ended', this.audioEventHandlers.ended);\n }\n this.audioEventHandlers = {};\n this.audioElement = null;\n }\n if (this.audioBlobUrl) {\n URL.revokeObjectURL(this.audioBlobUrl);\n this.audioBlobUrl = null;\n }\n }\n\n getSpeakerLabel(speaker: number): string {\n const customLabels = this.speakerLabels();\n if (customLabels[speaker]) {\n return customLabels[speaker];\n }\n return SPEAKER_LABELS[speaker] || `Pessoa ${speaker + 1}`;\n }\n\n shouldShowSpeakerLabel(segmentIndex: number): boolean {\n const segs = this.segments();\n if (segmentIndex === 0) return true;\n const currentSpeaker = segs[segmentIndex]?.speaker;\n const previousSpeaker = segs[segmentIndex - 1]?.speaker;\n return currentSpeaker !== previousSpeaker;\n }\n\n getMicButtonLabel(): string {\n if (this.isPaused()) {\n return 'Retomar gravação';\n }\n if (this.isRecording()) {\n return 'Pausar gravação';\n }\n return 'Iniciar gravação';\n }\n\n async toggleRecording(): Promise<void> {\n if (this.isPaused()) {\n this.resumeRecording();\n } else if (this.isRecording()) {\n this.pauseRecording();\n } else {\n await this.startRecording();\n }\n }\n\n pauseRecording(): void {\n if (!this.isRecording() || this.isPaused()) return;\n this.audioCapture.pauseCapture();\n this.isPaused.set(true);\n }\n\n resumeRecording(): void {\n if (!this.isPaused()) return;\n this.audioCapture.resumeCapture();\n this.isPaused.set(false);\n }\n\n async finishSession(): Promise<void> {\n if (!this.isRecording() && !this.isPaused()) return;\n\n const sessionId = this.socket.getSessionId();\n\n await this.stopRecording();\n\n const allEntries = this.entries();\n const fullTranscript = allEntries.map((e) => e.text).join(' ');\n\n this.sessionFinished.emit({ transcript: fullTranscript, entries: allEntries });\n\n this.partialText.set('');\n this.currentSpeaker.set(undefined);\n\n this.lastSessionId.set(sessionId);\n }\n\n toggleTemplateMenu(): void {\n this.showTemplateMenu.update((v) => !v);\n }\n\n async selectTemplate(template: TemplateOption): Promise<void> {\n if (this.isGenerating()) return;\n\n this.showTemplateMenu.set(false);\n\n const lambdaUrl = this.lambdaUrl();\n if (!lambdaUrl) {\n this.generationError.emit(new Error('Lambda URL not provided'));\n return;\n }\n\n const sessionId = this.lastSessionId();\n if (!sessionId) {\n this.generationError.emit(new Error('No session available'));\n return;\n }\n\n this.generateAbortController?.abort();\n this.generateAbortController = new AbortController();\n\n this.isGenerating.set(true);\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n const token = this.token();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(`${lambdaUrl}/generate`, {\n method: 'POST',\n headers,\n signal: this.generateAbortController.signal,\n body: JSON.stringify({\n sessionId,\n outputSchema: template.content,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || `HTTP ${response.status}`);\n }\n\n const result = await response.json();\n\n this.documentGenerated.emit({\n sessionId,\n templateId: template.id,\n content: result.content,\n generatedAt: result.generatedAt,\n });\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') return;\n this.generationError.emit(err instanceof Error ? err : new Error(String(err)));\n } finally {\n this.isGenerating.set(false);\n }\n }\n\n async loadSession(): Promise<void> {\n const sid = this.sessionId();\n const api = this.apiUrl();\n\n if (!sid || !api) return;\n\n this.isLoadingSession.set(true);\n\n try {\n const headers: Record<string, string> = {};\n const token = this.token();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(`${api}/session/${sid}`, { headers });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data: SessionPlaybackData = await response.json();\n this.sessionData.set(data);\n\n await this.loadAudio(data.audioUrl);\n } catch (err) {\n this.error.emit(err instanceof Error ? err : new Error(String(err)));\n } finally {\n this.isLoadingSession.set(false);\n }\n }\n\n async resumeSession(sessionId: string): Promise<void> {\n const api = this.apiUrl();\n if (!api) return;\n\n this.isLoadingSession.set(true);\n\n try {\n const headers: Record<string, string> = {};\n const token = this.token();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(`${api}/session/${sessionId}`, { headers });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data: SessionPlaybackData = await response.json();\n\n const entries: TranscriptEntry[] = data.transcription.segments.map((seg, idx) => ({\n id: idx + 1,\n text: seg.text,\n speaker: seg.speaker,\n isFinal: true,\n startTime: seg.startTime,\n endTime: seg.endTime,\n }));\n\n this.entryIdCounter = entries.length;\n this.entries.set(entries);\n this.lastSessionId.set(sessionId);\n } catch (err) {\n this.error.emit(err instanceof Error ? err : new Error(String(err)));\n } finally {\n this.isLoadingSession.set(false);\n }\n }\n\n private async loadAudio(pcmUrl: string): Promise<void> {\n this.cleanupPlayback();\n\n const response = await fetch(pcmUrl);\n if (!response.ok) {\n throw new Error(`Failed to load audio: HTTP ${response.status}`);\n }\n\n const pcmData = await response.arrayBuffer();\n\n const wavData = pcmToWav(pcmData);\n this.audioBlobUrl = createAudioBlobUrl(wavData);\n\n this.audioElement = new Audio(this.audioBlobUrl);\n\n this.audioEventHandlers.loadedmetadata = () => {\n this.audioDuration.set(this.audioElement!.duration);\n };\n this.audioEventHandlers.timeupdate = () => {\n this.audioCurrentTime.set(this.audioElement!.currentTime);\n this.updateActiveSegment();\n };\n this.audioEventHandlers.ended = () => {\n this.isPlaying.set(false);\n };\n\n this.audioElement.addEventListener('loadedmetadata', this.audioEventHandlers.loadedmetadata);\n this.audioElement.addEventListener('timeupdate', this.audioEventHandlers.timeupdate);\n this.audioElement.addEventListener('ended', this.audioEventHandlers.ended);\n }\n\n togglePlayback(): void {\n if (!this.audioElement) return;\n\n if (this.isPlaying()) {\n this.audioElement.pause();\n this.isPlaying.set(false);\n } else {\n this.audioElement.play();\n this.isPlaying.set(true);\n }\n }\n\n seekTo(event: Event): void {\n const input = event.target as HTMLInputElement | null;\n if (!input) return;\n const time = parseFloat(input.value);\n if (this.audioElement && !isNaN(time)) {\n this.audioElement.currentTime = time;\n this.audioCurrentTime.set(time);\n }\n }\n\n setPlaybackRate(event: Event): void {\n const select = event.target as HTMLSelectElement | null;\n if (!select) return;\n const rate = parseFloat(select.value);\n if (isNaN(rate)) return;\n this.playbackRate.set(rate);\n if (this.audioElement) {\n this.audioElement.playbackRate = rate;\n }\n }\n\n seekToSegment(segment: TranscriptSegment): void {\n if (this.audioElement) {\n this.audioElement.currentTime = segment.startTime;\n this.audioCurrentTime.set(segment.startTime);\n if (!this.isPlaying()) {\n this.togglePlayback();\n }\n }\n }\n\n seekToWord(word: TranscriptionWord, event: Event): void {\n event.stopPropagation();\n if (this.audioElement) {\n this.audioElement.currentTime = word.start;\n this.audioCurrentTime.set(word.start);\n if (!this.isPlaying()) {\n this.togglePlayback();\n }\n }\n }\n\n formatTimeDisplay(seconds: number): string {\n return formatTime(seconds);\n }\n\n getSpeakerColor(speaker: number | undefined): string {\n if (speaker === undefined) return 'var(--scribe-border-color)';\n const colors = [\n 'var(--scribe-speaker-0)',\n 'var(--scribe-speaker-1)',\n 'var(--scribe-speaker-2)',\n 'var(--scribe-speaker-3)',\n ];\n return colors[speaker % colors.length];\n }\n\n private updateActiveSegment(): void {\n const time = this.audioCurrentTime();\n const segs = this.segments();\n\n const seg = segs.find((s) => time >= s.startTime && time <= s.endTime);\n this.activeSegmentId.set(seg?.id ?? null);\n\n if (seg?.words) {\n const wordIdx = seg.words.findIndex((w) => time >= w.start && time <= w.end);\n this.activeWordIndex.set(wordIdx >= 0 ? wordIdx : null);\n } else {\n this.activeWordIndex.set(null);\n }\n\n this.scrollToActiveSegment();\n }\n\n private scrollToActiveSegment(): void {\n const activeId = this.activeSegmentId();\n if (!activeId) return;\n\n const container = this.elementRef.nativeElement.querySelector('.scribe-transcript-playback');\n const activeEl = container?.querySelector(`[data-segment-id=\"${activeId}\"]`);\n\n if (activeEl && container) {\n const containerRect = container.getBoundingClientRect();\n const activeRect = activeEl.getBoundingClientRect();\n\n if (activeRect.top < containerRect.top || activeRect.bottom > containerRect.bottom) {\n activeEl.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }\n }\n\n private async startRecording(): Promise<void> {\n try {\n await this.socket.connect(this.wsUrl(), this.token(), this.premium());\n await this.audioCapture.startCapture();\n this.isRecording.set(true);\n this.isPaused.set(false);\n\n const sessionId = this.socket.getSessionId();\n if (sessionId) {\n this.sessionStarted.emit(sessionId);\n }\n } catch (err) {\n this.error.emit(err instanceof Error ? err : new Error('Failed to start recording'));\n await this.cleanup();\n }\n }\n\n private async stopRecording(): Promise<void> {\n await this.audioCapture.stopCapture();\n this.socket.disconnect();\n this.isRecording.set(false);\n this.isPaused.set(false);\n }\n\n private async cleanup(): Promise<void> {\n await this.audioCapture.stopCapture();\n this.socket.disconnect();\n this.isRecording.set(false);\n this.isPaused.set(false);\n }\n\n private handleTranscription(event: TranscriptionEvent): void {\n if (!event.transcript) return;\n\n if (event.type === 'final') {\n const entry: TranscriptEntry = {\n id: ++this.entryIdCounter,\n text: event.transcript,\n speaker: event.speaker,\n isFinal: true,\n startTime: event.start,\n endTime: event.end,\n };\n\n this.entries.update((entries) => [...entries, entry]);\n this.partialText.set('');\n this.currentSpeaker.set(undefined);\n } else if (event.type === 'partial') {\n this.partialText.set(event.transcript);\n this.currentSpeaker.set(event.speaker);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["DEFAULT_CONFIG"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"medc-com-br-ngx-jaimes-scribe.mjs","sources":["../../../libs/ngx-jaimes-scribe/src/lib/services/vad.service.ts","../../../libs/ngx-jaimes-scribe/src/lib/services/audio-capture.service.ts","../../../libs/ngx-jaimes-scribe/src/lib/services/scribe-socket.service.ts","../../../libs/ngx-jaimes-scribe/src/lib/utils/pcm-to-wav.ts","../../../libs/ngx-jaimes-scribe/src/lib/components/recorder/recorder.component.ts","../../../libs/ngx-jaimes-scribe/src/medc-com-br-ngx-jaimes-scribe.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\nexport type VadState = 'idle' | 'speech' | 'silence_pending' | 'silence';\n\nexport interface VadConfig {\n speechThreshold: number;\n silenceThreshold: number;\n silenceDebounceMs: number;\n}\n\nconst DEFAULT_CONFIG: VadConfig = {\n speechThreshold: 8,\n silenceThreshold: 3,\n silenceDebounceMs: 1500,\n};\n\n@Injectable({ providedIn: 'root' })\nexport class VadService {\n private state: VadState = 'idle';\n private silenceStartTime: number | null = null;\n private config = { ...DEFAULT_CONFIG };\n\n readonly state$ = new BehaviorSubject<VadState>('idle');\n\n analyzeLevel(level: number): { isSilence: boolean } {\n const now = Date.now();\n\n if (level >= this.config.speechThreshold) {\n this.state = 'speech';\n this.silenceStartTime = null;\n this.state$.next('speech');\n return { isSilence: false };\n }\n\n if (level < this.config.silenceThreshold) {\n if (this.state === 'speech') {\n this.silenceStartTime = now;\n this.state = 'silence_pending';\n } else if (this.state === 'silence_pending' && this.silenceStartTime) {\n if (now - this.silenceStartTime >= this.config.silenceDebounceMs) {\n this.state = 'silence';\n this.state$.next('silence');\n }\n }\n } else {\n if (this.state === 'silence_pending') {\n this.state = 'speech';\n this.silenceStartTime = null;\n }\n }\n\n return { isSilence: this.state === 'silence' };\n }\n\n reset(): void {\n this.state = 'idle';\n this.silenceStartTime = null;\n this.state$.next('idle');\n }\n\n getState(): VadState {\n return this.state;\n }\n}\n","import { Injectable, InjectionToken, inject, NgZone } from '@angular/core';\nimport { Subject, Observable, BehaviorSubject } from 'rxjs';\nimport { VadService } from './vad.service';\n\nexport interface AudioCaptureConfig {\n workletUrl: string;\n levelUpdateInterval: number;\n}\n\nexport const AUDIO_CAPTURE_CONFIG = new InjectionToken<AudioCaptureConfig>('AUDIO_CAPTURE_CONFIG');\n\nconst DEFAULT_CONFIG: AudioCaptureConfig = {\n workletUrl: '/assets/pcm-processor.js',\n levelUpdateInterval: 50,\n};\n\nexport interface AudioChunk {\n data: ArrayBuffer;\n isSilence: boolean;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class AudioCaptureService {\n private config: AudioCaptureConfig;\n private ngZone: NgZone;\n private vadService: VadService;\n private audioContext: AudioContext | null = null;\n private workletNode: AudioWorkletNode | null = null;\n private analyserNode: AnalyserNode | null = null;\n private source: MediaStreamAudioSourceNode | null = null;\n private stream: MediaStream | null = null;\n private workletRegistered = false;\n private levelInterval: ReturnType<typeof setInterval> | null = null;\n private paused = false;\n\n private audioChunkSubject = new Subject<AudioChunk>();\n private audioLevelSubject = new BehaviorSubject<number>(0);\n private errorSubject = new Subject<Error>();\n\n audioChunk$: Observable<AudioChunk> = this.audioChunkSubject.asObservable();\n audioLevel$: Observable<number> = this.audioLevelSubject.asObservable();\n error$: Observable<Error> = this.errorSubject.asObservable();\n\n constructor() {\n const injectedConfig = inject(AUDIO_CAPTURE_CONFIG, { optional: true });\n this.config = injectedConfig ?? DEFAULT_CONFIG;\n this.ngZone = inject(NgZone);\n this.vadService = inject(VadService);\n }\n\n async startCapture(): Promise<void> {\n try {\n this.stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n channelCount: 1,\n echoCancellation: true,\n noiseSuppression: true,\n },\n });\n\n this.audioContext = new AudioContext();\n\n if (!this.workletRegistered) {\n await this.audioContext.audioWorklet.addModule(this.config.workletUrl);\n this.workletRegistered = true;\n }\n\n this.workletNode = new AudioWorkletNode(this.audioContext, 'pcm-processor', {\n processorOptions: {\n inputSampleRate: this.audioContext.sampleRate,\n },\n });\n\n this.workletNode.port.onmessage = (event: MessageEvent<ArrayBuffer>) => {\n if (!this.paused) {\n const level = this.getAudioLevel();\n const { isSilence } = this.vadService.analyzeLevel(level);\n this.audioChunkSubject.next({ data: event.data, isSilence });\n }\n };\n\n this.analyserNode = this.audioContext.createAnalyser();\n this.analyserNode.fftSize = 256;\n this.analyserNode.smoothingTimeConstant = 0.8;\n\n this.source = this.audioContext.createMediaStreamSource(this.stream);\n this.source.connect(this.analyserNode);\n this.source.connect(this.workletNode);\n\n this.startLevelMonitoring();\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Failed to start audio capture');\n this.errorSubject.next(err);\n throw err;\n }\n }\n\n async stopCapture(): Promise<void> {\n this.stopLevelMonitoring();\n this.paused = false;\n this.vadService.reset();\n\n if (this.workletNode) {\n this.workletNode.port.close();\n this.workletNode.disconnect();\n this.workletNode = null;\n }\n\n if (this.analyserNode) {\n this.analyserNode.disconnect();\n this.analyserNode = null;\n }\n\n if (this.source) {\n this.source.disconnect();\n this.source = null;\n }\n\n if (this.audioContext) {\n await this.audioContext.close();\n this.audioContext = null;\n this.workletRegistered = false;\n }\n\n if (this.stream) {\n this.stream.getTracks().forEach((track) => track.stop());\n this.stream = null;\n }\n\n this.audioLevelSubject.next(0);\n }\n\n pauseCapture(): void {\n if (this.isCapturing() && !this.paused) {\n this.paused = true;\n }\n }\n\n resumeCapture(): void {\n if (this.isCapturing() && this.paused) {\n this.paused = false;\n }\n }\n\n isCapturing(): boolean {\n return this.workletNode !== null && this.stream !== null;\n }\n\n isPaused(): boolean {\n return this.paused;\n }\n\n getSampleRate(): number | null {\n return this.audioContext?.sampleRate ?? null;\n }\n\n private startLevelMonitoring(): void {\n this.stopLevelMonitoring();\n\n this.ngZone.runOutsideAngular(() => {\n this.levelInterval = setInterval(() => {\n const level = this.getAudioLevel();\n this.ngZone.run(() => {\n this.audioLevelSubject.next(level);\n });\n }, this.config.levelUpdateInterval);\n });\n }\n\n private stopLevelMonitoring(): void {\n if (this.levelInterval) {\n clearInterval(this.levelInterval);\n this.levelInterval = null;\n }\n }\n\n private getAudioLevel(): number {\n if (!this.analyserNode) {\n return 0;\n }\n\n const dataArray = new Uint8Array(this.analyserNode.frequencyBinCount);\n this.analyserNode.getByteFrequencyData(dataArray);\n\n const sum = dataArray.reduce((acc, val) => acc + val, 0);\n const average = sum / dataArray.length;\n\n return Math.round((average / 255) * 100);\n }\n}\n","import { Injectable, InjectionToken, inject, NgZone } from '@angular/core';\nimport { BehaviorSubject, Subject, Observable } from 'rxjs';\nimport type { TranscriptionEvent } from '@medc-com-br/jaimes-shared';\n\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';\n\nexport interface ScribeSocketConfig {\n reconnectAttempts: number;\n reconnectBaseDelay: number;\n chunkBufferInterval: number;\n}\n\nexport const SCRIBE_SOCKET_CONFIG = new InjectionToken<ScribeSocketConfig>('SCRIBE_SOCKET_CONFIG');\n\nconst DEFAULT_CONFIG: ScribeSocketConfig = {\n reconnectAttempts: 5,\n reconnectBaseDelay: 1000,\n chunkBufferInterval: 250,\n};\n\n@Injectable({ providedIn: 'root' })\nexport class ScribeSocketService {\n private config: ScribeSocketConfig;\n private ngZone: NgZone;\n private ws: WebSocket | null = null;\n private wsUrl: string | null = null;\n private token: string | null = null;\n private premium = false;\n private reconnectAttempt = 0;\n private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\n private intentionalClose = false;\n\n private chunkBuffer: string[] = [];\n private sendInterval: ReturnType<typeof setInterval> | null = null;\n private keepaliveInterval: ReturnType<typeof setInterval> | null = null;\n private currentlyInSilence = false;\n\n private connectionStateSubject = new BehaviorSubject<ConnectionState>('disconnected');\n private transcriptionSubject = new Subject<TranscriptionEvent>();\n private errorSubject = new Subject<Error>();\n private sessionIdSubject = new BehaviorSubject<string | null>(null);\n\n connectionState$: Observable<ConnectionState> = this.connectionStateSubject.asObservable();\n transcription$: Observable<TranscriptionEvent> = this.transcriptionSubject.asObservable();\n error$: Observable<Error> = this.errorSubject.asObservable();\n sessionId$: Observable<string | null> = this.sessionIdSubject.asObservable();\n\n constructor() {\n const injectedConfig = inject(SCRIBE_SOCKET_CONFIG, { optional: true });\n this.config = injectedConfig ?? DEFAULT_CONFIG;\n this.ngZone = inject(NgZone);\n }\n\n async connect(url: string, token: string, premium = false): Promise<void> {\n if (this.connectionStateSubject.getValue() === 'connecting') {\n throw new Error('Connection already in progress');\n }\n\n if (this.isConnected()) {\n this.disconnect();\n }\n\n this.clearReconnectTimeout();\n this.wsUrl = url;\n this.token = token;\n this.premium = premium;\n this.intentionalClose = false;\n this.reconnectAttempt = 0;\n\n return this.createConnection();\n }\n\n disconnect(): void {\n this.intentionalClose = true;\n this.flushAndStopBuffering();\n this.clearReconnectTimeout();\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.close(1000, 'Client disconnect');\n }\n this.ws = null;\n\n this.connectionStateSubject.next('disconnected');\n this.sessionIdSubject.next(null);\n }\n\n sendAudioChunk(chunk: ArrayBuffer, isSilence: boolean): void {\n const message = JSON.stringify({\n type: 'audio',\n isSilence,\n data: this.arrayBufferToBase64(chunk),\n });\n this.chunkBuffer.push(message);\n\n if (isSilence && !this.currentlyInSilence) {\n this.currentlyInSilence = true;\n this.startKeepaliveInterval();\n } else if (!isSilence && this.currentlyInSilence) {\n this.currentlyInSilence = false;\n this.stopKeepaliveInterval();\n }\n }\n\n private startKeepaliveInterval(): void {\n this.stopKeepaliveInterval();\n this.keepaliveInterval = setInterval(() => {\n if (this.isConnected()) {\n this.ws!.send(JSON.stringify({ type: 'keepalive' }));\n }\n }, 3000);\n }\n\n private stopKeepaliveInterval(): void {\n if (this.keepaliveInterval) {\n clearInterval(this.keepaliveInterval);\n this.keepaliveInterval = null;\n }\n }\n\n private arrayBufferToBase64(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n\n isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n getSessionId(): string | null {\n return this.sessionIdSubject.getValue();\n }\n\n private createConnection(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.wsUrl) {\n reject(new Error('WebSocket URL is required'));\n return;\n }\n\n this.connectionStateSubject.next('connecting');\n const params = new URLSearchParams({ premium: String(this.premium) });\n if (this.token) {\n params.set('token', this.token);\n }\n const url = `${this.wsUrl}?${params.toString()}`;\n\n this.ws = new WebSocket(url);\n this.ws.binaryType = 'arraybuffer';\n\n this.ws.onopen = () => {\n this.ngZone.run(() => {\n this.reconnectAttempt = 0;\n this.connectionStateSubject.next('connected');\n this.startBuffering();\n resolve();\n });\n };\n\n this.ws.onerror = () => {\n this.ngZone.run(() => {\n const error = new Error('WebSocket connection error');\n this.errorSubject.next(error);\n if (this.connectionStateSubject.getValue() === 'connecting') {\n reject(error);\n }\n });\n };\n\n this.ws.onmessage = (event) => {\n this.ngZone.run(() => {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'connected' && data.sessionId) {\n this.sessionIdSubject.next(data.sessionId);\n }\n this.transcriptionSubject.next(data as TranscriptionEvent);\n } catch (e) {\n const error = new Error(`Failed to parse WebSocket message: ${e instanceof Error ? e.message : String(e)}`);\n console.error(error.message);\n this.errorSubject.next(error);\n }\n });\n };\n\n this.ws.onclose = (event) => {\n this.ngZone.run(() => {\n this.stopBuffering();\n\n if (!this.intentionalClose && event.code !== 1000) {\n this.attemptReconnect();\n } else {\n this.connectionStateSubject.next('disconnected');\n this.sessionIdSubject.next(null);\n }\n });\n };\n });\n }\n\n private attemptReconnect(): void {\n if (this.reconnectAttempt >= this.config.reconnectAttempts) {\n this.connectionStateSubject.next('disconnected');\n this.errorSubject.next(new Error('Max reconnection attempts reached'));\n return;\n }\n\n this.connectionStateSubject.next('reconnecting');\n const delay = this.config.reconnectBaseDelay * Math.pow(2, this.reconnectAttempt);\n this.reconnectAttempt++;\n\n this.reconnectTimeout = setTimeout(() => {\n this.createConnection().catch(() => {});\n }, delay);\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n }\n\n private startBuffering(): void {\n this.stopBuffering();\n\n this.sendInterval = setInterval(() => {\n if (this.chunkBuffer.length > 0 && this.isConnected()) {\n for (const msg of this.chunkBuffer) {\n this.ws!.send(msg);\n }\n this.chunkBuffer = [];\n }\n }, this.config.chunkBufferInterval);\n }\n\n private flushAndStopBuffering(): void {\n if (this.sendInterval) {\n clearInterval(this.sendInterval);\n this.sendInterval = null;\n }\n\n if (this.chunkBuffer.length > 0 && this.isConnected()) {\n for (const msg of this.chunkBuffer) {\n this.ws!.send(msg);\n }\n }\n this.chunkBuffer = [];\n this.stopKeepaliveInterval();\n this.currentlyInSilence = false;\n }\n\n private stopBuffering(): void {\n if (this.sendInterval) {\n clearInterval(this.sendInterval);\n this.sendInterval = null;\n }\n this.chunkBuffer = [];\n }\n\n}\n","const SAMPLE_RATE = 16000;\nconst NUM_CHANNELS = 1;\nconst BITS_PER_SAMPLE = 16;\n\nfunction writeString(view: DataView, offset: number, str: string): void {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n}\n\nfunction concatBuffers(buffer1: ArrayBuffer, buffer2: ArrayBuffer): ArrayBuffer {\n const combined = new Uint8Array(buffer1.byteLength + buffer2.byteLength);\n combined.set(new Uint8Array(buffer1), 0);\n combined.set(new Uint8Array(buffer2), buffer1.byteLength);\n return combined.buffer;\n}\n\nexport function pcmToWav(pcmData: ArrayBuffer, sampleRate = SAMPLE_RATE): ArrayBuffer {\n const header = new ArrayBuffer(44);\n const view = new DataView(header);\n\n const byteRate = sampleRate * NUM_CHANNELS * (BITS_PER_SAMPLE / 8);\n const blockAlign = NUM_CHANNELS * (BITS_PER_SAMPLE / 8);\n\n // RIFF chunk descriptor\n writeString(view, 0, 'RIFF');\n view.setUint32(4, 36 + pcmData.byteLength, true);\n writeString(view, 8, 'WAVE');\n\n // fmt sub-chunk\n writeString(view, 12, 'fmt ');\n view.setUint32(16, 16, true); // SubChunk1Size (16 for PCM)\n view.setUint16(20, 1, true); // AudioFormat (1 = PCM)\n view.setUint16(22, NUM_CHANNELS, true); // NumChannels\n view.setUint32(24, sampleRate, true); // SampleRate\n view.setUint32(28, byteRate, true); // ByteRate\n view.setUint16(32, blockAlign, true); // BlockAlign\n view.setUint16(34, BITS_PER_SAMPLE, true); // BitsPerSample\n\n // data sub-chunk\n writeString(view, 36, 'data');\n view.setUint32(40, pcmData.byteLength, true);\n\n return concatBuffers(header, pcmData);\n}\n\nexport function createAudioBlobUrl(wavData: ArrayBuffer): string {\n const blob = new Blob([wavData], { type: 'audio/wav' });\n return URL.createObjectURL(blob);\n}\n\nexport function formatTime(seconds: number): string {\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","import { Component, inject, signal, input, output, OnDestroy, computed, HostListener, ElementRef, effect } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs';\nimport { AudioCaptureService } from '../../services/audio-capture.service';\nimport { ScribeSocketService, ConnectionState } from '../../services/scribe-socket.service';\nimport { pcmToWav, createAudioBlobUrl, formatTime } from '../../utils/pcm-to-wav';\nimport type { TranscriptionEvent, TemplateOption, GeneratedDocument, SessionPlaybackData, TranscriptSegment, TranscriptionWord } from '@medc-com-br/jaimes-shared';\n\ninterface TranscriptEntry {\n id: number;\n text: string;\n speaker?: number;\n isFinal: boolean;\n startTime?: number;\n endTime?: number;\n}\n\nexport type RecorderMode = 'recording' | 'playback';\n\ninterface SpeakerGroup {\n speaker?: number;\n entries: TranscriptEntry[];\n}\n\nconst SPEAKER_LABELS: Record<number, string> = {\n 0: 'Pessoa 1',\n 1: 'Pessoa 2',\n 2: 'Pessoa 3',\n 3: 'Pessoa 4',\n};\n\n@Component({\n selector: 'ngx-jaimes-scribe-recorder',\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"scribe-recorder\">\n @if (mode() === 'playback') {\n <!-- Playback Mode -->\n <div class=\"scribe-playback\">\n @if (isLoadingSession()) {\n <div class=\"scribe-loading\">\n <svg class=\"scribe-icon scribe-icon--spinner\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32\" stroke-linecap=\"round\"/>\n </svg>\n <span>Carregando sessão...</span>\n </div>\n } @else if (sessionData()) {\n <!-- Audio Player -->\n <div class=\"scribe-player\">\n <div class=\"scribe-player-row\">\n <button\n class=\"scribe-btn scribe-btn--play\"\n (click)=\"togglePlayback()\"\n [attr.aria-label]=\"isPlaying() ? 'Pausar' : 'Reproduzir'\"\n >\n @if (isPlaying()) {\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/>\n </svg>\n } @else {\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\"/>\n </svg>\n }\n </button>\n\n <input\n type=\"range\"\n class=\"scribe-timeline-slider\"\n [min]=\"0\"\n [max]=\"audioDuration()\"\n [value]=\"audioCurrentTime()\"\n step=\"0.1\"\n (input)=\"seekTo($event)\"\n aria-label=\"Posição do áudio\"\n />\n\n <select\n class=\"scribe-speed\"\n [value]=\"playbackRate()\"\n (change)=\"setPlaybackRate($event)\"\n aria-label=\"Velocidade de reprodução\"\n >\n <option value=\"0.5\">0.5x</option>\n <option value=\"0.75\">0.75x</option>\n <option value=\"1\">1x</option>\n <option value=\"1.25\">1.25x</option>\n <option value=\"1.5\">1.5x</option>\n <option value=\"2\">2x</option>\n </select>\n </div>\n <div class=\"scribe-time\">\n {{ formatTimeDisplay(audioCurrentTime()) }} / {{ formatTimeDisplay(audioDuration()) }}\n </div>\n </div>\n\n <!-- Transcription with Highlight -->\n <div class=\"scribe-transcript-playback\">\n @for (segment of segments(); track segment.id; let idx = $index) {\n <div\n class=\"scribe-segment\"\n [class.scribe-segment--active]=\"activeSegmentId() === segment.id\"\n [style.--speaker-color]=\"getSpeakerColor(segment.speaker)\"\n [attr.data-segment-id]=\"segment.id\"\n (click)=\"seekToSegment(segment)\"\n >\n @if (segment.speaker !== undefined && shouldShowSpeakerLabel(idx)) {\n <span class=\"scribe-speaker-label\" [class]=\"'scribe-speaker--' + segment.speaker\">\n {{ getSpeakerLabel(segment.speaker) }}\n </span>\n }\n\n <p class=\"scribe-segment-text\">\n @if (segment.words?.length) {\n @for (word of segment.words; track $index; let i = $index) {\n <span\n class=\"scribe-word\"\n [class.scribe-word--active]=\"activeSegmentId() === segment.id && activeWordIndex() === i\"\n (click)=\"seekToWord(word, $event)\"\n >{{ word.word }}</span>{{ ' ' }}\n }\n } @else {\n {{ segment.text }}\n }\n </p>\n </div>\n }\n @if (segments().length === 0) {\n <span class=\"scribe-placeholder\">Nenhuma transcrição disponível.</span>\n }\n </div>\n } @else {\n <div class=\"scribe-error\">\n <span>Não foi possível carregar a sessão.</span>\n </div>\n }\n </div>\n } @else {\n <!-- Recording Mode -->\n @if (isLoadingSession()) {\n <div class=\"scribe-loading\">\n <svg class=\"scribe-icon scribe-icon--spinner\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32\" stroke-linecap=\"round\"/>\n </svg>\n <span>Carregando sessão...</span>\n </div>\n } @else {\n <div class=\"scribe-controls\">\n @if (!hasFinishedSession()) {\n <button\n class=\"scribe-btn scribe-btn--mic\"\n [class.scribe-btn--active]=\"isRecording() && !isPaused()\"\n [class.scribe-btn--paused]=\"isPaused()\"\n [class.scribe-btn--connecting]=\"connectionState() === 'connecting'\"\n [disabled]=\"connectionState() === 'connecting'\"\n (click)=\"toggleRecording()\"\n [attr.aria-label]=\"getMicButtonLabel()\"\n >\n @if (connectionState() === 'connecting') {\n <svg class=\"scribe-icon scribe-icon--spinner\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32\" stroke-linecap=\"round\"/>\n </svg>\n } @else if (isPaused()) {\n <!-- Play icon when paused -->\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\"/>\n </svg>\n } @else if (isRecording()) {\n <!-- Pause icon when recording -->\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/>\n </svg>\n } @else {\n <!-- Mic icon when idle -->\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\">\n <path d=\"M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm-1-9c0-.55.45-1 1-1s1 .45 1 1v6c0 .55-.45 1-1 1s-1-.45-1-1V5z\"/>\n <path d=\"M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z\"/>\n </svg>\n }\n </button>\n\n <div class=\"scribe-level\" [class.scribe-level--active]=\"isRecording() && !isPaused()\">\n <div class=\"scribe-level__fill\" [style.width.%]=\"isPaused() ? 0 : audioLevel()\"></div>\n </div>\n\n <button\n class=\"scribe-btn scribe-btn--finish\"\n [disabled]=\"!isRecording() && !isPaused()\"\n (click)=\"finishSession()\"\n aria-label=\"Finalizar gravação\"\n >\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"currentColor\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/>\n </svg>\n <span>Finalizar</span>\n </button>\n }\n\n @if (hasFinishedSession() && templates().length > 0) {\n <div class=\"scribe-generate-container\">\n <button\n class=\"scribe-btn scribe-btn--generate\"\n [disabled]=\"isGenerating()\"\n [attr.aria-expanded]=\"showTemplateMenu()\"\n aria-haspopup=\"menu\"\n (click)=\"toggleTemplateMenu()\"\n aria-label=\"Gerar resumo\"\n >\n @if (isGenerating()) {\n <svg class=\"scribe-icon scribe-icon--spinner\" viewBox=\"0 0 24 24\" width=\"20\" height=\"20\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32\" stroke-linecap=\"round\"/>\n </svg>\n <span>Gerando...</span>\n } @else {\n <svg class=\"scribe-icon\" viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"currentColor\">\n <path d=\"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11zm-3-7h-2v2h-2v-2H9v-2h2V9h2v2h2v2z\"/>\n </svg>\n <span>Gerar Resumo</span>\n }\n </button>\n\n @if (showTemplateMenu()) {\n <div class=\"scribe-template-menu\" role=\"menu\">\n @for (template of templates(); track template.id) {\n <button\n class=\"scribe-template-item\"\n role=\"menuitem\"\n (click)=\"selectTemplate(template)\"\n >\n <span class=\"scribe-template-name\">{{ template.name }}</span>\n @if (template.description) {\n <span class=\"scribe-template-desc\">{{ template.description }}</span>\n }\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"scribe-transcript\" [class.scribe-transcript--empty]=\"speakerGroups().length === 0 && !partialText()\">\n @if (speakerGroups().length === 0 && !partialText()) {\n <span class=\"scribe-placeholder\">A transcrição aparecerá aqui...</span>\n } @else {\n @for (group of speakerGroups(); track $index) {\n <div class=\"scribe-speaker-block\" [attr.data-speaker]=\"group.speaker\">\n @if (group.speaker !== undefined && group.speaker !== null) {\n <span class=\"scribe-speaker-label\" [class]=\"'scribe-speaker--' + group.speaker\">\n {{ getSpeakerLabel(group.speaker) }}\n </span>\n }\n <div class=\"scribe-speaker-text\">\n @for (entry of group.entries; track entry.id) {\n <span class=\"scribe-text scribe-text--final\">{{ entry.text }} </span>\n }\n </div>\n </div>\n }\n @if (partialText()) {\n <div class=\"scribe-speaker-block scribe-speaker-block--partial\">\n @if (currentSpeaker() !== undefined && currentSpeaker() !== null) {\n <span class=\"scribe-speaker-label\" [class]=\"'scribe-speaker--' + currentSpeaker()\">\n {{ getSpeakerLabel(currentSpeaker()!) }}\n </span>\n }\n <div class=\"scribe-speaker-text\">\n <span class=\"scribe-text scribe-text--partial\">{{ partialText() }}</span>\n </div>\n </div>\n }\n }\n </div>\n }\n }\n </div>\n `,\n styles: [`\n :host {\n --scribe-primary: #4caf50;\n --scribe-primary-dark: #388e3c;\n --scribe-primary-light: #81c784;\n --scribe-danger: #f44336;\n --scribe-danger-dark: #d32f2f;\n --scribe-text-color: #212121;\n --scribe-text-partial: #9e9e9e;\n --scribe-font-family: inherit;\n --scribe-font-size: 1rem;\n --scribe-bg: #ffffff;\n --scribe-bg-transcript: #f5f5f5;\n --scribe-border-radius: 8px;\n --scribe-border-color: #e0e0e0;\n --scribe-level-bg: #e0e0e0;\n --scribe-level-fill: #4caf50;\n\n --scribe-speaker-0: #2196f3;\n --scribe-speaker-1: #9c27b0;\n --scribe-speaker-2: #ff9800;\n --scribe-speaker-3: #009688;\n\n display: block;\n font-family: var(--scribe-font-family);\n font-size: var(--scribe-font-size);\n }\n\n .scribe-recorder {\n background: var(--scribe-bg);\n border-radius: var(--scribe-border-radius);\n }\n\n .scribe-controls {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1rem;\n }\n\n .scribe-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem;\n border: none;\n border-radius: var(--scribe-border-radius);\n font-family: var(--scribe-font-family);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .scribe-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .scribe-btn--mic {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: var(--scribe-bg-transcript);\n color: var(--scribe-text-color);\n }\n\n .scribe-btn--mic:hover:not(:disabled) {\n background: var(--scribe-border-color);\n }\n\n .scribe-btn--mic.scribe-btn--active {\n background: var(--scribe-danger);\n color: white;\n animation: pulse-recording 1.5s ease-in-out infinite;\n }\n\n .scribe-btn--mic.scribe-btn--paused {\n background: var(--scribe-primary);\n color: white;\n }\n\n .scribe-btn--mic.scribe-btn--paused:hover:not(:disabled) {\n background: var(--scribe-primary-dark);\n }\n\n .scribe-btn--mic.scribe-btn--connecting {\n background: var(--scribe-primary-light);\n color: white;\n }\n\n .scribe-btn--finish {\n padding: 0.75rem 1.25rem;\n background: var(--scribe-primary);\n color: white;\n }\n\n .scribe-btn--finish:hover:not(:disabled) {\n background: var(--scribe-primary-dark);\n }\n\n .scribe-icon {\n flex-shrink: 0;\n }\n\n .scribe-icon--spinner {\n animation: spin 1s linear infinite;\n }\n\n .scribe-level {\n flex: 1;\n height: 8px;\n background: var(--scribe-level-bg);\n border-radius: 4px;\n overflow: hidden;\n opacity: 0.5;\n transition: opacity 0.2s ease;\n }\n\n .scribe-level--active {\n opacity: 1;\n }\n\n .scribe-level__fill {\n height: 100%;\n background: var(--scribe-level-fill);\n border-radius: 4px;\n transition: width 0.05s ease-out;\n }\n\n .scribe-transcript {\n min-height: 120px;\n max-height: 400px;\n overflow-y: auto;\n padding: 1rem;\n margin: 0 1rem 1rem;\n background: var(--scribe-bg-transcript);\n border-radius: var(--scribe-border-radius);\n line-height: 1.6;\n }\n\n .scribe-transcript--empty {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .scribe-placeholder {\n color: var(--scribe-text-partial);\n font-style: italic;\n }\n\n .scribe-speaker-block {\n margin-bottom: 0.75rem;\n padding-left: 0.5rem;\n border-left: 3px solid var(--scribe-border-color);\n }\n\n .scribe-speaker-block--partial {\n opacity: 0.7;\n }\n\n .scribe-speaker-block[data-speaker=\"0\"] {\n border-left-color: var(--scribe-speaker-0);\n }\n\n .scribe-speaker-block[data-speaker=\"1\"] {\n border-left-color: var(--scribe-speaker-1);\n }\n\n .scribe-speaker-block[data-speaker=\"2\"] {\n border-left-color: var(--scribe-speaker-2);\n }\n\n .scribe-speaker-block[data-speaker=\"3\"] {\n border-left-color: var(--scribe-speaker-3);\n }\n\n .scribe-speaker-label {\n display: inline-block;\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n padding: 0.125rem 0.5rem;\n border-radius: 4px;\n margin-bottom: 0.25rem;\n color: white;\n background: var(--scribe-border-color);\n }\n\n .scribe-speaker--0 {\n background: var(--scribe-speaker-0);\n }\n\n .scribe-speaker--1 {\n background: var(--scribe-speaker-1);\n }\n\n .scribe-speaker--2 {\n background: var(--scribe-speaker-2);\n }\n\n .scribe-speaker--3 {\n background: var(--scribe-speaker-3);\n }\n\n .scribe-speaker-text {\n margin-top: 0.25rem;\n }\n\n .scribe-text {\n word-wrap: break-word;\n }\n\n .scribe-text--final {\n color: var(--scribe-text-color);\n }\n\n .scribe-text--partial {\n color: var(--scribe-text-partial);\n font-style: italic;\n }\n\n .scribe-generate-container {\n position: relative;\n margin-left: 0.5rem;\n }\n\n .scribe-btn--generate {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n background: var(--scribe-primary);\n color: white;\n border: none;\n border-radius: var(--scribe-border-radius);\n font-family: var(--scribe-font-family);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .scribe-btn--generate:hover:not(:disabled) {\n background: var(--scribe-primary-dark);\n }\n\n .scribe-btn--generate:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n }\n\n .scribe-template-menu {\n position: absolute;\n top: 100%;\n left: 0;\n margin-top: 0.25rem;\n min-width: 220px;\n background: var(--scribe-bg);\n border: 1px solid var(--scribe-border-color);\n border-radius: var(--scribe-border-radius);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n z-index: 100;\n overflow: hidden;\n }\n\n .scribe-template-item {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n padding: 0.75rem 1rem;\n border: none;\n background: transparent;\n cursor: pointer;\n text-align: left;\n transition: background 0.15s ease;\n }\n\n .scribe-template-item:hover {\n background: var(--scribe-bg-transcript);\n }\n\n .scribe-template-item:not(:last-child) {\n border-bottom: 1px solid var(--scribe-border-color);\n }\n\n .scribe-template-name {\n font-weight: 500;\n color: var(--scribe-text-color);\n }\n\n .scribe-template-desc {\n font-size: 0.75rem;\n color: var(--scribe-text-partial);\n margin-top: 0.25rem;\n }\n\n @keyframes pulse-recording {\n 0%, 100% { box-shadow: 0 0 0 0 rgba(244, 67, 54, 0.4); }\n 50% { box-shadow: 0 0 0 8px rgba(244, 67, 54, 0); }\n }\n\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* Playback Mode Styles */\n .scribe-playback {\n padding: 1rem;\n }\n\n .scribe-loading,\n .scribe-error {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 2rem;\n color: var(--scribe-text-partial);\n }\n\n .scribe-player {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding: 1rem;\n background: var(--scribe-bg-transcript);\n border-radius: var(--scribe-border-radius);\n margin-bottom: 1rem;\n }\n\n .scribe-player-row {\n display: flex;\n align-items: center;\n gap: 1rem;\n }\n\n .scribe-btn--play {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: var(--scribe-primary);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s ease;\n flex-shrink: 0;\n }\n\n .scribe-btn--play:hover {\n background: var(--scribe-primary-dark);\n }\n\n .scribe-timeline-slider {\n flex: 1;\n cursor: pointer;\n height: 6px;\n -webkit-appearance: none;\n appearance: none;\n background: var(--scribe-level-bg);\n border-radius: 3px;\n outline: none;\n }\n\n .scribe-timeline-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 14px;\n height: 14px;\n background: var(--scribe-primary);\n border-radius: 50%;\n cursor: pointer;\n }\n\n .scribe-timeline-slider::-moz-range-thumb {\n width: 14px;\n height: 14px;\n background: var(--scribe-primary);\n border-radius: 50%;\n cursor: pointer;\n border: none;\n }\n\n .scribe-time {\n font-size: 0.75rem;\n color: var(--scribe-text-partial);\n text-align: center;\n }\n\n .scribe-speed {\n padding: 0.375rem 0.5rem;\n border-radius: 4px;\n border: 1px solid var(--scribe-border-color);\n background: var(--scribe-bg);\n font-size: 0.875rem;\n cursor: pointer;\n }\n\n .scribe-transcript-playback {\n max-height: 400px;\n overflow-y: auto;\n scroll-behavior: smooth;\n padding: 0.5rem;\n }\n\n .scribe-segment {\n padding: 0.75rem 1rem;\n margin-bottom: 0.5rem;\n border-left: 3px solid var(--speaker-color, var(--scribe-border-color));\n background: var(--scribe-bg);\n border-radius: 0 var(--scribe-border-radius) var(--scribe-border-radius) 0;\n cursor: pointer;\n transition: background 0.2s ease;\n }\n\n .scribe-segment:hover {\n background: var(--scribe-bg-transcript);\n }\n\n .scribe-segment--active {\n background: rgba(76, 175, 80, 0.1);\n border-left-color: var(--scribe-primary);\n }\n\n .scribe-segment-text {\n margin: 0.25rem 0 0 0;\n line-height: 1.6;\n }\n\n .scribe-word {\n transition: background 0.15s ease, color 0.15s ease;\n padding: 0 1px;\n border-radius: 2px;\n }\n\n .scribe-word:hover {\n background: rgba(0, 0, 0, 0.05);\n cursor: pointer;\n }\n\n .scribe-word--active {\n background: var(--scribe-primary);\n color: white;\n }\n `],\n})\nexport class RecorderComponent implements OnDestroy {\n private audioCapture = inject(AudioCaptureService);\n private socket = inject(ScribeSocketService);\n private elementRef = inject(ElementRef);\n private subscriptions: Subscription[] = [];\n private entryIdCounter = 0;\n private generateAbortController: AbortController | null = null;\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (!this.showTemplateMenu()) return;\n const target = event.target as HTMLElement;\n if (!this.elementRef.nativeElement.contains(target)) {\n this.showTemplateMenu.set(false);\n }\n }\n\n wsUrl = input<string>('');\n token = input<string>('');\n speakerLabels = input<Record<number, string>>({});\n premium = input<boolean>(false);\n templates = input<TemplateOption[]>([]);\n lambdaUrl = input<string>('');\n\n sessionId = input<string | undefined>();\n apiUrl = input<string>('');\n resumeSessionId = input<string | undefined>();\n\n sessionStarted = output<string>();\n sessionFinished = output<{ transcript: string; entries: TranscriptEntry[] }>();\n error = output<Error>();\n documentGenerated = output<GeneratedDocument>();\n generationError = output<Error>();\n\n isRecording = signal(false);\n isPaused = signal(false);\n audioLevel = signal(0);\n connectionState = signal<ConnectionState>('disconnected');\n entries = signal<TranscriptEntry[]>([]);\n partialText = signal('');\n currentSpeaker = signal<number | undefined>(undefined);\n showTemplateMenu = signal(false);\n isGenerating = signal(false);\n lastSessionId = signal<string | null>(null);\n\n isPlaying = signal(false);\n isLoadingSession = signal(false);\n audioCurrentTime = signal(0);\n audioDuration = signal(0);\n playbackRate = signal(1);\n sessionData = signal<SessionPlaybackData | null>(null);\n activeSegmentId = signal<string | null>(null);\n activeWordIndex = signal<number | null>(null);\n\n private audioElement: HTMLAudioElement | null = null;\n private audioBlobUrl: string | null = null;\n\n mode = computed<RecorderMode>(() =>\n this.sessionId() ? 'playback' : 'recording'\n );\n\n segments = computed(() =>\n this.sessionData()?.transcription.segments ?? []\n );\n\n hasFinishedSession = computed(() =>\n this.lastSessionId() !== null &&\n !this.isRecording() &&\n !this.isPaused()\n );\n\n speakerGroups = computed<SpeakerGroup[]>(() => {\n const allEntries = this.entries();\n if (allEntries.length === 0) return [];\n\n const groups: SpeakerGroup[] = [];\n let currentGroup: SpeakerGroup | null = null;\n\n for (const entry of allEntries) {\n if (!currentGroup || currentGroup.speaker !== entry.speaker) {\n currentGroup = { speaker: entry.speaker, entries: [] };\n groups.push(currentGroup);\n }\n currentGroup.entries.push(entry);\n }\n\n return groups;\n });\n\n constructor() {\n this.subscriptions.push(\n this.audioCapture.audioLevel$.subscribe((level) => {\n this.audioLevel.set(level);\n }),\n this.socket.connectionState$.subscribe((state) => {\n this.connectionState.set(state);\n }),\n this.socket.transcription$.subscribe((event) => {\n this.handleTranscription(event);\n }),\n this.socket.error$.subscribe((err) => {\n this.error.emit(err);\n }),\n this.audioCapture.error$.subscribe((err) => {\n this.error.emit(err);\n }),\n this.audioCapture.audioChunk$.subscribe(({ data, isSilence }) => {\n this.socket.sendAudioChunk(data, isSilence);\n })\n );\n\n effect(() => {\n const sid = this.sessionId();\n const api = this.apiUrl();\n if (sid && api && this.mode() === 'playback') {\n this.loadSession();\n }\n });\n\n effect(() => {\n const resumeId = this.resumeSessionId();\n const api = this.apiUrl();\n if (resumeId && api && this.mode() === 'recording') {\n this.resumeSession(resumeId);\n }\n });\n }\n\n ngOnDestroy(): void {\n this.subscriptions.forEach((sub) => sub.unsubscribe());\n this.generateAbortController?.abort();\n this.cleanup();\n this.cleanupPlayback();\n }\n\n private audioEventHandlers: {\n loadedmetadata?: () => void;\n timeupdate?: () => void;\n ended?: () => void;\n } = {};\n\n private cleanupPlayback(): void {\n if (this.audioElement) {\n this.audioElement.pause();\n if (this.audioEventHandlers.loadedmetadata) {\n this.audioElement.removeEventListener('loadedmetadata', this.audioEventHandlers.loadedmetadata);\n }\n if (this.audioEventHandlers.timeupdate) {\n this.audioElement.removeEventListener('timeupdate', this.audioEventHandlers.timeupdate);\n }\n if (this.audioEventHandlers.ended) {\n this.audioElement.removeEventListener('ended', this.audioEventHandlers.ended);\n }\n this.audioEventHandlers = {};\n this.audioElement = null;\n }\n if (this.audioBlobUrl) {\n URL.revokeObjectURL(this.audioBlobUrl);\n this.audioBlobUrl = null;\n }\n }\n\n getSpeakerLabel(speaker: number): string {\n const customLabels = this.speakerLabels();\n if (customLabels[speaker]) {\n return customLabels[speaker];\n }\n return SPEAKER_LABELS[speaker] || `Pessoa ${speaker + 1}`;\n }\n\n shouldShowSpeakerLabel(segmentIndex: number): boolean {\n const segs = this.segments();\n if (segmentIndex === 0) return true;\n const currentSpeaker = segs[segmentIndex]?.speaker;\n const previousSpeaker = segs[segmentIndex - 1]?.speaker;\n return currentSpeaker !== previousSpeaker;\n }\n\n getMicButtonLabel(): string {\n if (this.isPaused()) {\n return 'Retomar gravação';\n }\n if (this.isRecording()) {\n return 'Pausar gravação';\n }\n return 'Iniciar gravação';\n }\n\n async toggleRecording(): Promise<void> {\n if (this.isPaused()) {\n this.resumeRecording();\n } else if (this.isRecording()) {\n this.pauseRecording();\n } else {\n await this.startRecording();\n }\n }\n\n pauseRecording(): void {\n if (!this.isRecording() || this.isPaused()) return;\n this.audioCapture.pauseCapture();\n this.isPaused.set(true);\n }\n\n resumeRecording(): void {\n if (!this.isPaused()) return;\n this.audioCapture.resumeCapture();\n this.isPaused.set(false);\n }\n\n async finishSession(): Promise<void> {\n if (!this.isRecording() && !this.isPaused()) return;\n\n const sessionId = this.socket.getSessionId();\n\n await this.stopRecording();\n\n const allEntries = this.entries();\n const fullTranscript = allEntries.map((e) => e.text).join(' ');\n\n this.sessionFinished.emit({ transcript: fullTranscript, entries: allEntries });\n\n this.partialText.set('');\n this.currentSpeaker.set(undefined);\n\n this.lastSessionId.set(sessionId);\n }\n\n toggleTemplateMenu(): void {\n this.showTemplateMenu.update((v) => !v);\n }\n\n async selectTemplate(template: TemplateOption): Promise<void> {\n if (this.isGenerating()) return;\n\n this.showTemplateMenu.set(false);\n\n const lambdaUrl = this.lambdaUrl();\n if (!lambdaUrl) {\n this.generationError.emit(new Error('Lambda URL not provided'));\n return;\n }\n\n const sessionId = this.lastSessionId();\n if (!sessionId) {\n this.generationError.emit(new Error('No session available'));\n return;\n }\n\n this.generateAbortController?.abort();\n this.generateAbortController = new AbortController();\n\n this.isGenerating.set(true);\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n const token = this.token();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(`${lambdaUrl}/generate`, {\n method: 'POST',\n headers,\n signal: this.generateAbortController.signal,\n body: JSON.stringify({\n sessionId,\n outputSchema: template.content,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || `HTTP ${response.status}`);\n }\n\n const result = await response.json();\n\n this.documentGenerated.emit({\n sessionId,\n templateId: template.id,\n content: result.content,\n generatedAt: result.generatedAt,\n });\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') return;\n this.generationError.emit(err instanceof Error ? err : new Error(String(err)));\n } finally {\n this.isGenerating.set(false);\n }\n }\n\n async loadSession(): Promise<void> {\n const sid = this.sessionId();\n const api = this.apiUrl();\n\n if (!sid || !api) return;\n\n this.isLoadingSession.set(true);\n\n try {\n const headers: Record<string, string> = {};\n const token = this.token();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(`${api}/session/${sid}`, { headers });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data: SessionPlaybackData = await response.json();\n this.sessionData.set(data);\n\n await this.loadAudio(data.audioUrl);\n } catch (err) {\n this.error.emit(err instanceof Error ? err : new Error(String(err)));\n } finally {\n this.isLoadingSession.set(false);\n }\n }\n\n async resumeSession(sessionId: string): Promise<void> {\n const api = this.apiUrl();\n if (!api) return;\n\n this.isLoadingSession.set(true);\n\n try {\n const headers: Record<string, string> = {};\n const token = this.token();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(`${api}/session/${sessionId}`, { headers });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data: SessionPlaybackData = await response.json();\n\n const entries: TranscriptEntry[] = data.transcription.segments.map((seg, idx) => ({\n id: idx + 1,\n text: seg.text,\n speaker: seg.speaker,\n isFinal: true,\n startTime: seg.startTime,\n endTime: seg.endTime,\n }));\n\n this.entryIdCounter = entries.length;\n this.entries.set(entries);\n this.lastSessionId.set(sessionId);\n } catch (err) {\n this.error.emit(err instanceof Error ? err : new Error(String(err)));\n } finally {\n this.isLoadingSession.set(false);\n }\n }\n\n private async loadAudio(pcmUrl: string): Promise<void> {\n this.cleanupPlayback();\n\n const response = await fetch(pcmUrl);\n if (!response.ok) {\n throw new Error(`Failed to load audio: HTTP ${response.status}`);\n }\n\n const pcmData = await response.arrayBuffer();\n\n const wavData = pcmToWav(pcmData);\n this.audioBlobUrl = createAudioBlobUrl(wavData);\n\n this.audioElement = new Audio(this.audioBlobUrl);\n\n this.audioEventHandlers.loadedmetadata = () => {\n this.audioDuration.set(this.audioElement!.duration);\n };\n this.audioEventHandlers.timeupdate = () => {\n this.audioCurrentTime.set(this.audioElement!.currentTime);\n this.updateActiveSegment();\n };\n this.audioEventHandlers.ended = () => {\n this.isPlaying.set(false);\n };\n\n this.audioElement.addEventListener('loadedmetadata', this.audioEventHandlers.loadedmetadata);\n this.audioElement.addEventListener('timeupdate', this.audioEventHandlers.timeupdate);\n this.audioElement.addEventListener('ended', this.audioEventHandlers.ended);\n }\n\n togglePlayback(): void {\n if (!this.audioElement) return;\n\n if (this.isPlaying()) {\n this.audioElement.pause();\n this.isPlaying.set(false);\n } else {\n this.audioElement.play();\n this.isPlaying.set(true);\n }\n }\n\n seekTo(event: Event): void {\n const input = event.target as HTMLInputElement | null;\n if (!input) return;\n const time = parseFloat(input.value);\n if (this.audioElement && !isNaN(time)) {\n this.audioElement.currentTime = time;\n this.audioCurrentTime.set(time);\n }\n }\n\n setPlaybackRate(event: Event): void {\n const select = event.target as HTMLSelectElement | null;\n if (!select) return;\n const rate = parseFloat(select.value);\n if (isNaN(rate)) return;\n this.playbackRate.set(rate);\n if (this.audioElement) {\n this.audioElement.playbackRate = rate;\n }\n }\n\n seekToSegment(segment: TranscriptSegment): void {\n if (this.audioElement) {\n this.audioElement.currentTime = segment.startTime;\n this.audioCurrentTime.set(segment.startTime);\n if (!this.isPlaying()) {\n this.togglePlayback();\n }\n }\n }\n\n seekToWord(word: TranscriptionWord, event: Event): void {\n event.stopPropagation();\n if (this.audioElement) {\n this.audioElement.currentTime = word.start;\n this.audioCurrentTime.set(word.start);\n if (!this.isPlaying()) {\n this.togglePlayback();\n }\n }\n }\n\n formatTimeDisplay(seconds: number): string {\n return formatTime(seconds);\n }\n\n getSpeakerColor(speaker: number | undefined): string {\n if (speaker === undefined) return 'var(--scribe-border-color)';\n const colors = [\n 'var(--scribe-speaker-0)',\n 'var(--scribe-speaker-1)',\n 'var(--scribe-speaker-2)',\n 'var(--scribe-speaker-3)',\n ];\n return colors[speaker % colors.length];\n }\n\n private updateActiveSegment(): void {\n const time = this.audioCurrentTime();\n const segs = this.segments();\n\n const seg = segs.find((s) => time >= s.startTime && time <= s.endTime);\n this.activeSegmentId.set(seg?.id ?? null);\n\n if (seg?.words) {\n const wordIdx = seg.words.findIndex((w) => time >= w.start && time <= w.end);\n this.activeWordIndex.set(wordIdx >= 0 ? wordIdx : null);\n } else {\n this.activeWordIndex.set(null);\n }\n\n this.scrollToActiveSegment();\n }\n\n private scrollToActiveSegment(): void {\n const activeId = this.activeSegmentId();\n if (!activeId) return;\n\n const container = this.elementRef.nativeElement.querySelector('.scribe-transcript-playback');\n const activeEl = container?.querySelector(`[data-segment-id=\"${activeId}\"]`);\n\n if (activeEl && container) {\n const containerRect = container.getBoundingClientRect();\n const activeRect = activeEl.getBoundingClientRect();\n\n if (activeRect.top < containerRect.top || activeRect.bottom > containerRect.bottom) {\n activeEl.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }\n }\n\n private async startRecording(): Promise<void> {\n try {\n await this.socket.connect(this.wsUrl(), this.token(), this.premium());\n await this.audioCapture.startCapture();\n this.isRecording.set(true);\n this.isPaused.set(false);\n\n const sessionId = this.socket.getSessionId();\n if (sessionId) {\n this.sessionStarted.emit(sessionId);\n }\n } catch (err) {\n this.error.emit(err instanceof Error ? err : new Error('Failed to start recording'));\n await this.cleanup();\n }\n }\n\n private async stopRecording(): Promise<void> {\n await this.audioCapture.stopCapture();\n this.socket.disconnect();\n this.isRecording.set(false);\n this.isPaused.set(false);\n }\n\n private async cleanup(): Promise<void> {\n await this.audioCapture.stopCapture();\n this.socket.disconnect();\n this.isRecording.set(false);\n this.isPaused.set(false);\n }\n\n private handleTranscription(event: TranscriptionEvent): void {\n if (!event.transcript) return;\n\n if (event.type === 'final') {\n const entry: TranscriptEntry = {\n id: ++this.entryIdCounter,\n text: event.transcript,\n speaker: event.speaker,\n isFinal: true,\n startTime: event.start,\n endTime: event.end,\n };\n\n this.entries.update((entries) => [...entries, entry]);\n this.partialText.set('');\n this.currentSpeaker.set(undefined);\n } else if (event.type === 'partial') {\n this.partialText.set(event.transcript);\n this.currentSpeaker.set(event.speaker);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["DEFAULT_CONFIG"],"mappings":"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"}
|