@xxmachina/components 19.51.0 → 19.81.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/fesm2022/xxmachina-components-extras-flow.mjs +73 -140
  2. package/fesm2022/xxmachina-components-extras-flow.mjs.map +1 -1
  3. package/fesm2022/xxmachina-components-features-query.mjs +3 -29
  4. package/fesm2022/xxmachina-components-features-query.mjs.map +1 -1
  5. package/fesm2022/xxmachina-components-groups-query-form.mjs +0 -54
  6. package/fesm2022/xxmachina-components-groups-query-form.mjs.map +1 -1
  7. package/fesm2022/xxmachina-components-molecules-inline-edit-field.mjs +0 -1
  8. package/fesm2022/xxmachina-components-molecules-inline-edit-field.mjs.map +1 -1
  9. package/fesm2022/xxmachina-components-molecules-user-avatar-menu.mjs +96 -0
  10. package/fesm2022/xxmachina-components-molecules-user-avatar-menu.mjs.map +1 -0
  11. package/fesm2022/xxmachina-components-molecules-weekly-header.mjs +2 -2
  12. package/fesm2022/xxmachina-components-molecules-workspace-selector.mjs +123 -0
  13. package/fesm2022/xxmachina-components-molecules-workspace-selector.mjs.map +1 -0
  14. package/fesm2022/xxmachina-components-organisms-calendar-section.mjs +2 -2
  15. package/fesm2022/xxmachina-components-organisms-calendar-section.mjs.map +1 -1
  16. package/fesm2022/xxmachina-components-organisms-event-input-section.mjs +0 -1
  17. package/fesm2022/xxmachina-components-organisms-event-input-section.mjs.map +1 -1
  18. package/fesm2022/xxmachina-components-organisms-terminal-input-section.mjs +2 -18
  19. package/fesm2022/xxmachina-components-organisms-terminal-input-section.mjs.map +1 -1
  20. package/fesm2022/xxmachina-components-organisms-video-trimmer-section.mjs +0 -3
  21. package/fesm2022/xxmachina-components-organisms-video-trimmer-section.mjs.map +1 -1
  22. package/fesm2022/xxmachina-components-organisms-xterm.mjs +283 -261
  23. package/fesm2022/xxmachina-components-organisms-xterm.mjs.map +1 -1
  24. package/fesm2022/xxmachina-components-pages-command.mjs +3 -9
  25. package/fesm2022/xxmachina-components-pages-command.mjs.map +1 -1
  26. package/fesm2022/xxmachina-components-pages-query-v2.mjs +0 -13
  27. package/fesm2022/xxmachina-components-pages-query-v2.mjs.map +1 -1
  28. package/fesm2022/xxmachina-components-pages-query.mjs +3 -67
  29. package/fesm2022/xxmachina-components-pages-query.mjs.map +1 -1
  30. package/fesm2022/xxmachina-components-pages-thread.mjs +2 -18
  31. package/fesm2022/xxmachina-components-pages-thread.mjs.map +1 -1
  32. package/fesm2022/{xxmachina-components-routes-commands-command.routes-CSwIdXZg.mjs → xxmachina-components-routes-commands-command.routes-Ca2yVrwL.mjs} +1 -2
  33. package/fesm2022/xxmachina-components-routes-commands-command.routes-Ca2yVrwL.mjs.map +1 -0
  34. package/fesm2022/{xxmachina-components-routes-commands-pages.routes-j2xVop4W.mjs → xxmachina-components-routes-commands-pages.routes-COpFeEsz.mjs} +2 -2
  35. package/fesm2022/{xxmachina-components-routes-commands-pages.routes-j2xVop4W.mjs.map → xxmachina-components-routes-commands-pages.routes-COpFeEsz.mjs.map} +1 -1
  36. package/fesm2022/xxmachina-components-routes-commands.mjs +1 -2
  37. package/fesm2022/xxmachina-components-routes-commands.mjs.map +1 -1
  38. package/fesm2022/xxmachina-components-routes-pages.mjs +0 -1
  39. package/fesm2022/xxmachina-components-routes-pages.mjs.map +1 -1
  40. package/fesm2022/xxmachina-components-routes-queries.mjs +0 -2
  41. package/fesm2022/xxmachina-components-routes-queries.mjs.map +1 -1
  42. package/fesm2022/{xxmachina-components-routes-query-pages.routes-CxTbOJDQ.mjs → xxmachina-components-routes-query-pages.routes-BNuONo3g.mjs} +1 -5
  43. package/fesm2022/xxmachina-components-routes-query-pages.routes-BNuONo3g.mjs.map +1 -0
  44. package/fesm2022/xxmachina-components-routes-query.mjs +1 -1
  45. package/fesm2022/{xxmachina-components-routes-resources-pages.routes-CRXxavHb.mjs → xxmachina-components-routes-resources-pages.routes-DEu2qpeu.mjs} +2 -2
  46. package/fesm2022/{xxmachina-components-routes-resources-pages.routes-CRXxavHb.mjs.map → xxmachina-components-routes-resources-pages.routes-DEu2qpeu.mjs.map} +1 -1
  47. package/fesm2022/{xxmachina-components-routes-resources-resource.routes-CkkmqB2_.mjs → xxmachina-components-routes-resources-resource.routes-CWxi2agj.mjs} +1 -2
  48. package/fesm2022/xxmachina-components-routes-resources-resource.routes-CWxi2agj.mjs.map +1 -0
  49. package/fesm2022/xxmachina-components-routes-resources.mjs +1 -1
  50. package/fesm2022/xxmachina-components-routes-transformer.mjs +0 -1
  51. package/fesm2022/xxmachina-components-routes-transformer.mjs.map +1 -1
  52. package/fesm2022/xxmachina-components-services-forms-query.mjs +1 -1
  53. package/fesm2022/xxmachina-components-services-forms-query.mjs.map +1 -1
  54. package/fesm2022/xxmachina-components-services-graphql.mjs +0 -4
  55. package/fesm2022/xxmachina-components-services-graphql.mjs.map +1 -1
  56. package/fesm2022/xxmachina-components-services-json-schema.mjs +6 -12
  57. package/fesm2022/xxmachina-components-services-json-schema.mjs.map +1 -1
  58. package/fesm2022/xxmachina-components-services-query.mjs +0 -7
  59. package/fesm2022/xxmachina-components-services-query.mjs.map +1 -1
  60. package/fesm2022/xxmachina-components-services-recording.mjs +0 -13
  61. package/fesm2022/xxmachina-components-services-recording.mjs.map +1 -1
  62. package/fesm2022/xxmachina-components-services-thread.mjs +0 -2
  63. package/fesm2022/xxmachina-components-services-thread.mjs.map +1 -1
  64. package/fesm2022/xxmachina-components-services-version.mjs +171 -0
  65. package/fesm2022/xxmachina-components-services-version.mjs.map +1 -0
  66. package/fesm2022/xxmachina-components-services-workspace-switcher.mjs +9 -0
  67. package/fesm2022/xxmachina-components-services-workspace-switcher.mjs.map +1 -0
  68. package/fesm2022/xxmachina-components-templates-agent.mjs +98 -146
  69. package/fesm2022/xxmachina-components-templates-agent.mjs.map +1 -1
  70. package/fesm2022/xxmachina-components-templates-background.mjs +10 -30
  71. package/fesm2022/xxmachina-components-templates-background.mjs.map +1 -1
  72. package/fesm2022/xxmachina-components-templates-env.mjs +295 -0
  73. package/fesm2022/xxmachina-components-templates-env.mjs.map +1 -0
  74. package/fesm2022/xxmachina-components-templates-flow-nodes-issue.mjs.map +1 -1
  75. package/fesm2022/xxmachina-components-templates-flow.mjs +1 -1
  76. package/fesm2022/xxmachina-components-templates-flow.mjs.map +1 -1
  77. package/fesm2022/xxmachina-components-templates-machina-icon-button-menu.mjs +78 -0
  78. package/fesm2022/xxmachina-components-templates-machina-icon-button-menu.mjs.map +1 -0
  79. package/fesm2022/xxmachina-components.mjs +9 -10
  80. package/fesm2022/xxmachina-components.mjs.map +1 -1
  81. package/package.json +25 -1
  82. package/types/xxmachina-components-extras-flow.d.ts +8 -43
  83. package/types/xxmachina-components-extras-flow.d.ts.map +1 -1
  84. package/types/xxmachina-components-features-query.d.ts +3 -24
  85. package/types/xxmachina-components-features-query.d.ts.map +1 -1
  86. package/types/xxmachina-components-groups-query-form.d.ts +2 -2
  87. package/types/xxmachina-components-molecules-user-avatar-menu.d.ts +19 -0
  88. package/types/xxmachina-components-molecules-user-avatar-menu.d.ts.map +1 -0
  89. package/types/xxmachina-components-molecules-workspace-selector.d.ts +25 -0
  90. package/types/xxmachina-components-molecules-workspace-selector.d.ts.map +1 -0
  91. package/types/xxmachina-components-organisms-xterm.d.ts +130 -111
  92. package/types/xxmachina-components-organisms-xterm.d.ts.map +1 -1
  93. package/types/xxmachina-components-pages-query-v2.d.ts +0 -3
  94. package/types/xxmachina-components-pages-query-v2.d.ts.map +1 -1
  95. package/types/xxmachina-components-pages-query.d.ts +0 -19
  96. package/types/xxmachina-components-pages-query.d.ts.map +1 -1
  97. package/types/xxmachina-components-services-forms-query.d.ts +1 -1
  98. package/types/xxmachina-components-services-graphql.d.ts +0 -3
  99. package/types/xxmachina-components-services-graphql.d.ts.map +1 -1
  100. package/types/xxmachina-components-services-query.d.ts +0 -7
  101. package/types/xxmachina-components-services-query.d.ts.map +1 -1
  102. package/types/xxmachina-components-services-version.d.ts +32 -0
  103. package/types/xxmachina-components-services-version.d.ts.map +1 -0
  104. package/types/xxmachina-components-services-workspace-switcher.d.ts +17 -0
  105. package/types/xxmachina-components-services-workspace-switcher.d.ts.map +1 -0
  106. package/types/xxmachina-components-templates-agent.d.ts +2 -1
  107. package/types/xxmachina-components-templates-agent.d.ts.map +1 -1
  108. package/types/xxmachina-components-templates-env.d.ts +43 -0
  109. package/types/xxmachina-components-templates-env.d.ts.map +1 -0
  110. package/types/xxmachina-components-templates-flow-nodes-issue.d.ts +0 -2
  111. package/types/xxmachina-components-templates-flow-nodes-issue.d.ts.map +1 -1
  112. package/types/xxmachina-components-templates-machina-icon-button-menu.d.ts +18 -0
  113. package/types/xxmachina-components-templates-machina-icon-button-menu.d.ts.map +1 -0
  114. package/types/xxmachina-components.d.ts +2 -0
  115. package/types/xxmachina-components.d.ts.map +1 -1
  116. package/fesm2022/xxmachina-components-routes-commands-command.routes-CSwIdXZg.mjs.map +0 -1
  117. package/fesm2022/xxmachina-components-routes-query-pages.routes-CxTbOJDQ.mjs.map +0 -1
  118. package/fesm2022/xxmachina-components-routes-resources-resource.routes-CkkmqB2_.mjs.map +0 -1
@@ -26,34 +26,26 @@ class TerminalInputSectionOrganism {
26
26
  action = output();
27
27
  inputField = viewChild('inputField', ...(ngDevMode ? [{ debugName: "inputField" }] : []));
28
28
  componentId = this.speechService.generateComponentId();
29
- // このコンポーネントがアクティブかどうか
30
29
  isRecording = computed(() => this.speechService.isListening() &&
31
30
  this.speechService.isActiveComponent(this.componentId), ...(ngDevMode ? [{ debugName: "isRecording" }] : []));
32
- // IME変換中かどうかのフラグ
33
31
  isComposing = false;
34
- // IME変換中にEnterが押されたかどうか(確定Enterの検出用)
35
32
  enterPressedDuringComposition = false;
36
33
  constructor() {
37
- // アクティブな場合のみ、音声認識結果を入力フィールドに反映
38
34
  effect(() => {
39
35
  if (this.enableVoiceInput() && this.speechService.isActiveComponent(this.componentId)) {
40
36
  const transcript = this.speechService.transcript();
41
37
  const text = transcript.finalized + transcript.interim;
42
- // clear()時は空文字でsetValueしてフォームもクリア
43
38
  this.control().setValue(text);
44
39
  }
45
40
  });
46
- // autoMode + selectedSessionId の変化を検知し、書き込み先を登録
47
41
  effect(() => {
48
42
  const autoMode = this.speechService.autoModeEnabled();
49
43
  const selectedId = this.speechService.selectedSessionId();
50
44
  const sid = this.sessionId();
51
45
  if (autoMode && sid && selectedId === sid) {
52
- // Speech APIは動き続けている。書き込み先を自分に登録するだけ
53
46
  untracked(() => this.speechService.activateComponent(this.componentId));
54
47
  }
55
48
  else if (autoMode && sid && selectedId !== sid) {
56
- // deactivate: 別セッションに切り替わった → 入力欄にテキストがあれば送信
57
49
  untracked(() => this.send());
58
50
  }
59
51
  });
@@ -64,8 +56,6 @@ class TerminalInputSectionOrganism {
64
56
  }
65
57
  onCompositionEnd() {
66
58
  this.isComposing = false;
67
- // Chromeではkeydownがcompositionendより先に発火するため、
68
- // IME確定のEnterを検出した場合はcompositionend後に送信する
69
59
  if (this.enterPressedDuringComposition) {
70
60
  this.enterPressedDuringComposition = false;
71
61
  setTimeout(() => this.send(), 0);
@@ -73,7 +63,6 @@ class TerminalInputSectionOrganism {
73
63
  }
74
64
  handleKeydown(event) {
75
65
  if (this.isComposing) {
76
- // IME変換中のEnterを記録(確定Enter = 送信トリガー)
77
66
  if (event.key === 'Enter' && !event.shiftKey) {
78
67
  this.enterPressedDuringComposition = true;
79
68
  }
@@ -94,7 +83,6 @@ class TerminalInputSectionOrganism {
94
83
  if (this.clearOnSend()) {
95
84
  this.control().reset();
96
85
  this.resetTextareaHeight();
97
- // 自動モード時: stopしない。clear()でtranscriptだけリセット
98
86
  if (this.isRecording()) {
99
87
  this.speechService.clear();
100
88
  }
@@ -104,14 +92,10 @@ class TerminalInputSectionOrganism {
104
92
  adjustTextareaHeight() {
105
93
  const textarea = this.inputField()?.nativeElement;
106
94
  if (textarea) {
107
- // overflowを一時的にhiddenにしてscrollHeightを正確に取得
108
95
  textarea.style.overflow = 'hidden';
109
- // 一旦高さを最小に設定してscrollHeightを正確に取得
110
96
  textarea.style.height = '0px';
111
- // scrollHeightに合わせて高さを設定(最大200px)
112
97
  const newHeight = Math.min(textarea.scrollHeight, 200);
113
98
  textarea.style.height = `${newHeight}px`;
114
- // overflowを元に戻す
115
99
  textarea.style.overflow = 'auto';
116
100
  }
117
101
  }
@@ -128,7 +112,7 @@ class TerminalInputSectionOrganism {
128
112
  this.speechService.toggle(this.componentId);
129
113
  }
130
114
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: TerminalInputSectionOrganism, deps: [], target: i0.ɵɵFactoryTarget.Component });
131
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: TerminalInputSectionOrganism, isStandalone: true, selector: "organisms-terminal-input-section", inputs: { control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, clearOnSend: { classPropertyName: "clearOnSend", publicName: "clearOnSend", isSignal: true, isRequired: false, transformFunction: null }, enableVoiceInput: { classPropertyName: "enableVoiceInput", publicName: "enableVoiceInput", isSignal: true, isRequired: false, transformFunction: null }, sessionId: { classPropertyName: "sessionId", publicName: "sessionId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { classAttribute: "organism terminal-input section" }, viewQueries: [{ propertyName: "inputField", first: true, predicate: ["inputField"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"input-line\">\n <span class=\"input-prefix\">{{ prefix() }}</span>\n <div class=\"input-container\">\n <textarea\n #inputField\n class=\"terminal-input\"\n [formControl]=\"control()\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"handleKeydown($event)\"\n (input)=\"onInput()\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n rows=\"1\"\n ></textarea>\n </div>\n @if (enableVoiceInput() && speechService.isSupported) {\n <button\n mat-icon-button\n (click)=\"toggleVoiceInput()\"\n [matTooltip]=\"isRecording() ? '\u97F3\u58F0\u5165\u529B\u505C\u6B62' : '\u97F3\u58F0\u5165\u529B'\"\n [class.recording]=\"isRecording()\">\n <mat-icon>{{ isRecording() ? 'mic' : 'mic_none' }}</mat-icon>\n </button>\n }\n <button mat-icon-button (click)=\"send()\" matTooltip=\"\u9001\u4FE1\">\n <mat-icon>send</mat-icon>\n </button>\n</div>\n", styles: [":host{display:block;display:flex;background:#0000004d;border-top:1px solid rgba(255,255,255,.1)}.input-line{display:flex;align-items:center;width:100%;gap:8px;padding:8px 12px}.input-prefix{color:#0dbc79;font-family:SF Mono,Cascadia Code,monospace;font-size:14px;flex-shrink:0}.input-container{flex:1;display:flex}.input-container .terminal-input{width:100%;max-height:200px;background:#0003;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#e0e0e0;font-family:SF Mono,Cascadia Code,monospace;font-size:14px;line-height:20px;padding:8px 12px;resize:none;outline:none;overflow-y:auto;display:block;box-sizing:border-box}.input-container .terminal-input:focus{border-color:#0dbc7980;box-shadow:0 0 0 2px #0dbc7933}.input-container .terminal-input::placeholder{color:#ffffff4d}button{color:#0dbc79}button:hover{background:#0dbc791a}button.recording{color:#f44336;animation:pulse 1.5s infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
115
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: TerminalInputSectionOrganism, isStandalone: true, selector: "organisms-terminal-input-section", inputs: { control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, clearOnSend: { classPropertyName: "clearOnSend", publicName: "clearOnSend", isSignal: true, isRequired: false, transformFunction: null }, enableVoiceInput: { classPropertyName: "enableVoiceInput", publicName: "enableVoiceInput", isSignal: true, isRequired: false, transformFunction: null }, sessionId: { classPropertyName: "sessionId", publicName: "sessionId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { classAttribute: "organism terminal-input section" }, viewQueries: [{ propertyName: "inputField", first: true, predicate: ["inputField"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"input-line\">\n <span class=\"input-prefix\">{{ prefix() }}</span>\n <div class=\"input-container\">\n <textarea\n #inputField\n class=\"terminal-input\"\n [formControl]=\"control()\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"handleKeydown($event)\"\n (input)=\"onInput()\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n rows=\"1\"\n ></textarea>\n </div>\n @if (enableVoiceInput() && speechService.isSupported) {\n <button\n mat-icon-button\n (click)=\"toggleVoiceInput()\"\n [matTooltip]=\"isRecording() ? '\u97F3\u58F0\u5165\u529B\u505C\u6B62' : '\u97F3\u58F0\u5165\u529B'\"\n [class.recording]=\"isRecording()\">\n <mat-icon>{{ isRecording() ? 'mic' : 'mic_none' }}</mat-icon>\n </button>\n }\n <button mat-icon-button (click)=\"send()\" matTooltip=\"\u9001\u4FE1\">\n <mat-icon>send</mat-icon>\n </button>\n</div>\n", styles: [":host{display:block;display:flex;background:#0000004d;border-top:1px solid rgba(255,255,255,.1)}.input-line{display:flex;align-items:center;width:100%;gap:8px;padding:8px 12px}.input-prefix{color:#3f3;font-family:SF Mono,Cascadia Code,monospace;font-size:14px;flex-shrink:0}.input-container{flex:1;display:flex}.input-container .terminal-input{width:100%;max-height:200px;background:#0003;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#e0e0e0;font-family:SF Mono,Cascadia Code,monospace;font-size:14px;line-height:20px;padding:8px 12px;resize:none;outline:none;overflow-y:auto;display:block;box-sizing:border-box}.input-container .terminal-input:focus{border-color:#33ff3380;box-shadow:0 0 0 2px #3f33}.input-container .terminal-input::placeholder{color:#ffffff4d}button{color:#3f3}button:hover{background:#33ff331a}button.recording{color:#f44336;animation:pulse 1.5s infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
132
116
  }
133
117
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: TerminalInputSectionOrganism, decorators: [{
134
118
  type: Component,
@@ -137,7 +121,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImpor
137
121
  MatButtonModule,
138
122
  MatIconModule,
139
123
  MatTooltipModule
140
- ], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'organism terminal-input section' }, template: "<div class=\"input-line\">\n <span class=\"input-prefix\">{{ prefix() }}</span>\n <div class=\"input-container\">\n <textarea\n #inputField\n class=\"terminal-input\"\n [formControl]=\"control()\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"handleKeydown($event)\"\n (input)=\"onInput()\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n rows=\"1\"\n ></textarea>\n </div>\n @if (enableVoiceInput() && speechService.isSupported) {\n <button\n mat-icon-button\n (click)=\"toggleVoiceInput()\"\n [matTooltip]=\"isRecording() ? '\u97F3\u58F0\u5165\u529B\u505C\u6B62' : '\u97F3\u58F0\u5165\u529B'\"\n [class.recording]=\"isRecording()\">\n <mat-icon>{{ isRecording() ? 'mic' : 'mic_none' }}</mat-icon>\n </button>\n }\n <button mat-icon-button (click)=\"send()\" matTooltip=\"\u9001\u4FE1\">\n <mat-icon>send</mat-icon>\n </button>\n</div>\n", styles: [":host{display:block;display:flex;background:#0000004d;border-top:1px solid rgba(255,255,255,.1)}.input-line{display:flex;align-items:center;width:100%;gap:8px;padding:8px 12px}.input-prefix{color:#0dbc79;font-family:SF Mono,Cascadia Code,monospace;font-size:14px;flex-shrink:0}.input-container{flex:1;display:flex}.input-container .terminal-input{width:100%;max-height:200px;background:#0003;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#e0e0e0;font-family:SF Mono,Cascadia Code,monospace;font-size:14px;line-height:20px;padding:8px 12px;resize:none;outline:none;overflow-y:auto;display:block;box-sizing:border-box}.input-container .terminal-input:focus{border-color:#0dbc7980;box-shadow:0 0 0 2px #0dbc7933}.input-container .terminal-input::placeholder{color:#ffffff4d}button{color:#0dbc79}button:hover{background:#0dbc791a}button.recording{color:#f44336;animation:pulse 1.5s infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}\n"] }]
124
+ ], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'organism terminal-input section' }, template: "<div class=\"input-line\">\n <span class=\"input-prefix\">{{ prefix() }}</span>\n <div class=\"input-container\">\n <textarea\n #inputField\n class=\"terminal-input\"\n [formControl]=\"control()\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"handleKeydown($event)\"\n (input)=\"onInput()\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n rows=\"1\"\n ></textarea>\n </div>\n @if (enableVoiceInput() && speechService.isSupported) {\n <button\n mat-icon-button\n (click)=\"toggleVoiceInput()\"\n [matTooltip]=\"isRecording() ? '\u97F3\u58F0\u5165\u529B\u505C\u6B62' : '\u97F3\u58F0\u5165\u529B'\"\n [class.recording]=\"isRecording()\">\n <mat-icon>{{ isRecording() ? 'mic' : 'mic_none' }}</mat-icon>\n </button>\n }\n <button mat-icon-button (click)=\"send()\" matTooltip=\"\u9001\u4FE1\">\n <mat-icon>send</mat-icon>\n </button>\n</div>\n", styles: [":host{display:block;display:flex;background:#0000004d;border-top:1px solid rgba(255,255,255,.1)}.input-line{display:flex;align-items:center;width:100%;gap:8px;padding:8px 12px}.input-prefix{color:#3f3;font-family:SF Mono,Cascadia Code,monospace;font-size:14px;flex-shrink:0}.input-container{flex:1;display:flex}.input-container .terminal-input{width:100%;max-height:200px;background:#0003;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#e0e0e0;font-family:SF Mono,Cascadia Code,monospace;font-size:14px;line-height:20px;padding:8px 12px;resize:none;outline:none;overflow-y:auto;display:block;box-sizing:border-box}.input-container .terminal-input:focus{border-color:#33ff3380;box-shadow:0 0 0 2px #3f33}.input-container .terminal-input::placeholder{color:#ffffff4d}button{color:#3f3}button:hover{background:#33ff331a}button.recording{color:#f44336;animation:pulse 1.5s infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}\n"] }]
141
125
  }], ctorParameters: () => [], propDecorators: { control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], clearOnSend: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearOnSend", required: false }] }], enableVoiceInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableVoiceInput", required: false }] }], sessionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "sessionId", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], inputField: [{ type: i0.ViewChild, args: ['inputField', { isSignal: true }] }] } });
142
126
 
143
127
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"xxmachina-components-organisms-terminal-input-section.mjs","sources":["../../../../../packages/@xxmachina/components/src/lib/organisms/terminal-input-section/terminal-input-section.organism.ts","../../../../../packages/@xxmachina/components/src/lib/organisms/terminal-input-section/terminal-input-section.organism.html","../../../../../packages/@xxmachina/components/src/lib/organisms/terminal-input-section/xxmachina-components-organisms-terminal-input-section.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, effect, ElementRef, inject, input, output, untracked, viewChild } from '@angular/core';\n\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { Action } from '@ng-atomic/core';\nimport { SpeechService } from '@xxmachina/common/services/speech';\n\nexport enum ActionId {\n SEND = 'send',\n}\n\n@Component({\n selector: 'organisms-terminal-input-section',\n standalone: true,\n imports: [\n ReactiveFormsModule,\n MatButtonModule,\n MatIconModule,\n MatTooltipModule\n],\n templateUrl: './terminal-input-section.organism.html',\n styleUrls: ['./terminal-input-section.organism.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'organism terminal-input section' },\n})\nexport class TerminalInputSectionOrganism {\n static readonly ActionId = ActionId;\n\n readonly speechService = inject(SpeechService);\n\n readonly control = input(new FormControl('', { nonNullable: true }));\n readonly placeholder = input('Enter command...');\n readonly prefix = input('>');\n readonly clearOnSend = input(true);\n readonly enableVoiceInput = input(false);\n readonly sessionId = input<string | undefined>(undefined);\n\n readonly action = output<Action<string>>();\n\n readonly inputField = viewChild<ElementRef<HTMLTextAreaElement>>('inputField');\n\n private readonly componentId = this.speechService.generateComponentId();\n\n // このコンポーネントがアクティブかどうか\n readonly isRecording = computed(() =>\n this.speechService.isListening() &&\n this.speechService.isActiveComponent(this.componentId)\n );\n\n // IME変換中かどうかのフラグ\n private isComposing = false;\n // IME変換中にEnterが押されたかどうか(確定Enterの検出用)\n private enterPressedDuringComposition = false;\n\n constructor() {\n // アクティブな場合のみ、音声認識結果を入力フィールドに反映\n effect(() => {\n if (this.enableVoiceInput() && this.speechService.isActiveComponent(this.componentId)) {\n const transcript = this.speechService.transcript();\n const text = transcript.finalized + transcript.interim;\n // clear()時は空文字でsetValueしてフォームもクリア\n this.control().setValue(text);\n }\n });\n\n // autoMode + selectedSessionId の変化を検知し、書き込み先を登録\n effect(() => {\n const autoMode = this.speechService.autoModeEnabled();\n const selectedId = this.speechService.selectedSessionId();\n const sid = this.sessionId();\n if (autoMode && sid && selectedId === sid) {\n // Speech APIは動き続けている。書き込み先を自分に登録するだけ\n untracked(() => this.speechService.activateComponent(this.componentId));\n } else if (autoMode && sid && selectedId !== sid) {\n // deactivate: 別セッションに切り替わった → 入力欄にテキストがあれば送信\n untracked(() => this.send());\n }\n });\n }\n\n onCompositionStart() {\n this.isComposing = true;\n this.enterPressedDuringComposition = false;\n }\n\n onCompositionEnd() {\n this.isComposing = false;\n // Chromeではkeydownがcompositionendより先に発火するため、\n // IME確定のEnterを検出した場合はcompositionend後に送信する\n if (this.enterPressedDuringComposition) {\n this.enterPressedDuringComposition = false;\n setTimeout(() => this.send(), 0);\n }\n }\n\n handleKeydown(event: KeyboardEvent) {\n if (this.isComposing) {\n // IME変換中のEnterを記録(確定Enter = 送信トリガー)\n if (event.key === 'Enter' && !event.shiftKey) {\n this.enterPressedDuringComposition = true;\n }\n return;\n }\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.send();\n }\n }\n\n onInput() {\n this.adjustTextareaHeight();\n }\n\n send() {\n const value = this.control().value.trim();\n if (value) {\n this.action.emit({ id: ActionId.SEND, payload: value });\n if (this.clearOnSend()) {\n this.control().reset();\n this.resetTextareaHeight();\n // 自動モード時: stopしない。clear()でtranscriptだけリセット\n if (this.isRecording()) {\n this.speechService.clear();\n }\n }\n }\n }\n\n private adjustTextareaHeight() {\n const textarea = this.inputField()?.nativeElement;\n if (textarea) {\n // overflowを一時的にhiddenにしてscrollHeightを正確に取得\n textarea.style.overflow = 'hidden';\n // 一旦高さを最小に設定してscrollHeightを正確に取得\n textarea.style.height = '0px';\n // scrollHeightに合わせて高さを設定(最大200px)\n const newHeight = Math.min(textarea.scrollHeight, 200);\n textarea.style.height = `${newHeight}px`;\n // overflowを元に戻す\n textarea.style.overflow = 'auto';\n }\n }\n\n private resetTextareaHeight() {\n const textarea = this.inputField()?.nativeElement;\n if (textarea) {\n textarea.style.height = 'auto';\n }\n }\n\n focus() {\n this.inputField()?.nativeElement?.focus();\n }\n\n toggleVoiceInput() {\n this.speechService.toggle(this.componentId);\n }\n}\n","<div class=\"input-line\">\n <span class=\"input-prefix\">{{ prefix() }}</span>\n <div class=\"input-container\">\n <textarea\n #inputField\n class=\"terminal-input\"\n [formControl]=\"control()\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"handleKeydown($event)\"\n (input)=\"onInput()\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n rows=\"1\"\n ></textarea>\n </div>\n @if (enableVoiceInput() && speechService.isSupported) {\n <button\n mat-icon-button\n (click)=\"toggleVoiceInput()\"\n [matTooltip]=\"isRecording() ? '音声入力停止' : '音声入力'\"\n [class.recording]=\"isRecording()\">\n <mat-icon>{{ isRecording() ? 'mic' : 'mic_none' }}</mat-icon>\n </button>\n }\n <button mat-icon-button (click)=\"send()\" matTooltip=\"送信\">\n <mat-icon>send</mat-icon>\n </button>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xxmachina-components-organisms-terminal-input-section.mjs","sources":["../../../../../packages/@xxmachina/components/src/lib/organisms/terminal-input-section/terminal-input-section.organism.ts","../../../../../packages/@xxmachina/components/src/lib/organisms/terminal-input-section/terminal-input-section.organism.html","../../../../../packages/@xxmachina/components/src/lib/organisms/terminal-input-section/xxmachina-components-organisms-terminal-input-section.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, effect, ElementRef, inject, input, output, untracked, viewChild } from '@angular/core';\n\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { Action } from '@ng-atomic/core';\nimport { SpeechService } from '@xxmachina/common/services/speech';\n\nexport enum ActionId {\n SEND = 'send',\n}\n\n@Component({\n selector: 'organisms-terminal-input-section',\n standalone: true,\n imports: [\n ReactiveFormsModule,\n MatButtonModule,\n MatIconModule,\n MatTooltipModule\n],\n templateUrl: './terminal-input-section.organism.html',\n styleUrls: ['./terminal-input-section.organism.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'organism terminal-input section' },\n})\nexport class TerminalInputSectionOrganism {\n static readonly ActionId = ActionId;\n\n readonly speechService = inject(SpeechService);\n\n readonly control = input(new FormControl('', { nonNullable: true }));\n readonly placeholder = input('Enter command...');\n readonly prefix = input('>');\n readonly clearOnSend = input(true);\n readonly enableVoiceInput = input(false);\n readonly sessionId = input<string | undefined>(undefined);\n\n readonly action = output<Action<string>>();\n\n readonly inputField = viewChild<ElementRef<HTMLTextAreaElement>>('inputField');\n\n private readonly componentId = this.speechService.generateComponentId();\n\n \n readonly isRecording = computed(() =>\n this.speechService.isListening() &&\n this.speechService.isActiveComponent(this.componentId)\n );\n\n \n private isComposing = false;\n \n private enterPressedDuringComposition = false;\n\n constructor() {\n \n effect(() => {\n if (this.enableVoiceInput() && this.speechService.isActiveComponent(this.componentId)) {\n const transcript = this.speechService.transcript();\n const text = transcript.finalized + transcript.interim;\n \n this.control().setValue(text);\n }\n });\n\n \n effect(() => {\n const autoMode = this.speechService.autoModeEnabled();\n const selectedId = this.speechService.selectedSessionId();\n const sid = this.sessionId();\n if (autoMode && sid && selectedId === sid) {\n \n untracked(() => this.speechService.activateComponent(this.componentId));\n } else if (autoMode && sid && selectedId !== sid) {\n \n untracked(() => this.send());\n }\n });\n }\n\n onCompositionStart() {\n this.isComposing = true;\n this.enterPressedDuringComposition = false;\n }\n\n onCompositionEnd() {\n this.isComposing = false;\n \n \n if (this.enterPressedDuringComposition) {\n this.enterPressedDuringComposition = false;\n setTimeout(() => this.send(), 0);\n }\n }\n\n handleKeydown(event: KeyboardEvent) {\n if (this.isComposing) {\n \n if (event.key === 'Enter' && !event.shiftKey) {\n this.enterPressedDuringComposition = true;\n }\n return;\n }\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.send();\n }\n }\n\n onInput() {\n this.adjustTextareaHeight();\n }\n\n send() {\n const value = this.control().value.trim();\n if (value) {\n this.action.emit({ id: ActionId.SEND, payload: value });\n if (this.clearOnSend()) {\n this.control().reset();\n this.resetTextareaHeight();\n \n if (this.isRecording()) {\n this.speechService.clear();\n }\n }\n }\n }\n\n private adjustTextareaHeight() {\n const textarea = this.inputField()?.nativeElement;\n if (textarea) {\n \n textarea.style.overflow = 'hidden';\n \n textarea.style.height = '0px';\n \n const newHeight = Math.min(textarea.scrollHeight, 200);\n textarea.style.height = `${newHeight}px`;\n \n textarea.style.overflow = 'auto';\n }\n }\n\n private resetTextareaHeight() {\n const textarea = this.inputField()?.nativeElement;\n if (textarea) {\n textarea.style.height = 'auto';\n }\n }\n\n focus() {\n this.inputField()?.nativeElement?.focus();\n }\n\n toggleVoiceInput() {\n this.speechService.toggle(this.componentId);\n }\n}\n","<div class=\"input-line\">\n <span class=\"input-prefix\">{{ prefix() }}</span>\n <div class=\"input-container\">\n <textarea\n #inputField\n class=\"terminal-input\"\n [formControl]=\"control()\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"handleKeydown($event)\"\n (input)=\"onInput()\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n rows=\"1\"\n ></textarea>\n </div>\n @if (enableVoiceInput() && speechService.isSupported) {\n <button\n mat-icon-button\n (click)=\"toggleVoiceInput()\"\n [matTooltip]=\"isRecording() ? '音声入力停止' : '音声入力'\"\n [class.recording]=\"isRecording()\">\n <mat-icon>{{ isRecording() ? 'mic' : 'mic_none' }}</mat-icon>\n </button>\n }\n <button mat-icon-button (click)=\"send()\" matTooltip=\"送信\">\n <mat-icon>send</mat-icon>\n </button>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -11,7 +11,6 @@ import { toSignal } from '@angular/core/rxjs-interop';
11
11
 
12
12
  class VideoTrimmerSectionOrganismStore {
13
13
  images = input([], ...(ngDevMode ? [{ debugName: "images" }] : []));
14
- // blobをcomputedでimageのsrcに変換する
15
14
  imageSrcList = computed(() => (this.images() ?? []).map(blob => URL.createObjectURL(blob)), ...(ngDevMode ? [{ debugName: "imageSrcList" }] : []));
16
15
  control = input(inject(FormBuilder).group({
17
16
  duration: [0],
@@ -23,11 +22,9 @@ class VideoTrimmerSectionOrganismStore {
23
22
  width = toSignal(this.width$);
24
23
  frameSize = computed(() => Math.round(this.width() / 100), ...(ngDevMode ? [{ debugName: "frameSize" }] : []));
25
24
  frames = computed(() => {
26
- // frameSizeの数だけimageSrcListを分割する
27
25
  const frameSize = this.frameSize();
28
26
  const images = this.imageSrcList().map(src => [...Array(this.frameSize())].map(() => src)).flat();
29
27
  console.debug('images:', images.length);
30
- // imagesを均等な感覚で12枚に絞る
31
28
  const interval = Math.floor(images.length / this.frameSize());
32
29
  return images.filter((_, i) => i % interval === 0);
33
30
  }, ...(ngDevMode ? [{ debugName: "frames" }] : []));
@@ -1 +1 @@
1
- {"version":3,"file":"xxmachina-components-organisms-video-trimmer-section.mjs","sources":["../../../../../packages/@xxmachina/components/src/lib/organisms/video-trimmer-section/video-trimmer-section.organism.ts","../../../../../packages/@xxmachina/components/src/lib/organisms/video-trimmer-section/xxmachina-components-organisms-video-trimmer-section.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Directive, ElementRef, computed, inject, input } from '@angular/core';\nimport { MatSliderModule } from '@angular/material/slider';\nimport { FormBuilder, ReactiveFormsModule } from '@angular/forms';\nimport { formatSeconds } from '@ng-atomic/common/utils';\nimport { NgAtomicComponent } from '@ng-atomic/core';\nimport { fromEvent, map, startWith } from 'rxjs';\nimport { toSignal } from '@angular/core/rxjs-interop';\n\n@Directive({ standalone: true })\nexport class VideoTrimmerSectionOrganismStore {\n readonly images = input<Blob[]>([]);\n // blobをcomputedでimageのsrcに変換する\n readonly imageSrcList = computed(() => (this.images() ?? []).map(blob => URL.createObjectURL(blob)));\n\n readonly control = input(inject(FormBuilder).group({\n duration: [0],\n start: [0],\n end: [100],\n }));\n\n readonly el = inject(ElementRef);\n readonly width$ = fromEvent(window, 'resize').pipe(\n startWith(null),\n map(() => this.el.nativeElement.clientWidth),\n );\n readonly width = toSignal(this.width$);\n\n readonly frameSize = computed(() => Math.round(this.width() / 100));\n\n readonly frames = computed(() => {\n // frameSizeの数だけimageSrcListを分割する\n const frameSize = this.frameSize();\n const images = this.imageSrcList().map(src => [...Array(this.frameSize())].map(() => src)).flat();\n console.debug('images:', images.length);\n // imagesを均等な感覚で12枚に絞る\n const interval = Math.floor(images.length / this.frameSize());\n return images.filter((_, i) => i % interval === 0);\n });\n}\n\n@Component({\n selector: 'organisms-video-trimmer-section',\n standalone: true,\n imports: [\n MatSliderModule,\n ReactiveFormsModule,\n ],\n template: `\n <div class=\"frames\">\n @for (image of store.frames(); track image) {\n <img [style.width] [src]=\"image\" />\n }\n </div>\n <mat-slider min=\"0\" max=\"100\" discrete [displayWith]=\"formatLabel\">\n <input [formControl]=\"store.control().get(['start'])\" matSliderStartThumb>\n <input [formControl]=\"store.control().get(['end'])\" matSliderEndThumb>\n </mat-slider>\n `,\n styleUrls: ['./video-trimmer-section.organism.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n hostDirectives: [\n {\n directive: VideoTrimmerSectionOrganismStore,\n inputs: ['images', 'control'],\n }\n ]\n})\nexport class VideoTrimmerSectionOrganism extends NgAtomicComponent {\n protected store = inject(VideoTrimmerSectionOrganismStore);\n\n formatLabel = (value: number): string => {\n const seconds = Math.round(value / 100 * this.store.control().value.duration!);\n return formatSeconds(seconds);\n }\n}\n\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xxmachina-components-organisms-video-trimmer-section.mjs","sources":["../../../../../packages/@xxmachina/components/src/lib/organisms/video-trimmer-section/video-trimmer-section.organism.ts","../../../../../packages/@xxmachina/components/src/lib/organisms/video-trimmer-section/xxmachina-components-organisms-video-trimmer-section.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Directive, ElementRef, computed, inject, input } from '@angular/core';\nimport { MatSliderModule } from '@angular/material/slider';\nimport { FormBuilder, ReactiveFormsModule } from '@angular/forms';\nimport { formatSeconds } from '@ng-atomic/common/utils';\nimport { NgAtomicComponent } from '@ng-atomic/core';\nimport { fromEvent, map, startWith } from 'rxjs';\nimport { toSignal } from '@angular/core/rxjs-interop';\n\n@Directive({ standalone: true })\nexport class VideoTrimmerSectionOrganismStore {\n readonly images = input<Blob[]>([]);\n \n readonly imageSrcList = computed(() => (this.images() ?? []).map(blob => URL.createObjectURL(blob)));\n\n readonly control = input(inject(FormBuilder).group({\n duration: [0],\n start: [0],\n end: [100],\n }));\n\n readonly el = inject(ElementRef);\n readonly width$ = fromEvent(window, 'resize').pipe(\n startWith(null),\n map(() => this.el.nativeElement.clientWidth),\n );\n readonly width = toSignal(this.width$);\n\n readonly frameSize = computed(() => Math.round(this.width() / 100));\n\n readonly frames = computed(() => {\n \n const frameSize = this.frameSize();\n const images = this.imageSrcList().map(src => [...Array(this.frameSize())].map(() => src)).flat();\n console.debug('images:', images.length);\n \n const interval = Math.floor(images.length / this.frameSize());\n return images.filter((_, i) => i % interval === 0);\n });\n}\n\n@Component({\n selector: 'organisms-video-trimmer-section',\n standalone: true,\n imports: [\n MatSliderModule,\n ReactiveFormsModule,\n ],\n template: `\n <div class=\"frames\">\n @for (image of store.frames(); track image) {\n <img [style.width] [src]=\"image\" />\n }\n </div>\n <mat-slider min=\"0\" max=\"100\" discrete [displayWith]=\"formatLabel\">\n <input [formControl]=\"store.control().get(['start'])\" matSliderStartThumb>\n <input [formControl]=\"store.control().get(['end'])\" matSliderEndThumb>\n </mat-slider>\n `,\n styleUrls: ['./video-trimmer-section.organism.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n hostDirectives: [\n {\n directive: VideoTrimmerSectionOrganismStore,\n inputs: ['images', 'control'],\n }\n ]\n})\nexport class VideoTrimmerSectionOrganism extends NgAtomicComponent {\n protected store = inject(VideoTrimmerSectionOrganismStore);\n\n formatLabel = (value: number): string => {\n const seconds = Math.round(value / 100 * this.store.control().value.duration!);\n return formatSeconds(seconds);\n }\n}\n\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}