@shotstack/cli 0.13.0 → 0.14.0
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/dist/shotstack.js +1 -1
- package/package.json +1 -1
- package/skills/shotstack/SKILL.md +3 -1
- package/skills/shotstack/references/beat-sync.md +3 -1
- package/skills/shotstack/references/html5-effects.md +1 -1
- package/skills/shotstack/references/html5-snippets.md +3 -3
- package/skills/shotstack/references/html5.md +38 -7
- package/skills/shotstack/references/ingest.md +7 -0
- package/skills/shotstack/shared/agent-core.md +3 -2
package/dist/shotstack.js
CHANGED
|
@@ -20,7 +20,7 @@ Expecting one of '${r.join("', '")}'`);if(this._lifeCycleHooks[e])this._lifeCycl
|
|
|
20
20
|
`),this.outputHelp({error:!0});let r=t||{},n=r.exitCode||1,o=r.code||"commander.error";this._exit(n,o,e)}_parseOptionsEnv(){this.options.forEach((e)=>{if(e.envVar&&e.envVar in k.env){let t=e.attributeName();if(this.getOptionValue(t)===void 0||["default","config","env"].includes(this.getOptionValueSource(t)))if(e.required||e.optional)this.emit(`optionEnv:${e.name()}`,k.env[e.envVar]);else this.emit(`optionEnv:${e.name()}`)}})}_parseOptionsImplied(){let e=new wu(this.options),t=(r)=>this.getOptionValue(r)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(r));this.options.filter((r)=>r.implied!==void 0&&t(r.attributeName())&&e.valueFromOption(this.getOptionValue(r.attributeName()),r)).forEach((r)=>{Object.keys(r.implied).filter((n)=>!t(n)).forEach((n)=>{this.setOptionValueWithSource(n,r.implied[n],"implied")})})}missingArgument(e){let t=`error: missing required argument '${e}'`;this.error(t,{code:"commander.missingArgument"})}optionMissingArgument(e){let t=`error: option '${e.flags}' argument missing`;this.error(t,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(e){let t=`error: required option '${e.flags}' not specified`;this.error(t,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(e,t){let r=(s)=>{let i=s.attributeName(),c=this.getOptionValue(i),p=this.options.find((h)=>h.negate&&i===h.attributeName()),l=this.options.find((h)=>!h.negate&&i===h.attributeName());if(p&&(p.presetArg===void 0&&c===!1||p.presetArg!==void 0&&c===p.presetArg))return p;return l||s},n=(s)=>{let i=r(s),c=i.attributeName();if(this.getOptionValueSource(c)==="env")return`environment variable '${i.envVar}'`;return`option '${i.flags}'`},o=`error: ${n(e)} cannot be used with ${n(t)}`;this.error(o,{code:"commander.conflictingOption"})}unknownOption(e){if(this._allowUnknownOption)return;let t="";if(e.startsWith("--")&&this._showSuggestionAfterError){let n=[],o=this;do{let s=o.createHelp().visibleOptions(o).filter((i)=>i.long).map((i)=>i.long);n=n.concat(s),o=o.parent}while(o&&!o._enablePositionalOptions);t=Er(e,n)}let r=`error: unknown option '${e}'${t}`;this.error(r,{code:"commander.unknownOption"})}_excessArguments(e){if(this._allowExcessArguments)return;let t=this.registeredArguments.length,r=t===1?"":"s",o=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${t} argument${r} but got ${e.length}.`;this.error(o,{code:"commander.excessArguments"})}unknownCommand(){let e=this.args[0],t="";if(this._showSuggestionAfterError){let n=[];this.createHelp().visibleCommands(this).forEach((o)=>{if(n.push(o.name()),o.alias())n.push(o.alias())}),t=Er(e,n)}let r=`error: unknown command '${e}'${t}`;this.error(r,{code:"commander.unknownCommand"})}version(e,t,r){if(e===void 0)return this._version;this._version=e,t=t||"-V, --version",r=r||"output the version number";let n=this.createOption(t,r);return this._versionOptionName=n.attributeName(),this._registerOption(n),this.on("option:"+n.name(),()=>{this._outputConfiguration.writeOut(`${e}
|
|
21
21
|
`),this._exit(0,"commander.version",e)}),this}description(e,t){if(e===void 0&&t===void 0)return this._description;if(this._description=e,t)this._argsDescription=t;return this}summary(e){if(e===void 0)return this._summary;return this._summary=e,this}alias(e){if(e===void 0)return this._aliases[0];let t=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler)t=this.commands[this.commands.length-1];if(e===t._name)throw Error("Command alias can't be the same as its name");let r=this.parent?._findCommand(e);if(r){let n=[r.name()].concat(r.aliases()).join("|");throw Error(`cannot add alias '${e}' to command '${this.name()}' as already have command '${n}'`)}return t._aliases.push(e),this}aliases(e){if(e===void 0)return this._aliases;return e.forEach((t)=>this.alias(t)),this}usage(e){if(e===void 0){if(this._usage)return this._usage;let t=this.registeredArguments.map((r)=>$u(r));return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?t:[]).join(" ")}return this._usage=e,this}name(e){if(e===void 0)return this._name;return this._name=e,this}nameFromFilename(e){return this._name=K.basename(e,K.extname(e)),this}executableDir(e){if(e===void 0)return this._executableDir;return this._executableDir=e,this}helpInformation(e){let t=this.createHelp();if(t.helpWidth===void 0)t.helpWidth=e&&e.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth();return t.formatHelp(this,t)}_getHelpContext(e){e=e||{};let t={error:!!e.error},r;if(t.error)r=(n)=>this._outputConfiguration.writeErr(n);else r=(n)=>this._outputConfiguration.writeOut(n);return t.write=e.write||r,t.command=this,t}outputHelp(e){let t;if(typeof e==="function")t=e,e=void 0;let r=this._getHelpContext(e);this._getCommandAndAncestors().reverse().forEach((o)=>o.emit("beforeAllHelp",r)),this.emit("beforeHelp",r);let n=this.helpInformation(r);if(t){if(n=t(n),typeof n!=="string"&&!Buffer.isBuffer(n))throw Error("outputHelp callback must return a string or a Buffer")}if(r.write(n),this._getHelpOption()?.long)this.emit(this._getHelpOption().long);this.emit("afterHelp",r),this._getCommandAndAncestors().forEach((o)=>o.emit("afterAllHelp",r))}helpOption(e,t){if(typeof e==="boolean"){if(e)this._helpOption=this._helpOption??void 0;else this._helpOption=null;return this}return e=e??"-h, --help",t=t??"display help for command",this._helpOption=this.createOption(e,t),this}_getHelpOption(){if(this._helpOption===void 0)this.helpOption(void 0,void 0);return this._helpOption}addHelpOption(e){return this._helpOption=e,this}help(e){this.outputHelp(e);let t=k.exitCode||0;if(t===0&&e&&typeof e!=="function"&&e.error)t=1;this._exit(t,"commander.help","(outputHelp)")}addHelpText(e,t){let r=["beforeAll","before","after","afterAll"];if(!r.includes(e))throw Error(`Unexpected value for position to addHelpText.
|
|
22
22
|
Expecting one of '${r.join("', '")}'`);let n=`${e}Help`;return this.on(n,(o)=>{let s;if(typeof t==="function")s=t({error:o.error,command:o.command});else s=t;if(s)o.write(`${s}
|
|
23
|
-
`)}),this}_outputHelpIfRequested(e){let t=this._getHelpOption();if(t&&e.find((n)=>t.is(n)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function Pr(e){return e.map((t)=>{if(!t.startsWith("--inspect"))return t;let r,n="127.0.0.1",o="9229",s;if((s=t.match(/^(--inspect(-brk)?)$/))!==null)r=s[1];else if((s=t.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(r=s[1],/^\d+$/.test(s[3]))o=s[3];else n=s[3];else if((s=t.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)r=s[1],n=s[3],o=s[4];if(r&&o!=="0")return`${r}=${n}:${parseInt(o)+1}`;return t})}zu.Command=kt});var Ot={};Wa(Ot,{program:()=>Ir,createCommand:()=>jr,createOption:()=>Fr,createArgument:()=>Dr,Command:()=>Lr,Option:()=>Ur,Argument:()=>Mr,Help:()=>vr,CommanderError:()=>Vr,InvalidArgumentError:()=>qr,InvalidOptionArgumentError:()=>Jr},{program:(Xd)=>Ir=Xd,createCommand:(Xd)=>jr=Xd,createOption:(Xd)=>Fr=Xd,createArgument:(Xd)=>Dr=Xd,Command:(Xd)=>Lr=Xd,Option:(Xd)=>Ur=Xd,Argument:(Xd)=>Mr=Xd,Help:(Xd)=>vr=Xd,CommanderError:(Xd)=>Vr=Xd,InvalidArgumentError:(Xd)=>qr=Xd,InvalidOptionArgumentError:(Xd)=>Jr=Xd});var{Argument:Cr}=Ke(),{Command:Zt}=Rr(),{CommanderError:ku,InvalidArgumentError:Nr}=je(),{Help:Zu}=wt(),{Option:Tr}=zt();var Ir=new Zt,jr=(e)=>new Zt(e),Fr=(e,t)=>new Tr(e,t),Dr=(e,t)=>new Cr(e,t),Lr=Zt,Ur=Tr,Mr=Cr,vr=Zu,Vr=ku,qr=Nr,Jr=Nr;var{program:tm,createCommand:rm,createArgument:nm,createOption:om,CommanderError:sm,InvalidArgumentError:We,InvalidOptionArgumentError:im,Command:F,Argument:am,Option:um,Help:cm}=Ot;import{readFile as Ef}from"node:fs/promises";import{resolve as Pf}from"node:path";var Br={name:"@shotstack/cli",version:"0.
|
|
23
|
+
`)}),this}_outputHelpIfRequested(e){let t=this._getHelpOption();if(t&&e.find((n)=>t.is(n)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function Pr(e){return e.map((t)=>{if(!t.startsWith("--inspect"))return t;let r,n="127.0.0.1",o="9229",s;if((s=t.match(/^(--inspect(-brk)?)$/))!==null)r=s[1];else if((s=t.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(r=s[1],/^\d+$/.test(s[3]))o=s[3];else n=s[3];else if((s=t.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)r=s[1],n=s[3],o=s[4];if(r&&o!=="0")return`${r}=${n}:${parseInt(o)+1}`;return t})}zu.Command=kt});var Ot={};Wa(Ot,{program:()=>Ir,createCommand:()=>jr,createOption:()=>Fr,createArgument:()=>Dr,Command:()=>Lr,Option:()=>Ur,Argument:()=>Mr,Help:()=>vr,CommanderError:()=>Vr,InvalidArgumentError:()=>qr,InvalidOptionArgumentError:()=>Jr},{program:(Xd)=>Ir=Xd,createCommand:(Xd)=>jr=Xd,createOption:(Xd)=>Fr=Xd,createArgument:(Xd)=>Dr=Xd,Command:(Xd)=>Lr=Xd,Option:(Xd)=>Ur=Xd,Argument:(Xd)=>Mr=Xd,Help:(Xd)=>vr=Xd,CommanderError:(Xd)=>Vr=Xd,InvalidArgumentError:(Xd)=>qr=Xd,InvalidOptionArgumentError:(Xd)=>Jr=Xd});var{Argument:Cr}=Ke(),{Command:Zt}=Rr(),{CommanderError:ku,InvalidArgumentError:Nr}=je(),{Help:Zu}=wt(),{Option:Tr}=zt();var Ir=new Zt,jr=(e)=>new Zt(e),Fr=(e,t)=>new Tr(e,t),Dr=(e,t)=>new Cr(e,t),Lr=Zt,Ur=Tr,Mr=Cr,vr=Zu,Vr=ku,qr=Nr,Jr=Nr;var{program:tm,createCommand:rm,createArgument:nm,createOption:om,CommanderError:sm,InvalidArgumentError:We,InvalidOptionArgumentError:im,Command:F,Argument:am,Option:um,Help:cm}=Ot;import{readFile as Ef}from"node:fs/promises";import{resolve as Pf}from"node:path";var Br={name:"@shotstack/cli",version:"0.14.0",description:"Command-line interface for the Shotstack video rendering API.",license:"Apache-2.0",homepage:"https://github.com/shotstack/shotstack-cli",repository:{type:"git",url:"git+https://github.com/shotstack/shotstack-cli.git"},bugs:{url:"https://github.com/shotstack/shotstack-cli/issues"},type:"module",bin:{shotstack:"dist/shotstack.js"},files:["dist/shotstack.js","skills"],scripts:{start:"bun run src/index.ts",build:"bun build src/index.ts --target=node --minify --outfile=dist/shotstack.js --banner='#!/usr/bin/env node' && chmod +x dist/shotstack.js",prepack:"bun run build",typecheck:"tsc --noEmit",test:"bun test"},dependencies:{"@shotstack/schemas":"^1.22.0",commander:"^12.1.0",zod:"^4.4.3"},devDependencies:{"@types/bun":"latest",typescript:"^5.6.0"}};var Fe=Br.version,Hr=`shotstack-cli/${Fe} (${process.platform}-${process.arch})`;class ee extends Error{status;body;constructor(e,t,r){super(r);this.status=e;this.body=t;this.name="ApiError"}get isTransient(){return this.status>=500||this.status===429}}function q(e){let t=e.env.baseUrl.replace(/\/$/,"");async function r(n,o,s){let i=await fetch(`${t}${o}`,{method:n,headers:{"x-api-key":e.apiKey,"x-shotstack-origin":"cli","x-shotstack-environment":e.env.name,"user-agent":Hr,...s!==void 0?{"content-type":"application/json"}:{}},body:s!==void 0?JSON.stringify(s):void 0}),c=await i.text(),p=c?Eu(c):void 0;if(!i.ok)throw new ee(i.status,p??c,`${n} ${o} → ${i.status} ${i.statusText}`);return p}return{post:(n,o)=>r("POST",n,o),put:(n,o)=>r("PUT",n,o),get:(n)=>r("GET",n),del:(n)=>r("DELETE",n)}}function Eu(e){try{return JSON.parse(e)}catch{return e}}import{mkdir as Pu,writeFile as Ru,chmod as Cu}from"node:fs/promises";import{readFileSync as Nu}from"node:fs";import{join as Et,dirname as Tu}from"node:path";import{homedir as Gr}from"node:os";function ke(){if(process.platform==="win32"){let e=process.env.APPDATA??Et(Gr(),"AppData","Roaming");return Et(e,"shotstack","credentials.json")}return Et(Gr(),".shotstack","credentials.json")}function Pt(e){try{let t=JSON.parse(Nu(e,"utf8"));if(t&&typeof t==="object"&&!Array.isArray(t))return t}catch{}return{}}function Kr(e,t=ke()){return Pt(t)[e]?.trim()||void 0}async function Wr(e,t,r=ke()){let n=Pt(r);n[e]=t.trim(),await Rt(r,n)}async function Yr(e,t=ke()){let r=Pt(t);if(!(e in r))return!1;return delete r[e],await Rt(t,r),!0}async function Qr(e=ke()){await Rt(e,{})}async function Rt(e,t){await Pu(Tu(e),{recursive:!0,mode:448}),await Ru(e,JSON.stringify(t,null,2)+`
|
|
24
24
|
`,{mode:384}),await Cu(e,384).catch(()=>{})}class ue extends Error{constructor(e){let t=e?` for env "${e}"`:"",r=e?`shotstack login --env ${e}`:"shotstack login";super(`No Shotstack API key found${t}. Run \`${r}\` to save one, or set SHOTSTACK_API_KEY. Get a key at https://shotstack.io.`);this.name="MissingApiKeyError"}}function U(e,t){let r=process.env.SHOTSTACK_API_KEY?.trim();if(r)return r;let n=Kr(e,t);if(n)return n;throw new ue(e)}var R=["dev","stage","v1"];class Ze extends Error{constructor(e){super(`Invalid environment "${e}". Use one of: ${R.join(", ")}.`);this.name="InvalidEnvError"}}function me(e){let t=e??process.env.SHOTSTACK_ENV?.trim()??"v1";if(!ju(t))throw new Ze(t);return t}function J(e,t="edit"){let r=Iu(t);if(r)return{name:"custom",baseUrl:r};let n=me(e);return{name:n,baseUrl:`https://api.shotstack.io/${t}/${n}`}}function Iu(e){return(e==="ingest"?process.env.SHOTSTACK_INGEST_BASE_URL:process.env.SHOTSTACK_API_BASE_URL)?.trim()||void 0}function ju(e){return R.includes(e)}function C(e){if(e==="json")return"json";return"text"}function E(e,t,r){if(e==="json")console.log(JSON.stringify(t));else console.log(r)}import{mkdir as Fu,appendFile as Du,stat as rn,readFile as Lu,writeFile as nn}from"node:fs/promises";import{join as Ct,dirname as Uu}from"node:path";import{homedir as Xr}from"node:os";var Mu=1e6,vu=500000,en=2000;function Ye(){if(process.platform==="win32"){let e=process.env.APPDATA??Ct(Xr(),"AppData","Roaming");return Ct(e,"shotstack","log.jsonl")}return Ct(Xr(),".shotstack","log.jsonl")}function Vu(e,t=new Date){let r={ts:t.toISOString(),cmd:e.cmd,args:e.args.map(Wu),exit:e.exit,durationMs:e.durationMs};if(e.renderId)r.renderId=e.renderId;if(e.response!==void 0)r.response=Qu(Nt(e.response));if(e.error)r.error=qu(e.error);return r}function qu(e){return{name:e.name,message:typeof e.message==="string"?Tt(e.message):String(e.message)}}function Ju(e){if(e instanceof Error)return{name:e.name,message:e.message};if(e===void 0||e===null)return;return{name:"Unknown",message:String(e)}}async function tn(e,t=Ye()){let r=Vu(e),n=JSON.stringify(r)+`
|
|
25
25
|
`;if(await Fu(Uu(t),{recursive:!0,mode:448}),!await Bu(t))await nn(t,"",{mode:384});await Du(t,n),await Hu(t)}async function Bu(e){try{return await rn(e),!0}catch{return!1}}async function Hu(e){let t=await rn(e).catch(()=>null);if(!t||t.size<=Mu)return;let r=await Lu(e),n=r.subarray(Math.max(0,r.length-vu)),o=n.indexOf(10),s=o>=0?n.subarray(o+1):n;await nn(e,s,{mode:384})}var Gu=/^https?:\/\//i,Ku=/(https?:\/\/[^\s'"<>?]+)\?[^\s'"<>]*?(?:Signature|X-Amz-[A-Za-z0-9-]+|x-amz-security-token)=[^\s'"<>]*/gi;function Tt(e){return e.replace(Ku,"$1?[redacted-signed]")}function Wu(e){if(typeof e!=="string")return e;if(e.startsWith("-"))return e;if(Gu.test(e))return Tt(e);if(/[\/\\]/.test(e))return Yu(e);return e}function Yu(e){let t=e.split(/[\/\\]/);return t[t.length-1]||e}function Nt(e){if(typeof e==="string")return Tt(e);if(Array.isArray(e))return e.map(Nt);if(e&&typeof e==="object"){let t={};for(let[r,n]of Object.entries(e))t[r]=Nt(n);return t}return e}function Qu(e){let t=JSON.stringify(e);if(t===void 0||t.length<=en)return e;return t.slice(0,en)+"...[truncated]"}async function B(e,t,r){let n=Date.now();try{let o=await r(),s=o.exitCode??0;if(await tn({cmd:e,args:t,exit:s,durationMs:Date.now()-n,renderId:o.renderId,response:o.response}).catch(()=>{}),s!==0)process.exit(s)}catch(o){let s=Xu(o),i=o instanceof ee?o.body:void 0;throw await tn({cmd:e,args:t,exit:s,durationMs:Date.now()-n,response:i,error:Ju(o)}).catch(()=>{}),o}}function Xu(e){if(e instanceof ee)return e.isTransient?2:1;if(e instanceof ue||e instanceof Ze)return 1;if(e instanceof Error&&e.code==="ENOENT")return 1;return 2}function H(e){let t=process.argv.slice(2),r=t.indexOf(e);return r>=0?t.slice(r+1):t}var ec=new Set(["done","failed"]),tc=3000,on=new F("status").description("Poll the status of a Shotstack render").argument("<id>","Render ID returned by `shotstack render`").option("--watch","Poll continuously until the render reaches a terminal state").option("--env <name>",`Environment: ${R.join(" | ")}`).option("--output <format>","Output format: text | json","text").action(async(e,t)=>{await B("status",H("status"),async()=>{let r=C(t.output),n=J(t.env),o=U(n.name),s=q({apiKey:o,env:n}),i=await It(s,e,r,t.watch===!0),c=i.status==="failed"?1:0;return{renderId:i.id,response:i,exitCode:c}})});async function It(e,t,r,n){while(!0){let s=(await e.get(`/render/${encodeURIComponent(t)}`)).response;if(E(r,s,rc(s)),!n||ec.has(s.status))return s;await nc(tc)}}function rc(e){let t=[e.status];if(e.url)t.push(e.url);if(e.error)t.push(`error: ${e.error}`);return t.join(" ")}function nc(e){return new Promise((t)=>setTimeout(t,e))}var sn;function m(e,t,r){function n(c,p){if(!c._zod)Object.defineProperty(c,"_zod",{value:{def:p,constr:i,traits:new Set},enumerable:!1});if(c._zod.traits.has(e))return;c._zod.traits.add(e),t(c,p);let l=i.prototype,h=Object.keys(l);for(let y=0;y<h.length;y++){let A=h[y];if(!(A in c))c[A]=l[A].bind(c)}}let o=r?.Parent??Object;class s extends o{}Object.defineProperty(s,"name",{value:e});function i(c){var p;let l=r?.Parent?new s:this;n(l,c),(p=l._zod).deferred??(p.deferred=[]);for(let h of l._zod.deferred)h();return l}return Object.defineProperty(i,"init",{value:n}),Object.defineProperty(i,Symbol.hasInstance,{value:(c)=>{if(r?.Parent&&c instanceof r.Parent)return!0;return c?._zod?.traits?.has(e)}}),Object.defineProperty(i,"name",{value:e}),i}var Lm=Symbol("zod_brand");class ae extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class De extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`);this.name="ZodEncodeError"}}(sn=globalThis).__zod_globalConfig??(sn.__zod_globalConfig={});var Oe=globalThis.__zod_globalConfig;function te(e){if(e)Object.assign(Oe,e);return Oe}function Xe(e){let t=Object.values(e).filter((n)=>typeof n==="number");return Object.entries(e).filter(([n,o])=>t.indexOf(+n)===-1).map(([n,o])=>o)}function Le(e,t){if(typeof t==="bigint")return t.toString();return t}function Ue(e){return{get value(){{let r=e();return Object.defineProperty(this,"value",{value:r}),r}throw Error("cached value already set")}}}function et(e){return e===null||e===void 0}function tt(e){let t=e.startsWith("^")?1:0,r=e.endsWith("$")?e.length-1:e.length;return e.slice(t,r)}function un(e,t){let r=e/t,n=Math.round(r),o=Number.EPSILON*Math.max(Math.abs(r),1);if(Math.abs(r-n)<o)return 0;return r-n}var an=Symbol("evaluating");function P(e,t,r){let n=void 0;Object.defineProperty(e,t,{get(){if(n===an)return;if(n===void 0)n=an,n=r();return n},set(o){Object.defineProperty(e,t,{value:o})},configurable:!0})}function he(e,t,r){Object.defineProperty(e,t,{value:r,writable:!0,enumerable:!0,configurable:!0})}function ce(...e){let t={};for(let r of e){let n=Object.getOwnPropertyDescriptors(r);Object.assign(t,n)}return Object.defineProperties({},t)}function Ft(e){return JSON.stringify(e)}function cn(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}var Dt="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function Ee(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}var pn=Ue(()=>{if(Oe.jitless)return!1;if(typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch(e){return!1}});function ge(e){if(Ee(e)===!1)return!1;let t=e.constructor;if(t===void 0)return!0;if(typeof t!=="function")return!0;let r=t.prototype;if(Ee(r)===!1)return!1;if(Object.prototype.hasOwnProperty.call(r,"isPrototypeOf")===!1)return!1;return!0}function Lt(e){if(ge(e))return{...e};if(Array.isArray(e))return[...e];if(e instanceof Map)return new Map(e);if(e instanceof Set)return new Set(e);return e}var ln=new Set(["string","number","symbol"]);function pe(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function se(e,t,r){let n=new e._zod.constr(t??e._zod.def);if(!t||r?.parent)n._zod.parent=e;return n}function w(e){let t=e;if(!t)return{};if(typeof t==="string")return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw Error("Cannot specify both `message` and `error` params");t.error=t.message}if(delete t.message,typeof t.error==="string")return{...t,error:()=>t.error};return t}function fn(e){return Object.keys(e).filter((t)=>e[t]._zod.optin==="optional"&&e[t]._zod.optout==="optional")}var dn={safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-340282346638528860000000000000000000000,340282346638528860000000000000000000000],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]};function oc(e,t){let r=e._zod.def,n=r.checks;if(n&&n.length>0)throw Error(".pick() cannot be used on object schemas containing refinements");let s=ce(e._zod.def,{get shape(){let i={};for(let c in t){if(!(c in r.shape))throw Error(`Unrecognized key: "${c}"`);if(!t[c])continue;i[c]=r.shape[c]}return he(this,"shape",i),i},checks:[]});return se(e,s)}function sc(e,t){let r=e._zod.def,n=r.checks;if(n&&n.length>0)throw Error(".omit() cannot be used on object schemas containing refinements");let s=ce(e._zod.def,{get shape(){let i={...e._zod.def.shape};for(let c in t){if(!(c in r.shape))throw Error(`Unrecognized key: "${c}"`);if(!t[c])continue;delete i[c]}return he(this,"shape",i),i},checks:[]});return se(e,s)}function ic(e,t){if(!ge(t))throw Error("Invalid input to extend: expected a plain object");let r=e._zod.def.checks;if(r&&r.length>0){let s=e._zod.def.shape;for(let i in t)if(Object.getOwnPropertyDescriptor(s,i)!==void 0)throw Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}let o=ce(e._zod.def,{get shape(){let s={...e._zod.def.shape,...t};return he(this,"shape",s),s}});return se(e,o)}function ac(e,t){if(!ge(t))throw Error("Invalid input to safeExtend: expected a plain object");let r=ce(e._zod.def,{get shape(){let n={...e._zod.def.shape,...t};return he(this,"shape",n),n}});return se(e,r)}function uc(e,t){if(e._zod.def.checks?.length)throw Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");let r=ce(e._zod.def,{get shape(){let n={...e._zod.def.shape,...t._zod.def.shape};return he(this,"shape",n),n},get catchall(){return t._zod.def.catchall},checks:t._zod.def.checks??[]});return se(e,r)}function cc(e,t,r){let o=t._zod.def.checks;if(o&&o.length>0)throw Error(".partial() cannot be used on object schemas containing refinements");let i=ce(t._zod.def,{get shape(){let c=t._zod.def.shape,p={...c};if(r)for(let l in r){if(!(l in c))throw Error(`Unrecognized key: "${l}"`);if(!r[l])continue;p[l]=e?new e({type:"optional",innerType:c[l]}):c[l]}else for(let l in c)p[l]=e?new e({type:"optional",innerType:c[l]}):c[l];return he(this,"shape",p),p},checks:[]});return se(t,i)}function pc(e,t,r){let n=ce(t._zod.def,{get shape(){let o=t._zod.def.shape,s={...o};if(r)for(let i in r){if(!(i in s))throw Error(`Unrecognized key: "${i}"`);if(!r[i])continue;s[i]=new e({type:"nonoptional",innerType:o[i]})}else for(let i in o)s[i]=new e({type:"nonoptional",innerType:o[i]});return he(this,"shape",s),s}});return se(t,n)}function _e(e,t=0){if(e.aborted===!0)return!0;for(let r=t;r<e.issues.length;r++)if(e.issues[r]?.continue!==!0)return!0;return!1}function mn(e,t=0){if(e.aborted===!0)return!0;for(let r=t;r<e.issues.length;r++)if(e.issues[r]?.continue===!1)return!0;return!1}function le(e,t){return t.map((r)=>{var n;return(n=r).path??(n.path=[]),r.path.unshift(e),r})}function Qe(e){return typeof e==="string"?e:e?.message}function re(e,t,r){let n=e.message?e.message:Qe(e.inst?._zod.def?.error?.(e))??Qe(t?.error?.(e))??Qe(r.customError?.(e))??Qe(r.localeError?.(e))??"Invalid input",{inst:o,continue:s,input:i,...c}=e;if(c.path??(c.path=[]),c.message=n,t?.reportInput)c.input=i;return c}function rt(e){if(Array.isArray(e))return"array";if(typeof e==="string")return"string";return"unknown"}function xe(...e){let[t,r,n]=e;if(typeof t==="string")return{message:t,code:"custom",input:r,inst:n};return{...t}}var hn=(e,t)=>{e.name="$ZodError",Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),e.message=JSON.stringify(t,Le,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},nt=m("$ZodError",hn),Ut=m("$ZodError",hn,{Parent:Error});function gn(e,t=(r)=>r.message){let r={},n=[];for(let o of e.issues)if(o.path.length>0)r[o.path[0]]=r[o.path[0]]||[],r[o.path[0]].push(t(o));else n.push(t(o));return{formErrors:n,fieldErrors:r}}function _n(e,t=(r)=>r.message){let r={_errors:[]},n=(o,s=[])=>{for(let i of o.issues)if(i.code==="invalid_union"&&i.errors.length)i.errors.map((c)=>n({issues:c},[...s,...i.path]));else if(i.code==="invalid_key")n({issues:i.issues},[...s,...i.path]);else if(i.code==="invalid_element")n({issues:i.issues},[...s,...i.path]);else{let c=[...s,...i.path];if(c.length===0)r._errors.push(t(i));else{let p=r,l=0;while(l<c.length){let h=c[l];if(l!==c.length-1)p[h]=p[h]||{_errors:[]};else p[h]=p[h]||{_errors:[]},p[h]._errors.push(t(i));p=p[h],l++}}}};return n(e),r}var ot=(e)=>(t,r,n,o)=>{let s=n?{...n,async:!1}:{async:!1},i=t._zod.run({value:r,issues:[]},s);if(i instanceof Promise)throw new ae;if(i.issues.length){let c=new(o?.Err??e)(i.issues.map((p)=>re(p,s,te())));throw Dt(c,o?.callee),c}return i.value};var st=(e)=>async(t,r,n,o)=>{let s=n?{...n,async:!0}:{async:!0},i=t._zod.run({value:r,issues:[]},s);if(i instanceof Promise)i=await i;if(i.issues.length){let c=new(o?.Err??e)(i.issues.map((p)=>re(p,s,te())));throw Dt(c,o?.callee),c}return i.value};var Me=(e)=>(t,r,n)=>{let o=n?{...n,async:!1}:{async:!1},s=t._zod.run({value:r,issues:[]},o);if(s instanceof Promise)throw new ae;return s.issues.length?{success:!1,error:new(e??nt)(s.issues.map((i)=>re(i,o,te())))}:{success:!0,data:s.value}},xn=Me(Ut),ve=(e)=>async(t,r,n)=>{let o=n?{...n,async:!0}:{async:!0},s=t._zod.run({value:r,issues:[]},o);if(s instanceof Promise)s=await s;return s.issues.length?{success:!1,error:new e(s.issues.map((i)=>re(i,o,te())))}:{success:!0,data:s.value}},yn=ve(Ut),bn=(e)=>(t,r,n)=>{let o=n?{...n,direction:"backward"}:{direction:"backward"};return ot(e)(t,r,o)};var $n=(e)=>(t,r,n)=>ot(e)(t,r,n);var An=(e)=>async(t,r,n)=>{let o=n?{...n,direction:"backward"}:{direction:"backward"};return st(e)(t,r,o)};var wn=(e)=>async(t,r,n)=>st(e)(t,r,n);var zn=(e)=>(t,r,n)=>{let o=n?{...n,direction:"backward"}:{direction:"backward"};return Me(e)(t,r,o)};var Sn=(e)=>(t,r,n)=>Me(e)(t,r,n);var kn=(e)=>async(t,r,n)=>{let o=n?{...n,direction:"backward"}:{direction:"backward"};return ve(e)(t,r,o)};var Zn=(e)=>async(t,r,n)=>ve(e)(t,r,n);var On=/^[cC][0-9a-z]{6,}$/,En=/^[0-9a-z]+$/,Pn=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,Rn=/^[0-9a-vA-V]{20}$/,Cn=/^[A-Za-z0-9]{27}$/,Nn=/^[a-zA-Z0-9_-]{21}$/,Tn=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;var In=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,Mt=(e)=>{if(!e)return/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`)};var jn=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;var fc="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";function Fn(){return new RegExp(fc,"u")}var Dn=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,Ln=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;var Un=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,Mn=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,vn=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,vt=/^[A-Za-z0-9_-]*$/;var Vn=/^https?$/,qn=/^\+[1-9]\d{6,14}$/,Jn="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))",Bn=new RegExp(`^${Jn}$`);function Hn(e){return typeof e.precision==="number"?e.precision===-1?"(?:[01]\\d|2[0-3]):[0-5]\\d":e.precision===0?"(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d":`(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{${e.precision}}`:"(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?"}function Gn(e){return new RegExp(`^${Hn(e)}$`)}function Kn(e){let t=Hn({precision:e.precision}),r=["Z"];if(e.local)r.push("");if(e.offset)r.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");let n=`${t}(?:${r.join("|")})`;return new RegExp(`^${Jn}T(?:${n})$`)}var Wn=(e)=>{let t=e?`[\\s\\S]{${e?.minimum??0},${e?.maximum??""}}`:"[\\s\\S]*";return new RegExp(`^${t}$`)};var Yn=/^-?\d+$/,Vt=/^-?\d+(?:\.\d+)?$/,Qn=/^(?:true|false)$/i,Xn=/^null$/i;var eo=/^[^A-Z]*$/,to=/^[^a-z]*$/;var Y=m("$ZodCheck",(e,t)=>{var r;e._zod??(e._zod={}),e._zod.def=t,(r=e._zod).onattach??(r.onattach=[])}),ro={number:"number",bigint:"bigint",object:"date"},qt=m("$ZodCheckLessThan",(e,t)=>{Y.init(e,t);let r=ro[typeof t.value];e._zod.onattach.push((n)=>{let o=n._zod.bag,s=(t.inclusive?o.maximum:o.exclusiveMaximum)??Number.POSITIVE_INFINITY;if(t.value<s)if(t.inclusive)o.maximum=t.value;else o.exclusiveMaximum=t.value}),e._zod.check=(n)=>{if(t.inclusive?n.value<=t.value:n.value<t.value)return;n.issues.push({origin:r,code:"too_big",maximum:typeof t.value==="object"?t.value.getTime():t.value,input:n.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),Jt=m("$ZodCheckGreaterThan",(e,t)=>{Y.init(e,t);let r=ro[typeof t.value];e._zod.onattach.push((n)=>{let o=n._zod.bag,s=(t.inclusive?o.minimum:o.exclusiveMinimum)??Number.NEGATIVE_INFINITY;if(t.value>s)if(t.inclusive)o.minimum=t.value;else o.exclusiveMinimum=t.value}),e._zod.check=(n)=>{if(t.inclusive?n.value>=t.value:n.value>t.value)return;n.issues.push({origin:r,code:"too_small",minimum:typeof t.value==="object"?t.value.getTime():t.value,input:n.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),no=m("$ZodCheckMultipleOf",(e,t)=>{Y.init(e,t),e._zod.onattach.push((r)=>{var n;(n=r._zod.bag).multipleOf??(n.multipleOf=t.value)}),e._zod.check=(r)=>{if(typeof r.value!==typeof t.value)throw Error("Cannot mix number and bigint in multiple_of check.");if(typeof r.value==="bigint"?r.value%t.value===BigInt(0):un(r.value,t.value)===0)return;r.issues.push({origin:typeof r.value,code:"not_multiple_of",divisor:t.value,input:r.value,inst:e,continue:!t.abort})}}),oo=m("$ZodCheckNumberFormat",(e,t)=>{Y.init(e,t),t.format=t.format||"float64";let r=t.format?.includes("int"),n=r?"int":"number",[o,s]=dn[t.format];e._zod.onattach.push((i)=>{let c=i._zod.bag;if(c.format=t.format,c.minimum=o,c.maximum=s,r)c.pattern=Yn}),e._zod.check=(i)=>{let c=i.value;if(r){if(!Number.isInteger(c)){i.issues.push({expected:n,format:t.format,code:"invalid_type",continue:!1,input:c,inst:e});return}if(!Number.isSafeInteger(c)){if(c>0)i.issues.push({input:c,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:n,inclusive:!0,continue:!t.abort});else i.issues.push({input:c,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:n,inclusive:!0,continue:!t.abort});return}}if(c<o)i.issues.push({origin:"number",input:c,code:"too_small",minimum:o,inclusive:!0,inst:e,continue:!t.abort});if(c>s)i.issues.push({origin:"number",input:c,code:"too_big",maximum:s,inclusive:!0,inst:e,continue:!t.abort})}});var so=m("$ZodCheckMaxLength",(e,t)=>{var r;Y.init(e,t),(r=e._zod.def).when??(r.when=(n)=>{let o=n.value;return!et(o)&&o.length!==void 0}),e._zod.onattach.push((n)=>{let o=n._zod.bag.maximum??Number.POSITIVE_INFINITY;if(t.maximum<o)n._zod.bag.maximum=t.maximum}),e._zod.check=(n)=>{let o=n.value;if(o.length<=t.maximum)return;let i=rt(o);n.issues.push({origin:i,code:"too_big",maximum:t.maximum,inclusive:!0,input:o,inst:e,continue:!t.abort})}}),io=m("$ZodCheckMinLength",(e,t)=>{var r;Y.init(e,t),(r=e._zod.def).when??(r.when=(n)=>{let o=n.value;return!et(o)&&o.length!==void 0}),e._zod.onattach.push((n)=>{let o=n._zod.bag.minimum??Number.NEGATIVE_INFINITY;if(t.minimum>o)n._zod.bag.minimum=t.minimum}),e._zod.check=(n)=>{let o=n.value;if(o.length>=t.minimum)return;let i=rt(o);n.issues.push({origin:i,code:"too_small",minimum:t.minimum,inclusive:!0,input:o,inst:e,continue:!t.abort})}}),ao=m("$ZodCheckLengthEquals",(e,t)=>{var r;Y.init(e,t),(r=e._zod.def).when??(r.when=(n)=>{let o=n.value;return!et(o)&&o.length!==void 0}),e._zod.onattach.push((n)=>{let o=n._zod.bag;o.minimum=t.length,o.maximum=t.length,o.length=t.length}),e._zod.check=(n)=>{let o=n.value,s=o.length;if(s===t.length)return;let i=rt(o),c=s>t.length;n.issues.push({origin:i,...c?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:n.value,inst:e,continue:!t.abort})}}),Ve=m("$ZodCheckStringFormat",(e,t)=>{var r,n;if(Y.init(e,t),e._zod.onattach.push((o)=>{let s=o._zod.bag;if(s.format=t.format,t.pattern)s.patterns??(s.patterns=new Set),s.patterns.add(t.pattern)}),t.pattern)(r=e._zod).check??(r.check=(o)=>{if(t.pattern.lastIndex=0,t.pattern.test(o.value))return;o.issues.push({origin:"string",code:"invalid_format",format:t.format,input:o.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})});else(n=e._zod).check??(n.check=()=>{})}),uo=m("$ZodCheckRegex",(e,t)=>{Ve.init(e,t),e._zod.check=(r)=>{if(t.pattern.lastIndex=0,t.pattern.test(r.value))return;r.issues.push({origin:"string",code:"invalid_format",format:"regex",input:r.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),co=m("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=eo),Ve.init(e,t)}),po=m("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=to),Ve.init(e,t)}),lo=m("$ZodCheckIncludes",(e,t)=>{Y.init(e,t);let r=pe(t.includes),n=new RegExp(typeof t.position==="number"?`^.{${t.position}}${r}`:r);t.pattern=n,e._zod.onattach.push((o)=>{let s=o._zod.bag;s.patterns??(s.patterns=new Set),s.patterns.add(n)}),e._zod.check=(o)=>{if(o.value.includes(t.includes,t.position))return;o.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:o.value,inst:e,continue:!t.abort})}}),fo=m("$ZodCheckStartsWith",(e,t)=>{Y.init(e,t);let r=new RegExp(`^${pe(t.prefix)}.*`);t.pattern??(t.pattern=r),e._zod.onattach.push((n)=>{let o=n._zod.bag;o.patterns??(o.patterns=new Set),o.patterns.add(r)}),e._zod.check=(n)=>{if(n.value.startsWith(t.prefix))return;n.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:n.value,inst:e,continue:!t.abort})}}),mo=m("$ZodCheckEndsWith",(e,t)=>{Y.init(e,t);let r=new RegExp(`.*${pe(t.suffix)}$`);t.pattern??(t.pattern=r),e._zod.onattach.push((n)=>{let o=n._zod.bag;o.patterns??(o.patterns=new Set),o.patterns.add(r)}),e._zod.check=(n)=>{if(n.value.endsWith(t.suffix))return;n.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:n.value,inst:e,continue:!t.abort})}});var ho=m("$ZodCheckOverwrite",(e,t)=>{Y.init(e,t),e._zod.check=(r)=>{r.value=t.tx(r.value)}});class Bt{constructor(e=[]){if(this.content=[],this.indent=0,this)this.args=e}indented(e){this.indent+=1,e(this),this.indent-=1}write(e){if(typeof e==="function"){e(this,{execution:"sync"}),e(this,{execution:"async"});return}let r=e.split(`
|
|
26
26
|
`).filter((s)=>s),n=Math.min(...r.map((s)=>s.length-s.trimStart().length)),o=r.map((s)=>s.slice(n)).map((s)=>" ".repeat(this.indent*2)+s);for(let s of o)this.content.push(s)}compile(){let e=Function,t=this?.args,n=[...(this?.content??[""]).map((o)=>` ${o}`)];return new e(...t,n.join(`
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@ This skill loads in **terminal-based AI agents** (Claude Code, Cursor, Codex CLI
|
|
|
15
15
|
|
|
16
16
|
## Check versions once per session
|
|
17
17
|
|
|
18
|
-
This skill is version **0.
|
|
18
|
+
This skill is version **0.14.0** and needs `@shotstack/cli` **0.13.0** or later. Before the first `shotstack` command in a session:
|
|
19
19
|
|
|
20
20
|
1. Run `shotstack --version`. If it is older than 0.13.0, tell the user: what this skill documents, such as `analyze`, is missing until they run `npm install -g @shotstack/cli@latest`.
|
|
21
21
|
2. Run `npm view @shotstack/cli version`. If it is newer than this skill's version, tell the user an update is available and ask whether to install it. Only on a yes, run `npx skills update shotstack -y` and `npm install -g @shotstack/cli@latest`. Never update without asking. `npx skills check` is not a read-only check: it installs the update.
|
|
@@ -90,6 +90,8 @@ SRC=$(shotstack ingest upload ./clip.mp4 --watch --output json | tail -n1 | jq -
|
|
|
90
90
|
# …then reference "$SRC" as an asset.src in your Edit JSON and run `shotstack render`.
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
+
This includes images and fonts for an `html5` page: put the URL in its `html` or `css`.
|
|
94
|
+
|
|
93
95
|
The bare command (no `--watch`) returns only an `id`; the hosted `source` URL does not exist until ingestion is `ready`. Always `--watch` (or follow up with `shotstack ingest status <id> --watch`) when you need the URL.
|
|
94
96
|
|
|
95
97
|
Other ingest subcommands: `ingest fetch <url>` (host a copy of a remote URL), `ingest status <id>`, `ingest list`, `ingest delete <id>`. **Read [`references/ingest.md`](references/ingest.md) for the full upload→render workflow, status values, and supported file types.**
|
|
@@ -18,8 +18,10 @@ Host a local file with `shotstack ingest upload <file> --watch`. Generate a trac
|
|
|
18
18
|
|
|
19
19
|
Analysis is free, takes 15–30 s and reads the first 10 minutes of the track.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
The `src` must be a direct, public link to an audio or video file: share pages and redirects are refused.
|
|
22
22
|
<!-- surface:cli -->
|
|
23
|
+
It needs an API key (`shotstack login`).
|
|
24
|
+
|
|
23
25
|
```sh
|
|
24
26
|
shotstack analyze https://shotstack-assets.s3.amazonaws.com/music/unminus/lit.mp3 --output json > map.json
|
|
25
27
|
```
|
|
@@ -102,7 +102,7 @@ What you can build inside one `html5` clip, listed by the effect you'd reach for
|
|
|
102
102
|
- **WebGL, shaders, 3D models:** use CSS 2.5D and SVG filters.
|
|
103
103
|
- **Video or audio inside the clip:** put footage and sound on other timeline tracks; `html5` is the graphics layer.
|
|
104
104
|
- **Scroll, drag or pointer-driven animation:** capture is time-driven only.
|
|
105
|
-
- **Remote
|
|
105
|
+
- **Remote scripts, and images or fonts you haven't ingested:** inline them as `data:` URIs. Images and fonts you ingested work by URL; see [`html5.md`](html5.md).
|
|
106
106
|
|
|
107
107
|
## Cost
|
|
108
108
|
|
|
@@ -16,8 +16,8 @@ Read [`html5.md`](html5.md) for the rules these obey. The non-negotiables:
|
|
|
16
16
|
- **Size the clip to the content, not the canvas.** `html, body` pinned to the clip's `width`/`height`; place with `offset` (`{x:0,y:0}` is centred, `y` positive is up). Use **px**, never `vw`/`vh`/`%`.
|
|
17
17
|
- **The body is transparent by default** — the clip composites over the layers below (only set an opaque background if you want one).
|
|
18
18
|
- **Canvas only from the seek hook.** Draw canvas 2D inside `window.__shotstackSeek(ms)`, never in a `requestAnimationFrame` loop. WebGL is blank in the cloud render. SVG or positioned DOM is usually lighter.
|
|
19
|
-
- **No network.** gsap (with its plugins), anime, d3 and lottie are preloaded; external `<script src>`, `fetch`, remote `<img>`, and remote fonts are all CSP-blocked
|
|
20
|
-
- **Fonts:** `timeline.fonts[]` does **not** reach `html5` and remote `@font-face` is blocked. These snippets name a display font first but render in the `system-ui` fallback unless you
|
|
19
|
+
- **No network.** gsap (with its plugins), anime, d3 and lottie are preloaded; external `<script src>`, `fetch`, remote `<img>`, and remote fonts are all CSP-blocked. Inline them as `data:` URIs, or use the URL of an image or font you ingested (see [`html5.md`](html5.md)).
|
|
20
|
+
- **Fonts:** `timeline.fonts[]` does **not** reach `html5` and remote `@font-face` is blocked. These snippets name a display font first but render in the `system-ui` fallback unless you load the font, from an ingested font's URL or a `data:` `@font-face`.
|
|
21
21
|
- **Use unique element IDs for GSAP targets, not `:nth-child` or compound CSS selectors.** Studio preview doesn't resolve `.parent:nth-child(n) .child` patterns; `#id` works everywhere. When animating repeated elements (list rows, bars, cards), generate a unique ID per item (`id="row0"`, `id="bar0"`) rather than relying on structural selectors.
|
|
22
22
|
|
|
23
23
|
Coordinates below assume a **1080×1920 vertical** canvas; adjust `offset` for other sizes.
|
|
@@ -48,7 +48,7 @@ The reference entrance: opacity, blur and a 16 px rise settle **together** off o
|
|
|
48
48
|
}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
`base` (0.6 s) entrance on `power3.out`, then a `hold` (1.5 s) settle. Swap `{{title}}` via top-level `merge[]`. `Clash Display` falls back to `system-ui` unless you
|
|
51
|
+
`base` (0.6 s) entrance on `power3.out`, then a `hold` (1.5 s) settle. Swap `{{title}}` via top-level `merge[]`. `Clash Display` falls back to `system-ui` unless you load it, from an ingested font's URL or a `data:` `@font-face` (see Fonts above).
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -11,7 +11,7 @@ This is the **modern replacement for the deprecated `html` asset.** `html5` runs
|
|
|
11
11
|
- Required and optional fields
|
|
12
12
|
- Preloaded libraries
|
|
13
13
|
- The browser harness (deterministic auto-seek)
|
|
14
|
-
- Sandbox restrictions: no network,
|
|
14
|
+
- Sandbox restrictions: no network; ingested images and fonts by URL, everything else inline
|
|
15
15
|
- Sizing
|
|
16
16
|
- 3D: what renders in preview and render
|
|
17
17
|
- Worked example: animated lower-third (GSAP)
|
|
@@ -89,25 +89,56 @@ Frames are captured by **seeking** the animation to each timestamp, not by playi
|
|
|
89
89
|
|
|
90
90
|
**Duration comes from the clip's `length`** — there's no animation-duration auto-detection. Size your animation to run within (or fill) the clip's `length`.
|
|
91
91
|
|
|
92
|
-
## Sandbox restrictions: no network,
|
|
92
|
+
## Sandbox restrictions: no network, ingested files by URL
|
|
93
93
|
|
|
94
94
|
The iframe renders under a strict Content-Security-Policy (`default-src 'none'`), in both Studio preview and cloud render. Nothing is fetched from the network at render time:
|
|
95
95
|
|
|
96
96
|
- **No external `<script src=>`.** Only the bundled GSAP/anime.js/D3/Lottie run (they're inlined for you). Another library would have to be inlined into your `js` — and must be seekable.
|
|
97
97
|
- **No `fetch` / `XMLHttpRequest`** (`connect-src 'none'`). Bundle any data inline — e.g. the JS array in the bar-chart example.
|
|
98
|
-
- **No remote images** (`img-src 'self' data: blob:`).
|
|
99
|
-
- **No remote fonts** (`font-src 'self' data:`)
|
|
98
|
+
- **No remote images** (`img-src 'self' data: blob:`), except images you ingested (below). Otherwise embed images as `data:` URIs. A `data:image/svg+xml` background is fine.
|
|
99
|
+
- **No remote fonts** (`font-src 'self' data:`), except fonts you ingested (below). See *Fonts in HTML5*.
|
|
100
|
+
|
|
101
|
+
### Images and fonts you ingested
|
|
102
|
+
|
|
103
|
+
Reference an ingested image or font by its `source` URL, straight from `html` or `css`: an `<img src>`, a CSS `url()` or an `@font-face` `src`. Before capture the renderer fetches each file and inlines it, so the page itself still makes no request.
|
|
104
|
+
|
|
105
|
+
<!-- surface:cli -->
|
|
106
|
+
Upload with `shotstack ingest upload`, or host a copy of a URL with `shotstack ingest fetch`:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
PHOTO=$(shotstack ingest upload ./hero.jpg --watch --output json | tail -n1 | jq -r .source)
|
|
110
|
+
FONT=$(shotstack ingest upload ./Brand.woff2 --watch --output json | tail -n1 | jq -r .source)
|
|
111
|
+
```
|
|
112
|
+
<!-- /surface -->
|
|
113
|
+
|
|
114
|
+
```css
|
|
115
|
+
@font-face { font-family: 'Brand'; src: url(<FONT>) format('woff2'); }
|
|
116
|
+
.hero { background: url(<PHOTO>) center / cover; }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- **Same account and environment only.** A file ingested on `stage` works in `stage` renders, not in `v1`, and another account's files are refused. Every other remote URL is still blocked.
|
|
120
|
+
- **10 MiB per file, 25 MiB per page.** A file counts once for every place the page references it, so reference a large image once (a CSS class, say) and reuse the class.
|
|
121
|
+
- **Size images to the clip.** A photo much larger than the clip makes a heavier page and a slower capture. If the source has a WebP rendition named `html5-512`, `html5-1024`, `html5-2048` or `html5-4096`, the renderer uses the smallest one that covers the clip's longest edge; otherwise it uses the original.
|
|
122
|
+
- **A file that can't be used fails the render**, for example one that's missing, too large, or not an image or font.
|
|
123
|
+
- **Studio's preview doesn't load ingested files yet**, so they show as missing there. The render is unaffected.
|
|
124
|
+
<!-- surface:cli -->
|
|
125
|
+
- Until Studio supports them, check the page with `shotstack render <file> --env stage --watch`.
|
|
126
|
+
<!-- /surface -->
|
|
100
127
|
|
|
101
128
|
### Fonts in HTML5
|
|
102
129
|
|
|
103
|
-
`timeline.fonts[]` does **not** apply to `html5` assets (it loads fonts for `rich-text` / `rich-caption` only), and a remote `@font-face` URL (Google Fonts, etc.) is CSP-blocked.
|
|
130
|
+
`timeline.fonts[]` does **not** apply to `html5` assets (it loads fonts for `rich-text` / `rich-caption` only), and a remote `@font-face` URL (Google Fonts, etc.) is CSP-blocked. Three ways to get a custom font into an `html5` clip:
|
|
104
131
|
|
|
105
|
-
1. **
|
|
132
|
+
1. **Ingest it and use its URL** (see *Images and fonts you ingested*).
|
|
133
|
+
<!-- surface:cli -->
|
|
134
|
+
For a Google Font, `shotstack ingest fetch` the font file's `fonts.gstatic.com` URL and use the hosted copy.
|
|
135
|
+
<!-- /surface -->
|
|
136
|
+
2. **Inline it as a `data:` `@font-face`** — base64-encode the `.woff2` / `.ttf`:
|
|
106
137
|
```css
|
|
107
138
|
@font-face { font-family: 'Brand'; src: url('data:font/woff2;base64,<…>') format('woff2'); }
|
|
108
139
|
.title { font-family: 'Brand', sans-serif; }
|
|
109
140
|
```
|
|
110
|
-
|
|
141
|
+
3. **Use a system family** (`system-ui`, `Arial`, `Georgia`, …) — resolves with no load, but each machine picks its own font, so text in Studio's preview won't match the cloud render exactly. Embed a font whenever the text must match.
|
|
111
142
|
|
|
112
143
|
An unresolved family silently falls back to the browser default — the render won't fail, but the text won't be your font. For a single styled line, a `rich-text` asset (which *does* use `timeline.fonts[]`; verified catalogue in `shared/agent-core.md`) is simpler than a `data:` font embed.
|
|
113
144
|
|
|
@@ -78,6 +78,13 @@ shotstack studio edit.json
|
|
|
78
78
|
Remember `tracks[0]` is the **top** layer (see `shared/agent-core.md`), so the
|
|
79
79
|
logo track sits above the video.
|
|
80
80
|
|
|
81
|
+
## Images and fonts in an html5 page
|
|
82
|
+
|
|
83
|
+
An `html5` page can use images and fonts you ingested by putting their
|
|
84
|
+
`source` URLs in its `html` or `css` (`<img src>`, CSS `url()`, `@font-face`).
|
|
85
|
+
The file must belong to the same account and environment as the render. Limits
|
|
86
|
+
and details are in [`html5.md`](html5.md).
|
|
87
|
+
|
|
81
88
|
## Fetch a remote URL instead of uploading
|
|
82
89
|
|
|
83
90
|
If the media is already at a URL but you want Shotstack to host its own copy
|
|
@@ -168,8 +168,9 @@ Pick `output.resolution` (preset) OR `output.size.width`+`output.size.height` (c
|
|
|
168
168
|
| `sd` | 1024×576 @ 25 |
|
|
169
169
|
| `hd` | 1280×720 @ 25 (default) |
|
|
170
170
|
| `1080` | 1920×1080 @ 25 |
|
|
171
|
+
| `4k` | 3840×2160 @ 25 (Pro, Scale and Volume plans) |
|
|
171
172
|
|
|
172
|
-
Custom sizes must be divisible by 2.
|
|
173
|
+
Custom sizes must be divisible by 2, up to 3840px on each side (1920px for `gif`). Video can be up to 3840×2160 pixels in any shape, for example 2160×3840 for vertical 4K; larger sizes are rejected. Video above 1920×1080 pixels needs a plan that includes 4K.
|
|
173
174
|
|
|
174
175
|
## Merge fields
|
|
175
176
|
|
|
@@ -231,7 +232,7 @@ Use only the **current** asset types; the deprecated ones still parse but should
|
|
|
231
232
|
| `audio` | Audio clip placed at a specific time on the timeline, or AI-generated speech or music from a `prompt`. |
|
|
232
233
|
| `rich-text` | Styled text overlay with full typography control. **Use this instead of `text`/`html`/`title`.** |
|
|
233
234
|
| `svg` | Vector graphics from raw SVG markup: `src` starts with `<svg`, never a URL or `data:` URI (the render fails). See **`svg` assets** below. |
|
|
234
|
-
| `html5` | Self-contained HTML/CSS/JS page rendered in an iframe (motion graphics, charts, animated overlays). Preloads gsap with its plugins (SplitText, DrawSVG, MorphSVG, MotionPath, Flip and more), d3, anime and lottie. See `references/html5.md`. **Never use the deprecated `html` asset.** |
|
|
235
|
+
| `html5` | Self-contained HTML/CSS/JS page rendered in an iframe (motion graphics, charts, animated overlays). Preloads gsap with its plugins (SplitText, DrawSVG, MorphSVG, MotionPath, Flip and more), d3, anime and lottie. Images and fonts: the URL of a file you ingested, or a `data:` URI; other remote URLs are blocked. See `references/html5.md`. **Never use the deprecated `html` asset.** |
|
|
235
236
|
| `rich-caption` | Word-level animated captions sourced from audio, video, or subtitle files. See `references/caption.md`. |
|
|
236
237
|
| `luma` | Luma matte for masking effects. |
|
|
237
238
|
|