@cueframe/kernel 0.1.0 → 0.1.1
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.
- package/LICENSE +661 -0
- package/dist/_members/composition/ops/compositionOps.d.ts +1 -0
- package/dist/_members/composition/projection/behind-readiness.d.ts +127 -0
- package/dist/_members/composition/projection/index.d.ts +2 -0
- package/dist/_members/composition/projection/reframe-readiness.d.ts +156 -0
- package/dist/_members/composition/validators/composition.d.ts +42 -25
- package/dist/_members/composition/validators/render.d.ts +32 -0
- package/dist/_members/core/render/compositionRender.d.ts +17 -1
- package/dist/_members/core/render/types.d.ts +31 -0
- package/dist/authoring/build-tools.js +6 -6
- package/dist/authoring/context.js +4 -4
- package/dist/authoring/tools.js +5 -5
- package/dist/authoring.js +11 -9
- package/dist/{chunk-ZB3C3HM7.js → chunk-7FO3ZJ43.js} +3 -0
- package/dist/{chunk-ODL7GQJG.js → chunk-AP6ZIVAV.js} +2 -2
- package/dist/{chunk-IBYQG46O.js → chunk-AQBREB5O.js} +1 -1
- package/dist/{chunk-YIOY2XEO.js → chunk-DK2ODBNT.js} +15 -5
- package/dist/{chunk-JRQVPFLF.js → chunk-HY3RIEZW.js} +1 -1
- package/dist/{chunk-GEA7E2FL.js → chunk-JJ6XD7NG.js} +151 -1
- package/dist/{chunk-COYMZ76S.js → chunk-MBCXCJOE.js} +1 -1
- package/dist/{chunk-37NJ27UU.js → chunk-OCFDUCF4.js} +3 -0
- package/dist/{chunk-VOO5FQSS.js → chunk-PDYO3DOJ.js} +5 -5
- package/dist/{chunk-MXFAADCQ.js → chunk-PODIYN2K.js} +9 -2
- package/dist/{chunk-NFEGPWGS.js → chunk-TOJEXFXL.js} +1 -1
- package/dist/{chunk-LM4WDUQJ.js → chunk-UHGSZZDI.js} +1 -1
- package/dist/{chunk-XWKZB5U5.js → chunk-ZWMV6DD2.js} +24 -1
- package/dist/compose/renderer.js +3 -3
- package/dist/compose.js +6 -6
- package/dist/composition/graphics-plan.js +1 -1
- package/dist/composition/ops.js +3 -3
- package/dist/composition/primitive-catalog.js +1 -1
- package/dist/composition/projection.js +19 -3
- package/dist/composition/validators.js +6 -4
- package/dist/composition-ops.js +8 -6
- package/dist/composition.js +24 -6
- package/dist/{context-OKX3HHFS.js → context-YWUZDG5X.js} +4 -4
- package/dist/core/render.js +3 -3
- package/dist/core/select.js +2 -2
- package/dist/core.js +3 -3
- package/dist/errors.js +1 -1
- package/dist/mcp/adapter.js +1 -0
- package/dist/media-model/testing.js +1071 -718
- package/dist/nle-export/server.js +328 -130
- package/dist/nle-export.js +7 -6
- package/package.json +13 -14
- package/dist/_members/account-model/index.js +0 -4
- package/dist/_members/account-model/testing/conversationStoreContract.js +0 -168
- package/dist/_members/account-model/testing/index.js +0 -7
- package/dist/_members/account-model/testing/restorePointStoreContract.js +0 -69
- package/dist/_members/account-model/types/index.js +0 -1
- package/dist/_members/account-model/validators/contextFile.js +0 -18
- package/dist/_members/account-model/validators/conversation.js +0 -95
- package/dist/_members/account-model/validators/dashboardInsight.js +0 -16
- package/dist/_members/account-model/validators/index.js +0 -7
- package/dist/_members/account-model/validators/sessionToken.js +0 -49
- package/dist/_members/account-model/validators/uploadToken.js +0 -16
- package/dist/_members/account-model/validators/userSettings.js +0 -12
- package/dist/_members/account-model/validators/workingComposition.js +0 -20
- package/dist/_members/brand-derivation/constants.js +0 -20
- package/dist/_members/brand-derivation/contrastSafe.js +0 -114
- package/dist/_members/brand-derivation/index.js +0 -1
- package/dist/_members/cloud-import/chunk-XKO6ZSWI.js +0 -162
- package/dist/_members/cloud-import/chunk-XKO6ZSWI.js.map +0 -1
- package/dist/_members/cloud-import/index.js +0 -241
- package/dist/_members/cloud-import/index.js.map +0 -1
- package/dist/_members/cloud-import/multipartUpload.js +0 -7
- package/dist/_members/cloud-import/multipartUpload.js.map +0 -1
- package/dist/_members/composition/audio/audioMix.js +0 -61
- package/dist/_members/composition/audio/index.js +0 -5
- package/dist/_members/composition/audio/mixStaging.js +0 -195
- package/dist/_members/composition/audio/musicPack.generated.js +0 -136
- package/dist/_members/composition/audio/musicPack.js +0 -36
- package/dist/_members/composition/audio/pack.generated.js +0 -603
- package/dist/_members/composition/audio/pack.js +0 -48
- package/dist/_members/composition/audio/palette.js +0 -134
- package/dist/_members/composition/autozoom/index.js +0 -83
- package/dist/_members/composition/brand-kit.js +0 -45
- package/dist/_members/composition/brief/contract.js +0 -209
- package/dist/_members/composition/color-grade.js +0 -80
- package/dist/_members/composition/depth.js +0 -8
- package/dist/_members/composition/fixtures/index.js +0 -143
- package/dist/_members/composition/fixtures/vaayaErrored.d.ts +0 -25
- package/dist/_members/composition/fixtures/vaayaErrored.js +0 -203
- package/dist/_members/composition/fonts.js +0 -162
- package/dist/_members/composition/graphics-plan/compile.js +0 -221
- package/dist/_members/composition/graphics-plan/index.js +0 -10
- package/dist/_members/composition/graphics-plan/instantiateMotif.js +0 -44
- package/dist/_members/composition/graphics-plan/motion.js +0 -66
- package/dist/_members/composition/graphics-plan/schemas.js +0 -261
- package/dist/_members/composition/graphics-plan/solve.js +0 -145
- package/dist/_members/composition/index.js +0 -5
- package/dist/_members/composition/invariants/clipPlacement.js +0 -69
- package/dist/_members/composition/invariants/composition.js +0 -28
- package/dist/_members/composition/invariants/errors.js +0 -10
- package/dist/_members/composition/invariants/etag.js +0 -38
- package/dist/_members/composition/invariants/ids.js +0 -33
- package/dist/_members/composition/invariants/index.js +0 -9
- package/dist/_members/composition/invariants/keyframes.js +0 -45
- package/dist/_members/composition/invariants/markers.js +0 -29
- package/dist/_members/composition/invariants/time.js +0 -20
- package/dist/_members/composition/invariants/tracks.js +0 -304
- package/dist/_members/composition/ops/compositionOps.js +0 -1056
- package/dist/_members/composition/ops/headlessStore.js +0 -94
- package/dist/_members/composition/ops/index.js +0 -4
- package/dist/_members/composition/ops/selectors.js +0 -118
- package/dist/_members/composition/ops/timeline-word.js +0 -1
- package/dist/_members/composition/ops/transcript.js +0 -77
- package/dist/_members/composition/ops/types.js +0 -16
- package/dist/_members/composition/primitive-catalog/catalogQuery.js +0 -150
- package/dist/_members/composition/primitive-catalog/disabled.js +0 -32
- package/dist/_members/composition/primitive-catalog/generated/meta.js +0 -15161
- package/dist/_members/composition/primitive-catalog/index.js +0 -46
- package/dist/_members/composition/primitive-catalog/paramValidation.js +0 -231
- package/dist/_members/composition/primitive-catalog/projection.js +0 -164
- package/dist/_members/composition/primitive-catalog/types.js +0 -14
- package/dist/_members/composition/projection/behind-placement.js +0 -62
- package/dist/_members/composition/projection/brandKit.js +0 -482
- package/dist/_members/composition/projection/cardTokens.js +0 -209
- package/dist/_members/composition/projection/composition-floor.js +0 -582
- package/dist/_members/composition/projection/cropProjection.js +0 -257
- package/dist/_members/composition/projection/index.js +0 -7
- package/dist/_members/composition/projection/occlusion-budget.js +0 -104
- package/dist/_members/composition/projection/safe-zones.js +0 -99
- package/dist/_members/composition/reframe/aspectLoss.js +0 -115
- package/dist/_members/composition/reframe/coverage.js +0 -62
- package/dist/_members/composition/reframe/derive.js +0 -73
- package/dist/_members/composition/reframe/index.js +0 -109
- package/dist/_members/composition/reframe/kenBurns.js +0 -64
- package/dist/_members/composition/reframe/shotScale.js +0 -176
- package/dist/_members/composition/reframe/trajectory.js +0 -124
- package/dist/_members/composition/timeline/compound.js +0 -134
- package/dist/_members/composition/timeline/index.js +0 -9
- package/dist/_members/composition/timeline/intent.js +0 -228
- package/dist/_members/composition/timeline/keyframes.js +0 -121
- package/dist/_members/composition/timeline/link.js +0 -59
- package/dist/_members/composition/timeline/occupancy.js +0 -36
- package/dist/_members/composition/timeline/placement.js +0 -74
- package/dist/_members/composition/timeline/plan.js +0 -31
- package/dist/_members/composition/timeline/resolve.js +0 -170
- package/dist/_members/composition/timeline/trims.js +0 -278
- package/dist/_members/composition/types/index.js +0 -1
- package/dist/_members/composition/validators/brandKit.js +0 -295
- package/dist/_members/composition/validators/composePlan.js +0 -113
- package/dist/_members/composition/validators/composition.js +0 -703
- package/dist/_members/composition/validators/font.js +0 -34
- package/dist/_members/composition/validators/graphicKinds.js +0 -30
- package/dist/_members/composition/validators/index.js +0 -9
- package/dist/_members/composition/validators/project.js +0 -29
- package/dist/_members/composition/validators/registry.js +0 -41
- package/dist/_members/composition/validators/render.js +0 -139
- package/dist/_members/composition/validators/session.js +0 -37
- package/dist/_members/composition/validators/webhook.js +0 -72
- package/dist/_members/composition-ops/alphaLayers.js +0 -141
- package/dist/_members/composition-ops/index.js +0 -637
- package/dist/_members/composition-ops/materializeGrid.js +0 -99
- package/dist/_members/composition-ops/opRecorder.js +0 -196
- package/dist/_members/composition-ops/recordingStore.js +0 -14
- package/dist/_members/composition-ops/replaceRegion.js +0 -102
- package/dist/_members/composition-ops/testFixtures.js +0 -19
- package/dist/_members/core/index.js +0 -5
- package/dist/_members/core/render/bookends.js +0 -53
- package/dist/_members/core/render/captions.js +0 -127
- package/dist/_members/core/render/compositionRender.js +0 -1249
- package/dist/_members/core/render/deriveTrajectory.js +0 -889
- package/dist/_members/core/render/emphasis.js +0 -16
- package/dist/_members/core/render/eval/cropBox.js +0 -139
- package/dist/_members/core/render/eval/inclusion.js +0 -96
- package/dist/_members/core/render/eval/index.js +0 -146
- package/dist/_members/core/render/eval/metrics.js +0 -94
- package/dist/_members/core/render/exportSettings.js +0 -65
- package/dist/_members/core/render/index.js +0 -20
- package/dist/_members/core/render/mapFaceToPerson.js +0 -73
- package/dist/_members/core/render/types.js +0 -8
- package/dist/_members/core/render/vcam/cameraPath.js +0 -248
- package/dist/_members/core/render/vcam/constants.js +0 -115
- package/dist/_members/core/render/vcam/errorCodes.js +0 -39
- package/dist/_members/core/render/vcam/framing.js +0 -136
- package/dist/_members/core/render/vcam/requiredRegion.js +0 -137
- package/dist/_members/core/render/vcam/shots.js +0 -53
- package/dist/_members/core/render/vcam/subjectSet.js +0 -388
- package/dist/_members/core/select/errorCodes.js +0 -38
- package/dist/_members/core/select/index.js +0 -26
- package/dist/_members/core/select/model.js +0 -18
- package/dist/_members/core/select/select.js +0 -244
- package/dist/_members/core/select/stabilize.js +0 -242
- package/dist/_members/core/types.js +0 -7
- package/dist/_members/errors/index.js +0 -1
- package/dist/_members/errors/registry.js +0 -560
- package/dist/_members/foundation/codes/index.js +0 -31
- package/dist/_members/foundation/index.js +0 -2
- package/dist/_members/foundation/primitives/index.js +0 -5
- package/dist/_members/mcp/adapter.js +0 -771
- package/dist/_members/mcp/burnedNames.js +0 -73
- package/dist/_members/mcp/core.js +0 -390
- package/dist/_members/mcp/curation.js +0 -792
- package/dist/_members/mcp/executor.js +0 -142
- package/dist/_members/mcp/format.js +0 -9
- package/dist/_members/mcp/generated/catalogPreviews.js +0 -95
- package/dist/_members/mcp/generated/harness.js +0 -81
- package/dist/_members/mcp/generated/operations.js +0 -131
- package/dist/_members/mcp/index.js +0 -50
- package/dist/_members/mcp/internalLoopTools.js +0 -109
- package/dist/_members/mcp/prompts.js +0 -45
- package/dist/_members/mcp/resources.js +0 -166
- package/dist/_members/mcp/server.js +0 -340
- package/dist/_members/mcp/wait.js +0 -378
- package/dist/_members/mcp/x402Meta.js +0 -66
- package/dist/_members/media-model/api.js +0 -175
- package/dist/_members/media-model/index.js +0 -1
- package/dist/_members/media-model/media-kind.js +0 -116
- package/dist/_members/media-model/testing/index.js +0 -1
- package/dist/_members/media-model/testing/mediaStoreContract.js +0 -82
- package/dist/_members/media-model/transcriptSearch.js +0 -70
- package/dist/_members/media-model/transcriptSearchCases.json +0 -79
- package/dist/_members/nle-export/compact-timeline.js +0 -73
- package/dist/_members/nle-export/compact-timeline.js.map +0 -1
- package/dist/_members/nle-export/composition-to-input.js +0 -147
- package/dist/_members/nle-export/composition-to-input.js.map +0 -1
- package/dist/_members/nle-export/fcpxml.js +0 -159
- package/dist/_members/nle-export/fcpxml.js.map +0 -1
- package/dist/_members/nle-export/index.js +0 -12
- package/dist/_members/nle-export/index.js.map +0 -1
- package/dist/_members/nle-export/premiere.js +0 -161
- package/dist/_members/nle-export/premiere.js.map +0 -1
- package/dist/_members/nle-export/server/index.js +0 -2
- package/dist/_members/nle-export/server/index.js.map +0 -1
- package/dist/_members/nle-export/server/pack-zip.js +0 -38
- package/dist/_members/nle-export/server/pack-zip.js.map +0 -1
- package/dist/_members/nle-export/srt.js +0 -50
- package/dist/_members/nle-export/srt.js.map +0 -1
- package/dist/_members/nle-export/types.js +0 -9
- package/dist/_members/nle-export/types.js.map +0 -1
- package/dist/_members/nle-export/xml/index.js +0 -11
- package/dist/_members/nle-export/xml/index.js.map +0 -1
- package/dist/_members/nle-export/xml-utils.js +0 -48
- package/dist/_members/nle-export/xml-utils.js.map +0 -1
- package/dist/_members/perception/activeSpeaker.js +0 -103
- package/dist/_members/perception/audioQuality.js +0 -76
- package/dist/_members/perception/energyBeat.js +0 -99
- package/dist/_members/perception/identityMatch.js +0 -91
- package/dist/_members/perception/index.js +0 -48
- package/dist/_members/perception/visualQuality.js +0 -95
- package/dist/_members/plane/conformance.js +0 -90
- package/dist/_members/plane/contract.js +0 -49
- package/dist/_members/plane/index.js +0 -16
- package/dist/_members/primitives/backgrounds/index.js +0 -32
- package/dist/_members/primitives/backgrounds/index.js.map +0 -1
- package/dist/_members/primitives/captions/index.js +0 -398
- package/dist/_members/primitives/captions/index.js.map +0 -1
- package/dist/_members/primitives/chunk-2LVE4UIT.js +0 -139
- package/dist/_members/primitives/chunk-2LVE4UIT.js.map +0 -1
- package/dist/_members/primitives/chunk-3IQUH6KK.js +0 -20
- package/dist/_members/primitives/chunk-3IQUH6KK.js.map +0 -1
- package/dist/_members/primitives/chunk-3OMURV6Q.js +0 -112
- package/dist/_members/primitives/chunk-3OMURV6Q.js.map +0 -1
- package/dist/_members/primitives/chunk-4IS6TMEG.js +0 -21
- package/dist/_members/primitives/chunk-4IS6TMEG.js.map +0 -1
- package/dist/_members/primitives/chunk-5MWGAEGQ.js +0 -1644
- package/dist/_members/primitives/chunk-5MWGAEGQ.js.map +0 -1
- package/dist/_members/primitives/chunk-7RRPFPQK.js +0 -15
- package/dist/_members/primitives/chunk-7RRPFPQK.js.map +0 -1
- package/dist/_members/primitives/chunk-DH5TRZK2.js +0 -125
- package/dist/_members/primitives/chunk-DH5TRZK2.js.map +0 -1
- package/dist/_members/primitives/chunk-E3KNUSFG.js +0 -2337
- package/dist/_members/primitives/chunk-E3KNUSFG.js.map +0 -1
- package/dist/_members/primitives/chunk-G2B3G4HK.js +0 -47
- package/dist/_members/primitives/chunk-G2B3G4HK.js.map +0 -1
- package/dist/_members/primitives/chunk-HFPFGZXT.js +0 -1494
- package/dist/_members/primitives/chunk-HFPFGZXT.js.map +0 -1
- package/dist/_members/primitives/chunk-HIWVFZVH.js +0 -19
- package/dist/_members/primitives/chunk-HIWVFZVH.js.map +0 -1
- package/dist/_members/primitives/chunk-IDAL6G3Y.js +0 -134
- package/dist/_members/primitives/chunk-IDAL6G3Y.js.map +0 -1
- package/dist/_members/primitives/chunk-KNC6JP5F.js +0 -34
- package/dist/_members/primitives/chunk-KNC6JP5F.js.map +0 -1
- package/dist/_members/primitives/chunk-KYRDVZST.js +0 -459
- package/dist/_members/primitives/chunk-KYRDVZST.js.map +0 -1
- package/dist/_members/primitives/chunk-LWLHS2NS.js +0 -3410
- package/dist/_members/primitives/chunk-LWLHS2NS.js.map +0 -1
- package/dist/_members/primitives/chunk-QAQ3P7DR.js +0 -8855
- package/dist/_members/primitives/chunk-QAQ3P7DR.js.map +0 -1
- package/dist/_members/primitives/chunk-ROV2ODWC.js +0 -81
- package/dist/_members/primitives/chunk-ROV2ODWC.js.map +0 -1
- package/dist/_members/primitives/chunk-TCRC2FH3.js +0 -183
- package/dist/_members/primitives/chunk-TCRC2FH3.js.map +0 -1
- package/dist/_members/primitives/chunk-US4YEDAA.js +0 -96
- package/dist/_members/primitives/chunk-US4YEDAA.js.map +0 -1
- package/dist/_members/primitives/chunk-UVKRO5ER.js +0 -13
- package/dist/_members/primitives/chunk-UVKRO5ER.js.map +0 -1
- package/dist/_members/primitives/chunk-W4EIIF2I.js +0 -10
- package/dist/_members/primitives/chunk-W4EIIF2I.js.map +0 -1
- package/dist/_members/primitives/chunk-WPGKIPCO.js +0 -3563
- package/dist/_members/primitives/chunk-WPGKIPCO.js.map +0 -1
- package/dist/_members/primitives/chunk-WZFLEGMD.js +0 -1435
- package/dist/_members/primitives/chunk-WZFLEGMD.js.map +0 -1
- package/dist/_members/primitives/chunk-XHU3WBEI.js +0 -33
- package/dist/_members/primitives/chunk-XHU3WBEI.js.map +0 -1
- package/dist/_members/primitives/chunk-YN7WTZZ7.js +0 -46
- package/dist/_members/primitives/chunk-YN7WTZZ7.js.map +0 -1
- package/dist/_members/primitives/effects/index.js +0 -30
- package/dist/_members/primitives/effects/index.js.map +0 -1
- package/dist/_members/primitives/hero-text/index.js +0 -14
- package/dist/_members/primitives/hero-text/index.js.map +0 -1
- package/dist/_members/primitives/index.js +0 -64
- package/dist/_members/primitives/index.js.map +0 -1
- package/dist/_members/primitives/layouts/index.js +0 -24
- package/dist/_members/primitives/layouts/index.js.map +0 -1
- package/dist/_members/primitives/lib/easings.js +0 -26
- package/dist/_members/primitives/lib/easings.js.map +0 -1
- package/dist/_members/primitives/lib/index.js +0 -74
- package/dist/_members/primitives/lib/index.js.map +0 -1
- package/dist/_members/primitives/lib/palette.js +0 -72
- package/dist/_members/primitives/lib/palette.js.map +0 -1
- package/dist/_members/primitives/lib/preview.js +0 -8
- package/dist/_members/primitives/lib/preview.js.map +0 -1
- package/dist/_members/primitives/lib/schema.js +0 -12
- package/dist/_members/primitives/lib/schema.js.map +0 -1
- package/dist/_members/primitives/lib/seeded-random.js +0 -14
- package/dist/_members/primitives/lib/seeded-random.js.map +0 -1
- package/dist/_members/primitives/lib/text/contrast.js +0 -12
- package/dist/_members/primitives/lib/text/contrast.js.map +0 -1
- package/dist/_members/primitives/lib/text/fill.js +0 -8
- package/dist/_members/primitives/lib/text/fill.js.map +0 -1
- package/dist/_members/primitives/lib/text/fitText.js +0 -10
- package/dist/_members/primitives/lib/text/fitText.js.map +0 -1
- package/dist/_members/primitives/lib/text/marker.js +0 -8
- package/dist/_members/primitives/lib/text/marker.js.map +0 -1
- package/dist/_members/primitives/lib/text/motion.js +0 -16
- package/dist/_members/primitives/lib/text/motion.js.map +0 -1
- package/dist/_members/primitives/lib/text/recolor.js +0 -8
- package/dist/_members/primitives/lib/text/recolor.js.map +0 -1
- package/dist/_members/primitives/lib/text/spec.js +0 -1
- package/dist/_members/primitives/lib/text/spec.js.map +0 -1
- package/dist/_members/primitives/lib/text/stage.js +0 -8
- package/dist/_members/primitives/lib/text/stage.js.map +0 -1
- package/dist/_members/primitives/lib/text/typeface.js +0 -8
- package/dist/_members/primitives/lib/text/typeface.js.map +0 -1
- package/dist/_members/primitives/lib/tokens.js +0 -24
- package/dist/_members/primitives/lib/tokens.js.map +0 -1
- package/dist/_members/primitives/lib/types.js +0 -1
- package/dist/_members/primitives/lib/types.js.map +0 -1
- package/dist/_members/primitives/params-required.json +0 -153
- package/dist/_members/primitives/scenes/index.js +0 -25
- package/dist/_members/primitives/scenes/index.js.map +0 -1
- package/dist/_members/primitives/subject-foreground/index.js +0 -30
- package/dist/_members/primitives/subject-foreground/index.js.map +0 -1
- package/dist/_members/primitives/text/index.js +0 -57
- package/dist/_members/primitives/text/index.js.map +0 -1
- package/dist/_members/primitives/transitions/index.js +0 -67
- package/dist/_members/primitives/transitions/index.js.map +0 -1
- package/dist/_members/primitives/ui-blocks/index.js +0 -76
- package/dist/_members/primitives/ui-blocks/index.js.map +0 -1
- package/dist/_members/primitives/version-map.json +0 -105
- package/dist/_members/primitives/workspace.js +0 -60
- package/dist/_members/primitives/workspace.js.map +0 -1
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export const entityKey = (e) => {
|
|
2
|
-
switch (e.kind) {
|
|
3
|
-
case "clip":
|
|
4
|
-
return `clip:${e.clipId}`;
|
|
5
|
-
case "keyframe":
|
|
6
|
-
return `kf:${e.clipId}:${e.param}:${e.index}`;
|
|
7
|
-
case "transition":
|
|
8
|
-
return `tr:${e.clipId}`;
|
|
9
|
-
case "marker":
|
|
10
|
-
return `mk:${e.markerId}`;
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
const REFUSAL_TEXT = {
|
|
14
|
-
"incompatible-track": "That track cannot hold this kind of clip",
|
|
15
|
-
"track-not-found": "That track is no longer on the timeline",
|
|
16
|
-
"no-compatible-track-kind": "Nothing on this timeline can hold this kind of clip",
|
|
17
|
-
"clip-not-found": "That clip is no longer on the timeline",
|
|
18
|
-
"occupied-and-unresolvable": "There is no room there, and nothing that can be moved aside",
|
|
19
|
-
"zero-duration": "A clip needs a duration greater than zero",
|
|
20
|
-
};
|
|
21
|
-
export function refusalText(reason) {
|
|
22
|
-
return REFUSAL_TEXT[reason];
|
|
23
|
-
}
|
|
24
|
-
export const emptyPlan = (label) => ({
|
|
25
|
-
ops: [],
|
|
26
|
-
resultingSelection: [],
|
|
27
|
-
refusals: [],
|
|
28
|
-
label,
|
|
29
|
-
});
|
|
30
|
-
/** A plan that changes nothing is not applied; the caller snaps the UI back. */
|
|
31
|
-
export const planIsNoop = (plan) => plan.ops.length === 0;
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { classifyOverlap, collidingClips } from "./occupancy";
|
|
2
|
-
import { retimeChannel } from "./keyframes";
|
|
3
|
-
/** Timeline seconds below which a residue clip is not worth keeping. */
|
|
4
|
-
export const MIN_RESIDUE_SECONDS = 0.04;
|
|
5
|
-
/**
|
|
6
|
-
* The source window for a sub-range of an existing clip.
|
|
7
|
-
*
|
|
8
|
-
* `newStartTime`/`newDuration` are TIMELINE values; the trim window is SOURCE
|
|
9
|
-
* values, so the delta is scaled by playbackRate. A clip with no trim window
|
|
10
|
-
* (overlays, cards, components) has nothing to carry and returns undefined.
|
|
11
|
-
*/
|
|
12
|
-
export function trimForSubRange(clip, newStartTime, newDuration) {
|
|
13
|
-
const source = clip.source;
|
|
14
|
-
if (source.kind !== "media" || !source.trim)
|
|
15
|
-
return undefined;
|
|
16
|
-
const rate = source.playbackRate ?? 1;
|
|
17
|
-
const headDelta = (newStartTime - clip.startTime) * rate;
|
|
18
|
-
const start = source.trim.start + headDelta;
|
|
19
|
-
const end = start + newDuration * rate;
|
|
20
|
-
// Never widen past what the original window actually covered — a resolution
|
|
21
|
-
// must only ever remove frames, never invent them.
|
|
22
|
-
const clampedStart = Math.max(source.trim.start, start);
|
|
23
|
-
const clampedEnd = Math.min(source.trim.end, end);
|
|
24
|
-
if (!(clampedEnd > clampedStart))
|
|
25
|
-
return undefined;
|
|
26
|
-
return { ...source, trim: { ...source.trim, start: clampedStart, end: clampedEnd } };
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Channels re-timed for a clip whose window changed.
|
|
30
|
-
*
|
|
31
|
-
* Returns undefined when there is nothing to carry, so callers can spread it
|
|
32
|
-
* without inventing an empty `animate` key on clips that never had one.
|
|
33
|
-
*/
|
|
34
|
-
function animateForSubRange(clip, newStartTime, newDuration) {
|
|
35
|
-
if (!clip.animate)
|
|
36
|
-
return undefined;
|
|
37
|
-
const headDelta = newStartTime - clip.startTime;
|
|
38
|
-
const out = {};
|
|
39
|
-
for (const [param, channel] of Object.entries(clip.animate)) {
|
|
40
|
-
if (!channel)
|
|
41
|
-
continue;
|
|
42
|
-
const retimed = retimeChannel(channel, headDelta, newDuration);
|
|
43
|
-
// A channel with fewer than two points no longer varies; dropping it lets
|
|
44
|
-
// the clip's scalar value take over rather than leaving a dead key behind.
|
|
45
|
-
if (retimed.length >= 2)
|
|
46
|
-
out[param] = retimed;
|
|
47
|
-
}
|
|
48
|
-
// Every channel dropped → undefined, not `{}` — an empty record is a key
|
|
49
|
-
// that says "animated" about a clip that is not.
|
|
50
|
-
return Object.keys(out).length > 0 ? out : undefined;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Ops that clear `span` on `track`. Emits nothing when the span already fits,
|
|
54
|
-
* which is the common case — resolution is the exception, not the rule.
|
|
55
|
-
*/
|
|
56
|
-
export function resolveOverlaps(args) {
|
|
57
|
-
const { track, trackKind, span, policy, clipsById, newClipId } = args;
|
|
58
|
-
const collisions = collidingClips(track, span);
|
|
59
|
-
if (collisions.length === 0)
|
|
60
|
-
return { ops: [], refusals: [] };
|
|
61
|
-
if (policy === "refuse") {
|
|
62
|
-
return {
|
|
63
|
-
ops: [],
|
|
64
|
-
refusals: [{ reason: "occupied-and-unresolvable" }],
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
const ops = [];
|
|
68
|
-
const refusals = [];
|
|
69
|
-
const spanEnd = span.startTime + span.duration;
|
|
70
|
-
for (const collision of collisions) {
|
|
71
|
-
const clip = clipsById.get(collision.id);
|
|
72
|
-
if (!clip) {
|
|
73
|
-
// The occupancy row exists but the full clip does not — a projection bug,
|
|
74
|
-
// not a user error. Refuse rather than guess at the edit.
|
|
75
|
-
refusals.push({ reason: "clip-not-found", entity: { kind: "clip", clipId: collision.id } });
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
const clipEnd = clip.startTime + clip.duration;
|
|
79
|
-
switch (classifyOverlap(span, clip)) {
|
|
80
|
-
case "covers":
|
|
81
|
-
ops.push({ op: "removeClip", clipId: clip.id });
|
|
82
|
-
break;
|
|
83
|
-
case "trims-head": {
|
|
84
|
-
const newStart = spanEnd;
|
|
85
|
-
const newDuration = clipEnd - newStart;
|
|
86
|
-
if (newDuration < MIN_RESIDUE_SECONDS) {
|
|
87
|
-
ops.push({ op: "removeClip", clipId: clip.id });
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
ops.push({
|
|
91
|
-
op: "updateClip",
|
|
92
|
-
clipId: clip.id,
|
|
93
|
-
trackKind,
|
|
94
|
-
patch: {
|
|
95
|
-
startTime: newStart,
|
|
96
|
-
duration: newDuration,
|
|
97
|
-
source: trimForSubRange(clip, newStart, newDuration),
|
|
98
|
-
animate: animateForSubRange(clip, newStart, newDuration),
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
case "trims-tail": {
|
|
104
|
-
const newDuration = span.startTime - clip.startTime;
|
|
105
|
-
if (newDuration < MIN_RESIDUE_SECONDS) {
|
|
106
|
-
ops.push({ op: "removeClip", clipId: clip.id });
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
ops.push({
|
|
110
|
-
op: "updateClip",
|
|
111
|
-
clipId: clip.id,
|
|
112
|
-
trackKind,
|
|
113
|
-
patch: {
|
|
114
|
-
duration: newDuration,
|
|
115
|
-
source: trimForSubRange(clip, clip.startTime, newDuration),
|
|
116
|
-
animate: animateForSubRange(clip, clip.startTime, newDuration),
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
case "engulfed-by": {
|
|
122
|
-
// Head half stays in place and shortens; tail half becomes a new clip
|
|
123
|
-
// starting where the incoming span ends. Both carry their own window.
|
|
124
|
-
const headDuration = span.startTime - clip.startTime;
|
|
125
|
-
const tailStart = spanEnd;
|
|
126
|
-
const tailDuration = clipEnd - tailStart;
|
|
127
|
-
const keepHead = headDuration >= MIN_RESIDUE_SECONDS;
|
|
128
|
-
const keepTail = tailDuration >= MIN_RESIDUE_SECONDS;
|
|
129
|
-
if (!keepHead && !keepTail) {
|
|
130
|
-
ops.push({ op: "removeClip", clipId: clip.id });
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
if (keepHead) {
|
|
134
|
-
ops.push({
|
|
135
|
-
op: "updateClip",
|
|
136
|
-
clipId: clip.id,
|
|
137
|
-
trackKind,
|
|
138
|
-
patch: {
|
|
139
|
-
duration: headDuration,
|
|
140
|
-
source: trimForSubRange(clip, clip.startTime, headDuration),
|
|
141
|
-
animate: animateForSubRange(clip, clip.startTime, headDuration),
|
|
142
|
-
},
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
ops.push({ op: "removeClip", clipId: clip.id });
|
|
147
|
-
}
|
|
148
|
-
if (keepTail) {
|
|
149
|
-
const tailSource = trimForSubRange(clip, tailStart, tailDuration) ?? clip.source;
|
|
150
|
-
ops.push({
|
|
151
|
-
op: "insertClip",
|
|
152
|
-
trackId: track.id,
|
|
153
|
-
clip: {
|
|
154
|
-
...clip,
|
|
155
|
-
id: newClipId(),
|
|
156
|
-
startTime: tailStart,
|
|
157
|
-
duration: tailDuration,
|
|
158
|
-
source: tailSource,
|
|
159
|
-
...(animateForSubRange(clip, tailStart, tailDuration)
|
|
160
|
-
? { animate: animateForSubRange(clip, tailStart, tailDuration) }
|
|
161
|
-
: {}),
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return { ops, refusals };
|
|
170
|
-
}
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
import { retimeChannel } from "./keyframes";
|
|
2
|
-
import { emptyPlan } from "./plan";
|
|
3
|
-
import { linkPartners } from "./link";
|
|
4
|
-
/** Below this a residue clip is not worth keeping. Matches `resolve.ts`. */
|
|
5
|
-
const MIN_SECONDS = 0.04;
|
|
6
|
-
function contextFor(composition, clipId) {
|
|
7
|
-
for (const track of composition.tracks) {
|
|
8
|
-
const clips = track.contents.filter((c) => "source" in c);
|
|
9
|
-
const ordered = [...clips].sort((a, b) => a.startTime - b.startTime);
|
|
10
|
-
const index = ordered.findIndex((c) => c.id === clipId);
|
|
11
|
-
if (index >= 0) {
|
|
12
|
-
return { trackKind: track.kind, ordered, index, clip: ordered[index] };
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
/** Source window bounds, when the clip has one. */
|
|
18
|
-
function trimOf(clip) {
|
|
19
|
-
const source = clip.source;
|
|
20
|
-
if (source.kind !== "media" || !source.trim)
|
|
21
|
-
return null;
|
|
22
|
-
return { start: source.trim.start, end: source.trim.end, rate: source.playbackRate ?? 1 };
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* SLIP — shift the source window by `deltaSeconds` of TIMELINE time, leaving
|
|
26
|
-
* the clip's position and duration untouched.
|
|
27
|
-
*
|
|
28
|
-
* Refused when the clip has no source window (an overlay has nothing to slip)
|
|
29
|
-
* or when the shift would run off either end of the source. `sourceDuration`
|
|
30
|
-
* is required to police the far end — without it the far bound is unknowable
|
|
31
|
-
* and a "successful" slip could point past the end of the media.
|
|
32
|
-
*/
|
|
33
|
-
export function planSlip(composition, clipId, deltaSeconds, sourceDuration) {
|
|
34
|
-
const ctx = contextFor(composition, clipId);
|
|
35
|
-
if (!ctx)
|
|
36
|
-
return null;
|
|
37
|
-
const trim = trimOf(ctx.clip);
|
|
38
|
-
if (!trim)
|
|
39
|
-
return null;
|
|
40
|
-
const shift = deltaSeconds * trim.rate;
|
|
41
|
-
const start = trim.start + shift;
|
|
42
|
-
const end = trim.end + shift;
|
|
43
|
-
if (start < 0 || end > sourceDuration)
|
|
44
|
-
return null;
|
|
45
|
-
if (Math.abs(shift) < 1e-6)
|
|
46
|
-
return null;
|
|
47
|
-
const plan = emptyPlan("Slip clip");
|
|
48
|
-
const source = ctx.clip.source;
|
|
49
|
-
plan.ops.push({
|
|
50
|
-
op: "updateClip",
|
|
51
|
-
clipId,
|
|
52
|
-
trackKind: ctx.trackKind,
|
|
53
|
-
patch: {
|
|
54
|
-
// startTime and duration are DELIBERATELY absent: that is what makes this
|
|
55
|
-
// a slip rather than a move.
|
|
56
|
-
source: { ...source, trim: { ...source.trim, start, end } },
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
// LINK PARTNERS SLIP TOO, by the same delta. Slipping the video of an A/V
|
|
60
|
-
// pair without its audio is a lipsync break wearing a feature's name — the
|
|
61
|
-
// link seam covers selection and moves, and the trims must honour it as
|
|
62
|
-
// well (review pass 2, 2026-08-24). A partner that cannot make the same
|
|
63
|
-
// shift (no window, or it would run off ITS source) refuses the WHOLE slip:
|
|
64
|
-
// half a slip is the desync this exists to prevent.
|
|
65
|
-
for (const partnerId of linkPartners(composition, clipId)) {
|
|
66
|
-
const partnerCtx = contextFor(composition, partnerId);
|
|
67
|
-
if (!partnerCtx)
|
|
68
|
-
return null;
|
|
69
|
-
const partnerTrim = trimOf(partnerCtx.clip);
|
|
70
|
-
if (!partnerTrim)
|
|
71
|
-
return null;
|
|
72
|
-
const pShift = deltaSeconds * partnerTrim.rate;
|
|
73
|
-
const pStart = partnerTrim.start + pShift;
|
|
74
|
-
const pEnd = partnerTrim.end + pShift;
|
|
75
|
-
if (pStart < 0 || pEnd > sourceDuration)
|
|
76
|
-
return null;
|
|
77
|
-
const pSource = partnerCtx.clip.source;
|
|
78
|
-
plan.ops.push({
|
|
79
|
-
op: "updateClip",
|
|
80
|
-
clipId: partnerId,
|
|
81
|
-
trackKind: partnerCtx.trackKind,
|
|
82
|
-
patch: {
|
|
83
|
-
source: {
|
|
84
|
-
...pSource,
|
|
85
|
-
trim: { ...pSource.trim, start: pStart, end: pEnd },
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
plan.resultingSelection = [{ kind: "clip", clipId }];
|
|
91
|
-
return plan;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* ROLL — move the cut between `clipId` and the neighbour on the given side.
|
|
95
|
-
*
|
|
96
|
-
* Both clips change duration; the outer edges and everything downstream stay
|
|
97
|
-
* put. Refused when either side would fall below the minimum, or when either
|
|
98
|
-
* side lacks the source to cover its new length.
|
|
99
|
-
*/
|
|
100
|
-
export function planRoll(composition, clipId, side, deltaSeconds, sourceDurations) {
|
|
101
|
-
const ctx = contextFor(composition, clipId);
|
|
102
|
-
if (!ctx)
|
|
103
|
-
return null;
|
|
104
|
-
// REFUSED on a linked clip. A roll moves this lane's cut and nothing else,
|
|
105
|
-
// which silently desyncs the pair on the other lane — and a paired roll (the
|
|
106
|
-
// multi-track edit that would keep them together) is not built. Refusal is
|
|
107
|
-
// honest; a desync wearing a roll's name is not (review pass 2, 2026-08-24).
|
|
108
|
-
if (linkPartners(composition, clipId).length > 0)
|
|
109
|
-
return null;
|
|
110
|
-
const neighbour = side === "left" ? ctx.ordered[ctx.index - 1] : ctx.ordered[ctx.index + 1];
|
|
111
|
-
if (!neighbour)
|
|
112
|
-
return null;
|
|
113
|
-
// Only a genuine seam rolls. Two clips with a gap between them have no shared
|
|
114
|
-
// cut to move, and pretending otherwise would silently close the gap.
|
|
115
|
-
const seamOk = side === "left"
|
|
116
|
-
? Math.abs(neighbour.startTime + neighbour.duration - ctx.clip.startTime) < 1e-6
|
|
117
|
-
: Math.abs(ctx.clip.startTime + ctx.clip.duration - neighbour.startTime) < 1e-6;
|
|
118
|
-
if (!seamOk)
|
|
119
|
-
return null;
|
|
120
|
-
const ops = [];
|
|
121
|
-
const clipPatch = {};
|
|
122
|
-
const neighbourPatch = {};
|
|
123
|
-
if (side === "left") {
|
|
124
|
-
const clipStart = ctx.clip.startTime + deltaSeconds;
|
|
125
|
-
const clipDuration = ctx.clip.duration - deltaSeconds;
|
|
126
|
-
const neighbourDuration = neighbour.duration + deltaSeconds;
|
|
127
|
-
if (clipDuration < MIN_SECONDS || neighbourDuration < MIN_SECONDS)
|
|
128
|
-
return null;
|
|
129
|
-
if (!windowCovers(ctx.clip, deltaSeconds, clipDuration, sourceDurations, "head"))
|
|
130
|
-
return null;
|
|
131
|
-
if (!windowCovers(neighbour, 0, neighbourDuration, sourceDurations, "tail"))
|
|
132
|
-
return null;
|
|
133
|
-
Object.assign(clipPatch, {
|
|
134
|
-
startTime: clipStart,
|
|
135
|
-
duration: clipDuration,
|
|
136
|
-
...subRange(ctx.clip, deltaSeconds, clipDuration),
|
|
137
|
-
});
|
|
138
|
-
Object.assign(neighbourPatch, {
|
|
139
|
-
duration: neighbourDuration,
|
|
140
|
-
...subRange(neighbour, 0, neighbourDuration),
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
const clipDuration = ctx.clip.duration + deltaSeconds;
|
|
145
|
-
const neighbourStart = neighbour.startTime + deltaSeconds;
|
|
146
|
-
const neighbourDuration = neighbour.duration - deltaSeconds;
|
|
147
|
-
if (clipDuration < MIN_SECONDS || neighbourDuration < MIN_SECONDS)
|
|
148
|
-
return null;
|
|
149
|
-
if (!windowCovers(ctx.clip, 0, clipDuration, sourceDurations, "tail"))
|
|
150
|
-
return null;
|
|
151
|
-
if (!windowCovers(neighbour, deltaSeconds, neighbourDuration, sourceDurations, "head"))
|
|
152
|
-
return null;
|
|
153
|
-
Object.assign(clipPatch, {
|
|
154
|
-
duration: clipDuration,
|
|
155
|
-
...subRange(ctx.clip, 0, clipDuration),
|
|
156
|
-
});
|
|
157
|
-
Object.assign(neighbourPatch, {
|
|
158
|
-
startTime: neighbourStart,
|
|
159
|
-
duration: neighbourDuration,
|
|
160
|
-
...subRange(neighbour, deltaSeconds, neighbourDuration),
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
ops.push({ op: "updateClip", clipId, trackKind: ctx.trackKind, patch: clipPatch });
|
|
164
|
-
ops.push({
|
|
165
|
-
op: "updateClip",
|
|
166
|
-
clipId: neighbour.id,
|
|
167
|
-
trackKind: ctx.trackKind,
|
|
168
|
-
patch: neighbourPatch,
|
|
169
|
-
});
|
|
170
|
-
const plan = emptyPlan("Roll edit");
|
|
171
|
-
plan.ops = ops;
|
|
172
|
-
plan.resultingSelection = [{ kind: "clip", clipId }];
|
|
173
|
-
return plan;
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* SLIDE — move the clip in time; its neighbours absorb the difference.
|
|
177
|
-
*
|
|
178
|
-
* The clip's own content and duration are untouched; the previous clip grows
|
|
179
|
-
* or shrinks and the next one does the opposite, so nothing beyond the pair
|
|
180
|
-
* moves. Refused without neighbours on both sides — a slide with nothing to
|
|
181
|
-
* absorb into is just a move, and the caller should ask for that instead.
|
|
182
|
-
*/
|
|
183
|
-
export function planSlide(composition, clipId, deltaSeconds, sourceDurations) {
|
|
184
|
-
const ctx = contextFor(composition, clipId);
|
|
185
|
-
if (!ctx)
|
|
186
|
-
return null;
|
|
187
|
-
// Same refusal as roll, for the same reason — a slide re-times the clip and
|
|
188
|
-
// BOTH neighbours on this lane only.
|
|
189
|
-
if (linkPartners(composition, clipId).length > 0)
|
|
190
|
-
return null;
|
|
191
|
-
const before = ctx.ordered[ctx.index - 1];
|
|
192
|
-
const after = ctx.ordered[ctx.index + 1];
|
|
193
|
-
if (!before || !after)
|
|
194
|
-
return null;
|
|
195
|
-
if (Math.abs(deltaSeconds) < 1e-6)
|
|
196
|
-
return null;
|
|
197
|
-
const beforeDuration = before.duration + deltaSeconds;
|
|
198
|
-
const afterStart = after.startTime + deltaSeconds;
|
|
199
|
-
const afterDuration = after.duration - deltaSeconds;
|
|
200
|
-
if (beforeDuration < MIN_SECONDS || afterDuration < MIN_SECONDS)
|
|
201
|
-
return null;
|
|
202
|
-
if (!windowCovers(before, 0, beforeDuration, sourceDurations, "tail"))
|
|
203
|
-
return null;
|
|
204
|
-
if (!windowCovers(after, deltaSeconds, afterDuration, sourceDurations, "head"))
|
|
205
|
-
return null;
|
|
206
|
-
const plan = emptyPlan("Slide clip");
|
|
207
|
-
plan.ops = [
|
|
208
|
-
{
|
|
209
|
-
op: "updateClip",
|
|
210
|
-
clipId: before.id,
|
|
211
|
-
trackKind: ctx.trackKind,
|
|
212
|
-
patch: { duration: beforeDuration, ...subRange(before, 0, beforeDuration) },
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
op: "updateClip",
|
|
216
|
-
clipId,
|
|
217
|
-
trackKind: ctx.trackKind,
|
|
218
|
-
// Content untouched — only where it sits.
|
|
219
|
-
patch: { startTime: ctx.clip.startTime + deltaSeconds },
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
op: "updateClip",
|
|
223
|
-
clipId: after.id,
|
|
224
|
-
trackKind: ctx.trackKind,
|
|
225
|
-
patch: {
|
|
226
|
-
startTime: afterStart,
|
|
227
|
-
duration: afterDuration,
|
|
228
|
-
...subRange(after, deltaSeconds, afterDuration),
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
];
|
|
232
|
-
plan.resultingSelection = [{ kind: "clip", clipId }];
|
|
233
|
-
return plan;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Does the clip's source cover `newDuration` after moving its head by
|
|
237
|
-
* `headDelta`? A clip with no window (an overlay, a card) has nothing to run
|
|
238
|
-
* out of and always passes.
|
|
239
|
-
*/
|
|
240
|
-
function windowCovers(clip, headDelta, newDuration, sourceDurations, grow) {
|
|
241
|
-
const trim = trimOf(clip);
|
|
242
|
-
if (!trim)
|
|
243
|
-
return true;
|
|
244
|
-
const start = trim.start + headDelta * trim.rate;
|
|
245
|
-
const end = start + newDuration * trim.rate;
|
|
246
|
-
if (start < 0)
|
|
247
|
-
return false;
|
|
248
|
-
const source = clip.source;
|
|
249
|
-
const total = source.kind === "media" ? sourceDurations[source.mediaId] : undefined;
|
|
250
|
-
if (grow === "tail" && total !== undefined && end > total + 1e-6)
|
|
251
|
-
return false;
|
|
252
|
-
return end > start;
|
|
253
|
-
}
|
|
254
|
-
/** The patch fields carrying a clip's window + keyframes into a new sub-range. */
|
|
255
|
-
function subRange(clip, headDelta, newDuration) {
|
|
256
|
-
const out = {};
|
|
257
|
-
const trim = trimOf(clip);
|
|
258
|
-
if (trim) {
|
|
259
|
-
const start = trim.start + headDelta * trim.rate;
|
|
260
|
-
out.source = {
|
|
261
|
-
...clip.source,
|
|
262
|
-
trim: { start, end: start + newDuration * trim.rate },
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
if (clip.animate) {
|
|
266
|
-
const animate = {};
|
|
267
|
-
for (const [param, channel] of Object.entries(clip.animate)) {
|
|
268
|
-
if (!channel)
|
|
269
|
-
continue;
|
|
270
|
-
const retimed = retimeChannel(channel, headDelta, newDuration);
|
|
271
|
-
if (retimed.length >= 2)
|
|
272
|
-
animate[param] = retimed;
|
|
273
|
-
}
|
|
274
|
-
if (Object.keys(animate).length > 0)
|
|
275
|
-
out.animate = animate;
|
|
276
|
-
}
|
|
277
|
-
return out;
|
|
278
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|