m0saic 0.2.2 → 0.3.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 +22 -7
- package/README.md +23 -5
- package/dist/browseE2e.js +1 -1
- package/dist/connectionsFromEnv.js +1 -1
- package/dist/e2eTemplateVariants.js +1 -1
- package/dist/frontDoor.js +1 -1
- package/dist/index.js +1 -1
- package/dist/inlineDsl.js +1 -1
- package/dist/mcp/bridgeClient.js +1 -0
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +1 -0
- package/dist/mosaicxRunner.js +1 -1
- package/dist/outputPattern.js +1 -1
- package/dist/showcaseFeed.js +1 -1
- package/dist/templateDoctor.js +1 -1
- package/dist/utils/checkFeasibility.js +1 -1
- package/dist/utils/collectRenderErrors.js +1 -1
- package/dist/utils/enrichImageAlphaFromDoc.js +1 -1
- package/dist/utils/ensureFfmpeg.js +1 -1
- package/dist/utils/extractLayoutMeta.js +1 -1
- package/dist/utils/failureHints.js +1 -1
- package/dist/utils/ffmpegProbe.js +1 -1
- package/dist/utils/formatM0saicForCli.js +1 -1
- package/dist/utils/hashFile.js +1 -1
- package/dist/utils/helpGroups.js +1 -1
- package/dist/utils/installContext.js +1 -0
- package/dist/utils/invocation.js +1 -1
- package/dist/utils/licenseActivation.js +1 -0
- package/dist/utils/licenseActivationWorker.js +1 -0
- package/dist/utils/mosaicSpinner.js +1 -1
- package/dist/utils/parseDimensions.js +1 -1
- package/dist/utils/pathInfo.js +1 -1
- package/dist/utils/readJsonArg.js +1 -1
- package/dist/utils/renderOutcome.js +1 -1
- package/dist/utils/renderReport.js +1 -1
- package/dist/utils/renderSignals.js +1 -1
- package/dist/utils/renderWorkspace.js +1 -1
- package/dist/utils/reportOutputFormat.js +1 -0
- package/dist/utils/setupFfmpeg.js +1 -1
- package/dist/utils/telemetry.js +1 -1
- package/dist/utils/telemetryFlushWorker.js +1 -1
- package/dist/utils/telemetryUpstream.js +1 -1
- package/dist/utils/telemetryUsage.js +1 -1
- package/dist/utils/toolchainConfig.js +1 -1
- package/dist/utils/tutorialDuration.js +1 -1
- package/dist/utils/updateCheck.js +1 -1
- package/dist/utils/updateCheckWorker.js +1 -1
- package/dist/utils/validateSourceCounts.js +1 -1
- package/dist/utils/versions.js +1 -1
- package/dist/webCustomizeLink.js +1 -1
- package/node_modules/@m0saic/community-m/NOTICE +9 -0
- package/node_modules/@m0saic/community-m/release.json +2 -2
- package/node_modules/@m0saic/core/dist/core/buildChildMosaicSource.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildChunkCommands.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildEncodeCommands.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildLavfiSource.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildMediaSource.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildMosaicNode.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildMosaicPlanFromFile.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildSvgTextSource.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildTextRenderCommand.js +1 -1
- package/node_modules/@m0saic/core/dist/core/collectRefTargets.js +1 -1
- package/node_modules/@m0saic/core/dist/core/index.js +1 -1
- package/node_modules/@m0saic/core/dist/core/maskCacheDir.js +1 -1
- package/node_modules/@m0saic/core/dist/core/maskWorkerBridge.js +1 -1
- package/node_modules/@m0saic/core/dist/core/playbackPlaySpeed.js +1 -1
- package/node_modules/@m0saic/core/dist/core/prepareProps.js +1 -1
- package/node_modules/@m0saic/core/dist/core/primaryOutput.js +1 -1
- package/node_modules/@m0saic/core/dist/core/rasterizeMaskPng.js +1 -1
- package/node_modules/@m0saic/core/dist/core/rasterizeSvgMediaPng.js +1 -1
- package/node_modules/@m0saic/core/dist/core/refTargetTap.js +1 -1
- package/node_modules/@m0saic/core/dist/core/resolveMasks.js +1 -1
- package/node_modules/@m0saic/core/dist/core/resolveMasksSync.js +1 -1
- package/node_modules/@m0saic/core/dist/core/resolveStrokeRingsSync.js +1 -1
- package/node_modules/@m0saic/core/dist/core/roundedRectMask.js +1 -1
- package/node_modules/@m0saic/core/dist/core/strokeRing.js +1 -1
- package/node_modules/@m0saic/core/dist/core/svgRaster.js +1 -1
- package/node_modules/@m0saic/core/dist/defaults.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/backgroundImageInput.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/bufferGuard.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/ffmpegCommands.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBackdropBlur.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBlur.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBorderRadius.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyCamera.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyChromaKey.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyFade.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyGrade.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyMask.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyNoise.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyPixelize.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyRotate.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyStroke.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyTileEffects.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/coverCrop.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/index.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/sourceRectCrop.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/gridLowering.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/index.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/splitAvMux.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/threadGuard.js +1 -1
- package/node_modules/@m0saic/core/dist/flatten/index.js +1 -1
- package/node_modules/@m0saic/core/dist/fs/index.js +1 -1
- package/node_modules/@m0saic/core/dist/fs/tempWorkspace.js +1 -1
- package/node_modules/@m0saic/core/dist/index.js +1 -1
- package/node_modules/@m0saic/core/dist/media/buildAssetManifestFromInputs.js +1 -1
- package/node_modules/@m0saic/core/dist/media/buildMediaRegistryFromInput.js +1 -1
- package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromInvocationProps.js +1 -1
- package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromMosaicRenderableFile.js +1 -1
- package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromProps.js +1 -1
- package/node_modules/@m0saic/core/dist/media/index.js +1 -1
- package/node_modules/@m0saic/core/dist/media/internalMintAsset.js +1 -1
- package/node_modules/@m0saic/core/dist/media/remoteUrl.js +1 -1
- package/node_modules/@m0saic/core/dist/media/stageUnsafeFilenames.js +1 -1
- package/node_modules/@m0saic/core/dist/media/types.js +1 -1
- package/node_modules/@m0saic/core/dist/output/index.js +1 -1
- package/node_modules/@m0saic/core/dist/output/resolveOutputFormat.js +1 -1
- package/node_modules/@m0saic/core/dist/output/types.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/cellLuminanceProbe.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/extractSubtitleCues.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/helpers.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/index.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/luminanceProbe.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/probeMedia.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/runFFprobe.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/types.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/engineRedaction.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/ffmpegFailure.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/filterPreflight.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/hashFile.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/index.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/pathInfo.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/perfHeatmap.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/perfReport.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/pipelineM0p.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/renderCostModel.constants.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/renderCostModel.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/renderReport.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/renderSidecars.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/resolveMosaicx.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/runPlan.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/types.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/upstream.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/writeSidecars.js +1 -1
- package/node_modules/@m0saic/core/dist/types/chunk.js +1 -1
- package/node_modules/@m0saic/core/dist/types/index.js +1 -1
- package/node_modules/@m0saic/core/dist/types/mosaic-plan.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/assertTiming.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/command.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/createEngineContext.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/createTemplateRenderCache.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/ffmpegColor.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/formatDuration.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/fsSafeId.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/index.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/lowerRenderableToMosaicDocument.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/movSafeCodec.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/resolveBoxFrac.js +1 -1
- package/node_modules/@m0saic/core/dist/validate/index.js +1 -1
- package/node_modules/@m0saic/core/scripts/mask-rasterize-core.js +1 -1
- package/node_modules/@m0saic/core/scripts/mask-rasterize-worker.js +1 -1
- package/node_modules/@m0saic/core/scripts/mask-worker-thread.js +1 -1
- package/node_modules/@m0saic/dictionary/NOTICE +9 -0
- package/node_modules/@m0saic/dictionary/README.md +315 -0
- package/node_modules/@m0saic/dictionary/package.json +1 -1
- package/node_modules/@m0saic/dsl/package.json +1 -1
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/agent.js +6 -0
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0/parseM0File.js +1 -1
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0/serializeM0File.js +2 -2
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0c/m0cFile.js +3 -3
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/types.js +1 -1
- package/node_modules/@m0saic/dsl-file-formats/package.json +1 -1
- package/node_modules/@m0saic/dsl-stdlib/dist/cjs/builders/bakeM0cInsets.js +1 -0
- package/node_modules/@m0saic/dsl-stdlib/dist/cjs/builders/index.js +1 -1
- package/node_modules/@m0saic/dsl-stdlib/package.json +1 -1
- package/node_modules/@m0saic/knowledge/LICENSE +21 -0
- package/node_modules/@m0saic/knowledge/README.md +71 -0
- package/node_modules/@m0saic/knowledge/dist/index.js +1 -0
- package/node_modules/@m0saic/knowledge/docs/README.md +60 -0
- package/node_modules/@m0saic/knowledge/docs/file-formats/m0-iteration-protocol.md +120 -0
- package/node_modules/@m0saic/knowledge/docs/file-formats/m0p-and-custom-field.md +195 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/README.md +27 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/composition-arithmetic.md +278 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/dsl-complexity.md +75 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/dsl-rules.md +367 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/feasibility-precision-quantization.md +591 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/m0-construction-methods.md +201 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/precision-tiers.md +84 -0
- package/node_modules/@m0saic/knowledge/docs/m0saic-thesis.md +95 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/README.md +24 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/agent-at-the-canvas.md +108 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/cli-usage.md +475 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/ffmpeg-expression-limits.md +117 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/reduce-to-one.md +96 -0
- package/node_modules/@m0saic/knowledge/docs/skills/README.md +40 -0
- package/node_modules/@m0saic/knowledge/docs/skills/axis-and-geometry.md +103 -0
- package/node_modules/@m0saic/knowledge/docs/skills/dsl-stdlib-method-catalog.md +7 -0
- package/node_modules/@m0saic/knowledge/docs/skills/identity.md +123 -0
- package/node_modules/@m0saic/knowledge/docs/skills/labels-and-masks.md +170 -0
- package/node_modules/@m0saic/knowledge/docs/skills/m0saic-string-generation.md +251 -0
- package/node_modules/@m0saic/knowledge/docs/skills/more-atoms-not-bigger-atoms.md +77 -0
- package/node_modules/@m0saic/knowledge/docs/skills/overlay-semantics.md +194 -0
- package/node_modules/@m0saic/knowledge/docs/skills/parse-apis.md +79 -0
- package/node_modules/@m0saic/knowledge/docs/skills/passthrough-semantics.md +136 -0
- package/node_modules/@m0saic/knowledge/docs/skills/structural-construction.md +86 -0
- package/node_modules/@m0saic/knowledge/docs/skills/text-in-templates.md +126 -0
- package/node_modules/@m0saic/knowledge/docs/skills/zero-overlay-analysis.md +87 -0
- package/node_modules/@m0saic/knowledge/docs/templates/README.md +65 -0
- package/node_modules/@m0saic/knowledge/docs/templates/capability-templates.md +72 -0
- package/node_modules/@m0saic/knowledge/docs/templates/construction-strategy.md +329 -0
- package/node_modules/@m0saic/knowledge/docs/templates/data-pipeline.md +324 -0
- package/node_modules/@m0saic/knowledge/docs/templates/emission-patterns.md +130 -0
- package/node_modules/@m0saic/knowledge/docs/templates/geometry-recipes.md +248 -0
- package/node_modules/@m0saic/knowledge/docs/templates/layout-contract.md +168 -0
- package/node_modules/@m0saic/knowledge/docs/templates/output-resolution-tree.md +210 -0
- package/node_modules/@m0saic/knowledge/docs/templates/patterns/case-study-lessons.md +69 -0
- package/node_modules/@m0saic/knowledge/docs/templates/patterns/perf-authoring-rules.md +100 -0
- package/node_modules/@m0saic/knowledge/docs/templates/patterns/primitive-extraction-pattern.md +103 -0
- package/node_modules/@m0saic/knowledge/docs/templates/philosophy-and-contract.md +310 -0
- package/node_modules/@m0saic/knowledge/docs/templates/recursion-nested-rendering.md +154 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/grid.md +104 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/json-prop-type.md +169 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/mosaic-color.md +81 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/mosaic-placement-props.md +103 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/prop-bindings.md +338 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/template-flags.md +236 -0
- package/node_modules/@m0saic/knowledge/docs/templates/render-lifecycle.md +117 -0
- package/node_modules/@m0saic/knowledge/docs/templates/rendering-model-contract.md +392 -0
- package/node_modules/@m0saic/knowledge/docs/templates/standalone-pack-authoring.md +309 -0
- package/node_modules/@m0saic/knowledge/docs/templates/theming.md +81 -0
- package/node_modules/@m0saic/knowledge/docs/templates/ui-controls.md +150 -0
- package/node_modules/@m0saic/knowledge/package.json +6 -0
- package/node_modules/@m0saic/momo-types/README.md +109 -0
- package/node_modules/@m0saic/momo-types/dist/agent.js +1 -6
- package/node_modules/@m0saic/momo-types/dist/context.js +1 -1
- package/node_modules/@m0saic/momo-types/package.json +1 -1
- package/node_modules/@m0saic/platform/README.md +3 -0
- package/node_modules/@m0saic/platform/dist/cjs/index.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/mosaic/outputKind/outputKind.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/mosaic/propBindings/index.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/mosaic/propBindings/propBindings.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/mosaic/validate/validateSources.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/packages/mosaicPackages.js +1 -0
- package/node_modules/@m0saic/platform/dist/cjs/paths/m0saicRoot.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/lifecycle.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/preview.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/sender.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/usageRecorder.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/usageStore.js +3 -3
- package/node_modules/@m0saic/platform/dist/cjs/template-repos/index.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/template-repos/loadTemplateRepoFromPath.js +4 -4
- package/node_modules/@m0saic/platform/dist/cjs/template-repos/templateCatalogSidecars.js +2 -0
- package/node_modules/@m0saic/platform/dist/cjs/templateCatalog/index.js +1 -0
- package/node_modules/@m0saic/platform/dist/cjs/templateCatalog/templateCatalog.js +1 -0
- package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/baseline.json +25 -97
- package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/index.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/install.js +2 -2
- package/node_modules/@m0saic/platform/dist/cjs/toolchain/goldenFfmpeg.js +6 -6
- package/node_modules/@m0saic/platform/package.json +1 -1
- package/node_modules/@m0saic/product/dist/communityRelease.js +1 -1
- package/node_modules/@m0saic/product/dist/freeTierLicense.js +1 -1
- package/node_modules/@m0saic/product/dist/index.js +1 -1
- package/node_modules/@m0saic/product/dist/licenseActivationNotice.js +1 -0
- package/node_modules/@m0saic/product/dist/licenseFile.js +1 -0
- package/node_modules/@m0saic/product/dist/licenseToken.js +1 -1
- package/node_modules/@m0saic/product/dist/makeScratchPath.js +1 -0
- package/node_modules/@m0saic/product/dist/postRenderWrapper.js +1 -1
- package/node_modules/@m0saic/product/dist/publicKeys.js +1 -1
- package/node_modules/@m0saic/product/dist/revokedKeys.js +1 -1
- package/node_modules/@m0saic/product/dist/upstreamDefaults.js +1 -1
- package/node_modules/@m0saic/product/dist/workspaceScaffold.js +1 -0
- package/node_modules/@m0saic/template-utils/dist/brand/hello-world/helloWorld.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/geometry-contract/frameResolution.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/geometry-contract/index.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/geometry-contract/layoutConstraint.js +2 -2
- package/node_modules/@m0saic/template-utils/dist/m0saic/loadSession.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/render/createDesignContext.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/sources/makeErrorMosaic.js +2 -2
- package/node_modules/@m0saic/template-utils/dist/sources/svgTextSource.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/template/auditRenderedTemplate.js +5 -5
- package/node_modules/@m0saic/template-utils/dist/template/auditSchemaConventions.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/template/defineMosaicTemplate.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/template/resolveTemplateOutputHints.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/template/templateCatalogStore.js +1 -0
- package/node_modules/@m0saic/template-utils/dist/template/templateConventions.js +4 -4
- package/node_modules/@m0saic/template-utils/dist/template/templateRegistry.js +3 -3
- package/node_modules/@m0saic/template-utils/dist/template/validateTemplateProps.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/text/fitText.js +6 -6
- package/node_modules/@m0saic/template-utils/package.json +1 -1
- package/node_modules/@m0saic/templates/NOTICE +9 -0
- package/node_modules/@m0saic/templates/dist/catalog.js +1 -0
- package/node_modules/@m0saic/templates/dist/freeze.js +8 -8
- package/node_modules/@m0saic/templates/dist/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/_shared/canvas-handles.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/_shared/stand-in.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/agents/commit-feed/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/agents/commit-feed/v2/commit-feed.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/agents/commit-feed/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/agents/trace-timeline/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/agents/trace-timeline/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/agents/trace-timeline/v2/trace-timeline.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/_shared/alpine-conventions.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/bar-graph/v2/bar-graph.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/bar-graph/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/commit-feed/v3/commit-feed.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/commit-feed/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/contributor-table/v2/contributor-table.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/contributor-table/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/donut/v4/donut.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/donut/v4/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/heatmap/v3/heatmap.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/heatmap/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/kpi-card/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/kpi-card/v3/kpi-card.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/leaderboard/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/leaderboard/v2/leaderboard.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/line-chart/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/line-chart/v3/line-chart.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/progress-card/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/progress-card/v2/progress-card.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/stat-card/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/stat-card/v2/stat-card.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/timeline/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/timeline/v3/timeline.js +4 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/treemap/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/alpine/treemap/v3/treemap.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/benchmark/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/benchmark/report/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/benchmark/report/v2/report.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/brand/business-card/v2/business-card.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/brand/business-card/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/brand/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/brand/logo/v4/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/brand/logo/v4/logo_runner.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/charts/bar-graph/v3/bar-graph.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/charts/bar-graph/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/charts/donut/v5/donut.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/charts/donut/v5/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/charts/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/charts/line-chart/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/charts/line-chart/v2/line-chart.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/charts/stat-card/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/charts/stat-card/v2/stat-card.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/code/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/code/snippet-morph/v2/snippet-morph.js +3 -0
- package/node_modules/@m0saic/templates/dist/m0saic/collage/image-collage/v2/image-collage.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/collage/image-collage/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/collage/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/dsl-tutorial/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/dsl-tutorial/v2/dsl-tutorial.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/dsl-tutorial/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/github/year-card/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/github/year-card/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/github/year-card/v2/year-card.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/hero/ffmpeg-pulse/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/hero/ffmpeg-pulse/runner/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/hero/ffmpeg-pulse/runner/v2/runner.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/barcode/v2/barcode.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/barcode/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/v1/tutorial.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/v2/blur-regions.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/highlights/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/highlights/v2/highlights.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/highlights/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/logo-animate/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/logo-animate/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/logo-animate/v2/logo-animate.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/metadata-stamp/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/metadata-stamp/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/metadata-stamp/v2/metadata-stamp.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/qr/code/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/qr/code/v2/qr-code.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/qr/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/qr/stamp/v2/qr-stamp-custom.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid/v3/screencap-grid.js +4 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid_aspect_safe/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid_aspect_safe/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid_aspect_safe/v2/screencap-grid-aspect-safe.js +3 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/scroll_wall/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/scroll_wall/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/scroll_wall/v2/scroll-wall.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/subtitle-burn/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/subtitle-burn/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/subtitle-burn/v2/subtitle-burn.js +4 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/trickplay/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/trickplay/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/trickplay/v2/trickplay.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/video_to_png_sequence/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/video_to_png_sequence/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/video_to_png_sequence/v2/video-to-png-sequence.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/watermark/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/media/watermark/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/watermark/v2/watermark.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/primitives/grid/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/primitives/grid/v3/grid.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/social/quote-card/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/social/quote-card/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/social/quote-card/v2/quote-card.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/story/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/story/narrated-chapters/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/story/narrated-chapters/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/story/narrated-chapters/v2/narrated-chapters.js +4 -0
- package/node_modules/@m0saic/templates/dist/m0saic/story/scrapbook/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/story/scrapbook/v2/props.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/story/scrapbook/v2/scrapbook.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/theming/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/theming/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/theming/v2/theming.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/web/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/m0saic/web/page-skeleton/v2/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/web/page-skeleton/v2/page-skeleton.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/wireframe/base/v3/index.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/wireframe/base/v3/wireframe.js +1 -0
- package/node_modules/@m0saic/templates/dist/m0saic/wireframe/index.js +1 -1
- package/node_modules/@m0saic/templates/dist/repo.js +1 -1
- package/node_modules/@m0saic/templates/dist/template-catalog.json +5429 -0
- package/node_modules/@m0saic/templates/dist/template-registry.js +1 -1
- package/node_modules/@m0saic/templates/dist/web.js +1 -1
- package/node_modules/@m0saic/templates/package.json +1 -1
- package/node_modules/@m0saic/templates/template-catalog.json +5429 -0
- package/node_modules/@m0saic/templates/template-manifest.json +1030 -286
- package/node_modules/@m0saic/templates/web-template-ids.json +38 -0
- package/node_modules/@m0saic/templates-advanced/NOTICE +9 -0
- package/node_modules/@m0saic/text/package.json +1 -1
- package/node_modules/@m0saic/types/dist/analytics/consent.js +1 -1
- package/node_modules/@m0saic/types/dist/analytics/event.js +1 -1
- package/node_modules/@m0saic/types/dist/analytics/usageMetrics.js +1 -1
- package/node_modules/@m0saic/types/dist/identifiers/identifiers.js +1 -1
- package/node_modules/@m0saic/types/dist/telemetry/ffmpegFailure.js +1 -1
- package/node_modules/@m0saic/types/dist/template/template.js +1 -1
- package/node_modules/@m0saic/types/package.json +1 -1
- package/node_modules/@m0saic/types-internal/dist/analytics/featureKeys.js +1 -1
- package/package.json +13 -11
- package/resources/starter-base/starter-base.json +10 -0
- package/resources/starter-base/starter-base.tgz +0 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# m0 Generator Guidelines
|
|
2
|
+
|
|
3
|
+
Practical algorithm outline for generating valid m0 strings programmatically. **Prefer official helpers over hand-emitting tokens.**
|
|
4
|
+
|
|
5
|
+
> **Source of truth:**
|
|
6
|
+
> - Builders: [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/builders](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/builders)
|
|
7
|
+
> - Unified transforms: [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/transforms/unified](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/transforms/unified)
|
|
8
|
+
> - Validation: [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate)
|
|
9
|
+
> - Feasibility: [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/feasibility](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/feasibility)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 0. Prime directives
|
|
14
|
+
|
|
15
|
+
### 0.1 Prefer library ops over hand-writing strings
|
|
16
|
+
|
|
17
|
+
If an official op/helper exists for the transformation you want, **use it** instead of emitting raw m0 tokens.
|
|
18
|
+
|
|
19
|
+
Three primary sources of safe generation:
|
|
20
|
+
|
|
21
|
+
- **`@m0saic/dsl-stdlib/builders`** — high-level builders (`grid`, `weightedSplit`, `strip`, `container`, `aspectFit`, `placeRect`/`placeRects`, `rectsToM0`, `safeCanvas`, `snapGridFit`, `spotlight`, `comparison`, `rankedList`, `goldenSplit`, `goldenSpiral`, etc.). Full surface: see [`dsl-stdlib-method-catalog.md`](./dsl-stdlib-method-catalog.md).
|
|
22
|
+
- **`@m0saic/dsl-stdlib/transforms`** — unified ops (`split`, `replace`, `addOverlay`, `removeOverlay`, `setTileType`, `measureSplit`, `swapFrames`).
|
|
23
|
+
- **`@m0saic/dsl`** — low-level parsing + validation; never the right tool for *generation*.
|
|
24
|
+
|
|
25
|
+
Raw string emission is a **last resort.**
|
|
26
|
+
|
|
27
|
+
### 0.2 Use `grid` for grids
|
|
28
|
+
|
|
29
|
+
For row/column grids (equal cells, weighted cells, gutters, outer gutters), call:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { grid } from "@m0saic/dsl-stdlib";
|
|
33
|
+
|
|
34
|
+
const result = grid({ rows: 3, cols: 4, gutter: 0.05 });
|
|
35
|
+
// result.m0 — canonical m0 string
|
|
36
|
+
// result.totalX, result.totalY — split factors
|
|
37
|
+
// result.cellW, result.gutterW — resolved weights
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The builder handles weighted-split expansion via `0` carry runs, gutter `-` slots, the illegal `1(...)` / `1[...]` rule, exact classifier-count = child-slot count, and canonical output. **Don't hand-author split trees.**
|
|
41
|
+
|
|
42
|
+
Workflow: build the base layout with a builder, apply targeted edits with unified transforms, validate.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 1. Validation and feasibility
|
|
47
|
+
|
|
48
|
+
### 1.1 Always validate
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { validateM0String } from "@m0saic/dsl";
|
|
52
|
+
|
|
53
|
+
const v = validateM0String(m0);
|
|
54
|
+
if (!v.ok) {
|
|
55
|
+
// v.error is a single structured violation: { code, kind, message, ... }
|
|
56
|
+
// (singular — https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/errors/errors.ts M0ValidationResult)
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Boolean shortcut: `isValidM0String(m0)`.
|
|
61
|
+
|
|
62
|
+
The validator enforces grammar, token rules, overlay correctness, child-count exactness, the trailing-passthrough rule (trailing `0` is always invalid, even with overlay), and the no-sources rule (≥1 leaf `1` required somewhere in the layout). Overlay bodies do NOT need their own source — sourceless bodies like `1{-}` are legal (relaxed 2026-06-03; see [`overlay-semantics.md`](overlay-semantics.md)). See [`handbook/dsl-rules.md`](../handbook/dsl-rules.md) for the full grammar.
|
|
63
|
+
|
|
64
|
+
### 1.2 Check feasibility when dimensions are known
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { computeFeasibility } from "@m0saic/dsl";
|
|
68
|
+
|
|
69
|
+
const f = computeFeasibility(m0);
|
|
70
|
+
if (targetWidth < f.minWidthPx || targetHeight < f.minHeightPx) {
|
|
71
|
+
// Layout cannot render at this resolution — would produce 0-size frames.
|
|
72
|
+
throw new Error(`Below feasible: ${f.minWidthPx}×${f.minHeightPx}`);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If you parse anyway, `parseM0StringComplete` emits `SPLIT_EXCEEDS_AXIS` at parse time:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { parseM0StringComplete } from "@m0saic/dsl";
|
|
80
|
+
|
|
81
|
+
const parsed = parseM0StringComplete(m0, width, height);
|
|
82
|
+
// parsed.precision, parsed.warnings, optional parsed.error
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 1.3 Feasibility vs. precision (important distinction)
|
|
86
|
+
|
|
87
|
+
- **`computeFeasibility`** — exact `{ minWidthPx, minHeightPx }`. Accounts for nested same-axis splits, passthrough carry chains, overlays. Use for all feasibility decisions.
|
|
88
|
+
- **Precision** is a separate, independent floor (neither bounds the other). For a combined verdict use `evaluateM0` from `@m0saic/dsl-stdlib` — it returns `feasible`, `meetsPrecision`, and `recommendedMin` (the per-axis max of both floors). (`computePrecisionFromString` is an internal dsl helper, not public API.)
|
|
89
|
+
|
|
90
|
+
See [`../handbook/feasibility-precision-quantization.md`](../handbook/feasibility-precision-quantization.md) (canonical) for the two-floor model.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 2. Unified transforms — the canonical API for structural changes
|
|
95
|
+
|
|
96
|
+
When you mutate an existing string, use the unified transforms exported from `@m0saic/dsl-stdlib`. Every transform takes `(m0, target, options) → m0` where `target: TransformTarget` is a discriminated union.
|
|
97
|
+
|
|
98
|
+
### TransformTarget
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
type TransformTarget =
|
|
102
|
+
| { by: "logicalIndex"; index: number } // 0-based index of rendered frames (1/F only)
|
|
103
|
+
| { by: "span"; span: { start: number; end: number } } // exact char span
|
|
104
|
+
| { by: "stableKey"; key: string }; // structural identity path
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Pick the addressing mode that matches your invariant — `logicalIndex` for "the Nth rendered tile," `stableKey` for "this specific node, even after edits," `span` for parser-visible ranges. See [`../file-formats/m0p-and-custom-field.md`](../file-formats/m0p-and-custom-field.md) and [`identity.md`](identity.md) for identity semantics.
|
|
108
|
+
|
|
109
|
+
### 2.1 Split
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { split } from "@m0saic/dsl-stdlib";
|
|
113
|
+
|
|
114
|
+
// Uniform 3-way column split on the 0th tile
|
|
115
|
+
split(m0, { by: "logicalIndex", index: 0 }, { axis: "col", count: 3 });
|
|
116
|
+
|
|
117
|
+
// Weighted split: weights.length must equal count
|
|
118
|
+
split(m0, { by: "logicalIndex", index: 0 }, { axis: "col", count: 2, weights: [60, 40] });
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
GCD-reduces emitted DSL by default. Pass `weightMode: "literal"` to preserve exact slot count.
|
|
122
|
+
|
|
123
|
+
### 2.2 Measure-mode split
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { measureSplit } from "@m0saic/dsl-stdlib";
|
|
127
|
+
|
|
128
|
+
// axis "col" or "row"; count = granularity; ranges are {a, b} objects (inclusive)
|
|
129
|
+
// (MeasureSplitOptions — https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/transforms/unified/measureSplit.ts#L9)
|
|
130
|
+
measureSplit(m0, { by: "logicalIndex", index: 1 }, { axis: "row", count: 12, ranges: [{ a: 2, b: 8 }] });
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 2.3 Set leaf type
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { setTileType } from "@m0saic/dsl-stdlib";
|
|
137
|
+
|
|
138
|
+
// Change a leaf to "-" (null), ">" (passthrough), "F" (frame), or "1"
|
|
139
|
+
setTileType(m0, { by: "logicalIndex", index: 0 }, "-");
|
|
140
|
+
setTileType(m0, { by: "stableKey", key: "r/growc0/fc1" }, ">");
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 2.4 Add / remove overlay
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { addOverlay, removeOverlay } from "@m0saic/dsl-stdlib";
|
|
147
|
+
|
|
148
|
+
addOverlay(m0, { by: "logicalIndex", index: 2 }); // visual overlay
|
|
149
|
+
removeOverlay(m0, { by: "stableKey", key: "r/fc2" });
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 2.5 Replace / swap
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import { replace, swapFrames } from "@m0saic/dsl-stdlib";
|
|
156
|
+
|
|
157
|
+
replace(m0, { by: "logicalIndex", index: 0 }, "2(F,F)"); // replace subtree at target
|
|
158
|
+
swapFrames(m0, 0, 1); // swap rendered tiles — takes two logicalIndex numbers
|
|
159
|
+
// directly, NOT a TransformTarget (the one exception to §2)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 3. Repair-loop strategy
|
|
165
|
+
|
|
166
|
+
When validation fails, apply targeted repairs instead of regenerating from scratch.
|
|
167
|
+
|
|
168
|
+
### 3.1 ILLEGAL_ONE_SPLIT
|
|
169
|
+
|
|
170
|
+
Problem: `1(...)` or `1[...]` — wrapping a single child as a pseudo-container is illegal.
|
|
171
|
+
|
|
172
|
+
Fix: drop the `1(...)` wrapper or use `0`-runs instead.
|
|
173
|
+
|
|
174
|
+
### 3.2 Trailing passthrough
|
|
175
|
+
|
|
176
|
+
Problem: last child in a split is `0` (even with overlay — `0{...}` trailing is always invalid).
|
|
177
|
+
|
|
178
|
+
Fix:
|
|
179
|
+
- Replace trailing `0` with `-`: `2(1,0)` → `2(1,-)`
|
|
180
|
+
- Or replace trailing `0` with `1`: `2(1,0)` → `2(1,1)`
|
|
181
|
+
|
|
182
|
+
Don't use `2(1,0{1})` — trailing passthrough with overlay is still invalid.
|
|
183
|
+
|
|
184
|
+
### 3.3 TOKEN_COUNT mismatch
|
|
185
|
+
|
|
186
|
+
Problem: classifier `N` doesn't match the number of children.
|
|
187
|
+
|
|
188
|
+
Fix: adjust `N` to match children, or add/remove children to match `N`.
|
|
189
|
+
|
|
190
|
+
### 3.4 SPLIT_EXCEEDS_AXIS
|
|
191
|
+
|
|
192
|
+
Problem: classifier count exceeds available pixels on an axis.
|
|
193
|
+
|
|
194
|
+
Fixes (in order):
|
|
195
|
+
1. Reduce split count.
|
|
196
|
+
2. Collapse subtree to `1`.
|
|
197
|
+
3. Replace with fewer parts.
|
|
198
|
+
|
|
199
|
+
### 3.5 NO_SOURCES
|
|
200
|
+
|
|
201
|
+
Problem: the layout as a whole contains no leaf `1` (overlay bodies are allowed to be
|
|
202
|
+
sourceless — `ZERO_SOURCE_OVERLAY` is no longer raised).
|
|
203
|
+
|
|
204
|
+
Fix: ensure at least one `1` / `F` exists somewhere (a source inside an overlay counts:
|
|
205
|
+
`2(-,-){1}` is valid). See [`overlay-semantics.md`](overlay-semantics.md).
|
|
206
|
+
|
|
207
|
+
### 3.6 INVALID_CHAR / TOKEN_RULE
|
|
208
|
+
|
|
209
|
+
Problem: malformed output. **Generator bug** — fix the generation logic, don't band-aid the output.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 4. Overlay body constraints
|
|
214
|
+
|
|
215
|
+
Bodies are parsed as complete m0 sub-expressions: non-empty, not a bare `0`
|
|
216
|
+
(`INVALID_EMPTY`), no trailing passthrough — but they do **NOT** need a leaf `1`
|
|
217
|
+
(sourceless `{-}` / `{2(-,-)}` are legal; relaxed 2026-06-03). Full rules:
|
|
218
|
+
[`overlay-semantics.md`](overlay-semantics.md) and
|
|
219
|
+
[`structural-construction.md`](structural-construction.md) §7.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 5. Output format options
|
|
224
|
+
|
|
225
|
+
Most ops accept output options:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
{ output: "canonical" } // 1, 0
|
|
229
|
+
{ output: "pretty" } // F, >
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Agents should prefer canonical output for machine use unless pretty is explicitly required.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## 6. Precision warnings
|
|
237
|
+
|
|
238
|
+
High classifier counts emit `PRECISION_EXCEEDS_NORM` warnings (informational, never
|
|
239
|
+
blocking; raise the threshold via `parseM0StringComplete(s, w, h, { precisionNorm: 256 })`).
|
|
240
|
+
The two-floor feasibility/precision model:
|
|
241
|
+
[`../handbook/feasibility-precision-quantization.md`](../handbook/feasibility-precision-quantization.md).
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## See also
|
|
246
|
+
|
|
247
|
+
- [`../handbook/dsl-rules.md`](../handbook/dsl-rules.md) — full grammar.
|
|
248
|
+
- [`../handbook/feasibility-precision-quantization.md`](../handbook/feasibility-precision-quantization.md) — feasibility rules (canonical).
|
|
249
|
+
- [`structural-construction.md`](structural-construction.md) — structural-build patterns.
|
|
250
|
+
- [`overlay-semantics.md`](overlay-semantics.md) — overlay rules.
|
|
251
|
+
- [`parse-apis.md`](parse-apis.md) — parser entry points.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# More atoms, never bigger atoms — the scaling contract with ffmpeg
|
|
2
|
+
|
|
3
|
+
> The measured cliffs behind atom 1 (and the "graph-size OOM" debunk) live in
|
|
4
|
+
> [`../runtime/ffmpeg-expression-limits.md`](../runtime/ffmpeg-expression-limits.md).
|
|
5
|
+
> This is the general principle; that is the case study.
|
|
6
|
+
|
|
7
|
+
m0saic renders arbitrarily complex templates by splitting work into pieces.
|
|
8
|
+
That works because ffmpeg capacity scales with the NUMBER of things it is
|
|
9
|
+
given (commands, inputs, filters, files). It breaks when a feature grows a
|
|
10
|
+
single UNPARTITIONABLE ATOM with content. Chunking cannot rescue a bigger
|
|
11
|
+
atom — the atom is smaller than a command.
|
|
12
|
+
|
|
13
|
+
## The four atoms (with measured walls)
|
|
14
|
+
|
|
15
|
+
1. **One expression string.** `av_expr_parse` has a ~100 recursion budget:
|
|
16
|
+
~98 flat `+` terms or ~100 nesting levels, independent of char length.
|
|
17
|
+
Failure is a phantom `Cannot allocate memory` (−12) or `Invalid
|
|
18
|
+
argument` (−22) at graph init, in <80 ms. Applies to EVERY expression:
|
|
19
|
+
`enable`, `geq`, crop/scale/drawtext params, `%{eif}`.
|
|
20
|
+
2. **One filter's per-frame work.** `geq` interprets its expression per
|
|
21
|
+
pixel per plane per frame (nodes × W × H × fps). No crash — render time
|
|
22
|
+
explodes. Chunking does not reduce it: same pixels either way.
|
|
23
|
+
3. **One frame's memory.** frames-in-flight × W × H × 4 B. Buffering
|
|
24
|
+
filters (`loop=size=N`, `split`, framesync queues, `tpad`) and
|
|
25
|
+
resolution multiply it; filter COUNT does not (12,000 chained filters /
|
|
26
|
+
1.19 MB single graph verified fine).
|
|
27
|
+
4. **One process's argv.** Windows caps ~32 K → `ENAMETOOLONG`.
|
|
28
|
+
|
|
29
|
+
## The classification test (apply to any content-scaled feature)
|
|
30
|
+
|
|
31
|
+
When something scales with content (N tiles, steps, keyframes, data
|
|
32
|
+
points), ask: **which quantity grows?**
|
|
33
|
+
|
|
34
|
+
- Count of commands / inputs / filters / workspace files grows → MORE
|
|
35
|
+
ATOMS → fine; capacity, chunkable.
|
|
36
|
+
- A single expression, a single filter's per-pixel cost, a single frame's
|
|
37
|
+
resident bytes, or argv grows → BIGGER ATOM → redesign before shipping.
|
|
38
|
+
|
|
39
|
+
## Bigger-atom anti-patterns → more-atoms replacements
|
|
40
|
+
|
|
41
|
+
| anti-pattern (bigger atom) | replacement (more atoms / bounded atom) |
|
|
42
|
+
|---|---|
|
|
43
|
+
| nested `if(cond,…,else)` per keyframe (`expr = if(...,${expr})` builders) | flat gated sum: `lt(t,t0)*(v0)+(gte·lt)*seg+…+gte(t,tN)*(vN)` |
|
|
44
|
+
| `.join("+")` on a content-scaled window list, emitted raw | route through the funnels (below) or `rebalanceAdditiveChains` |
|
|
45
|
+
| `geq` on a canvas/panel-sized stream | static SVG/PNG mask + `alphamerge`; keep geq on small intermediates |
|
|
46
|
+
| animated values as ever-larger exprs | pre-render to a small intermediate (value `.mov`s, text renders) |
|
|
47
|
+
| content-scaled string inline in argv (`-i lavfi`, drawtext text) | workspace file (`-filter_complex_script`, `-graph_file`, `textfile=`) |
|
|
48
|
+
| full-res lossless-alpha (qtrle/argb) intermediates on opaque nodes | alpha intermediates only where alpha flows |
|
|
49
|
+
|
|
50
|
+
## Existing enforcement (route new work through these; do not bypass)
|
|
51
|
+
|
|
52
|
+
- `rebalanceAdditiveChains` (`@m0saic/platform` ffexpr) auto-applied at the
|
|
53
|
+
funnels: `quoteEnableArg` (all `:enable=`), `buildOverlayAlphaFilter`
|
|
54
|
+
(enable→geq alpha fold), `buildCameraFilters` (zoom/focus). >32 flat
|
|
55
|
+
terms → balanced tree (O(log n) depth, verified past 1024 terms); ≤32
|
|
56
|
+
passes byte-identical. It CANNOT fix nesting — builders must emit flat
|
|
57
|
+
shapes.
|
|
58
|
+
- Input-count split (`maxInputsPerCommand`) — more commands per node.
|
|
59
|
+
- Graph/text file lowering — argv atom stays constant.
|
|
60
|
+
- SVG rounding rasterizer (default) — rounding is a mask input, not geq.
|
|
61
|
+
|
|
62
|
+
Known bypasses to watch: hand-rolled lavfi `enable=` strings (dsl-string
|
|
63
|
+
caret track, dsl-canvas drawbox — currently ≤3 terms) and nested-if
|
|
64
|
+
builders in other templates (e.g. line-chart anim) that will hit atom 1 if
|
|
65
|
+
their datasets grow.
|
|
66
|
+
|
|
67
|
+
## Review greps
|
|
68
|
+
|
|
69
|
+
`join("+")` on generated arrays; recursive expr accumulation
|
|
70
|
+
(`= \`if(…,${expr})\``); `geq` fed by canvas-sized labels; content
|
|
71
|
+
interpolation into `-i`/argv rather than a workspace file.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
*Per-pixel eval cost (atom 2) is the next practical wall at denser grids — a
|
|
76
|
+
perf ceiling, not a crash; fix it representationally (masks, pre-rendered
|
|
77
|
+
intermediates), not by chunking.*
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
## Overlay Semantics & Paint Order
|
|
2
|
+
|
|
3
|
+
Overlays are recursive layout subtrees rendered inside an owner's rect — a first-class
|
|
4
|
+
compositional primitive, not just "layers". This doc covers attachment, paint order,
|
|
5
|
+
deferred zero-overlay paint, the overlay-body validity rule, and composition at scale.
|
|
6
|
+
|
|
7
|
+
> **Source of truth:** overlay parsing in [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts);
|
|
8
|
+
> overlay-body validation in [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate/m0StringValidator.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate/m0StringValidator.ts)
|
|
9
|
+
> (relaxation comment at lines 479–486); error codes in [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/errors/errors.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/errors/errors.ts).
|
|
10
|
+
> Every accept/reject example below was runtime-verified against https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/dist
|
|
11
|
+
> via `validateM0String` on 2026-07-27.
|
|
12
|
+
|
|
13
|
+
## Attachment: any node can own an overlay
|
|
14
|
+
|
|
15
|
+
Form:
|
|
16
|
+
|
|
17
|
+
node{ overlay_body }
|
|
18
|
+
|
|
19
|
+
`node` may be ANY node kind — not just `1`:
|
|
20
|
+
|
|
21
|
+
- `1` (tile), `0` (passthrough), `-` (null — child position only; see Logical Owner)
|
|
22
|
+
- `N(...)` / `N[...]` (splits)
|
|
23
|
+
- a node that is itself an overlay owner (chains)
|
|
24
|
+
|
|
25
|
+
No base `1` is required for an overlay to exist. A chain of full layouts is legal:
|
|
26
|
+
|
|
27
|
+
2(1,1){3(1,1,1){2(1,1)}} — base 2-col, overlay 3-col, overlay-on-overlay 2-col
|
|
28
|
+
|
|
29
|
+
Rules:
|
|
30
|
+
|
|
31
|
+
- At most ONE immediate overlay object per node — `1{1}{1}` rejects
|
|
32
|
+
(`OVERLAY_CHAIN`). Stack by nesting instead: `1{1{1}}`.
|
|
33
|
+
- The overlay body must validate independently as a full m0 string, recursively.
|
|
34
|
+
- Nesting depth is structurally unbounded — but see the render-cost caveat below.
|
|
35
|
+
|
|
36
|
+
Valid: `1{1}` · `2(1,1){1}` · `1{1{1}}` · `2(1,1){3(1,1,1){2(1,1)}}`
|
|
37
|
+
|
|
38
|
+
## Overlay rect = owner rect
|
|
39
|
+
|
|
40
|
+
The overlay subtree is parsed against owner.x / owner.y / owner.width / owner.height.
|
|
41
|
+
|
|
42
|
+
- It does NOT inherit sibling geometry.
|
|
43
|
+
- It does NOT escape its parent rect.
|
|
44
|
+
|
|
45
|
+
Applies to tile, group, null, and zero overlays alike.
|
|
46
|
+
|
|
47
|
+
## Overlays never mutate geometry
|
|
48
|
+
|
|
49
|
+
Overlay stacking, at any depth:
|
|
50
|
+
|
|
51
|
+
- does NOT change splitEven results or sibling sizes
|
|
52
|
+
- does NOT change structuralDepth
|
|
53
|
+
- does NOT alter stableKeys of the base structure
|
|
54
|
+
|
|
55
|
+
It only increments `overlayDepth` and adds paint layers. The base layout defines
|
|
56
|
+
geometry; overlay chains define drawing.
|
|
57
|
+
|
|
58
|
+
## Paint order
|
|
59
|
+
|
|
60
|
+
Deterministic, defined by engine traversal.
|
|
61
|
+
|
|
62
|
+
### Tile overlay
|
|
63
|
+
|
|
64
|
+
1{1}
|
|
65
|
+
|
|
66
|
+
1. Base tile
|
|
67
|
+
2. Overlay subtree (immediately after owner)
|
|
68
|
+
|
|
69
|
+
### Group overlay
|
|
70
|
+
|
|
71
|
+
2(1,1){1}
|
|
72
|
+
|
|
73
|
+
1. Child 0
|
|
74
|
+
2. Child 1
|
|
75
|
+
3. Group overlay — group overlays paint AFTER all base children.
|
|
76
|
+
|
|
77
|
+
### Zero overlay (deferred paint)
|
|
78
|
+
|
|
79
|
+
3(0{1},1,1)
|
|
80
|
+
|
|
81
|
+
Zero overlays do NOT paint immediately; they defer until the claimant renders:
|
|
82
|
+
|
|
83
|
+
1. Claimant tile
|
|
84
|
+
2. Deferred zero overlay
|
|
85
|
+
|
|
86
|
+
Multiple zero overlays in one run:
|
|
87
|
+
|
|
88
|
+
3(0{1},0{1},1)
|
|
89
|
+
|
|
90
|
+
1. Claimant
|
|
91
|
+
2. Larger-area zero overlay
|
|
92
|
+
3. Smaller-area zero overlay (top-most)
|
|
93
|
+
|
|
94
|
+
Deferred zero overlays are sorted by area DESCENDING → smaller overlays paint on top.
|
|
95
|
+
|
|
96
|
+
### Claimant with its own overlay
|
|
97
|
+
|
|
98
|
+
3(0{1},1{1},1)
|
|
99
|
+
|
|
100
|
+
1. Claimant tile
|
|
101
|
+
2. Claimant's own overlay
|
|
102
|
+
3. Deferred zero overlay — always after the claimant AND the claimant's overlay.
|
|
103
|
+
|
|
104
|
+
### Nested overlays
|
|
105
|
+
|
|
106
|
+
1{1{1}}
|
|
107
|
+
|
|
108
|
+
1. Base tile
|
|
109
|
+
2. First overlay
|
|
110
|
+
3. Nested overlay
|
|
111
|
+
|
|
112
|
+
## Logical owner `-`
|
|
113
|
+
|
|
114
|
+
`-{X}` marks `isLogicalOwner = true`: the base does not render, but the overlay rect
|
|
115
|
+
exists and carry is still absorbed if it is a claimant. Use for editor semantics and
|
|
116
|
+
labeling containers.
|
|
117
|
+
|
|
118
|
+
Position matters: `-{...}` is valid in a child slot or inside an overlay body, NOT as
|
|
119
|
+
the whole-string root — `2(-{1},1)` and `1{-{1}}` accept; bare `-{1}` rejects
|
|
120
|
+
(`TOKEN_RULE`), as does a bare `-` root (`INVALID_EMPTY`).
|
|
121
|
+
|
|
122
|
+
## Overlay depth vs structural depth
|
|
123
|
+
|
|
124
|
+
Two independent counters:
|
|
125
|
+
|
|
126
|
+
- `structuralDepth` — increases entering numeric containers; root = 0.
|
|
127
|
+
- `overlayDepth` — increases entering `{...}`; base layout = 0, first overlay = 1.
|
|
128
|
+
|
|
129
|
+
Overlay frames inherit the structuralDepth of their context and use a separate frame
|
|
130
|
+
namespace.
|
|
131
|
+
|
|
132
|
+
## Overlay body node rule (`INVALID_EMPTY`)
|
|
133
|
+
|
|
134
|
+
An overlay body `{...}` must contribute at least ONE node to the graph, but does not
|
|
135
|
+
have to paint. Logical-owner anchors (`-{X}`) are the common shape.
|
|
136
|
+
|
|
137
|
+
Rejected — zero nodes, or a single root with nothing to act on:
|
|
138
|
+
|
|
139
|
+
1{} — empty body; no nodes at all
|
|
140
|
+
1{0} — bare passthrough at the overlay root; nothing to donate to
|
|
141
|
+
1{-{}} — recursive: the inner `{}` is rejected (deepest offender reported)
|
|
142
|
+
|
|
143
|
+
Accepted — at least one node, even if nothing paints:
|
|
144
|
+
|
|
145
|
+
1{-} — single null node; logical-owner anchor
|
|
146
|
+
1{2(-,-)} — all-null split; structural nodes, no paint
|
|
147
|
+
1{2(0,-)} — passthrough with a sibling to donate space to
|
|
148
|
+
1{-{-}} — nested logical owners
|
|
149
|
+
1{-{2(0,-)}} — nested with structural content
|
|
150
|
+
1{2(-,1)} — overlay body has a source (always valid)
|
|
151
|
+
1{2[1,1]{1}} — nested overlay body has a source
|
|
152
|
+
|
|
153
|
+
The legacy `ZERO_SOURCE_OVERLAY` rule (body must contain at least one leaf `1`) was
|
|
154
|
+
relaxed 2026-06-03 — overlay bodies no longer have to paint, only exist as nodes
|
|
155
|
+
([`m0StringValidator.ts`](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate/m0StringValidator.ts):479–486).
|
|
156
|
+
The whole-string `NO_SOURCES` check still requires the OUTER (root) layout to produce
|
|
157
|
+
at least one source tile, so the renderer is never asked to draw a fully empty canvas.
|
|
158
|
+
|
|
159
|
+
Error code when rejected: `INVALID_EMPTY` (kind `SYNTAX`).
|
|
160
|
+
|
|
161
|
+
## Composition at scale: deep overlay stacks
|
|
162
|
+
|
|
163
|
+
Overlay chains are how large rect sets are composed: each `{}` wraps a full valid
|
|
164
|
+
subtree, and each layer paints inside the owner's rect. A 109-overlay brand mark —
|
|
165
|
+
each overlay an independently calculated m0saic drawing one precise rectangle — is a
|
|
166
|
+
measured working example; its serialized string ran to tens of thousands of
|
|
167
|
+
characters, which parse/validate/walk handle without issue.
|
|
168
|
+
|
|
169
|
+
Deep stacks are editor-clean: each overlay is its own layer, filterable by
|
|
170
|
+
`overlayDepth`, structurally independent, with no geometry coupling.
|
|
171
|
+
|
|
172
|
+
Use deep overlays for programmatic rect emission — dictionary-based layouts, glyphs,
|
|
173
|
+
masks, strict layering control. Prefer a single split when it expresses intent more
|
|
174
|
+
clearly or raw-string readability matters.
|
|
175
|
+
|
|
176
|
+
> ⚠️ **Render-cost caveat** (measured 2026-07-02): depth is free structurally, NOT at
|
|
177
|
+
> render time. Each overlay level is one sequential blend pass on ffmpeg's single
|
|
178
|
+
> graph thread, and past ~25 nested overlay layers inline-masks silently degrade
|
|
179
|
+
> (circles→squares, text→tofu) — engine wall W3. Deep stacks are cheap to WRITE
|
|
180
|
+
> and inspect, not cheap to RENDER — collapse time-disjoint line geometry into
|
|
181
|
+
> lavfi tracks first. Author-facing rules:
|
|
182
|
+
> [`../templates/patterns/perf-authoring-rules.md`](../templates/patterns/perf-authoring-rules.md)
|
|
183
|
+
> (R6). Deep dives are engine-internal: `.ai/moat/runtime/ffmpeg-limitations.md`,
|
|
184
|
+
> `.ai/moat/runtime/render-cost-model.md` — absent in the shipped copy.
|
|
185
|
+
|
|
186
|
+
## Invalid constructions (verified, with codes)
|
|
187
|
+
|
|
188
|
+
1{} — INVALID_EMPTY (empty body)
|
|
189
|
+
1{0} — INVALID_EMPTY (bare passthrough body)
|
|
190
|
+
1{-{}} — INVALID_EMPTY (recursive)
|
|
191
|
+
1{1}{1} — OVERLAY_CHAIN (two immediate overlays; nest instead)
|
|
192
|
+
1{{1}} — TOKEN_RULE (no owner token for the inner overlay)
|
|
193
|
+
1{2(1,0)} — PASSTHROUGH_TO_NOTHING (trailing `0` inside overlay body)
|
|
194
|
+
-{1} — TOKEN_RULE (`-{...}` cannot be the whole-string root)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Choosing the right parse API (and mapping frames → sources)
|
|
2
|
+
|
|
3
|
+
> **Source of truth:** [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts).
|
|
4
|
+
> All four parse exports re-exported from `@m0saic/dsl`. (A fifth,
|
|
5
|
+
> `parseM0StringToFullGraphWithTraversal`, was removed in the public-API prune —
|
|
6
|
+
> use `parseM0StringComplete` with `opts.trace`.)
|
|
7
|
+
|
|
8
|
+
## The canonical entry point: `parseM0StringComplete`
|
|
9
|
+
|
|
10
|
+
`parseM0StringComplete(input, width, height, opts?)` returns (on success):
|
|
11
|
+
|
|
12
|
+
- `ok: true`
|
|
13
|
+
- `ir.renderFrames` — RenderFrame[] in **paint order**
|
|
14
|
+
- `ir.editorFrames` — EditorFrame[] (full structural graph, always present)
|
|
15
|
+
- `ir.traversal` — optional DFS event stream if `opts.trace`
|
|
16
|
+
- `precision`, `resolutionDiagnostics`, `warnings`
|
|
17
|
+
|
|
18
|
+
Frames are one level deep under **`ir`**, not top-level. On failure:
|
|
19
|
+
`{ ok: false, error, precision, warnings }`. Other options:
|
|
20
|
+
`opts.materialize: "renderOnly"` (the cheap mode `parseM0StringToLogicalFrames`
|
|
21
|
+
rides on) and `opts.precisionNorm` (default 100; gates `PRECISION_EXCEEDS_NORM`
|
|
22
|
+
warnings). Prefer Complete for tooling, editor logic, anything non-trivial.
|
|
23
|
+
|
|
24
|
+
## The three cheaper tiers
|
|
25
|
+
|
|
26
|
+
| Tier | API | Returns | Use for |
|
|
27
|
+
|---|---|---|---|
|
|
28
|
+
| 1 | `parseM0StringToLogicalFrames(s, w, h)` | rendered leaves only, **logical order**; each has `rect`, `logicalIndex` (array index === logicalIndex), `meta` | template tile mapping — `cell-<logicalIndex>`, labels indexing, "Nth tile" logic |
|
|
29
|
+
| 2 | `parseM0StringToRenderFrames(s, w, h)` | renderable frames in **paint order**; each has `rect`, `paintOrder`, `logicalIndex` | engine paint plan / ffmpeg stacking |
|
|
30
|
+
| 3 | `parseM0StringToFullGraph(s, w, h)` | EVERYTHING as EditorFrame[] — roots, groups, leaves, passthroughs, nulls, overlay subtrees | editor UIs, structural analysis |
|
|
31
|
+
|
|
32
|
+
Key invariant (Tier 2): `paintOrder` is the compositing order; `logicalIndex` is
|
|
33
|
+
the logical tile index. There is **no `sourceIndex` field** — build sources by
|
|
34
|
+
`logicalIndex`, paint by `paintOrder`.
|
|
35
|
+
|
|
36
|
+
Common mistakes the wrong tier causes: confusing paint order with logical order,
|
|
37
|
+
attaching sources to the wrong index, losing overlays/group nodes in a UI.
|
|
38
|
+
|
|
39
|
+
## Identity on every frame
|
|
40
|
+
|
|
41
|
+
All frame views carry `meta` identity: deterministic StableKey, structuralDepth,
|
|
42
|
+
overlayDepth (separate axes; overlay keys live in the `/ov{depth}c{k}` namespace and
|
|
43
|
+
never shift structural keys). The full contract: [`identity.md`](identity.md).
|
|
44
|
+
|
|
45
|
+
## Frames → sources → children (the template bridge)
|
|
46
|
+
|
|
47
|
+
The standard pattern for turning geometry into a `MosaicDocument`:
|
|
48
|
+
|
|
49
|
+
1. Parse the layout — `parseM0StringToLogicalFrames` for leaf mapping. The public
|
|
50
|
+
frames APIs already exclude null-render nodes (the parser filters
|
|
51
|
+
`nullRender` internally — you do NOT hand-filter holes/containers).
|
|
52
|
+
2. For each frame: create a child renderable (often
|
|
53
|
+
`renderNestedTemplate(cellTemplateId, props, ctx)` —
|
|
54
|
+
https://github.com/m0saic-project/m0saic-packages/blob/main/packages/template-utils/src/render/renderNestedTemplate.ts#L35), attach it under
|
|
55
|
+
`children[id]`, push a `sources[]` entry referencing it.
|
|
56
|
+
3. Return `{ m0: <same layout>, config.sources, children }` (the document's layout
|
|
57
|
+
field is `m0` — https://github.com/m0saic-project/m0saic-packages/blob/main/packages/types/src/document/document.ts#L132).
|
|
58
|
+
|
|
59
|
+
Rules that keep the bridge deterministic:
|
|
60
|
+
|
|
61
|
+
- **Child IDs come from `frame.logicalIndex`** (e.g. `cell-${logicalIndex}`) — or
|
|
62
|
+
`frame.stableKey` when identity must survive structural edits. Never bare loop
|
|
63
|
+
order. ([`identity.md`](identity.md) owns the when-to-use-which.)
|
|
64
|
+
- **Size and time from `ctx.target`, never `ctx.output`** — `ctx.output` is
|
|
65
|
+
format/codec/alpha only ([`../templates/rendering-model-contract.md`](../templates/rendering-model-contract.md) Rule 5b).
|
|
66
|
+
- **Internal cell templates** (`internal: true`, id `…/cell/v1`) are the reusable
|
|
67
|
+
building block for per-tile content — wireframe-style label/debug tiles are the
|
|
68
|
+
canonical example.
|
|
69
|
+
- Props schemas: use `definePropsSchema` with typed defaults. (There is no
|
|
70
|
+
`constraints.isM0saicLayout` — an older revision of this guidance invented it;
|
|
71
|
+
the real constraint set is `MosaicPropConstraints`,
|
|
72
|
+
https://github.com/m0saic-project/m0saic-packages/blob/main/packages/types/src/template/template.ts#L108-146`.)
|
|
73
|
+
|
|
74
|
+
## Quick decision table
|
|
75
|
+
|
|
76
|
+
- Engine paint plan / ffmpeg stacking → `parseM0StringToRenderFrames`
|
|
77
|
+
- Template tile mapping / "Nth tile" logic → `parseM0StringToLogicalFrames`
|
|
78
|
+
- Full structural tree / editor UI → `parseM0StringToFullGraph`
|
|
79
|
+
- Traversal events, or anything multi-view → `parseM0StringComplete` (+ `opts.trace`)
|