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.
Files changed (34) hide show
  1. {cjm_transcript_segment_align-0.0.10/cjm_transcript_segment_align.egg-info → cjm_transcript_segment_align-0.0.12}/PKG-INFO +33 -45
  2. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/README.md +20 -21
  3. cjm_transcript_segment_align-0.0.12/cjm_transcript_segment_align/__init__.py +1 -0
  4. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/handlers.py +37 -20
  5. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/step_renderer.py +36 -36
  6. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/html_ids.py +1 -1
  7. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/routes/chrome.py +34 -31
  8. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12/cjm_transcript_segment_align.egg-info}/PKG-INFO +33 -45
  9. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align.egg-info/SOURCES.txt +0 -3
  10. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align.egg-info/requires.txt +2 -3
  11. cjm_transcript_segment_align-0.0.12/pyproject.toml +30 -0
  12. cjm_transcript_segment_align-0.0.10/cjm_transcript_segment_align/__init__.py +0 -1
  13. cjm_transcript_segment_align-0.0.10/cjm_transcript_segment_align.egg-info/not-zip-safe +0 -1
  14. cjm_transcript_segment_align-0.0.10/pyproject.toml +0 -11
  15. cjm_transcript_segment_align-0.0.10/settings.ini +0 -38
  16. cjm_transcript_segment_align-0.0.10/setup.py +0 -63
  17. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/LICENSE +0 -0
  18. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/MANIFEST.in +0 -0
  19. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/_modidx.py +0 -0
  20. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/__init__.py +0 -0
  21. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/helpers.py +0 -0
  22. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/keyboard_config.py +0 -0
  23. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/sync_controls.py +0 -0
  24. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/components/toolbar_state.py +0 -0
  25. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/models.py +0 -0
  26. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/routes/__init__.py +0 -0
  27. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/routes/forced_alignment.py +0 -0
  28. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/routes/init.py +0 -0
  29. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/services/__init__.py +0 -0
  30. {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.12}/cjm_transcript_segment_align/services/forced_alignment.py +0 -0
  31. {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
  32. {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
  33. {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
  34. {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.2
1
+ Metadata-Version: 2.4
2
2
  Name: cjm-transcript-segment-align
3
- Version: 0.0.10
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
- Home-page: https://github.com/cj-mills/cjm-transcript-segment-align
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
- Keywords: nbdev jupyter notebook python
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Developers
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: Programming Language :: Python :: 3.12
14
- Classifier: Programming Language :: Python :: 3.13
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
- Provides-Extra: dev
24
- Dynamic: author
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
- components_keyboard_config --> html_ids
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
- components_step_renderer --> html_ids
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
- routes_init --> components_keyboard_config
108
- routes_init --> html_ids
109
- routes_init --> components_handlers
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 --> routes_forced_alignment
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, controls, footer)
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
- components_keyboard_config --> html_ids
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
- components_step_renderer --> html_ids
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
- routes_init --> components_keyboard_config
72
- routes_init --> html_ids
73
- routes_init --> components_handlers
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 --> routes_forced_alignment
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, controls, footer)
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.controls import render_width_slider
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, is_auto_mode=result.is_auto_mode,
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
- # Toolbar OOB (with FA controls in extra_actions, NLTK Split disabled at init)
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
- render_toolbar(
461
- reset_url=urls.reset, ai_split_url=urls.ai_split, undo_url=urls.undo,
462
- can_undo=(result.history_depth > 0),
463
- visible_count=result.visible_count,
464
- is_auto_mode=result.is_auto_mode,
465
- extra_actions=build_extra_actions(fa_extra),
466
- nltk_split_disabled=True,
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
- # Controls OOB (width slider)
473
- controls_oob = Div(
474
- render_width_slider(SEG_CS_CONFIG, SEG_CS_IDS, card_width=result.card_width),
475
- id=CombinedHtmlIds.SHARED_CONTROLS,
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, controls_oob, footer_oob, mini_stats_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, controls, footer)
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
- segments = seg_state.get("segments", [])
241
- history = seg_state.get("history", [])
242
- visible_count = seg_state.get("visible_count", DEFAULT_VISIBLE_COUNT)
243
- toolbar_content = render_toolbar(
244
- reset_url=urls.reset,
245
- ai_split_url=urls.ai_split,
246
- undo_url=urls.undo,
247
- can_undo=(len(history) > 0),
248
- visible_count=visible_count,
249
- extra_actions=extra_actions,
250
- nltk_split_disabled=nltk_split_disabled,
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, controls, footer
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, controls, footer = _render_shared_chrome(
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, controls, footer = _render_shared_chrome(
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.controls import render_width_slider
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 (toolbar + controls)
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
- toolbar_content = render_seg_toolbar(
105
- reset_url=seg_urls.reset,
106
- ai_split_url=seg_urls.ai_split,
107
- undo_url=seg_urls.undo,
108
- can_undo=(len(history) > 0),
109
- visible_count=visible_count,
110
- is_auto_mode=is_auto_mode,
111
- extra_actions=build_extra_actions(fa_extra),
112
- nltk_split_disabled=nltk_disabled,
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 (toolbar with auto-play toggle + controls)
117
- visible_count = align_state.get("visible_count", 5)
118
- is_auto_mode = align_state.get("is_auto_mode", False)
119
- card_width = align_state.get("card_width", 40)
120
-
121
- toolbar_content = render_align_toolbar(
122
- visible_count=visible_count,
123
- is_auto_mode=is_auto_mode,
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, controls_oob, footer_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.2
1
+ Metadata-Version: 2.4
2
2
  Name: cjm-transcript-segment-align
3
- Version: 0.0.10
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
- Home-page: https://github.com/cj-mills/cjm-transcript-segment-align
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
- Keywords: nbdev jupyter notebook python
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Developers
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: Programming Language :: Python :: 3.12
14
- Classifier: Programming Language :: Python :: 3.13
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
- Provides-Extra: dev
24
- Dynamic: author
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
- components_keyboard_config --> html_ids
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
- components_step_renderer --> html_ids
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
- routes_init --> components_keyboard_config
108
- routes_init --> html_ids
109
- routes_init --> components_handlers
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 --> routes_forced_alignment
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, controls, footer)
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
@@ -1,7 +1,6 @@
1
1
  cjm-plugin-system
2
2
  cjm_transcription_plugin_system
3
3
  cjm_transcript_segmentation
4
- cjm_transcript_vad_align
4
+ cjm_transcript_vad_align>=0.0.15
5
5
  cjm_fasthtml_job_monitor
6
-
7
- [dev]
6
+ cjm_fasthtml_web_audio>=0.0.8
@@ -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,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
-