""" FCPXML Writer — Generate and modify Final Cut Pro XML files. This package provides two complementary workflows for working with FCPXML: **Generation** (``FCPXMLWriter``, in :mod:`.generator`): Build a new FCPXML document from Python dataclass objects (``Project``, ``Timeline``, ``Clip``, ``Marker``). Useful for creating rough cuts, montage exports, and template-based projects. **Modification** (``FCPXMLModifier``, in :mod:`.modifier`): Load an existing FCPXML file, apply surgical edits (markers, trims, reorders, transitions, speed changes, silence removal, etc.), and save. This is the primary API used by the MCP server's tool handlers. Layout ------ This was one 4.200-line module. It is now one module per subject, because the subjects barely touch each other: whoever is fixing a zoom ramp has no reason to scroll past subtitle layout to find it. helpers sanitising, scales, shared element builders document asset creation, timebases, serialisation (``write_fcpxml``) validation structural checks (``validate_fcpxml``) core ``ModifierCore``: load, indices, spine navigation, ``save`` one mixin per editing subject (markers, trim, speed, …) modifier ``FCPXMLModifier`` = core + every mixin generator ``FCPXMLWriter`` api one-line convenience wrappers Everything the rest of the project imported from the old module is re-exported here, so ``from fcpxml.writer import FCPXMLModifier`` keeps working unchanged — including the underscore-prefixed helpers the test suite reaches for. Architecture notes ------------------ - All time arithmetic uses ``TimeValue`` (rational fractions) — never floats — to match FCPXML's native ``"600/2400s"`` format and avoid rounding drift. - The ``FCPXMLModifier`` builds three in-memory indices at init (``clips``, ``resources``, ``formats``) so lookups are O(1) by ID/name. - Spine-based editing: clips live inside a ```` element (the primary storyline). Connected clips attach via ``lane`` attributes on spine clips. Most editing methods find the target clip in the spine, mutate it, then ripple offsets on subsequent siblings. - ``write_fcpxml()`` handles DTD-compliant serialisation and optional timebase enforcement for all output paths. """ from ..models import TimeValue from .api import add_marker_to_file, modify_fcpxml, trim_clip_in_file from .core import ModifierCore from .document import ( _STILL_IMAGE_EXTENSIONS, _enforce_standard_timebases, _ensure_video_asset, write_fcpxml, ) from .generator import FCPXMLWriter from .helpers import ( _ASSET_CLIP_CHILD_ORDER, _CHILD_ORDER_INDEX, _MAX_MARKER_NAME_LENGTH, _MAX_NOTE_LENGTH, CLIP_AND_AUDIO_TAGS, CLIP_TAGS, FCP_EFFECTS, HOLD_AT_CUT_THRESHOLD, SPINE_ELEMENT_TAGS, START_AT_CUT_THRESHOLD, _create_asset_element, _dtd_insert, _fmt_scale, _probe_audio_info, _sanitize_xml_value, build_marker_element, list_effects, ) from .modifier import FCPXMLModifier from .validation import ( _check_asset_sources, _check_child_order, _check_effect_refs, _check_frame_alignment, _check_required_attributes, _check_timebases, _document_frame_duration, validate_fcpxml, ) __all__ = [ "FCPXMLModifier", "FCPXMLWriter", "ModifierCore", "TimeValue", "FCP_EFFECTS", "CLIP_TAGS", "CLIP_AND_AUDIO_TAGS", "SPINE_ELEMENT_TAGS", "HOLD_AT_CUT_THRESHOLD", "START_AT_CUT_THRESHOLD", "add_marker_to_file", "build_marker_element", "list_effects", "modify_fcpxml", "trim_clip_in_file", "validate_fcpxml", "write_fcpxml", # Internos que o resto do projeto (e a suíte) já importava deste módulo # quando ele era um arquivo só. Ficam aqui para a divisão não virar uma # quebra de API disfarçada de reorganização. "_ASSET_CLIP_CHILD_ORDER", "_CHILD_ORDER_INDEX", "_MAX_MARKER_NAME_LENGTH", "_MAX_NOTE_LENGTH", "_STILL_IMAGE_EXTENSIONS", "_check_asset_sources", "_check_child_order", "_check_effect_refs", "_check_frame_alignment", "_check_required_attributes", "_check_timebases", "_create_asset_element", "_document_frame_duration", "_dtd_insert", "_enforce_standard_timebases", "_ensure_video_asset", "_fmt_scale", "_probe_audio_info", "_sanitize_xml_value", ]