cjm-transcript-segment-align 0.0.10__tar.gz → 0.0.12__tar.gz
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.
- {cjm_transcript_segment_align-0.0.10/cjm_transcript_segment_align.egg-info → cjm_transcript_segment_align-0.0.12}/PKG-INFO +33 -45
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/README.md +20 -21
- cjm_transcript_segment_align-0.0.12/cjm_transcript_segment_align/__init__.py +1 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/handlers.py +37 -20
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/step_renderer.py +36 -36
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/html_ids.py +1 -1
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/routes/chrome.py +34 -31
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12/cjm_transcript_segment_align.egg-info}/PKG-INFO +33 -45
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align.egg-info/SOURCES.txt +0 -3
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align.egg-info/requires.txt +2 -3
- cjm_transcript_segment_align-0.0.12/pyproject.toml +30 -0
- cjm_transcript_segment_align-0.0.10/cjm_transcript_segment_align/__init__.py +0 -1
- cjm_transcript_segment_align-0.0.10/cjm_transcript_segment_align.egg-info/not-zip-safe +0 -1
- cjm_transcript_segment_align-0.0.10/pyproject.toml +0 -11
- cjm_transcript_segment_align-0.0.10/settings.ini +0 -38
- cjm_transcript_segment_align-0.0.10/setup.py +0 -63
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/LICENSE +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/MANIFEST.in +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/_modidx.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/__init__.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/helpers.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/keyboard_config.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/sync_controls.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/toolbar_state.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/models.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/routes/__init__.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/routes/forced_alignment.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/routes/init.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/services/__init__.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/services/forced_alignment.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align.egg-info/dependency_links.txt +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align.egg-info/entry_points.txt +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align.egg-info/top_level.txt +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/setup.cfg +0 -0
|
@@ -1,38 +1,27 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: cjm-transcript-segment-align
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.12
|
|
4
4
|
Summary: FastHTML dual-column text segmentation & VAD alignment UI for transcript decomposition workflows with forced alignment-based text splitting for aligning text segments with VAD chunks.
|
|
5
|
-
|
|
6
|
-
Author: Christian J. Mills
|
|
7
|
-
Author-email: 9126128+cj-mills@users.noreply.github.com
|
|
5
|
+
Author-email: "Christian J. Mills" <9126128+cj-mills@users.noreply.github.com>
|
|
8
6
|
License: Apache-2.0
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
Project-URL: Repository, https://github.com/cj-mills/cjm-transcript-segment-align
|
|
8
|
+
Project-URL: Documentation, https://cj-mills.github.io/cjm-transcript-segment-align
|
|
9
|
+
Keywords: nbdev,jupyter,notebook,python
|
|
12
10
|
Classifier: Natural Language :: English
|
|
13
|
-
Classifier:
|
|
14
|
-
Classifier:
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
15
|
Requires-Python: >=3.12
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: cjm-plugin-system
|
|
19
19
|
Requires-Dist: cjm_transcription_plugin_system
|
|
20
20
|
Requires-Dist: cjm_transcript_segmentation
|
|
21
|
-
Requires-Dist: cjm_transcript_vad_align
|
|
21
|
+
Requires-Dist: cjm_transcript_vad_align>=0.0.15
|
|
22
22
|
Requires-Dist: cjm_fasthtml_job_monitor
|
|
23
|
-
|
|
24
|
-
Dynamic:
|
|
25
|
-
Dynamic: author-email
|
|
26
|
-
Dynamic: classifier
|
|
27
|
-
Dynamic: description
|
|
28
|
-
Dynamic: description-content-type
|
|
29
|
-
Dynamic: home-page
|
|
30
|
-
Dynamic: keywords
|
|
31
|
-
Dynamic: license
|
|
32
|
-
Dynamic: provides-extra
|
|
33
|
-
Dynamic: requires-dist
|
|
34
|
-
Dynamic: requires-python
|
|
35
|
-
Dynamic: summary
|
|
23
|
+
Requires-Dist: cjm_fasthtml_web_audio>=0.0.8
|
|
24
|
+
Dynamic: license-file
|
|
36
25
|
|
|
37
26
|
# cjm-transcript-segment-align
|
|
38
27
|
|
|
@@ -83,35 +72,35 @@ graph LR
|
|
|
83
72
|
routes_init[routes.init<br/>routes/init]
|
|
84
73
|
services_forced_alignment[services.forced_alignment<br/>forced_alignment]
|
|
85
74
|
|
|
86
|
-
components_handlers --> html_ids
|
|
87
|
-
components_handlers --> components_keyboard_config
|
|
88
|
-
components_handlers --> components_step_renderer
|
|
89
|
-
components_handlers --> services_forced_alignment
|
|
90
75
|
components_handlers --> components_sync_controls
|
|
91
76
|
components_handlers --> routes_forced_alignment
|
|
92
|
-
|
|
77
|
+
components_handlers --> components_step_renderer
|
|
78
|
+
components_handlers --> services_forced_alignment
|
|
79
|
+
components_handlers --> components_keyboard_config
|
|
80
|
+
components_handlers --> html_ids
|
|
93
81
|
components_keyboard_config --> components_sync_controls
|
|
94
|
-
|
|
82
|
+
components_keyboard_config --> html_ids
|
|
95
83
|
components_step_renderer --> components_helpers
|
|
96
|
-
components_step_renderer --> components_sync_controls
|
|
97
|
-
components_step_renderer --> components_keyboard_config
|
|
98
84
|
components_step_renderer --> components_toolbar_state
|
|
85
|
+
components_step_renderer --> html_ids
|
|
86
|
+
components_step_renderer --> components_keyboard_config
|
|
87
|
+
components_step_renderer --> components_sync_controls
|
|
99
88
|
components_toolbar_state --> components_sync_controls
|
|
100
|
-
routes_chrome --> html_ids
|
|
101
|
-
routes_chrome --> components_handlers
|
|
102
89
|
routes_chrome --> components_sync_controls
|
|
90
|
+
routes_chrome --> components_handlers
|
|
91
|
+
routes_chrome --> html_ids
|
|
103
92
|
routes_chrome --> components_step_renderer
|
|
104
|
-
routes_forced_alignment --> html_ids
|
|
105
|
-
routes_forced_alignment --> components_step_renderer
|
|
106
93
|
routes_forced_alignment --> components_sync_controls
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
routes_init -->
|
|
94
|
+
routes_forced_alignment --> components_step_renderer
|
|
95
|
+
routes_forced_alignment --> html_ids
|
|
96
|
+
routes_init --> routes_forced_alignment
|
|
110
97
|
routes_init --> models
|
|
98
|
+
routes_init --> components_handlers
|
|
99
|
+
routes_init --> components_keyboard_config
|
|
111
100
|
routes_init --> services_forced_alignment
|
|
112
|
-
routes_init --> components_sync_controls
|
|
113
101
|
routes_init --> components_step_renderer
|
|
114
|
-
routes_init -->
|
|
102
|
+
routes_init --> html_ids
|
|
103
|
+
routes_init --> components_sync_controls
|
|
115
104
|
routes_init --> routes_chrome
|
|
116
105
|
```
|
|
117
106
|
|
|
@@ -157,6 +146,7 @@ async def _handle_switch_chrome(
|
|
|
157
146
|
|
|
158
147
|
Client-side toolbar state restoration (sync button, auto-play toggle)
|
|
159
148
|
is handled by the centralized settle handler from toolbar_state.py.
|
|
149
|
+
Settings modals persist in the DOM — only the trigger buttons swap.
|
|
160
150
|
"""
|
|
161
151
|
```
|
|
162
152
|
|
|
@@ -479,9 +469,6 @@ def create_seg_mutation_wrapper(
|
|
|
479
469
|
Calls the _result handler variant, builds targeted OOB response with FA
|
|
480
470
|
controls in toolbar, and appends alignment status + mini-stats OOB.
|
|
481
471
|
Computes nltk_split_disabled from state for toolbar rendering.
|
|
482
|
-
|
|
483
|
-
When clear_fa_presplit=True (used for NLTK Split), clears the FA pre-split
|
|
484
|
-
snapshot so the toggle is replaced with the Force Align button.
|
|
485
472
|
"""
|
|
486
473
|
```
|
|
487
474
|
|
|
@@ -509,6 +496,7 @@ def create_seg_init_chrome_wrapper(
|
|
|
509
496
|
|
|
510
497
|
Saves nltk_presplit snapshot at init time for match detection.
|
|
511
498
|
FA controls are rendered in the toolbar via extra_actions.
|
|
499
|
+
Settings modals are rendered in a persistent container (both seg + align).
|
|
512
500
|
"""
|
|
513
501
|
```
|
|
514
502
|
|
|
@@ -842,7 +830,7 @@ def _render_shared_chrome(
|
|
|
842
830
|
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
|
|
843
831
|
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
|
|
844
832
|
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
|
|
845
|
-
) -> tuple: # (toolbar,
|
|
833
|
+
) -> tuple: # (toolbar, footer, settings_modals_container)
|
|
846
834
|
"""
|
|
847
835
|
Render shared chrome containers, populated with segmentation content when initialized.
|
|
848
836
|
|
|
@@ -47,35 +47,35 @@ graph LR
|
|
|
47
47
|
routes_init[routes.init<br/>routes/init]
|
|
48
48
|
services_forced_alignment[services.forced_alignment<br/>forced_alignment]
|
|
49
49
|
|
|
50
|
-
components_handlers --> html_ids
|
|
51
|
-
components_handlers --> components_keyboard_config
|
|
52
|
-
components_handlers --> components_step_renderer
|
|
53
|
-
components_handlers --> services_forced_alignment
|
|
54
50
|
components_handlers --> components_sync_controls
|
|
55
51
|
components_handlers --> routes_forced_alignment
|
|
56
|
-
|
|
52
|
+
components_handlers --> components_step_renderer
|
|
53
|
+
components_handlers --> services_forced_alignment
|
|
54
|
+
components_handlers --> components_keyboard_config
|
|
55
|
+
components_handlers --> html_ids
|
|
57
56
|
components_keyboard_config --> components_sync_controls
|
|
58
|
-
|
|
57
|
+
components_keyboard_config --> html_ids
|
|
59
58
|
components_step_renderer --> components_helpers
|
|
60
|
-
components_step_renderer --> components_sync_controls
|
|
61
|
-
components_step_renderer --> components_keyboard_config
|
|
62
59
|
components_step_renderer --> components_toolbar_state
|
|
60
|
+
components_step_renderer --> html_ids
|
|
61
|
+
components_step_renderer --> components_keyboard_config
|
|
62
|
+
components_step_renderer --> components_sync_controls
|
|
63
63
|
components_toolbar_state --> components_sync_controls
|
|
64
|
-
routes_chrome --> html_ids
|
|
65
|
-
routes_chrome --> components_handlers
|
|
66
64
|
routes_chrome --> components_sync_controls
|
|
65
|
+
routes_chrome --> components_handlers
|
|
66
|
+
routes_chrome --> html_ids
|
|
67
67
|
routes_chrome --> components_step_renderer
|
|
68
|
-
routes_forced_alignment --> html_ids
|
|
69
|
-
routes_forced_alignment --> components_step_renderer
|
|
70
68
|
routes_forced_alignment --> components_sync_controls
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
routes_init -->
|
|
69
|
+
routes_forced_alignment --> components_step_renderer
|
|
70
|
+
routes_forced_alignment --> html_ids
|
|
71
|
+
routes_init --> routes_forced_alignment
|
|
74
72
|
routes_init --> models
|
|
73
|
+
routes_init --> components_handlers
|
|
74
|
+
routes_init --> components_keyboard_config
|
|
75
75
|
routes_init --> services_forced_alignment
|
|
76
|
-
routes_init --> components_sync_controls
|
|
77
76
|
routes_init --> components_step_renderer
|
|
78
|
-
routes_init -->
|
|
77
|
+
routes_init --> html_ids
|
|
78
|
+
routes_init --> components_sync_controls
|
|
79
79
|
routes_init --> routes_chrome
|
|
80
80
|
```
|
|
81
81
|
|
|
@@ -121,6 +121,7 @@ async def _handle_switch_chrome(
|
|
|
121
121
|
|
|
122
122
|
Client-side toolbar state restoration (sync button, auto-play toggle)
|
|
123
123
|
is handled by the centralized settle handler from toolbar_state.py.
|
|
124
|
+
Settings modals persist in the DOM — only the trigger buttons swap.
|
|
124
125
|
"""
|
|
125
126
|
```
|
|
126
127
|
|
|
@@ -443,9 +444,6 @@ def create_seg_mutation_wrapper(
|
|
|
443
444
|
Calls the _result handler variant, builds targeted OOB response with FA
|
|
444
445
|
controls in toolbar, and appends alignment status + mini-stats OOB.
|
|
445
446
|
Computes nltk_split_disabled from state for toolbar rendering.
|
|
446
|
-
|
|
447
|
-
When clear_fa_presplit=True (used for NLTK Split), clears the FA pre-split
|
|
448
|
-
snapshot so the toggle is replaced with the Force Align button.
|
|
449
447
|
"""
|
|
450
448
|
```
|
|
451
449
|
|
|
@@ -473,6 +471,7 @@ def create_seg_init_chrome_wrapper(
|
|
|
473
471
|
|
|
474
472
|
Saves nltk_presplit snapshot at init time for match detection.
|
|
475
473
|
FA controls are rendered in the toolbar via extra_actions.
|
|
474
|
+
Settings modals are rendered in a persistent container (both seg + align).
|
|
476
475
|
"""
|
|
477
476
|
```
|
|
478
477
|
|
|
@@ -806,7 +805,7 @@ def _render_shared_chrome(
|
|
|
806
805
|
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
|
|
807
806
|
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
|
|
808
807
|
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
|
|
809
|
-
) -> tuple: # (toolbar,
|
|
808
|
+
) -> tuple: # (toolbar, footer, settings_modals_container)
|
|
810
809
|
"""
|
|
811
810
|
Render shared chrome containers, populated with segmentation content when initialized.
|
|
812
811
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.12"
|
|
@@ -16,10 +16,12 @@ from typing import Callable, Any, Dict, List, Optional, Tuple
|
|
|
16
16
|
from fasthtml.common import Div, Span, Button, FT
|
|
17
17
|
|
|
18
18
|
from cjm_fasthtml_interactions.core.state_store import get_session_id
|
|
19
|
-
from cjm_fasthtml_card_stack.components.
|
|
19
|
+
from cjm_fasthtml_card_stack.components.settings_modal import render_card_stack_settings_modal, render_settings_trigger
|
|
20
20
|
from cjm_fasthtml_card_stack.core.constants import DEFAULT_VISIBLE_COUNT
|
|
21
21
|
from cjm_fasthtml_daisyui.components.data_display.badge import badge, badge_styles, badge_sizes
|
|
22
|
+
from cjm_fasthtml_tailwind.utilities.sizing import w
|
|
22
23
|
from cjm_fasthtml_tailwind.utilities.layout import display_tw
|
|
24
|
+
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import flex_display, items, gap
|
|
23
25
|
from cjm_fasthtml_tailwind.core.base import combine_classes
|
|
24
26
|
|
|
25
27
|
from ..html_ids import CombinedHtmlIds
|
|
@@ -277,9 +279,6 @@ def create_seg_mutation_wrapper(
|
|
|
277
279
|
Calls the _result handler variant, builds targeted OOB response with FA
|
|
278
280
|
controls in toolbar, and appends alignment status + mini-stats OOB.
|
|
279
281
|
Computes nltk_split_disabled from state for toolbar rendering.
|
|
280
|
-
|
|
281
|
-
When clear_fa_presplit=True (used for NLTK Split), clears the FA pre-split
|
|
282
|
-
snapshot so the toggle is replaced with the Force Align button.
|
|
283
282
|
"""
|
|
284
283
|
@wraps(handler_result)
|
|
285
284
|
async def wrapped(
|
|
@@ -333,7 +332,7 @@ def create_seg_mutation_wrapper(
|
|
|
333
332
|
urls = kwargs.get("urls")
|
|
334
333
|
seg_oob = build_mutation_response(
|
|
335
334
|
result.segment_dicts, result.focused_index, result.visible_count,
|
|
336
|
-
result.history_depth, urls,
|
|
335
|
+
result.history_depth, urls,
|
|
337
336
|
extra_actions=build_extra_actions(fa_extra), nltk_split_disabled=nltk_disabled,
|
|
338
337
|
)
|
|
339
338
|
|
|
@@ -341,7 +340,6 @@ def create_seg_mutation_wrapper(
|
|
|
341
340
|
|
|
342
341
|
return wrapped
|
|
343
342
|
|
|
344
|
-
|
|
345
343
|
# %% ../../nbs/components/handlers.ipynb #f6a7b8c9
|
|
346
344
|
def wrap_align_mutation_handler(
|
|
347
345
|
handler: Callable, # Handler function to wrap
|
|
@@ -388,6 +386,7 @@ def create_seg_init_chrome_wrapper(
|
|
|
388
386
|
|
|
389
387
|
Saves nltk_presplit snapshot at init time for match detection.
|
|
390
388
|
FA controls are rendered in the toolbar via extra_actions.
|
|
389
|
+
Settings modals are rendered in a persistent container (both seg + align).
|
|
391
390
|
"""
|
|
392
391
|
async def wrapped_seg_init(
|
|
393
392
|
state_store:WorkflowStateStore,
|
|
@@ -455,24 +454,43 @@ def create_seg_init_chrome_wrapper(
|
|
|
455
454
|
seg_state, jm_trigger, fa_toggle_url, fa_available,
|
|
456
455
|
)
|
|
457
456
|
|
|
458
|
-
#
|
|
457
|
+
# Settings modal trigger for seg column
|
|
458
|
+
settings_trigger = render_settings_trigger(modal_id=SEG_CS_IDS.settings_modal)
|
|
459
|
+
|
|
460
|
+
# Toolbar OOB (settings trigger + toolbar with FA controls, NLTK Split disabled at init)
|
|
459
461
|
toolbar_oob = Div(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
462
|
+
Div(
|
|
463
|
+
settings_trigger,
|
|
464
|
+
render_toolbar(
|
|
465
|
+
reset_url=urls.reset, ai_split_url=urls.ai_split, undo_url=urls.undo,
|
|
466
|
+
can_undo=(result.history_depth > 0),
|
|
467
|
+
extra_actions=build_extra_actions(fa_extra),
|
|
468
|
+
nltk_split_disabled=True,
|
|
469
|
+
),
|
|
470
|
+
cls=combine_classes(flex_display, items.center, gap(2), w.full),
|
|
467
471
|
),
|
|
468
472
|
id=CombinedHtmlIds.SHARED_TOOLBAR,
|
|
469
473
|
hx_swap_oob="innerHTML"
|
|
470
474
|
)
|
|
471
475
|
|
|
472
|
-
#
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
+
# Settings modals OOB (both seg + align persist in DOM)
|
|
477
|
+
from cjm_transcript_vad_align.components.card_stack_config import (
|
|
478
|
+
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
479
|
+
)
|
|
480
|
+
seg_modal, _ = render_card_stack_settings_modal(
|
|
481
|
+
SEG_CS_CONFIG, SEG_CS_IDS,
|
|
482
|
+
current_count=result.visible_count,
|
|
483
|
+
card_width=result.card_width,
|
|
484
|
+
)
|
|
485
|
+
align_modal, _ = render_card_stack_settings_modal(
|
|
486
|
+
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
487
|
+
current_count=align_state.get("visible_count", 5),
|
|
488
|
+
card_width=align_state.get("card_width", 40),
|
|
489
|
+
)
|
|
490
|
+
settings_modals_oob = Div(
|
|
491
|
+
seg_modal,
|
|
492
|
+
align_modal,
|
|
493
|
+
id=CombinedHtmlIds.SETTINGS_MODALS,
|
|
476
494
|
hx_swap_oob="innerHTML"
|
|
477
495
|
)
|
|
478
496
|
|
|
@@ -499,12 +517,11 @@ def create_seg_init_chrome_wrapper(
|
|
|
499
517
|
|
|
500
518
|
return (
|
|
501
519
|
result.column_body, kb_system_oob, zone_change_js, chrome_switch_btn,
|
|
502
|
-
toolbar_oob,
|
|
520
|
+
toolbar_oob, settings_modals_oob, footer_oob, mini_stats_oob,
|
|
503
521
|
)
|
|
504
522
|
|
|
505
523
|
return wrapped_seg_init
|
|
506
524
|
|
|
507
|
-
|
|
508
525
|
# %% ../../nbs/components/handlers.ipynb #ecvyiypdxk
|
|
509
526
|
def create_align_init_chrome_wrapper(
|
|
510
527
|
should_play_fn:str="", # Consumer-defined play guard function name
|
|
@@ -35,8 +35,8 @@ from cjm_fasthtml_tailwind.core.base import combine_classes
|
|
|
35
35
|
from cjm_fasthtml_interactions.core.context import InteractionContext
|
|
36
36
|
|
|
37
37
|
# Card stack library
|
|
38
|
-
from cjm_fasthtml_card_stack.components.controls import render_width_slider
|
|
39
38
|
from cjm_fasthtml_card_stack.components.states import render_loading_state
|
|
39
|
+
from cjm_fasthtml_card_stack.components.settings_modal import render_card_stack_settings_modal
|
|
40
40
|
from cjm_fasthtml_card_stack.core.constants import DEFAULT_VISIBLE_COUNT, DEFAULT_CARD_WIDTH
|
|
41
41
|
|
|
42
42
|
# Local imports
|
|
@@ -63,7 +63,7 @@ from cjm_transcript_vad_align.components.step_renderer import (
|
|
|
63
63
|
render_align_footer_content,
|
|
64
64
|
)
|
|
65
65
|
from cjm_transcript_vad_align.components.card_stack_config import (
|
|
66
|
-
ALIGN_CS_IDS,
|
|
66
|
+
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
67
67
|
)
|
|
68
68
|
|
|
69
69
|
# Shared keyboard config (combined-level)
|
|
@@ -88,7 +88,6 @@ from .toolbar_state import generate_toolbar_restore_js
|
|
|
88
88
|
# Debug flag for combined step rendering tracing (set False in production)
|
|
89
89
|
DEBUG_COMBINED_RENDER = True
|
|
90
90
|
|
|
91
|
-
|
|
92
91
|
# %% ../../nbs/components/step_renderer.ipynb #e5f6a7b8
|
|
93
92
|
def _render_column_header(
|
|
94
93
|
title:str, # Column title (e.g., "Text Decomposition")
|
|
@@ -227,7 +226,7 @@ def _render_shared_chrome(
|
|
|
227
226
|
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
|
|
228
227
|
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
|
|
229
228
|
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
|
|
230
|
-
) -> tuple: # (toolbar,
|
|
229
|
+
) -> tuple: # (toolbar, footer, settings_modals_container)
|
|
231
230
|
"""Render shared chrome containers, populated with segmentation content when initialized.
|
|
232
231
|
|
|
233
232
|
Takes extracted state dicts from `extract_seg_state()` and `extract_alignment_state()`
|
|
@@ -235,19 +234,37 @@ def _render_shared_chrome(
|
|
|
235
234
|
"""
|
|
236
235
|
is_init = seg_state is not None and seg_state.get("is_initialized", False)
|
|
237
236
|
|
|
237
|
+
# --- Settings modals (both persist in DOM, triggers swap with toolbar) ---
|
|
238
|
+
seg_modal, seg_trigger = render_card_stack_settings_modal(
|
|
239
|
+
SEG_CS_CONFIG, SEG_CS_IDS,
|
|
240
|
+
current_count=seg_state.get("visible_count", DEFAULT_VISIBLE_COUNT) if seg_state else DEFAULT_VISIBLE_COUNT,
|
|
241
|
+
card_width=seg_state.get("card_width", DEFAULT_CARD_WIDTH) if seg_state else DEFAULT_CARD_WIDTH,
|
|
242
|
+
)
|
|
243
|
+
align_modal, align_trigger = render_card_stack_settings_modal(
|
|
244
|
+
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
245
|
+
current_count=align_state.get("visible_count", 5) if align_state else 5,
|
|
246
|
+
card_width=align_state.get("card_width", 40) if align_state else 40,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
settings_modals_container = Div(
|
|
250
|
+
seg_modal,
|
|
251
|
+
align_modal,
|
|
252
|
+
id=CombinedHtmlIds.SETTINGS_MODALS,
|
|
253
|
+
)
|
|
254
|
+
|
|
238
255
|
# --- Toolbar ---
|
|
239
256
|
if is_init and urls:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
257
|
+
toolbar_content = Div(
|
|
258
|
+
seg_trigger,
|
|
259
|
+
render_toolbar(
|
|
260
|
+
reset_url=urls.reset,
|
|
261
|
+
ai_split_url=urls.ai_split,
|
|
262
|
+
undo_url=urls.undo,
|
|
263
|
+
can_undo=(len(seg_state.get("history", [])) > 0),
|
|
264
|
+
extra_actions=extra_actions,
|
|
265
|
+
nltk_split_disabled=nltk_split_disabled,
|
|
266
|
+
),
|
|
267
|
+
cls=combine_classes(flex_display, items.center, gap(2), w.full),
|
|
251
268
|
)
|
|
252
269
|
else:
|
|
253
270
|
toolbar_content = _placeholder("Toolbar actions will appear here based on the active column.")
|
|
@@ -258,22 +275,7 @@ def _render_shared_chrome(
|
|
|
258
275
|
cls=str(p(2))
|
|
259
276
|
)
|
|
260
277
|
|
|
261
|
-
# --- Controls ---
|
|
262
|
-
if is_init:
|
|
263
|
-
card_width = seg_state.get("card_width", DEFAULT_CARD_WIDTH)
|
|
264
|
-
controls_content = render_width_slider(SEG_CS_CONFIG, SEG_CS_IDS, card_width=card_width)
|
|
265
|
-
else:
|
|
266
|
-
controls_content = _placeholder("Column-specific controls will appear here.")
|
|
267
|
-
|
|
268
|
-
controls = Div(
|
|
269
|
-
controls_content,
|
|
270
|
-
id=CombinedHtmlIds.SHARED_CONTROLS,
|
|
271
|
-
cls=str(p(2))
|
|
272
|
-
)
|
|
273
|
-
|
|
274
278
|
# --- Footer with both column footers + alignment status ---
|
|
275
|
-
# Note: seg_state["segments"] and align_state["vad_chunks"] are already deserialized
|
|
276
|
-
# objects from extract_seg_state/extract_alignment_state — don't call from_dict() again
|
|
277
279
|
seg_segments = seg_state.get("segments", []) if seg_state else []
|
|
278
280
|
segment_count = len(seg_segments)
|
|
279
281
|
align_chunks = align_state.get("vad_chunks", []) if align_state else []
|
|
@@ -306,8 +308,7 @@ def _render_shared_chrome(
|
|
|
306
308
|
)
|
|
307
309
|
)
|
|
308
310
|
|
|
309
|
-
return toolbar,
|
|
310
|
-
|
|
311
|
+
return toolbar, footer, settings_modals_container
|
|
311
312
|
|
|
312
313
|
# %% ../../nbs/components/step_renderer.ipynb #c9d0e1f2
|
|
313
314
|
# Shared column styling (reused by init handler for outerHTML swap)
|
|
@@ -528,7 +529,7 @@ def render_combined_step(
|
|
|
528
529
|
)
|
|
529
530
|
mini_stats_text = render_seg_mini_stats_text(segments)
|
|
530
531
|
|
|
531
|
-
toolbar,
|
|
532
|
+
toolbar, footer, settings_modals_container = _render_shared_chrome(
|
|
532
533
|
seg_state=seg_state,
|
|
533
534
|
align_state=align_state,
|
|
534
535
|
urls=seg_urls,
|
|
@@ -542,7 +543,7 @@ def render_combined_step(
|
|
|
542
543
|
mini_stats_text=mini_stats_text,
|
|
543
544
|
)
|
|
544
545
|
else:
|
|
545
|
-
toolbar,
|
|
546
|
+
toolbar, footer, settings_modals_container = _render_shared_chrome(
|
|
546
547
|
align_state=align_state,
|
|
547
548
|
)
|
|
548
549
|
seg_col = _render_seg_column(
|
|
@@ -630,7 +631,6 @@ def render_combined_step(
|
|
|
630
631
|
cls=combine_classes(flex_display, items.start, justify.between),
|
|
631
632
|
),
|
|
632
633
|
toolbar,
|
|
633
|
-
controls,
|
|
634
634
|
Div(
|
|
635
635
|
*columns_children,
|
|
636
636
|
id=CombinedHtmlIds.COLUMNS,
|
|
@@ -649,6 +649,7 @@ def render_combined_step(
|
|
|
649
649
|
toolbar_restore_script,
|
|
650
650
|
chrome_switch_btn,
|
|
651
651
|
active_column_input,
|
|
652
|
+
settings_modals_container, # Both settings modals persist in DOM
|
|
652
653
|
jm_modal_el, # Job monitor modal (page-level, outside columns)
|
|
653
654
|
jm_kb_script_el, # Job monitor keyboard script placeholder (for OOB pause/resume)
|
|
654
655
|
hints_modal, # Keyboard hints modal dialog
|
|
@@ -660,4 +661,3 @@ def render_combined_step(
|
|
|
660
661
|
p(4), p.x(2), p.b(0)
|
|
661
662
|
)
|
|
662
663
|
)
|
|
663
|
-
|
|
@@ -21,9 +21,9 @@ class CombinedHtmlIds:
|
|
|
21
21
|
# Shared Chrome
|
|
22
22
|
SHARED_HINTS = "sd-shared-hints"
|
|
23
23
|
SHARED_TOOLBAR = "sd-shared-toolbar"
|
|
24
|
-
SHARED_CONTROLS = "sd-shared-controls"
|
|
25
24
|
SHARED_FOOTER = "sd-shared-footer"
|
|
26
25
|
ALIGNMENT_STATUS = "sd-alignment-status"
|
|
26
|
+
SETTINGS_MODALS = "sd-settings-modals"
|
|
27
27
|
|
|
28
28
|
# Segmentation Column
|
|
29
29
|
SEG_COLUMN = "sd-seg-column"
|
|
@@ -10,7 +10,7 @@ from typing import Tuple, Dict, Callable
|
|
|
10
10
|
|
|
11
11
|
from fasthtml.common import APIRouter, Div
|
|
12
12
|
|
|
13
|
-
from cjm_fasthtml_card_stack.components.
|
|
13
|
+
from cjm_fasthtml_card_stack.components.settings_modal import render_settings_trigger
|
|
14
14
|
from cjm_fasthtml_card_stack.core.constants import DEFAULT_VISIBLE_COUNT, DEFAULT_CARD_WIDTH
|
|
15
15
|
|
|
16
16
|
from cjm_fasthtml_interactions.core.state_store import get_session_id
|
|
@@ -38,6 +38,12 @@ from cjm_transcript_vad_align.components.card_stack_config import (
|
|
|
38
38
|
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
+
from cjm_fasthtml_tailwind.utilities.sizing import w
|
|
42
|
+
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import (
|
|
43
|
+
flex_display, items, gap,
|
|
44
|
+
)
|
|
45
|
+
from cjm_fasthtml_tailwind.core.base import combine_classes
|
|
46
|
+
|
|
41
47
|
# Footer helper + FA extra_actions builder + match detection
|
|
42
48
|
from cjm_transcript_segment_align.components.step_renderer import (
|
|
43
49
|
render_footer_inner_content,
|
|
@@ -66,6 +72,7 @@ async def _handle_switch_chrome(
|
|
|
66
72
|
|
|
67
73
|
Client-side toolbar state restoration (sync button, auto-play toggle)
|
|
68
74
|
is handled by the centralized settle handler from toolbar_state.py.
|
|
75
|
+
Settings modals persist in the DOM — only the trigger buttons swap.
|
|
69
76
|
"""
|
|
70
77
|
form = await request.form()
|
|
71
78
|
active_column = form.get("active_column", "seg")
|
|
@@ -84,13 +91,10 @@ async def _handle_switch_chrome(
|
|
|
84
91
|
chunk_count = len(align_state.get("vad_chunks", []))
|
|
85
92
|
|
|
86
93
|
if active_column == "seg":
|
|
87
|
-
# Segmentation chrome (
|
|
94
|
+
# Segmentation chrome (settings trigger + toolbar)
|
|
88
95
|
segments = [TextSegment.from_dict(s) for s in seg_state.get("segments", [])]
|
|
89
96
|
history = seg_state.get("history", [])
|
|
90
97
|
focused_index = seg_state.get("focused_index", 0)
|
|
91
|
-
visible_count = seg_state.get("visible_count", DEFAULT_VISIBLE_COUNT)
|
|
92
|
-
is_auto_mode = seg_state.get("is_auto_mode", False)
|
|
93
|
-
card_width = seg_state.get("card_width", DEFAULT_CARD_WIDTH)
|
|
94
98
|
|
|
95
99
|
# Build FA extra_actions and NLTK Split disabled state
|
|
96
100
|
fa_extra = build_fa_extra_actions(
|
|
@@ -101,28 +105,32 @@ async def _handle_switch_chrome(
|
|
|
101
105
|
seg_state.get("segments", []), nltk_presplit,
|
|
102
106
|
)
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
settings_trigger = render_settings_trigger(modal_id=SEG_CS_IDS.settings_modal)
|
|
109
|
+
toolbar_content = Div(
|
|
110
|
+
settings_trigger,
|
|
111
|
+
render_seg_toolbar(
|
|
112
|
+
reset_url=seg_urls.reset,
|
|
113
|
+
ai_split_url=seg_urls.ai_split,
|
|
114
|
+
undo_url=seg_urls.undo,
|
|
115
|
+
can_undo=(len(history) > 0),
|
|
116
|
+
extra_actions=build_extra_actions(fa_extra),
|
|
117
|
+
nltk_split_disabled=nltk_disabled,
|
|
118
|
+
),
|
|
119
|
+
cls=combine_classes(flex_display, items.center, gap(2), w.full),
|
|
113
120
|
)
|
|
114
|
-
controls_content = render_width_slider(SEG_CS_CONFIG, SEG_CS_IDS, card_width=card_width)
|
|
115
121
|
else:
|
|
116
|
-
# Alignment chrome (
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
# Alignment chrome (settings trigger + speed selector + auto-play toggle)
|
|
123
|
+
# Read persisted state so chrome switches restore the user's current speed + auto-nav
|
|
124
|
+
settings_trigger = render_settings_trigger(modal_id=ALIGN_CS_IDS.settings_modal)
|
|
125
|
+
toolbar_content = Div(
|
|
126
|
+
settings_trigger,
|
|
127
|
+
render_align_toolbar(
|
|
128
|
+
current_speed=align_state.get("playback_speed", 1.0),
|
|
129
|
+
auto_navigate=align_state.get("auto_navigate", False),
|
|
130
|
+
speed_url=align_urls.speed_change,
|
|
131
|
+
),
|
|
132
|
+
cls=combine_classes(flex_display, items.center, gap(2), w.full),
|
|
124
133
|
)
|
|
125
|
-
controls_content = render_width_slider(ALIGN_CS_CONFIG, ALIGN_CS_IDS, card_width=card_width)
|
|
126
134
|
|
|
127
135
|
# --- Footer: both column footers always present ---
|
|
128
136
|
seg_segments = [TextSegment.from_dict(s) for s in seg_state.get("segments", [])]
|
|
@@ -136,24 +144,19 @@ async def _handle_switch_chrome(
|
|
|
136
144
|
if DEBUG_SWITCH_CHROME:
|
|
137
145
|
print(f"[SWITCH_CHROME] returning OOB swaps for {active_column}")
|
|
138
146
|
|
|
139
|
-
# Return OOB swaps
|
|
147
|
+
# Return OOB swaps (toolbar + footer — settings modals persist in DOM)
|
|
140
148
|
toolbar_oob = Div(
|
|
141
149
|
toolbar_content,
|
|
142
150
|
id=CombinedHtmlIds.SHARED_TOOLBAR,
|
|
143
151
|
hx_swap_oob="innerHTML"
|
|
144
152
|
)
|
|
145
|
-
controls_oob = Div(
|
|
146
|
-
controls_content,
|
|
147
|
-
id=CombinedHtmlIds.SHARED_CONTROLS,
|
|
148
|
-
hx_swap_oob="innerHTML"
|
|
149
|
-
)
|
|
150
153
|
footer_oob = Div(
|
|
151
154
|
render_footer_inner_content(seg_footer, align_footer, segment_count, chunk_count),
|
|
152
155
|
id=CombinedHtmlIds.SHARED_FOOTER,
|
|
153
156
|
hx_swap_oob="innerHTML"
|
|
154
157
|
)
|
|
155
158
|
|
|
156
|
-
return (toolbar_oob,
|
|
159
|
+
return (toolbar_oob, footer_oob)
|
|
157
160
|
|
|
158
161
|
# %% ../../nbs/routes/chrome.ipynb #g7b8c9d0
|
|
159
162
|
def init_chrome_router(
|
|
@@ -1,38 +1,27 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: cjm-transcript-segment-align
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.12
|
|
4
4
|
Summary: FastHTML dual-column text segmentation & VAD alignment UI for transcript decomposition workflows with forced alignment-based text splitting for aligning text segments with VAD chunks.
|
|
5
|
-
|
|
6
|
-
Author: Christian J. Mills
|
|
7
|
-
Author-email: 9126128+cj-mills@users.noreply.github.com
|
|
5
|
+
Author-email: "Christian J. Mills" <9126128+cj-mills@users.noreply.github.com>
|
|
8
6
|
License: Apache-2.0
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
Project-URL: Repository, https://github.com/cj-mills/cjm-transcript-segment-align
|
|
8
|
+
Project-URL: Documentation, https://cj-mills.github.io/cjm-transcript-segment-align
|
|
9
|
+
Keywords: nbdev,jupyter,notebook,python
|
|
12
10
|
Classifier: Natural Language :: English
|
|
13
|
-
Classifier:
|
|
14
|
-
Classifier:
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
15
|
Requires-Python: >=3.12
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: cjm-plugin-system
|
|
19
19
|
Requires-Dist: cjm_transcription_plugin_system
|
|
20
20
|
Requires-Dist: cjm_transcript_segmentation
|
|
21
|
-
Requires-Dist: cjm_transcript_vad_align
|
|
21
|
+
Requires-Dist: cjm_transcript_vad_align>=0.0.15
|
|
22
22
|
Requires-Dist: cjm_fasthtml_job_monitor
|
|
23
|
-
|
|
24
|
-
Dynamic:
|
|
25
|
-
Dynamic: author-email
|
|
26
|
-
Dynamic: classifier
|
|
27
|
-
Dynamic: description
|
|
28
|
-
Dynamic: description-content-type
|
|
29
|
-
Dynamic: home-page
|
|
30
|
-
Dynamic: keywords
|
|
31
|
-
Dynamic: license
|
|
32
|
-
Dynamic: provides-extra
|
|
33
|
-
Dynamic: requires-dist
|
|
34
|
-
Dynamic: requires-python
|
|
35
|
-
Dynamic: summary
|
|
23
|
+
Requires-Dist: cjm_fasthtml_web_audio>=0.0.8
|
|
24
|
+
Dynamic: license-file
|
|
36
25
|
|
|
37
26
|
# cjm-transcript-segment-align
|
|
38
27
|
|
|
@@ -83,35 +72,35 @@ graph LR
|
|
|
83
72
|
routes_init[routes.init<br/>routes/init]
|
|
84
73
|
services_forced_alignment[services.forced_alignment<br/>forced_alignment]
|
|
85
74
|
|
|
86
|
-
components_handlers --> html_ids
|
|
87
|
-
components_handlers --> components_keyboard_config
|
|
88
|
-
components_handlers --> components_step_renderer
|
|
89
|
-
components_handlers --> services_forced_alignment
|
|
90
75
|
components_handlers --> components_sync_controls
|
|
91
76
|
components_handlers --> routes_forced_alignment
|
|
92
|
-
|
|
77
|
+
components_handlers --> components_step_renderer
|
|
78
|
+
components_handlers --> services_forced_alignment
|
|
79
|
+
components_handlers --> components_keyboard_config
|
|
80
|
+
components_handlers --> html_ids
|
|
93
81
|
components_keyboard_config --> components_sync_controls
|
|
94
|
-
|
|
82
|
+
components_keyboard_config --> html_ids
|
|
95
83
|
components_step_renderer --> components_helpers
|
|
96
|
-
components_step_renderer --> components_sync_controls
|
|
97
|
-
components_step_renderer --> components_keyboard_config
|
|
98
84
|
components_step_renderer --> components_toolbar_state
|
|
85
|
+
components_step_renderer --> html_ids
|
|
86
|
+
components_step_renderer --> components_keyboard_config
|
|
87
|
+
components_step_renderer --> components_sync_controls
|
|
99
88
|
components_toolbar_state --> components_sync_controls
|
|
100
|
-
routes_chrome --> html_ids
|
|
101
|
-
routes_chrome --> components_handlers
|
|
102
89
|
routes_chrome --> components_sync_controls
|
|
90
|
+
routes_chrome --> components_handlers
|
|
91
|
+
routes_chrome --> html_ids
|
|
103
92
|
routes_chrome --> components_step_renderer
|
|
104
|
-
routes_forced_alignment --> html_ids
|
|
105
|
-
routes_forced_alignment --> components_step_renderer
|
|
106
93
|
routes_forced_alignment --> components_sync_controls
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
routes_init -->
|
|
94
|
+
routes_forced_alignment --> components_step_renderer
|
|
95
|
+
routes_forced_alignment --> html_ids
|
|
96
|
+
routes_init --> routes_forced_alignment
|
|
110
97
|
routes_init --> models
|
|
98
|
+
routes_init --> components_handlers
|
|
99
|
+
routes_init --> components_keyboard_config
|
|
111
100
|
routes_init --> services_forced_alignment
|
|
112
|
-
routes_init --> components_sync_controls
|
|
113
101
|
routes_init --> components_step_renderer
|
|
114
|
-
routes_init -->
|
|
102
|
+
routes_init --> html_ids
|
|
103
|
+
routes_init --> components_sync_controls
|
|
115
104
|
routes_init --> routes_chrome
|
|
116
105
|
```
|
|
117
106
|
|
|
@@ -157,6 +146,7 @@ async def _handle_switch_chrome(
|
|
|
157
146
|
|
|
158
147
|
Client-side toolbar state restoration (sync button, auto-play toggle)
|
|
159
148
|
is handled by the centralized settle handler from toolbar_state.py.
|
|
149
|
+
Settings modals persist in the DOM — only the trigger buttons swap.
|
|
160
150
|
"""
|
|
161
151
|
```
|
|
162
152
|
|
|
@@ -479,9 +469,6 @@ def create_seg_mutation_wrapper(
|
|
|
479
469
|
Calls the _result handler variant, builds targeted OOB response with FA
|
|
480
470
|
controls in toolbar, and appends alignment status + mini-stats OOB.
|
|
481
471
|
Computes nltk_split_disabled from state for toolbar rendering.
|
|
482
|
-
|
|
483
|
-
When clear_fa_presplit=True (used for NLTK Split), clears the FA pre-split
|
|
484
|
-
snapshot so the toggle is replaced with the Force Align button.
|
|
485
472
|
"""
|
|
486
473
|
```
|
|
487
474
|
|
|
@@ -509,6 +496,7 @@ def create_seg_init_chrome_wrapper(
|
|
|
509
496
|
|
|
510
497
|
Saves nltk_presplit snapshot at init time for match detection.
|
|
511
498
|
FA controls are rendered in the toolbar via extra_actions.
|
|
499
|
+
Settings modals are rendered in a persistent container (both seg + align).
|
|
512
500
|
"""
|
|
513
501
|
```
|
|
514
502
|
|
|
@@ -842,7 +830,7 @@ def _render_shared_chrome(
|
|
|
842
830
|
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
|
|
843
831
|
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
|
|
844
832
|
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
|
|
845
|
-
) -> tuple: # (toolbar,
|
|
833
|
+
) -> tuple: # (toolbar, footer, settings_modals_container)
|
|
846
834
|
"""
|
|
847
835
|
Render shared chrome containers, populated with segmentation content when initialized.
|
|
848
836
|
|
|
@@ -2,8 +2,6 @@ LICENSE
|
|
|
2
2
|
MANIFEST.in
|
|
3
3
|
README.md
|
|
4
4
|
pyproject.toml
|
|
5
|
-
settings.ini
|
|
6
|
-
setup.py
|
|
7
5
|
cjm_transcript_segment_align/__init__.py
|
|
8
6
|
cjm_transcript_segment_align/_modidx.py
|
|
9
7
|
cjm_transcript_segment_align/html_ids.py
|
|
@@ -12,7 +10,6 @@ cjm_transcript_segment_align.egg-info/PKG-INFO
|
|
|
12
10
|
cjm_transcript_segment_align.egg-info/SOURCES.txt
|
|
13
11
|
cjm_transcript_segment_align.egg-info/dependency_links.txt
|
|
14
12
|
cjm_transcript_segment_align.egg-info/entry_points.txt
|
|
15
|
-
cjm_transcript_segment_align.egg-info/not-zip-safe
|
|
16
13
|
cjm_transcript_segment_align.egg-info/requires.txt
|
|
17
14
|
cjm_transcript_segment_align.egg-info/top_level.txt
|
|
18
15
|
cjm_transcript_segment_align/components/__init__.py
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "cjm-transcript-segment-align"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "FastHTML dual-column text segmentation & VAD alignment UI for transcript decomposition workflows with forced alignment-based text splitting for aligning text segments with VAD chunks."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = {text = "Apache-2.0"}
|
|
12
|
+
authors = [{name = "Christian J. Mills", email = "9126128+cj-mills@users.noreply.github.com"}]
|
|
13
|
+
keywords = ['nbdev', 'jupyter', 'notebook', 'python']
|
|
14
|
+
classifiers = ["Natural Language :: English", "Intended Audience :: Developers", "Development Status :: 3 - Alpha", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only"]
|
|
15
|
+
dependencies = ['cjm-plugin-system', 'cjm_transcription_plugin_system', 'cjm_transcript_segmentation', 'cjm_transcript_vad_align>=0.0.15', 'cjm_fasthtml_job_monitor', 'cjm_fasthtml_web_audio>=0.0.8']
|
|
16
|
+
|
|
17
|
+
[project.urls]
|
|
18
|
+
Repository = "https://github.com/cj-mills/cjm-transcript-segment-align"
|
|
19
|
+
Documentation = "https://cj-mills.github.io/cjm-transcript-segment-align"
|
|
20
|
+
|
|
21
|
+
[project.entry-points.nbdev]
|
|
22
|
+
cjm_transcript_segment_align = "cjm_transcript_segment_align._modidx:d"
|
|
23
|
+
|
|
24
|
+
[tool.setuptools.dynamic]
|
|
25
|
+
version = {attr = "cjm_transcript_segment_align.__version__"}
|
|
26
|
+
|
|
27
|
+
[tool.setuptools.packages.find]
|
|
28
|
+
include = ["cjm_transcript_segment_align"]
|
|
29
|
+
|
|
30
|
+
[tool.nbdev]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.10"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools>=64.0,<76.0"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name="cjm-transcript-segment-align"
|
|
7
|
-
requires-python=">=3.12"
|
|
8
|
-
dynamic = [ "keywords", "description", "version", "dependencies", "optional-dependencies", "readme", "license", "authors", "classifiers", "entry-points", "scripts", "urls"]
|
|
9
|
-
|
|
10
|
-
[tool.uv]
|
|
11
|
-
cache-keys = [{ file = "pyproject.toml" }, { file = "settings.ini" }, { file = "setup.py" }]
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
[DEFAULT]
|
|
2
|
-
repo = cjm-transcript-segment-align
|
|
3
|
-
lib_name = cjm-transcript-segment-align
|
|
4
|
-
version = 0.0.10
|
|
5
|
-
min_python = 3.12
|
|
6
|
-
license = apache2
|
|
7
|
-
black_formatting = False
|
|
8
|
-
doc_path = _docs
|
|
9
|
-
lib_path = cjm_transcript_segment_align
|
|
10
|
-
nbs_path = nbs
|
|
11
|
-
recursive = True
|
|
12
|
-
tst_flags = notest
|
|
13
|
-
put_version_in_init = True
|
|
14
|
-
update_pyproject = True
|
|
15
|
-
branch = main
|
|
16
|
-
custom_sidebar = False
|
|
17
|
-
doc_host = https://cj-mills.github.io
|
|
18
|
-
doc_baseurl = /cjm-transcript-segment-align
|
|
19
|
-
git_url = https://github.com/cj-mills/cjm-transcript-segment-align
|
|
20
|
-
title = cjm-transcript-segment-align
|
|
21
|
-
audience = Developers
|
|
22
|
-
author = Christian J. Mills
|
|
23
|
-
author_email = 9126128+cj-mills@users.noreply.github.com
|
|
24
|
-
copyright = 2026 onwards, Christian J. Mills
|
|
25
|
-
description = FastHTML dual-column text segmentation & VAD alignment UI for transcript decomposition workflows with forced alignment-based text splitting for aligning text segments with VAD chunks.
|
|
26
|
-
keywords = nbdev jupyter notebook python
|
|
27
|
-
language = English
|
|
28
|
-
status = 3
|
|
29
|
-
user = cj-mills
|
|
30
|
-
requirements = cjm-plugin-system cjm_transcription_plugin_system cjm_transcript_segmentation cjm_transcript_vad_align cjm_fasthtml_job_monitor
|
|
31
|
-
readme_nb = index.ipynb
|
|
32
|
-
allowed_metadata_keys =
|
|
33
|
-
allowed_cell_metadata_keys =
|
|
34
|
-
jupyter_hooks = False
|
|
35
|
-
clean_ids = True
|
|
36
|
-
clear_all = False
|
|
37
|
-
skip_procs =
|
|
38
|
-
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
from pkg_resources import parse_version
|
|
2
|
-
from configparser import ConfigParser
|
|
3
|
-
import setuptools, shlex
|
|
4
|
-
assert parse_version(setuptools.__version__)>=parse_version('36.2')
|
|
5
|
-
|
|
6
|
-
# note: all settings are in settings.ini; edit there, not here
|
|
7
|
-
config = ConfigParser(delimiters=['='])
|
|
8
|
-
config.read('settings.ini', encoding='utf-8')
|
|
9
|
-
cfg = config['DEFAULT']
|
|
10
|
-
|
|
11
|
-
cfg_keys = 'version description keywords author author_email'.split()
|
|
12
|
-
expected = cfg_keys + "lib_name user branch license status min_python audience language".split()
|
|
13
|
-
for o in expected: assert o in cfg, "missing expected setting: {}".format(o)
|
|
14
|
-
setup_cfg = {o:cfg[o] for o in cfg_keys}
|
|
15
|
-
|
|
16
|
-
licenses = {
|
|
17
|
-
'apache2': 'Apache-2.0',
|
|
18
|
-
'mit': 'MIT',
|
|
19
|
-
'gpl2': 'GPL-2.0-only',
|
|
20
|
-
'gpl3': 'GPL-3.0-or-later',
|
|
21
|
-
'bsd3': 'BSD-3-Clause',
|
|
22
|
-
}
|
|
23
|
-
statuses = [ '1 - Planning', '2 - Pre-Alpha', '3 - Alpha',
|
|
24
|
-
'4 - Beta', '5 - Production/Stable', '6 - Mature', '7 - Inactive' ]
|
|
25
|
-
py_versions = '3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13'.split()
|
|
26
|
-
|
|
27
|
-
requirements = shlex.split(cfg.get('requirements', ''))
|
|
28
|
-
if cfg.get('pip_requirements'): requirements += shlex.split(cfg.get('pip_requirements', ''))
|
|
29
|
-
min_python = cfg['min_python']
|
|
30
|
-
dev_requirements = (cfg.get('dev_requirements') or '').split()
|
|
31
|
-
|
|
32
|
-
package_data = dict()
|
|
33
|
-
pkg_data = cfg.get('package_data', None)
|
|
34
|
-
if pkg_data:
|
|
35
|
-
package_data[cfg['lib_name']] = pkg_data.split() # split as multiple files might be listed
|
|
36
|
-
# Add package data to setup_cfg for setuptools.setup(..., **setup_cfg)
|
|
37
|
-
setup_cfg['package_data'] = package_data
|
|
38
|
-
|
|
39
|
-
setuptools.setup(
|
|
40
|
-
name = cfg['lib_name'],
|
|
41
|
-
license = licenses.get(cfg['license'].lower(), cfg['license']),
|
|
42
|
-
classifiers = [
|
|
43
|
-
'Development Status :: ' + statuses[int(cfg['status'])],
|
|
44
|
-
'Intended Audience :: ' + cfg['audience'].title(),
|
|
45
|
-
'Natural Language :: ' + cfg['language'].title(),
|
|
46
|
-
] + ['Programming Language :: Python :: '+o for o in py_versions[py_versions.index(min_python):]],
|
|
47
|
-
url = cfg['git_url'],
|
|
48
|
-
packages = setuptools.find_packages(),
|
|
49
|
-
include_package_data = True,
|
|
50
|
-
install_requires = requirements,
|
|
51
|
-
extras_require={ 'dev': dev_requirements },
|
|
52
|
-
dependency_links = cfg.get('dep_links','').split(),
|
|
53
|
-
python_requires = '>=' + cfg['min_python'],
|
|
54
|
-
long_description = open('README.md', encoding='utf-8').read(),
|
|
55
|
-
long_description_content_type = 'text/markdown',
|
|
56
|
-
zip_safe = False,
|
|
57
|
-
entry_points = {
|
|
58
|
-
'console_scripts': cfg.get('console_scripts','').split(),
|
|
59
|
-
'nbdev': [f'{cfg.get("lib_path")}={cfg.get("lib_path")}._modidx:d']
|
|
60
|
-
},
|
|
61
|
-
**setup_cfg)
|
|
62
|
-
|
|
63
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|