import { r as e } from "./examples-DRdr1S0s.js";
import { z as t } from "zod";
//#region src/validation/display-name.ts
var n = t.string().trim().check(t.refine((e) => e.length > 0, { message: "Name cannot be empty" })).describe("Non-empty display name");
function r(e) {
	let t = n.safeParse(e);
	return t.success ? {
		valid: !0,
		name: t.data
	} : {
		valid: !1,
		error: t.error.issues[0].message
	};
}
//#endregion
//#region src/validation/entity-name.ts
var i = /^[A-Z][a-zA-Z]*\d*$/, a = t.string().trim().check(t.refine((e) => e.length > 0, { message: "Name cannot be empty" }), t.refine((e) => i.test(e), { message: "Name must be in PascalCase (e.g., MyPlaceName or Place2). Any numbers must appear at the end." })).describe("PascalCase entity name for places and transitions");
function ee(e) {
	let t = a.safeParse(e);
	return t.success ? {
		valid: !0,
		name: t.data
	} : {
		valid: !1,
		error: t.error.issues[0].message
	};
}
//#endregion
//#region src/validation/variable-name.ts
var te = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/, o = t.string().trim().check(t.refine((e) => e.length > 0, { message: "Variable name cannot be empty" }), t.refine((e) => te.test(e), { message: "Variable name must be in lower_snake_case (e.g., crash_threshold or dt). Only lowercase letters, digits, and single underscores are allowed." })).describe("Lower snake_case variable name for parameters");
function ne(e) {
	let t = o.safeParse(e);
	return t.success ? {
		valid: !0,
		name: t.data
	} : {
		valid: !1,
		error: t.error.issues[0].message
	};
}
//#endregion
//#region src/schemas/entity-schemas.ts
var s = t.string().min(1).meta({ description: "Stable identifier for an SDCPN entity. Use unique IDs within the net." }), c = t.strictObject({
	x: t.number().meta({ description: "Horizontal canvas position." }),
	y: t.number().meta({ description: "Vertical canvas position." })
}).meta({ description: "Canvas position for a place or transition." }), l = t.strictObject({
	id: s,
	itemType: t.enum(["place", "transition"]).meta({ description: "Whether the positioned node is a place or transition." }),
	position: c
}).meta({ description: "A pending canvas-position update for one node." }), u = t.strictObject({
	placeId: s.meta({ description: "ID of the input place connected to the transition." }),
	weight: t.number().positive().meta({ description: "Number of tokens consumed from the input place per firing. For coloured input places this also determines the tuple length the transition's lambda and kernel see at `input.PlaceName` (weight 2 means a 2-token array)." }),
	type: t.enum(["standard", "inhibitor"]).meta({ description: "Standard arcs consume tokens from the input place; inhibitor arcs prevent firing when the source place has at least the weight indicated. Inhibitor arcs do NOT consume tokens and their place is NOT present in the lambda or kernel `input`." })
}).meta({ description: "Input arc from a place into a transition." }), d = t.strictObject({
	placeId: s.meta({ description: "ID of the output place connected from the transition." }),
	weight: t.number().positive().meta({ description: "Number of tokens produced into the output place." })
}).meta({ description: "Output arc from a transition into a place." }), f = t.enum(["input", "output"]).meta({ description: "Whether the arc connects a place into a transition or a transition out to a place." }), p = t.strictObject({
	elementId: s.meta({ description: "Stable identifier for this colour element." }),
	name: n.check(t.refine((e) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e), { message: "Element name must be a valid JavaScript identifier (start with a letter, `_`, or `$`; only letters, digits, `_`, `$` allowed)." })).meta({ description: "Token attribute identifier used DIRECTLY in code. Lambdas, kernels, dynamics, visualizers, and metrics destructure tokens as `{ <name> }`, so this must be a valid JavaScript identifier (e.g. `machine_damage_ratio`, `x`, `velocity`). Spaces, hyphens, and leading digits will break user code that references the attribute; prefer lower_snake_case for consistency with parameter naming." }),
	type: t.enum([
		"real",
		"integer",
		"boolean"
	]).meta({ description: "Primitive token attribute type. Note: the simulation buffer stores all values as Float64; `integer`/`boolean` are documentation/type-hints only, not enforced at runtime." })
}).meta({ description: "One typed attribute on a coloured token." }), m = t.strictObject({
	id: s,
	name: a.meta({ description: "PascalCase identifier used DIRECTLY in user code: lambdas and kernels reference input/output places as `input.PlaceName` and `{ PlaceName: [...] }`, metrics access them as `state.places.PlaceName.count`, scenario code-mode initial state keys are place names, and visualizer scope is implicitly per-place. Renaming a place breaks every code reference, so rename only when you also update dependent lambda/kernel/dynamics/metric/visualizer/scenario code in the same batch." }),
	colorId: s.nullable().meta({ description: "ID of the token colour/type accepted by this place, or null for uncoloured token counts. Uncoloured places have no token attributes and do not appear in lambda/kernel `input` objects." }),
	dynamicsEnabled: t.boolean().meta({ description: "Whether tokens in this place are updated by a differential equation during simulation. Dynamics only run when this is true AND `differentialEquationId` is set AND `colorId` is set." }),
	differentialEquationId: s.nullable().meta({ description: "ID of the differential equation used for continuous dynamics, or null when dynamics are disabled. The referenced equation's `colorId` MUST match this place's `colorId`." }),
	visualizerCode: t.string().optional().meta({ description: "Optional module: `export default Visualization(({ tokens, parameters }) => <JSX/>)`. JSX is compiled with React's CLASSIC runtime — do NOT `import React`, do NOT use `<>…</>` fragments (use `<g>` or explicit elements), and do NOT use hooks; treat it as a pure render. `tokens` is this place's current tokens (only meaningful for coloured places; empty for uncoloured). `parameters` is keyed by each parameter's `variableName` value (lower_snake_case, e.g. `parameters.crash_threshold`). Convention is to return a sized `<svg viewBox=\"0 0 800 600\">…</svg>`." }),
	showAsInitialState: t.boolean().optional().meta({ description: "Optional UI hint to show this place in the initial-state view." }),
	x: t.number().meta({ description: "Horizontal canvas position." }),
	y: t.number().meta({ description: "Vertical canvas position." })
}).meta({ description: "A Petri net place. Places store tokens and may optionally use colours and continuous dynamics." }), h = t.strictObject({
	id: s,
	name: n.meta({ description: "Human-readable transition name." }),
	inputArcs: t.array(u).meta({ description: "Input arcs that gate and consume tokens for this transition." }),
	outputArcs: t.array(d).meta({ description: "Output arcs that receive tokens after this transition fires." }),
	lambdaType: t.enum(["predicate", "stochastic"]).meta({ description: "Use predicate for boolean enabling logic; use stochastic for rate-based firing." }),
	lambdaCode: t.string().meta({ description: [
		"Module: `export default Lambda((input, parameters) => …)`.",
		"`input` is keyed by INPUT PLACE NAME (PascalCase) and the value is a tuple sized to that arc's weight (weight 2 means a 2-token array).",
		"Inhibitor arcs and uncoloured input places are NOT present in `input`.",
		"Each token is an object keyed by the colour type's element names (e.g. `{ x, y, velocity }`).",
		"`parameters` is keyed by each parameter's `variableName` value (lower_snake_case, e.g. `parameters.infection_rate`).",
		"Predicate lambdas MUST return a boolean (true = enabled given these tokens, false = disabled).",
		"Stochastic lambdas MUST return a non-negative finite number = expected firings per simulation second (0 disables, Infinity always fires).",
		"Lambda is called per token combination satisfying arc weights, so it MUST be deterministic — put randomness in the transition kernel, not here."
	].join(" ") }),
	transitionKernelCode: t.string().meta({ description: [
		"Module: `export default TransitionKernel((input, parameters) => …)`.",
		"`input` and `parameters` have the same shape as the transition's lambda.",
		"MUST return an object keyed by OUTPUT PLACE NAME with a tuple sized to that arc's weight. Coloured output places MUST be present; uncoloured output places MUST be omitted (they are auto-populated with empty tokens).",
		"Token attribute values can be plain numbers/booleans OR `Distribution.Gaussian(mean, sd)` / `Distribution.Uniform(min, max)` / `Distribution.Lognormal(mu, sigma)`; each distribution is sampled once per token, and chained `.map(fn)` calls on the same distribution share that single sample (useful for deriving multiple attributes from one draw).",
		"Always required even when no stochasticity is needed; use `export default TransitionKernel(() => ({}))` when every output place is uncoloured."
	].join(" ") }),
	x: t.number().meta({ description: "Horizontal canvas position." }),
	y: t.number().meta({ description: "Vertical canvas position." })
}).meta({ description: "A Petri net transition. Transitions connect places and define firing logic." }), g = t.strictObject({
	id: s,
	name: n.meta({ description: "Human-readable colour/type name." }),
	iconSlug: t.string().min(1).meta({ description: "Short icon identifier used by the UI for this colour/type. Typical values are `\"circle\"` or `\"square\"`; the UI defaults to `\"circle\"`." }),
	displayColor: t.string().min(1).meta({ description: "CSS colour string for the UI badge, e.g. `\"#1E90FF\"` or `\"rgb(30,144,255)\"`." }),
	elements: t.array(p).meta({ description: "Typed token attributes available on tokens of this colour/type. Element order matters: coloured initial state in scenario per_place mode supplies `number[][]` rows in this order." })
}).meta({ description: "A coloured-token type. Coloured places store token objects with these attributes." }), _ = t.strictObject({
	id: s,
	name: n.meta({ description: "Human-readable dynamics name." }),
	colorId: s.nullable().meta({ description: "ID of the colour/type whose token attributes this dynamics function updates. MUST match the `colorId` of every place that references this equation via `differentialEquationId`." }),
	code: t.string().meta({ description: [
		"Module: `export default Dynamics((tokens, parameters) => …)`.",
		"`tokens` is THIS place's current tokens only — `Array<{ [elementName]: number }>` — NOT all places' tokens.",
		"MUST return an array of the SAME LENGTH where each entry is `{ [elementName]: derivative }` (i.e. dx/dt, NOT the new value).",
		"Missing keys default to 0 silently, so return every element your colour type declares.",
		"`parameters` is keyed by each parameter's `variableName` value (lower_snake_case, e.g. `parameters.damage_per_second`)."
	].join(" ") })
}).meta({ description: "A differential equation for continuous dynamics on coloured tokens. The `colorId` MUST match the colour of every place that references this equation via `differentialEquationId`, and the returned derivative keys MUST cover that colour's elements." }), v = t.strictObject({
	id: s,
	name: n.meta({ description: "Human-readable parameter name." }),
	variableName: o.meta({ description: "lower_snake_case identifier used DIRECTLY in user code as `parameters.<value>` (e.g. `parameters.crash_threshold`, NOT `parameters.crashThreshold`). Must start with a lowercase letter; only `[a-z0-9_]` allowed." }),
	type: t.enum([
		"real",
		"integer",
		"boolean"
	]).meta({ description: "Primitive parameter type. Note: parameter values are stored numerically (booleans coerce via `Number()`); the type is primarily a documentation/UI hint." }),
	defaultValue: t.string().meta({ description: "Default parameter value as a plain numeric string (e.g. `\"3\"`, `\"0.05\"`). Parsed via `Number()` with a `|| 0` fallback, so non-numeric strings silently become 0. Expressions are NOT supported here — use scenario `parameterOverrides` for expressions." })
}).meta({ description: "A net-level parameter available to executable SDCPN code and scenarios." }), y = t.strictObject({
	id: s,
	name: n.meta({ description: "Human-readable metric name." }),
	description: t.string().optional().meta({ description: "Optional metric summary shown to users." }),
	code: t.string().meta({ description: [
		"Plain function body (NOT a module — no `export default`, no `Metric(...)` wrapper, no enclosing `function` declaration).",
		"The only variable in scope is `state`. The body MUST `return` a finite number — NaN, Infinity, and -Infinity throw and the metric series shows an error.",
		"Access places by NAME: `state.places.PlaceName.count` (token count for any place) and `state.places.PlaceName.tokens` (`Array<{ [elementName]: number }>` for coloured places; always `[]` for uncoloured places).",
		"`parameters` and `scenario` are NOT available inside metrics.",
		"Example: `const i = state.places.Infected.count; const r = state.places.Recovered.count; return (i + r) === 0 ? 0 : i / (i + r);`"
	].join(" ") })
}).meta({ description: "A simulation metric plotted over time." }), b = t.strictObject({
	type: t.enum([
		"real",
		"integer",
		"boolean",
		"ratio"
	]).meta({ description: "Primitive type for a user-tunable scenario variable. Use ratio for 0-1 proportions, integer for counts, real for rates or other continuous values, and boolean for switches." }),
	identifier: t.string().min(1, "Identifier cannot be empty").regex(/^[a-z][a-z0-9_]*$/, "Identifier must be snake_case").meta({ description: "Scenario-scoped identifier for a user-tunable variable. Reference it as scenario.identifier in parameterOverrides and initialState expressions. Must be snake_case." }),
	default: t.number().meta({ description: "Default numeric value for this scenario parameter, shown to the user before they adjust the scenario." })
}).meta({ description: "A user-tunable variable scoped to one scenario. Prefer scenario parameters for key assumptions the user may want to modify between simulation runs, such as population size, initial infected ratio, intervention strength, or stress-test severity." }), x = t.discriminatedUnion("type", [t.strictObject({
	type: t.literal("per_place"),
	content: t.record(t.string(), t.union([t.string(), t.array(t.array(t.number()))])).meta({ description: [
		"Map keyed by place ID (NOT place name).",
		"For uncoloured places, the value is a string expression with `parameters` and `scenario` in scope (e.g. `\"scenario.population * (1 - scenario.infected_ratio)\"`). The result is `Math.round`ed and clamped to >= 0 (token counts are always non-negative integers).",
		"For coloured places, the value is `number[][]` where each inner array supplies element values in the SAME ORDER as the colour type's `elements`. Extra columns throw at compile time; missing columns default to 0.",
		"`parameters` in expressions is keyed by each parameter's `variableName` value (lower_snake_case)."
	].join(" ") })
}).meta({ description: "Initial state specified place-by-place. Use this for most scenarios. The content keys MUST be existing place IDs." }), t.strictObject({
	type: t.literal("code"),
	content: t.string().meta({ description: [
		"Function body (NOT a module — no `export default`, no wrapper) with `parameters` and `scenario` in scope.",
		"MUST `return` an object keyed by PLACE NAME (NOT place ID — note the asymmetry with per_place mode, which uses place IDs).",
		"Per-place values: a number for uncoloured places (rounded and clamped to >= 0); `Array<{ [elementName]: number }>` for coloured places.",
		"Unknown place names in the returned object are silently dropped — typos produce an empty initial state with no error, so verify names exactly match."
	].join(" ") })
}).meta({ description: "Initial state specified by code. Use only when per_place expressions cannot express the setup (e.g. constructing many coloured tokens from a scenario parameter)." })]).meta({ description: "Initial token state for a scenario. Prefer type \"per_place\" (content keyed by place ID); use type \"code\" (content keyed by place NAME) only for advanced custom setup." }), S = t.strictObject({
	id: s,
	name: n.meta({ description: "Human-readable scenario name." }),
	description: t.string().optional().meta({ description: "Optional scenario summary shown to users." }),
	scenarioParameters: t.array(b).superRefine((e, t) => {
		let n = /* @__PURE__ */ new Set();
		for (let [r, i] of e.entries()) n.has(i.identifier) && t.addIssue({
			code: "custom",
			path: [r, "identifier"],
			message: `Duplicate identifier "${i.identifier}"`
		}), n.add(i.identifier);
	}).meta({ description: "User-tunable parameters available only within this scenario. Add scenario parameters for important scenario variables so users can adjust them without editing net-level parameters or code. Reference them as scenario.identifier in parameterOverrides and initialState expressions." }),
	parameterOverrides: t.record(t.string(), t.string()).default({}).meta({ description: [
		"Map from existing net-level parameter ID to a concrete value or expression for this scenario. Keys MUST be parameter IDs from the current net.",
		"Values may be numeric literals such as `\"1.5\"` or expressions using `scenario` and `parameters`, e.g. `\"scenario.transmission_multiplier * 0.4\"`.",
		"Inside an override expression, `parameters` resolves to net-level DEFAULTS (not other override results) — overrides cannot reference each other.",
		"Omit this field entirely, or use `{}`, when the scenario does not override any net-level parameters. Do NOT emit `\"\"` as a value (it is a no-op at runtime but adds noise)."
	].join(" ") }),
	initialState: x
}).meta({ description: "A reusable simulation scenario with user-tunable scenarioParameters, overrides for existing net-level parameters, and an initial token state. Prefer adding scenario parameters for key assumptions the user may want to modify between runs." }), C = m.omit({
	id: !0,
	x: !0,
	y: !0
}).partial().meta({ description: "Fields to assign to an existing place. Omitted fields are left unchanged." }), w = h.omit({
	id: !0,
	inputArcs: !0,
	outputArcs: !0,
	x: !0,
	y: !0
}).partial().meta({ description: "Fields to assign to an existing transition. Omitted fields are left unchanged." }), re = g.omit({
	id: !0,
	elements: !0
}).partial().meta({ description: "Fields to assign to an existing colour/type. Omitted fields are left unchanged." }), ie = p.omit({ elementId: !0 }).partial().meta({ description: "Fields to assign to an existing colour/type element. Omitted fields are left unchanged." }), ae = _.omit({ id: !0 }).partial().meta({ description: "Fields to assign to an existing differential equation. Omitted fields are left unchanged." }), T = v.omit({ id: !0 }).partial().meta({ description: "Fields to assign to an existing parameter. Omitted fields are left unchanged." }), E = S.omit({ id: !0 }).partial().meta({ description: "Fields to assign to an existing scenario. Omitted fields are left unchanged." }), D = y.omit({ id: !0 }).partial().meta({ description: "Fields to assign to an existing metric. Omitted fields are left unchanged." }), O = t.discriminatedUnion("type", [
	t.strictObject({
		type: t.literal("place"),
		id: s
	}),
	t.strictObject({
		type: t.literal("transition"),
		id: s
	}),
	t.strictObject({
		type: t.literal("arc"),
		id: s
	}),
	t.strictObject({
		type: t.literal("type"),
		id: s
	}),
	t.strictObject({
		type: t.literal("differentialEquation"),
		id: s
	}),
	t.strictObject({
		type: t.literal("parameter"),
		id: s
	})
]).meta({ description: "An item to delete. Arc IDs use Petrinaut's generated arc ID format." }), k = {
	addPlace: m.meta({ description: "Add a place that stores tokens in the SDCPN." }),
	updatePlace: t.strictObject({
		placeId: s,
		update: C
	}).meta({ description: "Update fields on an existing place." }),
	updatePlacePosition: t.strictObject({
		placeId: s,
		position: c
	}).meta({ description: "Update an existing place's canvas position." }),
	removePlace: t.strictObject({ placeId: s }).meta({ description: "Remove a place and any arcs connected to it." }),
	addTransition: h.meta({ description: "Add a transition with firing logic and arcs." }),
	updateTransition: t.strictObject({
		transitionId: s,
		update: w
	}).meta({ description: "Update a transition's properties, arcs, or executable code." }),
	updateTransitionPosition: t.strictObject({
		transitionId: s,
		position: c
	}).meta({ description: "Update an existing transition's canvas position." }),
	removeTransition: t.strictObject({ transitionId: s }).meta({ description: "Remove a transition." }),
	addArc: t.strictObject({
		transitionId: s,
		arcDirection: f,
		placeId: s,
		weight: t.number().positive().meta({ description: "Token multiplicity for the arc." })
	}).meta({ description: "Add an input or output arc to a transition." }),
	removeArc: t.strictObject({
		transitionId: s,
		arcDirection: f,
		placeId: s
	}).meta({ description: "Remove an input or output arc from a transition." }),
	updateArcWeight: t.strictObject({
		transitionId: s,
		arcDirection: f,
		placeId: s,
		weight: t.number().positive().meta({ description: "Replacement token multiplicity for the arc." })
	}).meta({ description: "Update the token weight on an existing arc." }),
	updateArcType: t.strictObject({
		transitionId: s,
		placeId: s,
		type: t.enum(["standard", "inhibitor"]).meta({ description: "Replacement input arc type." })
	}).meta({ description: "Update an existing input arc's type." }),
	updateArcPlace: t.strictObject({
		transitionId: s,
		arcDirection: f,
		oldPlaceId: s.meta({ description: "Current place ID used by the arc." }),
		newPlaceId: s.meta({ description: "Replacement place ID for the arc." })
	}).meta({ description: "Update the place endpoint on an existing arc." }),
	addType: g.meta({ description: "Add a coloured-token type." }),
	updateType: t.strictObject({
		typeId: s,
		update: re
	}).meta({ description: "Update fields on an existing colour/type." }),
	removeType: t.strictObject({ typeId: s }).meta({ description: "Remove a colour/type and clear references from places and dynamics." }),
	addTypeElement: t.strictObject({
		typeId: s,
		element: p
	}).meta({ description: "Add an element to a coloured-token type." }),
	updateTypeElement: t.strictObject({
		typeId: s,
		elementId: s,
		update: ie
	}).meta({ description: "Update fields on an existing type element." }),
	removeTypeElement: t.strictObject({
		typeId: s,
		elementId: s
	}).meta({ description: "Remove an element from a coloured-token type." }),
	moveTypeElement: t.strictObject({
		typeId: s,
		elementId: s,
		toIndex: t.number().int().nonnegative().meta({ description: "Destination index for the element within the type." })
	}).meta({ description: "Move an element within a coloured-token type." }),
	addDifferentialEquation: _.meta({ description: "Add continuous dynamics for a coloured-token type." }),
	updateDifferentialEquation: t.strictObject({
		equationId: s,
		update: ae
	}).meta({ description: "Update fields on an existing differential equation." }),
	removeDifferentialEquation: t.strictObject({ equationId: s }).meta({ description: "Remove a differential equation and clear references from places." }),
	addParameter: v.meta({ description: "Add a net-level parameter available to SDCPN code." }),
	updateParameter: t.strictObject({
		parameterId: s,
		update: T
	}).meta({ description: "Update fields on an existing parameter." }),
	removeParameter: t.strictObject({ parameterId: s }).meta({ description: "Remove a net-level parameter." }),
	addScenario: S.meta({ description: [
		"Add a simulation scenario.",
		"Include `scenarioParameters` for key user-tunable assumptions (reference them in expressions as `scenario.<identifier>`).",
		"`parameterOverrides` keys MUST be existing net-level parameter IDs; omit the field entirely when nothing is overridden.",
		"`initialState.content` keys are place IDs when `type` is `per_place`, but place NAMES when `type` is `code` (note the asymmetry)."
	].join(" ") }),
	updateScenario: t.strictObject({
		scenarioId: s,
		update: E
	}).meta({ description: "Update fields on an existing scenario." }),
	removeScenario: t.strictObject({ scenarioId: s }).meta({ description: "Remove a simulation scenario." }),
	addMetric: y.meta({ description: "Add a simulation metric (a time-series scalar plotted in the simulate view). Note: metric `code` is a plain function body with `state` in scope — do NOT wrap it in `export default Metric(...)` or any other module syntax." }),
	updateMetric: t.strictObject({
		metricId: s,
		update: D
	}).meta({ description: "Update fields on an existing metric." }),
	removeMetric: t.strictObject({ metricId: s }).meta({ description: "Remove a simulation metric." }),
	deleteItemsByIds: t.strictObject({ items: t.array(O).meta({ description: "Items to delete in one mutation." }) }).meta({ description: "Delete selected SDCPN items by ID." }),
	commitNodePositions: t.strictObject({ commits: t.array(l).meta({ description: "Node positions to commit." }) }).meta({ description: "Commit multiple place/transition positions." })
}, A = 1, oe = m.omit({ showAsInitialState: !0 }).shape, se = t.object({
	...u.shape,
	type: t.enum(["standard", "inhibitor"]).optional().default("standard")
}), ce = t.object({ ...d.shape }), le = t.object({
	...oe,
	id: t.string(),
	name: t.string()
}), j = t.object({
	...h.shape,
	id: t.string(),
	name: t.string(),
	inputArcs: t.array(se),
	outputArcs: t.array(ce)
}), M = t.object({
	...p.shape,
	elementId: t.string(),
	name: t.string()
}), N = t.object({
	...g.shape,
	id: t.string(),
	name: t.string(),
	elements: t.array(M)
}), P = t.object({
	..._.shape,
	id: t.string(),
	name: t.string(),
	colorId: t.string().nullable()
}), F = t.object({
	...v.shape,
	id: t.string(),
	name: t.string()
}), I = t.object({
	format: t.literal("petrinaut-sdcpn"),
	version: t.number().int().min(1).max(1),
	documentId: t.string().nullable(),
	data: t.object({
		places: t.array(le),
		transitions: t.array(j),
		types: t.array(N),
		differentialEquations: t.array(P),
		parameters: t.array(F)
	})
}), L = { applyAutoLayout: t.strictObject({ askUserFirst: t.boolean().meta({ description: [
	"Pass `true` to confirm with the user via a Yes/No prompt before applying.",
	"Pass `false` to apply immediately.",
	"Use `false` ONLY when you just built this net from scratch in the current conversation (no user-arranged content existed beforehand).",
	"Otherwise pass `true` so the user can decline — auto-layout will reposition every node."
].join(" ") }) }).meta({ description: [
	"Reposition every place and transition using an ELK layered layout.",
	"Use immediately after creating a net from scratch.",
	"For nets that already contained user-positioned nodes, pass `askUserFirst: true`",
	"so the user can confirm before running."
].join(" ") }) }, R = {
	...L,
	applyClipboardPaste: t.strictObject({ payload: I })
}, z = (e) => Object.keys(e), B = (e) => {
	if (!e.description) throw Error("Petrinaut AI tool schemas must have descriptions");
	return e.description;
};
function V(e) {
	let t = {}, n = (e, n) => {
		t[e] = {
			description: B(n),
			inputSchema: n
		};
	};
	for (let t of z(e)) n(t, e[t]);
	return t;
}
var H = "getLatestNetDefinition", U = "getNetCompilationErrors", W = "setNetTitle", G = "readPetrinautDoc", K = [
	"drawing-a-net",
	"petri-net-extensions",
	"useful-patterns",
	"simulation",
	"scenarios",
	"experiments",
	"ai-assistant",
	"visual-settings",
	"examples"
], q = {
	"drawing-a-net": "Top bar (mode selector, menu, version history, active experiments), canvas, sidebars, adding nodes, arcs, selection, keyboard shortcuts, import/export, auto-layout.",
	"petri-net-extensions": "Token types, parameters, differential equations, visualizers, transition kernels, distributions, firing rate vs predicate, inhibitor arcs, diagnostics.",
	"useful-patterns": "Duration modelling (exponential / non-exponential), resource pools, mutual exclusion, source / sink transitions, competing/routing transitions, multi-token arcs.",
	simulation: "Single-run simulation: initial state, simulation settings (scenario picker, dt, ODE solver, parameters), running, frame computation, deadlock, playback controls, timeline, locked editing.",
	scenarios: "Named simulation configurations: scenario parameters, parameter bindings, per-place vs code-mode initial state, running and switching scenarios.",
	experiments: "Monte Carlo batches: configuration (runs, seed, dt, max time, scenario), lifecycle/statuses, cancel/remove, results (median/mean/p10/p90), active-experiments popover.",
	"ai-assistant": "In-app AI assistant: opening the panel, conversation surface, prompt chips, tool cards, read-only/simulate-mode rules, host configuration.",
	"visual-settings": "Animations, keep-panels-mounted, minimap, snap-to-grid, compact vs classic nodes, partial selection, tree view, arc rendering style.",
	examples: "Walkthroughs of the built-in examples and the scenarios/metrics each ships with: SIR, Supply Chain, Deployment Pipeline, Production Machines, Satellites in Orbit, Probabilistic Satellites Launcher."
}, J = t.strictObject({}).describe("Get the current Petrinaut net state. Returns `{ title, definition }` where `title` is the user-visible net title and `definition` is the complete SDCPN net definition."), Y = t.strictObject({}).describe("Get the current TypeScript diagnostics for the Petrinaut net code. Use this after the net to check whether the model compiles."), X = t.strictObject({ title: t.string().min(1).max(120).meta({ description: "Short human-readable title for the net (sentence case, no quotes, ideally under ~60 characters)." }) }).describe("Set the human-readable title shown for the current Petrinaut net."), Z = t.strictObject({ doc: t.enum(K).meta({ description: "Which Petrinaut user-guide page to read. Pick the one whose summary best matches the user's question or what you need to verify before acting." }) }).describe("Read one page of the Petrinaut user guide. Use this when the user asks how a UI workflow works (panels, simulation controls, settings, examples), or when you need to confirm a UI detail before instructing them."), ue = {
	...k,
	...L,
	[H]: J,
	[U]: Y,
	[W]: X,
	[G]: Z
}, Q = V(k), $ = V(L), de = {
	...Q,
	...$,
	[H]: {
		description: B(J),
		inputSchema: J
	},
	[U]: {
		description: B(Y),
		inputSchema: Y
	},
	[W]: {
		description: B(X),
		inputSchema: X
	},
	[G]: {
		description: B(Z),
		inputSchema: Z
	}
};
function fe(e) {
	let t = { ...e.mutations };
	for (let n of z(L)) t[n] = e.commands[n];
	return t;
}
var pe = `You are an expert assistant for building Stochastic Dynamic Coloured Petri Nets (SDCPNs) in Petrinaut.

Use the provided tools to directly modify the current net. The tools use Petrinaut's raw mutation interfaces, so include stable IDs, full entity objects where required, and canvas positions for places and transitions.
You can check the current net state at any point using the ${H} tool, which returns \`{ title, definition }\` — the user-visible net title plus the complete SDCPN. Use it before making changes that depend on existing places, transitions, arcs, scenarios, metrics, parameters, or types, and consult the \`title\` when deciding whether the net could use a more descriptive name.
You can check current TypeScript compilation diagnostics at any point using the ${U} tool.
You can rename the net at any point using the ${W} tool.
You can read pages of the Petrinaut user guide at any point using the ${G} tool. Reach for it when the user asks how a UI workflow works (panels, simulation controls, visual settings, the built-in examples), or when you need to confirm a UI detail before instructing them. The available pages and what they cover:

${K.map((e) => `- \`${e}\` — ${q[e]}`).join("\n")}

Interview first, build second. Before creating a new net (or adding a substantial new subsystem to an existing one), do NOT jump straight to tool calls. Run a brief, focused interview to establish:

1. Process structure & timing — the key states/places, the events/transitions between them, capacity or routing constraints, and the typical rates/durations (e.g. arrival rate, mean service time, lifetime, retry interval). Flag where stochastic vs. predicate vs. continuous dynamics seem to fit.
2. Observables & metrics — what the user wants to measure once the model runs (throughput, utilisation, latency, queue length, conversion rate, stockouts, infection fraction, …). Each becomes a \`metric\`.
3. Scenarios — the what-if conditions they want to compare (baseline vs. surge, policy A vs. B, parameter sweeps). Each becomes a \`scenario\`, ideally driven by scenario parameters so they can be tweaked between runs.

Keep it tight: ask 2–4 grouped questions per turn, not a long form. Restate what you already understand so the user only has to fill gaps. If the request is already concrete and well-scoped (e.g. "fix this lambda", "add an arc from X to Y", "rename this place"), skip the interview and act.

Escape hatch. Every time you ask questions, explicitly tell the user they can say "make it up", "use sensible defaults", or similar, and you will pick plausible values (with a one-line justification for each major choice) and proceed. Do the same automatically if they reply tersely, with "you decide", or otherwise signal they don't want to specify details.

When creating or revising a net:
- Prefer small, meaningful mutations rather than replacing unrelated content.
- Use coloured-token types when tokens need attributes.
- Use parameters for values the user may want to tune.
- When adding scenarios, prefer scenario parameters for key assumptions the user may want to modify between runs. Reference them as scenario.identifier in parameter overrides and initial-state expressions.
- Use stochastic transition lambdas for rate-based firing.
- Use predicate transition lambdas for boolean firing conditions.
- Use transition kernels to transform or generate coloured tokens, including stochastic distributions.
- Use differential equations only for places whose coloured tokens have continuous dynamics.
- Suggest place visualisations. Once the structure is agreed, proactively propose 1–2 vivid, domain-specific \`visualizerCode\` ideas (e.g. a queue as a stacked bar, satellites as orbit dots, infected population as a heat-dot grid, machines as a row of state-coloured rectangles, inventory as a shelf of boxes) and offer to add them. Default to compact, single-glance SVGs sized for a place node, following the visualizer rules in the code-surface cheatsheet below.
- Keep executable code self-contained and readable.
- Title the net. After building or substantially extending a model, check the title returned by \`${H}\`. If it is \`Untitled\` or an obvious placeholder, call \`${W}\` with a concise, descriptive title (sentence case, ideally under ~60 characters). Don't overwrite a user-chosen title without being asked.

Validate every code-writing change. After any tool call that writes code — lambda, transition kernel, dynamics, visualizer, metric, or scenario code-mode initial state — call ${U} before continuing and fix any reported diagnostics before relying on the new code. Do not assume a code edit is correct just because the tool call succeeded; mutations only validate the schema, not the runtime contract.

Place names are part of the code surface: lambdas/kernels read \`input.PlaceName\`, metrics read \`state.places.PlaceName.count\`, and scenario code-mode initial state keys are place names. Renaming a place via \`updatePlace\` requires updating every dependent lambda, kernel, dynamics, metric, visualizer, and scenario in the same batch — otherwise you will silently break references.

Code-surface cheatsheet (exact shapes expected by the runtime):
- Transition lambda (\`transition.lambdaCode\`): \`export default Lambda((input, parameters) => …)\`. \`input.PlaceName\` is a tuple sized to the input arc weight; tokens are \`{ <elementName>: number }\`. Inhibitor arcs and uncoloured input places are NOT in \`input\`. Predicate → boolean; stochastic → non-negative finite rate in firings per simulation second (0 disables, Infinity always fires). Must be deterministic.
- Transition kernel (\`transition.transitionKernelCode\`): \`export default TransitionKernel((input, parameters) => …)\`. Return \`{ OutputPlaceName: [token, …] }\` sized to the output arc weight. Include only coloured output places; uncoloured output places are auto-populated. Use \`Distribution.Gaussian(mean, sd)\` / \`Distribution.Uniform(min, max)\` / \`Distribution.Lognormal(mu, sigma)\` for stochastic attributes; chained \`.map(fn)\` on the same distribution shares one draw. Always required (use \`() => ({})\` when no coloured outputs).
- Differential equation (\`differentialEquation.code\`): \`export default Dynamics((tokens, parameters) => …)\`. \`tokens\` is THIS place's tokens only. Return an array of the same length whose entries are \`{ <elementName>: derivative }\` (i.e. dx/dt, not the new value). The equation's \`colorId\` MUST match every referencing place's \`colorId\`.
- Place visualizer (\`place.visualizerCode\`): \`export default Visualization(({ tokens, parameters }) => <JSX/>)\`. Classic React runtime — do NOT import React, do NOT use \`<>…</>\` fragments, do NOT use hooks. Convention: return a sized \`<svg viewBox="0 0 W H">…</svg>\`.
- Metric (\`metric.code\`): a plain function body — NOT a module, no \`export default\`, no wrapper. The only variable in scope is \`state\`. Must \`return\` a finite number. Example: \`return state.places.Infected.count / (state.places.Susceptible.count + state.places.Infected.count + state.places.Recovered.count);\`. \`parameters\` and \`scenario\` are NOT available inside metrics.
- Scenario per_place initial state: \`content\` keys are place IDs; uncoloured values are expressions with \`parameters\` and \`scenario\` in scope; coloured values are \`number[][]\` rows in colour element order.
- Scenario code-mode initial state: function body returning \`{ PlaceName: tokens }\` keyed by NAME (asymmetric with per_place IDs); unknown names are silently dropped.
- Parameter access in any code surface: use \`parameters.<variableName>\` where \`<variableName>\` is the parameter's lower_snake_case \`variableName\` value (e.g. \`parameters.crash_threshold\`, never \`parameters.crashThreshold\`).

Auto-layout policy. Once you've finished adding or restructuring places and transitions, call \`applyAutoLayout\` so the canvas isn't littered with overlapping nodes at the origin. Pass \`askUserFirst: false\` ONLY when the net was empty at the start of the conversation and you built it from scratch. If user-arranged content existed beforehand — even if you only added a few nodes to it — pass \`askUserFirst: true\` and the user will be shown a Yes/No prompt. If they decline, leave the layout alone and continue without retrying unless they ask.

After calling tools, do not merely summarize the added or updated items, because the user can already see those changes in the UI. Final text should add extra value: explain important modelling choices, assumptions, how the pieces work together, and useful next checks or questions.

Here is a compact example Petrinaut document demonstrating coloured tokens, stochastic and predicate transitions, transition kernels with distributions, continuous dynamics, parameters, visualizer code, and scenarios:

\`\`\`json
${JSON.stringify(e, null, 2)}
\`\`\``;
//#endregion
export { h as A, p as C, d as D, u as E, r as F, a as M, ee as N, v as O, n as P, y as S, _ as T, A as _, Q as a, b, de as c, Z as d, G as f, R as g, L as h, $ as i, ne as j, m as k, K as l, W as m, H as n, pe as o, X as p, U as r, ue as s, fe as t, q as u, I as v, g as w, S as x, k as y };

//# sourceMappingURL=ai-6pQV2hFq.js.map