@doenet/doenetml-iframe 0.7.21-dev.406 → 0.7.21-dev.409

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/index.js CHANGED
@@ -1368,7 +1368,7 @@ class Indent {
1368
1368
  }
1369
1369
  const chrome$1 = "# Viewer chrome: buttons, panel headers, and other UI the reader interacts\n# with. Rendered on the main thread and selected by `uiLocale`.\n#\n# Message ids are lower-kebab-case Fluent identifiers, optionally with a\n# single `.attribute` suffix (`submit-button`, `answer-status.correct`).\n#\n# This catalog is the source of truth for every other locale: `lint:i18n`\n# rejects a translation that defines a key missing here. Run\n# `npm run codegen -w @doenet/i18n` after editing.\n\n\n## Answer submission — the check-work button and the status it reports.\n\nanswer-checking = Checking...\nanswer-submitting = Submitting...\n\n# Announced to a screen reader while the submission is in flight. Separate\n# from the button's own text, which is abbreviated.\nanswer-checking-status = Checking answer\nanswer-submitting-status = Submitting answer\n\nanswer-correct = Correct\nanswer-incorrect = Incorrect\n\n# Shown instead of a correctness verdict when the activity withholds\n# correctness: the response was recorded, nothing is claimed about it.\nanswer-response-saved = Response Saved\n\n# Partial credit. `-credit` is used when repeated attempts reduce the credit\n# available, `-correct` when they do not, and `-short` on a button too narrow\n# for a word.\nanswer-percent-credit = { $percent }% Credit\nanswer-percent-correct = { $percent }% Correct\nanswer-percent-short = { $percent } %\n\nmax-credit-available = Max credit available: { $percent }%\n\n# Fluent formats `{ $count }` with `Intl.NumberFormat`, so a four-digit\n# attempt count renders as \"1,000\" where the hand-built string said \"1000\".\n# That is the one place English output is not byte-identical to what this\n# replaced, and grouping is the locale-correct rendering, so it stands.\nattempts-remaining =\n { $count ->\n [0] no attempts remaining\n [one] { $count } attempt remaining\n *[other] { $count } attempts remaining\n }\n\n# Appended to an input's accessible name once its response has been graded,\n# so a screen reader reports the verdict along with the field.\nvalidation-correct = (Correct)\nvalidation-incorrect = (Incorrect)\nvalidation-partially-correct = (Partially correct)\n\n# Tooltip on the badge that reports how many responses have been submitted to\n# one answer, shown only to a host that asked for it. `$answerId` is the\n# answer's authored name and is never translated.\nanswer-show-responses =\n { $count ->\n [one] Show { $count } response to { $answerId }\n *[other] Show { $count } responses to { $answerId }\n }\n\n\n## Disclosure panels\n\nfeedback-heading = Feedback\n\n# Follows a disclosure panel's own heading — \"Solution (click to open)\" — and\n# is shared by `<solution>`, `<hint>`, and a collapsible `<section>`. The whole\n# parenthetical is one message: where the word for open or close falls inside\n# it is the translator's business.\ncollapsible-click-to-open = (click to open)\ncollapsible-click-to-close = (click to close)\n\n# Placeholder inside a panel that has been opened before its contents have\n# arrived from the core. Shared by `<solution>` and a collapsible `<section>`.\ncollapsible-initializing = Initializing...\n\n# Tooltip on a footnote marker, naming what activating it will do.\nfootnote-show = Show footnote\nfootnote-hide = Hide footnote\n\n# Tooltip on the ⓘ affordance that reveals an input's description.\ndescription-more-information = more information\n\n\n## Controls\n\nslider-previous = Prev\nslider-next = Next\n\nkeyboard-open = Open Keyboard\nkeyboard-close = Close Keyboard\n\n# Accessible names of a matrix input's size controls, whose visible labels are\n# the symbols `r-` `r+` `c-` `c+`.\nmatrix-remove-row = Remove row\nmatrix-add-row = Add row\nmatrix-remove-column = Remove column\nmatrix-add-column = Add column\n\n# Modes and actions of the subset-of-reals input's control strip. The button\n# that selects all of the reals is the symbol `R`, not a word, and stays in\n# place.\nsubset-add-remove-points = Add/Remove points\nsubset-toggle-points-intervals = Toggle points and intervals\nsubset-move-points = Move Points\nsubset-clear = Clear\n\n# Buttons that edit an orbital diagram: rows hold boxes, boxes hold up to\n# three spin arrows.\norbital-add-row = Add Row\norbital-remove-row = Remove Row\norbital-add-box = Add Box\norbital-remove-box = Remove Box\norbital-add-up-arrow = Add Up Arrow\norbital-add-down-arrow = Add Down Arrow\norbital-remove-arrow = Remove Arrow\n\n# Accessible name of the text field naming one row of an orbital diagram,\n# counting from 1.\norbital-row-label = Label for row { $row }\n\n# Labels the answer column of a pretzel exercise's grid.\npretzel-answer = Answer\n\n# Caption above the table a `<summaryStatistics>` renders. `$column` is the\n# authored name of the data column being summarized and is never translated.\n# The table's own headings (`mean`, `stdev`, `quartile1`, …) are the statistic\n# ids an author references, not prose, and stay in place.\nsummary-statistics-caption = Summary statistics of { $column }\n\n\n## Math input\n\n# Accessible name of the popover that previews the typed expression, and of\n# the rendered expression inside it.\nmath-input-preview-region = math expression preview\nmath-input-preview = Preview\nmath-input-invalid-expression = Invalid expression:\n\n\n## Document status\n\n# Shown while the core is still starting up and nothing can be rendered yet.\nviewer-initializing = Initializing...\n\n\n## Errors\n\n# Prefixes an error message wherever one is shown in place of content: an\n# `<error>` the core reported, the error boundary's fallback, and the\n# placeholder left where a renderer chunk failed to load.\nerror-heading = Error\n\n# Follows the error's own message inside that box, saying where in the source\n# the error was found. $span selects the sentence — one line or a range of\n# them — as a key rather than a phrase, so a translation is free to reorder the\n# whole of it. $startLine and $endLine are line numbers, and arrive as text\n# rather than as numbers so that line 1234 is not grouped as \"1,234\": a line\n# number is an identifier, not a quantity.\nerror-found-at =\n { $span ->\n [line] Found on line { $startLine }.\n *[lines] Found on lines { $startLine }–{ $endLine }.\n }\n\n# Banner above a document that compiled with at least one error in it.\ndocument-contains-errors = This document contains errors!\n\n# Headings of the tooltip the editor shows over a squiggle, naming what kind\n# of diagnostic it is. `-information` and `-hint` are styled identically but\n# are two different words; `-hint` is unreachable today, since nothing Doenet\n# raises is an LSP hint, and is here so the set is complete.\ndiagnostic-heading-error = Error\ndiagnostic-heading-warning = Warning\ndiagnostic-heading-information = Info\ndiagnostic-heading-hint = Hint\n\n# Headings of the same tooltip over an accessibility diagnostic, which says\n# what kind of problem it is rather than how severe. Level 1 is a failure\n# against the WCAG AA success criteria; level 2 is Doenet's own advice, which\n# no standard requires.\naccessibility-heading-level-1 = WCAG AA Accessibility Violation\naccessibility-heading-level-2 = Accessibility alert\n\n# Shown in place of the document when a renderer threw and the error boundary\n# caught it.\nsomething-went-wrong = Something went wrong.\n\n# Shown in place of a single renderer whose code chunk never arrived.\nrenderer-load-failed = a renderer failed to load. Please reload the page.\n\n# Shown in place of the document when the core worker could not be started\n# after retries, rather than leaving the pane blank.\ncore-start-failed = The document viewer could not be started. Please reload the page.\n";
1370
1370
  const content = '# Worker-generated content: style descriptions ("thick red line"), boolean\n# words, and other prose the core computes into the document. Selected by\n# `documentLocale`, which follows the content\'s language rather than the\n# reader\'s UI language.\n#\n# Message ids are lower-kebab-case Fluent identifiers, optionally with a\n# single `.attribute` suffix (`color.blue`, `noun.line-segment`).\n\n\n## Style vocabulary\n##\n## The words the style pipeline derives from a component\'s numeric and\n## enumerated style values. A word an author writes directly — `lineColorWord`,\n## `markerStyleWord`, and their siblings — passes through untranslated: the\n## author chose those words, and rewriting them would be a surprise. So does a\n## CSS named color asked for by name ("rebeccapurple"), which\n## `resolveColorWord` deliberately preserves.\n##\n## Every adjective here is handed `$gender`, the grammatical gender of the noun\n## it describes (see `noun-gender`). English has no agreement and ignores it; a\n## language that inflects selects on it.\n\n# The canonical color families a color value resolves to.\ncolor =\n .black = black\n .white = white\n .gray = gray\n .red = red\n .orange = orange\n .yellow = yellow\n .green = green\n .cyan = cyan\n .blue = blue\n .purple = purple\n .pink = pink\n .brown = brown\n\n# Stroke widths. Only the extremes are named — a middling width is described by\n# its color alone.\nline-width =\n .thick = thick\n .thin = thin\n\n# Dash patterns. A solid stroke is described by its color alone.\nline-style =\n .dashed = dashed\n .dotted = dotted\n\n# Patterns a shape\'s interior can be filled with. A solid fill is described by\n# its color alone.\nfill-style =\n .horizontal = horizontal lines\n .vertical = vertical lines\n .diagonal = diagonal lines\n .backdiagonal = reverse diagonal lines\n .dots = dots\n .diamonds = diamonds\n\n# The things being described. The shapes a point can be drawn as ("square",\n# "cross") are nouns too: a point\'s description names its marker shape rather\n# than always saying "point".\nnoun =\n .line = line\n .line-segment = line segment\n .ray = ray\n .vector = vector\n .curve = curve\n .function = function\n .parabola = parabola\n .polyline = polyline\n .polygon = polygon\n .triangle = triangle\n .rectangle = rectangle\n .circle = circle\n .region = region\n .point = point\n .square = square\n .diamond = diamond\n .cross = cross\n .plus = plus\n\n# A regular polygon names its side count, so it is a message of its own rather\n# than one of `noun`\'s attributes.\n#\n# `$part` splits the noun where a language needs it split: `head` is the word\n# the adjectives attach to, `tail` a complement that follows them. English\n# folds the side count into the head and has no tail; Spanish says "polígono\n# regular" and puts "de 5 lados" after the adjectives, so that they stay beside\n# the noun they agree with. `style-with-noun` and `style-filled-with-noun`\n# place the two halves.\n#\n# `$numSides` is a real number, so it is formatted by the locale\'s own rules —\n# a 1000-gon reads "1,000-sided" here and "de 1000 lados" in Spanish. That is\n# the number-formatting policy in the README, and the one place a description\n# is not character-for-character what the pre-catalog code produced.\nnoun-regular-polygon =\n { $part ->\n [tail] { "" }\n *[head] { $numSides }-sided regular polygon\n }\n\n# The grammatical gender of the noun being described, passed to every adjective\n# describing it so that translations can agree. English has no grammatical\n# gender, so every noun answers the same and the answer goes unused.\n#\n# `$noun` is one of `noun`\'s attribute names, `regular-polygon` for the shape\n# `noun-regular-polygon` names, or the head of a phrase the description builds\n# without naming it as a noun: `border`, `fill`, `text`, or `background`. A\n# word this message does not list falls to its default gender — which is also\n# what an author\'s own `markerStyleWord` gets, since the catalog has never seen\n# it.\nnoun-gender = neuter\n\n\n## Style composition\n##\n## `$parts` names which pieces the style actually supplies, so that a\n## translation can order and inflect each combination on its own terms instead\n## of substituting into a fixed English frame. An absent piece is a different\n## branch, never an empty placeable.\n\n# The adjectives describing a stroke: its width, its dash pattern, and its\n# color. Also describes a shape\'s border, where the color is dropped when it\n# matches the fill it surrounds.\nstyle-stroke =\n { $parts ->\n [width-style-color] { $width } { $lineStyle } { $color }\n [width-color] { $width } { $color }\n [style-color] { $lineStyle } { $color }\n [width-style] { $width } { $lineStyle }\n [width] { $width }\n [style] { $lineStyle }\n *[color] { $color }\n }\n\n# A style description followed by what it describes: "thick red line".\n#\n# `$nounTail` is the noun\'s trailing complement, for the nouns whose\n# translation splits around the adjectives (see `noun-regular-polygon`).\n# English has none today, so it only ever selects `noun` for itself — the other\n# variant is still what a partly-translated locale falls back to, and dropping\n# it would drop that locale\'s side count.\nstyle-with-noun =\n { $parts ->\n [noun-tail] { $description } { $noun } { $nounTail }\n *[noun] { $description } { $noun }\n }\n\n# The word marking a shape as filled.\n#\n# A key of its own, looked up by the code and handed to the messages below as\n# `$filled`, rather than literal text inside them: a language that inflects it\n# has to agree it with the shape. Referencing it from those messages would not\n# do — a term reference (`{ -filled }`) gets an empty scope and never sees\n# `$gender`, and a message reference resolves only inside its own bundle, so a\n# locale that translated `style-filled` but not this word would render the\n# reference literally instead of falling back to English.\nstyle-filled-word = filled\n\n# A filled shape, and the pattern its interior is drawn with, if any.\nstyle-filled =\n { $parts ->\n [pattern] { $filled } { $color } with { $pattern }\n *[plain] { $filled } { $color }\n }\n\n# The same, naming the shape: "filled blue circle with diamonds".\n#\n# The `-tail` variants carry the noun\'s trailing complement, as\n# `style-with-noun` does.\nstyle-filled-with-noun =\n { $parts ->\n [pattern] { $filled } { $color } { $noun } with { $pattern }\n [plain-tail] { $filled } { $color } { $noun } { $nounTail }\n [pattern-tail] { $filled } { $color } { $noun } { $nounTail } with { $pattern }\n *[plain] { $filled } { $color } { $noun }\n }\n\n# The border clause appended to a filled shape: "with a thick red border".\n#\n# `$parts` carries two distinctions English cares about: whether a fill pattern\n# was already mentioned, which makes this a further clause ("and") rather than\n# the first ("with"), and whether the surrounding description named the shape,\n# which is where English wants an article.\nstyle-border-clause =\n { $parts ->\n [with-article] with a { $border } border\n [and] and { $border } border\n [and-article] and a { $border } border\n *[with] with { $border } border\n }\n\n# How a shape\'s interior is filled, on its own: "blue diamonds".\nstyle-fill =\n { $parts ->\n [pattern] { $color } { $pattern }\n *[plain] { $color }\n }\n\nstyle-unfilled = unfilled\n\n# How a piece of text is styled: its color, and the background behind it.\nstyle-text =\n { $parts ->\n [background] { $color } with a { $background } background\n *[plain] { $color }\n }\n\n# What `backgroundColor` answers when nothing is drawn behind the text.\nstyle-background-none = none\n\n\n## Boolean words\n##\n## What a `<boolean>` or `<booleanInput>` *displays*.\n##\n## Not what it parses or serializes. `true` and `false` are DoenetML syntax —\n## an author writes them in the source, `<award>` compares against them, and\n## saved state stores them — so they stay English everywhere, in every\n## language, exactly as `<` stays `<`. Only the word the reader sees moves.\n##\n## The consequence is that a value has two spellings in a translated document,\n## and both have to be accepted where one is read back in: see\n## `booleanFromWord` in the worker.\n\nboolean-true = true\nboolean-false = false\n\n\n## Answer buttons\n##\n## The default text on an answer\'s submit button. Only the *default* is\n## translated: an author who writes `submitLabel="Ready?"` gets "Ready?" in\n## every locale, because they chose those words for their document and a\n## translation of it is not Doenet\'s to make.\n\n# Shown when the answer will report whether the response was right.\nanswer-submit-label = Check Work\n\n# Shown when it will not — the reader submits, and is told nothing more.\nanswer-submit-label-no-correctness = Submit Response\n\n\n## Sectional blocks\n##\n## The word a sectional block calls itself, which the reader sees in its\n## heading and on a `<solution>`\'s reveal control. Keyed by the element the\n## author writes, so `<subsection>` and `<subsubsection>` share `.section` —\n## they are all called a section.\n##\n## An author who writes `renameTo` has named the block themselves, and that\n## name passes through in every language.\n\nsection-name =\n .activity = Activity\n .aside = Aside\n .cascade = Cascade\n .definition = Definition\n .example = Example\n .exercise = Exercise\n .exercises = Exercises\n .given-answer = Answer\n .note = Note\n .objectives = Objectives\n .paragraphs = Paragraphs\n .part = Part\n .problem = Problem\n .problems = Problems\n .proof = Proof\n .question = Question\n .section = Section\n .solution = Solution\n .task = Task\n .theorem = Theorem\n\n# The heading a section builds for itself: "Example 2", "Section 1.3: Limits".\n#\n# `$parts` names which pieces are present and whether a `<title>` follows, so\n# that a translation orders and punctuates each combination on its own terms\n# rather than substituting into an English frame. English puts the word first\n# and separates a title with a colon — or with a period when the heading is a\n# bare number — and none of that is a given.\n#\n# The `-title` variants end in the separator, because what follows them is the\n# title child, rendered separately. Fluent trims trailing whitespace, so the\n# separator is written as a string literal to keep its space.\n#\n# `$sectionNumber` arrives as text ("2", "1.3") rather than as a number: it is\n# an identifier made of counters, and it is not the catalog\'s to reformat.\nsection-title-prefix =\n { $parts ->\n [name] { $sectionName }\n [number] { $sectionNumber }\n [name-title] { $sectionName }{ ": " }\n [number-title] { $sectionNumber }{ ". " }\n [name-number-title] { $sectionName } { $sectionNumber }{ ": " }\n *[name-number] { $sectionName } { $sectionNumber }\n }\n\n# The heading a `<hint>` shows when the author gave it no `<title>`.\nhint-title = Hint\n\n\n## Tables and figures\n##\n## The name a `<table>` or `<figure>` gives itself, which the renderer sets in\n## bold at the head of the title or caption: "Table 2", "Figure 3". An\n## unnumbered one is named by the bare word.\n##\n## The word and the number are one message rather than a word the code\n## concatenates a number onto, so that a language which orders or punctuates\n## them differently can say so.\n##\n## `$enumeration` arrives as text rather than as a number: it identifies the\n## table, so the thousandth one is "Table 1000" and not "Table 1,000".\n##\n## The `-title` and `-caption` branches end in the separator joining the name\n## to the authored title or caption, which the renderer used to write as a\n## literal `": "` of its own. That child is arbitrary marked-up content\n## rendered after this string rather than an argument passed into it, so where\n## it sits is the one thing a translation cannot reorder — the same shape\n## `section-title-prefix` has.\n\ntable-name =\n { $parts ->\n [numbered] Table { $enumeration }\n [numbered-title] Table { $enumeration }{ ": " }\n [unnumbered-title] Table{ ": " }\n *[unnumbered] Table\n }\n\nfigure-name =\n { $parts ->\n [numbered] Figure { $enumeration }\n [numbered-caption] Figure { $enumeration }{ ": " }\n [unnumbered-caption] Figure{ ": " }\n *[unnumbered] Figure\n }\n\n\n## Paginator controls\n##\n## The strip of controls that steps through a `<paginator>`\'s pages. All three\n## words are author-overridable attributes, so only the default is translated.\n\npaginator-previous = Previous\npaginator-next = Next\npaginator-page = Page\n\n# The status between the two buttons: "Page 3 of 5".\n#\n# Composed in the worker rather than in the renderer so that the whole of it is\n# in one language: `$pageLabel` is the `pageLabel` attribute, which an author\n# may have written themselves, and the words joining it to the counts have to\n# sit beside it in the same tongue.\n#\n# The two counts arrive as text, for the same reason `$enumeration` does above.\npaginator-page-status = { $pageLabel } { $currentPage } of { $numPages }\n\n\n## Piecewise functions\n##\n## `<piecewiseFunction>` renders each branch\'s domain as mathematics and writes\n## these three words around it: "if 1 < x < 2 or 4 < x < 5", and "otherwise"\n## for the branch that catches what the others leave. The inequalities are\n## notation and stay as they are; these are prose, and are read aloud as prose.\n##\n## `or` is the only conjunction the core composes into content. Everything else\n## that reads as "a, b, and c" is a diagnostic, and those are joined by\n## `Intl.ListFormat` at the moment the reader\'s language is known rather than\n## by a catalog word (see `DiagnosticListArg`).\n\npiecewise-condition-or = or\n\n# Introduces the domain a branch applies on; the mathematics follows it.\npiecewise-condition-if = if\n\n# The last branch, which applies wherever none of the earlier ones do.\npiecewise-condition-otherwise = otherwise\n\n\n## Chemistry\n##\n## The names the chemistry components generate. Symbols (`H`, `Fe`), formulas,\n## and anything an author\'s `<award>` compares against by value stay as they\n## are; only what is displayed as prose is here.\n##\n## Element names are keyed by symbol, which is the identifier the atom database\n## is read through and is itself never translated.\n##\n## An element\'s periodic group, its phase at STP and its metal category are not\n## here. They are enumerated values an author\'s `<award>` compares against —\n## `$atom.groupName = Noble Gas` — and translating one would break that\n## comparison the moment a document declared a language (#1577).\n\nelement-name =\n .h = Hydrogen\n .he = Helium\n .li = Lithium\n .be = Beryllium\n .b = Boron\n .c = Carbon\n .n = Nitrogen\n .o = Oxygen\n .f = Fluorine\n .ne = Neon\n .na = Sodium\n .mg = Magnesium\n .al = Aluminum\n .si = Silicon\n .p = Phosphorus\n .s = Sulfur\n .cl = Chlorine\n .ar = Argon\n .k = Potassium\n .ca = Calcium\n .sc = Scandium\n .ti = Titanium\n .v = Vanadium\n .cr = Chromium\n .mn = Manganese\n .fe = Iron\n .co = Cobalt\n .ni = Nickel\n .cu = Copper\n .zn = Zinc\n .ga = Gallium\n .ge = Germanium\n .as = Arsenic\n .se = Selenium\n .br = Bromine\n .kr = Krypton\n .rb = Rubidium\n .sr = Strontium\n .y = Yttrium\n .zr = Zirconium\n .nb = Niobium\n .mo = Molybdenum\n .tc = Technetium\n .ru = Ruthenium\n .rh = Rhodium\n .pd = Palladium\n .ag = Silver\n .cd = Cadmium\n .in = Indium\n .sn = Tin\n .sb = Antimony\n .te = Tellurium\n .i = Iodine\n .xe = Xenon\n .cs = Cesium\n .ba = Barium\n .la = Lanthanum\n .ce = Cerium\n .pr = Praseodymium\n .nd = Neodymium\n .pm = Promethium\n .sm = Samarium\n .eu = Europium\n .gd = Gadolinium\n .tb = Terbium\n .dy = Dysprosium\n .ho = Holmium\n .er = Erbium\n .tm = Thulium\n .yb = Ytterbium\n .lu = Lutetium\n .hf = Hafnium\n .ta = Tantalum\n .w = Tungsten\n .re = Rhenium\n .os = Osmium\n .ir = Iridium\n .pt = Platinum\n .au = Gold\n .hg = Mercury\n .tl = Thallium\n .pb = Lead\n .bi = Bismuth\n .po = Polonium\n .at = Astatine\n .rn = Radon\n .fr = Francium\n .ra = Radium\n .ac = Actinium\n .th = Thorium\n .pa = Protactinium\n .u = Uranium\n .np = Neptunium\n .pu = Plutonium\n .am = Americium\n .cm = Curium\n .bk = Berkelium\n .cf = Californium\n .es = Einsteinium\n .fm = Fermium\n .md = Mendelevium\n .no = Nobelium\n .lr = Lawrencium\n .rf = Rutherfordium\n .db = Dubnium\n .sg = Seaborgium\n .bh = Bohrium\n .hs = Hassium\n .mt = Meitnerium\n .ds = Darmstadtium\n .rg = Roentgenium\n .cn = Copernicium\n .nh = Nihonium\n .fl = Flerovium\n .mc = Moscovium\n .lv = Livermorium\n .ts = Tennessine\n .og = Oganesson\n\n# The name an anion takes, for the elements that have one.\n#\n# English derives these — strip a trailing "ine", add "ide", with a small table\n# for the words that rule does not fit — but that is English morphology, not a\n# fact about anions. So each language supplies the names it uses. An element\n# with no entry here is called by its own name, which is also what the English\n# rule does for everything it does not match.\nelement-anion-name =\n .h = Hydride\n .c = Carbide\n .n = Nitride\n .o = Oxide\n .f = Fluoride\n .p = Phosphide\n .s = Sulfide\n .cl = Chloride\n .br = Bromide\n .i = Iodide\n .at = Astatide\n .ts = Tennesside\n\n# A transition metal\'s ion, named with its oxidation state: "Iron (II)".\n#\n# The Roman numeral is IUPAC notation and is the same in every language. Where\n# it sits and how it is punctuated is not, which is why this is a message and\n# not a suffix the code appends.\nion-name-oxidation-state = { $name } ({ $numeral })\n\n# Shown in place of a chemical symbol or formula that names nothing. Rendered\n# into mathematics as well as into text, so the brackets around it are added by\n# the code — inside `\\text{}` for the LaTeX form — and are not part of the\n# message.\nchemistry-invalid-symbol = Invalid Chemical Symbol\nchemistry-invalid-ionic-compound = Invalid Ionic Compound\n';
1371
- const diagnostics = '# Errors and warnings surfaced to the reader or author. Produced by the worker\n# but addressed to whoever is looking at the screen, so these are selected by\n# `uiLocale`, not `documentLocale`.\n#\n# Message ids are lower-kebab-case Fluent identifiers, optionally with a\n# single `.attribute` suffix (`invalid-attribute-value`).\n#\n# Reached by stable diagnostic code rather than by a literal `t("key")` call:\n# `DIAGNOSTIC_CODES` in `src/diagnostics.ts` maps `doenet-w0001` to the id\n# below, and `lint:i18n` treats that registry as the call site. Adding a\n# message here without registering a code for it fails the lint as an orphan.\n#\n# Translators: `through`, `endpoint`, `midpointOffset`, `numDimensions` and the\n# like are DoenetML attribute names. They are part of the language, not prose,\n# and must be left in English exactly as written.\n\n## `<lineSegment>`\n\n# $attributes is a list of attribute names; $attributesCount is its length.\nline-segment-attributes-ignored-with-endpoints =\n { $attributesCount ->\n [one] { $attributes } is ignored when two endpoints are specified\n *[other] { $attributes } are ignored when two endpoints are specified\n }\n\n# $attributes is a list of attribute names; $attributesCount is its length.\nline-segment-attributes-ignored-with-endpoint-and-midpoint =\n { $attributesCount ->\n [one] { $attributes } is ignored when an endpoint and a midpoint are both specified\n *[other] { $attributes } are ignored when an endpoint and a midpoint are both specified\n }\n\nline-segment-midpoint-offset-without-midpoint = midpointOffset has no effect without a midpoint\n\n## `<line>`\n\nline-points-undetermined-dimensions = Line through points of undetermined dimensions.\n\nline-points-too-few-dimensions = Line must be through points of at least two dimensions.\n\n# $variables is a bare enumeration of variable names, not an "and" list.\nline-points-depend-on-variables = Line is through points that depend on variables: { $variables }.\n\nline-equation-invalid-format = Invalid format for equation of line in variables { $variable1 } and { $variable2 }.\n\n## `<ray>`\n\nray-overprescribed-through = Ray is prescribed by through, endpoint, and direction. Ignoring specified through.\n\nray-dimension-mismatch = numDimensions mismatch in ray.\n\n## `<vector>`\n\nvector-overprescribed-head = Vector is prescribed by head, tail, and displacement. Ignoring specified head.\n\nvector-dimension-mismatch = numDimensions mismatch in vector.\n\n## Attracting and constraining\n\n# $component is the DoenetML tag of the child that was named, e.g. "polygon".\nattract-to-without-nearest-point = Cannot attract to a `<{ $component }>` as it doesn\'t have a nearestPoint state variable.\n\nconstrain-to-without-nearest-point = Cannot constrain to a `<{ $component }>` as it doesn\'t have a nearestPoint state variable.\n\nconstrain-to-interior-without-nearest-point = Cannot constrain to interior of a `<{ $component }>` as it doesn\'t have a nearestPoint state variable.\n\n## `<choiceInput>`\n\n# Translators: `labelPosition` is an attribute name and stays in English.\nchoice-input-label-position-ignored = labelPosition is ignored for non-inline choiceInput\n\n## Ordering children by index\n##\n## These name the component in prose rather than as a tag, matching how the\n## messages have always read. The component names stay in English; the nouns\n## around them are prose and should be translated.\n\nchoice-input-indices-count-mismatch = Ignoring indices specified for choiceInput as number of indices doesn\'t match number of choice children.\n\npretzel-indices-count-mismatch = Ignoring indices specified for problem as number of indices doesn\'t match number of problem children.\n\nshuffle-indices-count-mismatch = Ignoring indices specified for shuffle as number of indices doesn\'t match number of components.\n\n# $component is `choiceInput`, `pretzel` or `shuffle` — a DoenetML component\n# name, so it stays in English.\nindices-ignored-out-of-range = Ignoring indices specified for { $component } as some indices out of range.\n\npretzel-indices-repeated = Ignoring indices specified for pretzel as some indices are repeated.\n\npretzel-circuit-first-index = Ignoring indices specified for pretzel in circuit mode as the first index must be 1.\n\n## `<shuffle>` and `<sort>`\n\n# $component is `shuffle` or `sort`. These two components accept the same\n# children and fail the same ways, so they share their messages.\nstring-children-need-type = For `<{ $component }>` to work with string children, a `type` attribute must be specified.\n\n# $type is what the author wrote; math, text, number and boolean are attribute\n# values and stay in English.\ninvalid-type-defaulting-to-math = Invalid type { $type } for { $component } component. Must be one of math, text, number, or boolean. Defaulting to math.\n\n# $value is the string child that could not be used.\nstring-not-valid-component-to-arrange = String "{ $value }" is not a valid component to { $component }. Ignoring.\n\n## Types and variables\n\ninvalid-type-defaulting-to-number = Invalid type { $type }, setting type to number.\n\ninvalid-variable-value = Invalid value of a variable: `{ $value }`\n\n## Variants\n\n# $index is what the author wrote, reproduced verbatim rather than as a number:\n# it reached this message precisely because it was not one.\nvariant-index-must-be-number = Variant index { $index } must be a number\n\nvariant-index-must-be-integer = Variant index { $index } must be an integer\n\n## `<sideBySide>`\n\n# $component is `sideBySide` or `sbsGroup`.\nside-by-side-absolute-widths = `<{ $component }>` is not implemented for absolute measurements. Setting widths to relative.\n\nside-by-side-absolute-margins = `<{ $component }>` is not implemented for absolute measurements. Setting margins to relative.\n\nside-by-side-no-block-child = Invalid `<{ $component }>`: it must have at least one block child.\n\n## `<label>`\n\n# Translators: `for` is an attribute name and stays in English.\nlabel-for-ignored-on-graphical = The `for` attribute on graphical `<label>` is ignored.\n\nlabel-for-must-resolve-to-one = The `for` attribute on `<label>` must resolve to exactly one component.\n\nlabel-for-unresolved = The `for` attribute on `<label>` could not be resolved to a component.\n\nlabel-for-answer-with-authored-inputs = The `for` attribute on `<label>` references an `<answer>` with explicitly authored inputs; reference the input directly.\n\nlabel-for-answer-without-input = The `for` attribute on `<label>` references an `<answer>` without an input to label.\n\nlabel-for-must-reference-input-or-answer = The `for` attribute on `<label>` must reference an input or an answer.\n\n## Accessibility\n\n# $component is a DoenetML tag, e.g. "graph" or "image".\naccessibility-short-description-or-decorative = For accessibility, `<{ $component }>` must either have a short description or be specified as decorative.\n\naccessibility-video-short-description = For accessibility, `<video>` must have a short description.\n\naccessibility-input-short-description-or-label = For accessibility, `<{ $component }>` must have a short description or a label.\n\n# The companion to the message above, for the input an `<answer>` creates on the\n# author\'s behalf. Two messages rather than one with the subject passed in: the\n# subject is a phrase here, not a name, and a phrase handed over as an argument\n# would never reach a translator.\naccessibility-answer-input-short-description-or-label = For accessibility, an `<answer>` creating an input must have a short description or a label.\n\naccessibility-short-description-contains-math = Short descriptions should not contain math components such as `<{ $component }>`. Spell out any math with words.\n\n# $colorName is an attribute name and stays in English. $ratio and $threshold\n# are contrast ratios; $mode says which theme the shortfall was measured in,\n# and is `dark` or `light`.\naccessibility-section-title-insufficient-contrast =\n { $mode ->\n [dark] { $colorName } has insufficient contrast for the section heading text (dark mode) ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1).\n *[other] { $colorName } has insufficient contrast for the section heading text ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1).\n }\n\n## `<circle>`\n\n# $count is the number of through points.\ncircle-through-points-non-numerical = Haven\'t implemented `<circle>` through { $count } points in case where the points don\'t have numerical values.\n\ncircle-too-many-through-points = Cannot calculate circle through more than 3 points.\n\ncircle-overprescribed-radius-center-points = Cannot calculate circle with specified radius, center and through points.\n\ncircle-center-with-multiple-points = Cannot calculate circle with specified center through more than 1 point.\n\n# $distance and $radius arrive as strings, not numbers: $radius is the author\'s\n# own value echoed back for diagnosis, and formatting it as a quantity would\n# round a radius of 0.0001 away to 0.\ncircle-radius-too-small = Cannot calculate circle: given that the distance between the two points is { $distance }, the specified radius { $radius } is too small.\n\ncircle-radius-with-many-points = Cannot create circle through more than two points with a specified radius.\n\ncircle-invalid-center-or-through-points = Invalid center or through points of circle.\n\ncircle-radius-center-with-multiple-points = Cannot calculate radius of circle with specified center through more than 1 point.\n\ncircle-change-radius-non-numerical = Cannot change radius of circle with non-numerical through points\n\ncircle-radius-with-points-non-numerical = Cannot create circle through more than one point with specified radius when don\'t have numerical values.\n\ncircle-change-center-non-numerical = Haven\'t implemented changing center of circle through points with non numerical values.\n\n## `<function>`\n\n# Two independent counts in one sentence, so the variants multiply out. A\n# select\'s variants each need their own line, so the inner one spans lines too;\n# that is safe because newlines inside a placeable never reach the rendered\n# value. Only text continuing onto a further line would.\nfunction-domain-insufficient-dimensions =\n { $intervals ->\n [one] Insufficient dimensions for domain for function. Domain has { $intervals } interval but the function has { $inputs ->\n [one] { $inputs } input\n *[other] { $inputs } inputs\n }.\n *[other] Insufficient dimensions for domain for function. Domain has { $intervals } intervals but the function has { $inputs ->\n [one] { $inputs } input\n *[other] { $inputs } inputs\n }.\n }\n\nfunction-domain-invalid-format = Invalid format for domain for function.\n\n# $type is what was being read off the point. It selects the wording rather\n# than being substituted into it: "maximum", "slope" and the rest are English\n# nouns, and a noun handed over as an argument would never reach a translator.\n# The catch-all reproduces the pre-catalog behavior for a value not listed here.\nfunction-ignoring-non-numerical =\n { $type ->\n [maximum] Ignoring non-numerical maximum of function.\n [minimum] Ignoring non-numerical minimum of function.\n [extremum] Ignoring non-numerical extremum of function.\n [point] Ignoring non-numerical point of function.\n [slope] Ignoring non-numerical slope of function.\n *[other] Ignoring non-numerical { $type } of function.\n }\n\nfunction-ignoring-empty =\n { $type ->\n [maximum] Ignoring empty maximum of function.\n [minimum] Ignoring empty minimum of function.\n [extremum] Ignoring empty extremum of function.\n [point] Ignoring empty point of function.\n *[other] Ignoring empty { $type } of function.\n }\n\nfunction-points-too-close = Function contains two points with locations too close together. Can\'t define function.\n\nfunction-iterates-input-output-mismatch =\n { $inputs ->\n [one] Function iterates are possible only if the number of inputs of the function is equal to the number of outputs. This function has { $inputs } input and { $outputs ->\n [one] { $outputs } output\n *[other] { $outputs } outputs\n }.\n *[other] Function iterates are possible only if the number of inputs of the function is equal to the number of outputs. This function has { $inputs } inputs and { $outputs ->\n [one] { $outputs } output\n *[other] { $outputs } outputs\n }.\n }\n\n## `<sequence>`\n\nsequence-invalid-length = Invalid length of sequence. Must be a non-negative integer.\n\n# $type is a sequence type: number, letters, or math.\nsequence-invalid-step = Invalid step of sequence. Must be a number for sequence of type { $type }.\n\n# $attribute is `from` or `to` — an attribute name, so it stays in English.\nsequence-invalid-endpoint-number = Invalid "{ $attribute }" of number sequence. Must be a number.\n\nsequence-invalid-endpoint-letters = Invalid "{ $attribute }" of letters sequence. Must be a letter combination.\n\nsequence-invalid-endpoint = Invalid "{ $attribute }" of sequence.\n\nselect-from-sequence-coprime-not-numbers = coprime ignored since not selecting numbers\n\nselect-from-sequence-coprime-with-exclude-combinations = coprime ignored since excludeCombinations specified\n\n## Resolving a `target`\n##\n## Raised by the components that take a `target` attribute. They resolve it\n## through the same code and fail the same two ways, so they share these two\n## messages rather than spelling each one out per component: $source is the tag\n## of the component that raised it, part of the DoenetML language, so it stays\n## in English.\n\ntarget-not-found = Invalid target for `<{ $source }>`: cannot find target.\n\n# $property is the state variable that was looked for; $component is the tag it\n# was looked for on.\ntarget-state-variable-not-found = Invalid target for `<{ $source }>`: cannot find a state variable named "{ $property }" on a `<{ $component }>`.\n\n## `<odeSystem>`\n\node-system-variables-match-independent = Variables of `<odeSystem>` must be different than independent variable.\n\node-system-duplicate-variable-names = Can\'t define ODE RHS functions with duplicate dependent variable names.\n\node-system-rhs-function-error = Cannot define ODE RHS function. Error creating mathjs function.\n\n## `<angle>`, `<parabola>`, and `<intersection>`\n\n# $count is how many line children were found.\nangle-too-many-lines = Cannot define an angle between { $count } lines\n\nangle-invalid-through-point = Invalid point in through of `<angle>`\n\nparabola-vertex-too-many-points = Haven\'t implemented parabola with vertex through more than 1 point.\n\nparabola-too-many-points = Haven\'t implemented parabola through more than 3 points.\n\nintersection-too-many-items = Haven\'t implemented intersection for more than two items\n\n## Other math components\n\nionic-compound-not-two-ions = Have not implemented ionic compound for anything other than two ions.\n\nionic-compound-needs-cation-and-anion = Ionic compound implemented only for one cation and one anion.\n\n# $equation is the equation as the author wrote it.\nsolve-equations-cannot-evaluate = Cannot solve equation as could not evaluate equation: { $equation }\n\n# Translators: `operandNumber` is an attribute name and stays in English.\nmath-operators-operand-number-required = Must specify a operandNumber when extracting a math operand.\n\neigen-decomposition-failed = Could not calculate eigenvalues of matrix\n\n## `<matchesPattern>`\n\n# Translators: `parameters` is an attribute name and stays in English.\n# $parameters lists the parameters as the author wrote them;\n# $parametersCount is how many there were.\nmatches-pattern-parameter-not-in-pattern =\n { $parametersCount ->\n [one] `<matchesPattern>`: the parameter { $parameters } does not occur in the pattern, so it will always match a blank.\n *[other] `<matchesPattern>`: the parameters { $parameters } do not occur in the pattern, so they will always match a blank.\n }\n\n## PreFigure renderer\n\n# Translators: xLabelPosition, yLabelPosition and their values are attribute\n# names and stay in English, as does the renderer\'s name.\nprefigure-x-label-position-unsupported = `<graph>`: xLabelPosition="left" is not supported in prefigure renderer; using right-position behavior.\n\nprefigure-y-label-position-unsupported = `<graph>`: yLabelPosition="bottom" is not supported in prefigure renderer; using top-position behavior.\n\nprefigure-invalid-axis-bounds = `<graph>`: invalid axis bounds for prefigure conversion; using default bbox (-10,-10,10,10).\n\nprefigure-invalid-width = `<graph>`: invalid width for prefigure conversion; using default diagram width 425.\n\nprefigure-invalid-aspect-ratio = `<graph>`: invalid aspectRatio for prefigure conversion; using default aspect ratio 1.\n\n# Translators: the renderer\'s name, prefigure, stays in English. "grid" here is\n# the coordinate grid itself rather than the attribute that asks for one, so it\n# is prose and is translated.\nprefigure-grid-spacing-too-fine = `<graph>`: the grid spacing is too fine for the axis limits; the grid is omitted in the prefigure renderer.\n\nprefigure-annotations-not-rendered = `<graph>`: annotations will not be rendered when not using the PreFigure renderer.\n\nmultiple-annotations-children = Multiple `<annotations>` children found in `<graph>`; all but the last one are ignored.\n\n## Referring to other components\n##\n## `<updateValue>`\'s own "cannot find target" messages are not here: it\n## resolves a target the same way `<animateFromSequence>` does and fails the\n## same ways, so the two share `target-not-found` and\n## `target-state-variable-not-found` above.\n\ncopy-unrecognized-component-type = Cannot extend or copy an unrecognized component type: { $type }.\n\ncopy-prop-not-found = Could not find prop { $property } on a component of type { $component }\n\ncollect-no-source = No source found for collect.\n\ncollect-invalid-component-type = Cannot collect components of type `<{ $component }>` as it is an invalid component type.\n\n# $reference is the reference exactly as the author wrote it, `$` and all —\n# the `$p.styleDescription[1]` of `<text extend="$p.styleDescription[1]" />`.\n# An index only means something applied to an array, and the thing named here\n# is not one. The reference is quoted back rather than explained because the\n# text in front of the author is the only part of this they can act on: the\n# state variable and component index the core knows about are its own business\n# and go to the console instead.\nreference-index-unavailable = Cannot reference index `{ $reference }`\n\n## `<callAction>`\n\n# $action is the `actionName` the author asked for, part of the DoenetML\n# language, so it stays in English. $reference is the `target` as written.\ncomponent-action-unavailable = Cannot call { $action } on component `{ $reference }`\n\n## `<dataFrame>`\n\n# $componentIdx is an internal index, passed as a string so it is not grouped\n# like a quantity; the odd spacing before the colon is reproduced from the\n# original message.\ndata-frame-inconsistent-row-lengths = Data has invalid shape. Rows has inconsistent lengths. Found in componentIdx :{ $componentIdx }\n\ndata-frame-duplicate-column-names = Data has duplicate column names. Found in componentIdx :{ $componentIdx }\n\ndata-frame-missing-column-name = Data is missing a column name. Found in componentIdx :{ $componentIdx }\n\n## `<answer>` and scoring\n\nanswer-award-depends-on-own-response = An award for this answer is based on the answer tag\'s own submitted response, which will lead to unexpected behavior.\n\n# Translators: maxNumAttempts and sectionWideCheckWork are attribute names.\nanswer-max-num-attempts-in-section-wide-check-work = Setting `maxNumAttempts` on an `<answer>` inside a container with `sectionWideCheckWork` has no effect, as the number of attempts is controlled by the container. Set `maxNumAttempts` on the container instead.\n\nnested-section-wide-check-work-max-num-attempts = Setting `maxNumAttempts` on a container with `sectionWideCheckWork` that is inside another container with `sectionWideCheckWork` has no effect, as the number of attempts is controlled by the outer container. Set `maxNumAttempts` on the outer container instead.\n\n# $attributes is a list of attribute names; $attributesCount is its length.\nanswer-attributes-need-symbolic-equality =\n { $attributesCount ->\n [one] The { $attributes } attribute will have no effect without symbolicEquality set.\n *[other] The { $attributes } attributes will have no effect without symbolicEquality set.\n }\n\nanswer-invalid-type = Invalid type for answer: { $type }\n\n## `<module>`, `<conditionalContent>`, `<slider>`, `<pretzel>`\n\nmodule-attribute-child-needs-name = Since the component `<{ $component }>` does not have a name, it cannot be used for a module attribute\n\nmodule-attribute-name-already-defined = The component `<{ $component } name="{ $name }">` cannot be used as an attribute for a module because the `<module>` component type already has a "{ $name }" attribute defined.\n\nconditional-content-condition-ignored = Attribute `condition` is ignored on a `<conditionalContent>` component with case or else children.\n\nslider-markers-type-mismatch = Markers type doesn\'t match slider type.\n\npretzel-problem-needs-statement-and-answer = Invalid pretzel: each `<problem>` must contain one `<statement>` and one `<answer>`.\n\npretzel-circuit-first-problem-distractor = Invalid pretzel: in mode="circuit", the first `<problem>` cannot be a distractor.\n\n## Attribute values\n\n# $values is a list of the values that were rejected, each already in\n# backticks; $valuesCount is how many there were.\nattribute-invalid-values =\n { $valuesCount ->\n [one] Invalid value { $values } for attribute `{ $attribute }`; ignoring.\n *[other] Invalid values { $values } for attribute `{ $attribute }`; ignoring.\n }\n\nattribute-must-be-references = Invalid value `{ $value }` for attribute `{ $attribute }`. Attribute must be composed of references that begin with a `$`.\n\n# $names is a list of the rejected names, each already in single quotes.\nmath-input-invalid-function-names = <mathInput>: ignored invalid function name(s) in { $attribute }: { $names }. Each name\'s display segment must be at least 2 characters (letters or dashes); an optional `|<mathspeak alternative>` suffix may follow.\n\n## Building components from the source\n\n# Raised while the source is being turned into components, by throwing rather\n# than by building a record: the thrower is caught, the component becomes an\n# `_error`, and the diagnostic is re-raised from it.\n\ncomponent-type-invalid = Invalid component type: `<{ $componentType }>`\n\nattribute-repeated = Cannot repeat attribute { $attribute }.\n\nattribute-invalid-for-component = Invalid attribute "{ $attribute }" for a component of type `<{ $componentType }>`.\n\n## Style definition contrast\n\n# $context names the pair being compared, $mode which colour scheme it was\n# rendered in. Both are symbolic — the phrase is chosen here so a translator\n# can rewrite it, rather than being handed over already in English.\nstyle-definition-insufficient-contrast =\n Style definition { $styleNumber } has insufficient contrast for { $context ->\n [text-on-background] text color against background color\n [high-contrast] high-contrast color against the canvas\n [line] line color against the canvas\n [marker] marker color against the canvas\n *[text-on-canvas] text color against the canvas\n }{ $mode ->\n [dark] { " (dark mode)" }\n *[light] { "" }\n } ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1).\n\n# $suggestion says whether a concrete replacement colour could be computed.\n# The attribute names and colour values in the `available` branch are\n# DoenetML source, not prose, and stay as they are in every language.\nstyle-definition-dark-mode-text-background-contrast =\n Although style definition { $styleNumber } has specified colors that provide sufficient contrast for light mode, the dark-mode colors derived from these values have insufficient contrast for the text color against the background color ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1). { $suggestion ->\n [available] To ensure sufficient contrast in dark mode, either increase the light-mode contrast (e.g., set { $lightAttribute }="{ $lightColor }") or override the dark-mode color (e.g., set { $darkAttribute }="{ $darkColor }").\n *[none] To ensure sufficient contrast in dark mode, increase the light-mode contrast or override the derived colors with textColorDarkMode and/or backgroundColorDarkMode.\n }\n\nstyle-definition-dark-mode-text-canvas-contrast =\n Although style definition { $styleNumber } has a specified text color that provides sufficient contrast for light mode, the dark-mode text color derived from this value has insufficient contrast against the canvas ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1). { $suggestion ->\n [available] To ensure sufficient contrast in dark mode, either increase the light-mode contrast (e.g., set textColor="{ $lightColor }") or override the dark-mode color (e.g., set textColorDarkMode="{ $darkColor }").\n *[none] To ensure sufficient contrast in dark mode, increase the light-mode contrast or override the derived color with textColorDarkMode.\n }\n\nsection-multiple-style-palettes = A section can select only one <stylePalette>; using the last one.\n\n## Unique variants\n\n# Explanations of why a component\'s unique variants could not be worked out.\n# $component is the tag that could not be analyzed and stays as written; the\n# reason is a separate message per situation, so a host can tell them apart by\n# code and a translator sees a whole sentence rather than a fragment.\n\nvariant-num-to-select-not-non-negative-integer = cannot determine unique variants of { $component } as numToSelect isn\'t a non-negative integer.\n\nvariant-num-to-select-not-constant-number = cannot determine unique variants of { $component } as numToSelect isn\'t constant number.\n\nvariant-with-replacement-not-constant-boolean = cannot determine unique variants of { $component } as withReplacement isn\'t constant boolean.\n\nvariant-select-weight-disables-unique = Unique variants for select disabled if have an option with selectWeight or selectForVariants specified\n\nvariant-coprime-undetermined = cannot determine unique variants of { $component } as cannot determine coprime is always false.\n\n# $attribute is an attribute name (`from`, `to`, `step`, `sort`, `length`) and\n# stays as written.\nvariant-attribute-not-constant = cannot determine unique variants of { $component } as { $attribute } isn\'t a constant.\n\nvariant-attribute-not-number = cannot determine unique variants of { $component } as { $attribute } isn\'t a number.\n\n# $type is the sequence type the component was declared with. $expected names\n# what the value had to be, symbolically, because which one applies depends on\n# both the type and the attribute.\nvariant-attribute-wrong-type-for-sequence =\n cannot determine unique variants of { $component } of { $type } type as { $attribute } isn\'t { $expected ->\n [letters-combination] a combination of letters\n [math-expression] a valid math expression\n [integer] an integer\n *[number] a number\n }.\n\nvariant-length-not-integer = cannot determine unique variants of { $component } as length isn\'t an integer.\n\nvariant-sort-not-implemented = have not implemented unique variants of a { $component } with sort\n\nvariant-exclude-combinations-not-implemented = have not implemented unique variants of a { $component } with excludeCombinations\n\nvariant-math-exclude-not-implemented = have not implemented unique variants of a { $component } of type math with exclude\n\nvariant-non-constant-exclude-not-implemented = have not implemented unique variants of a { $component } with non-constant exclude\n\n## PreFigure conversion\n\n# $subject identifies the component the warning is about, already written as\n# `<tag>` or `<tag> (name)`. It is composed in code rather than here because\n# Fluent terms cannot take a variable as an argument, so a shared subject\n# fragment cannot be parameterized from the catalog. It holds only a tag name,\n# a component name and punctuation — never a word — which is why a descendant\n# with no type reads `<?>` rather than `<unknown>`.\n\nprefigure-descendant-unsupported = { $subject }: unsupported in graph prefigure renderer; descendant skipped.\n\nprefigure-descendant-invalid-geometry = { $subject }: non-finite or incomplete geometry; descendant skipped.\n\nprefigure-curve-label-omitted = { $subject }: labels are not supported on converted curve elements; label omitted.\n\nprefigure-curve-unsupported-definition-type = { $subject }: unsupported curve function definition type \'{ $definitionType }\'; descendant skipped.\n\nprefigure-region-flip-functions-unsupported = { $subject }: unsupported flipFunctions attribute on regionBetweenCurves; descendant skipped.\n\nprefigure-region-non-formula-child = { $subject }: only formula-typed child functions are supported on regionBetweenCurves; descendant skipped.\n\n# $labelKind says which family of object carried the label, since the advice\n# is the same but the object is not.\nprefigure-label-position-unsupported =\n { $subject }: unsupported labelPosition \'{ $labelPosition }\' for { $labelKind ->\n [line-family] line-family label\n *[point] point label\n }; default PreFigure alignment used.\n\nprefigure-fill-style-unsupported = { $subject }: fill style \'{ $fillStyle }\' is unsupported by PreFigure; falling back to a solid fill.\n\nprefigure-line-style-unknown = { $subject }: unknown line style \'{ $lineStyle }\' omitted from PreFigure output.\n\nprefigure-marker-style-mapped-to-diamond = { $subject }: marker style \'{ $markerStyle }\' mapped to PreFigure style \'diamond\'.\n\nprefigure-marker-style-unsupported = { $subject }: marker style \'{ $markerStyle }\' is unsupported by PreFigure; default style used.\n\n## PreFigure annotations\n\nannotation-ref-unresolvable = `<annotation>`: invalid `ref`; cannot resolve target. Annotation omitted.\n\nannotation-ref-multiple-targets = `<annotation>`: `ref` resolved to multiple targets; using the first target.\n\nannotation-ref-outside-graph = `<annotation>`: invalid `ref`; target is outside the containing graph. Annotation omitted.\n\nannotation-ref-unsupported-target = `<annotation>`: invalid `ref`; target is not a supported graphical object in prefigure conversion. Annotation omitted.\n\nannotation-text-missing = `<annotation>`: missing or empty `text`; emitting empty text.\n\n## Composites and references\n\n# $componentType is the type the composite was asked to create, when it is\n# known; `none` when the composite did not say.\ncomposite-circular-dependency =\n { $componentType ->\n [none] Circular dependency detected.\n *[other] Circular dependency detected involving `<{ $componentType }>` component.\n }\n\n# $reference is the reference as the author wrote it, already carrying its `$`.\nreference-no-referent = No referent found for reference: `{ $reference }`\n\nreference-multiple-referents = Multiple referents found for reference: `{ $reference }`\n\n## Children that do not match\n\nchildren-invalid-attribute-format = Invalid format for attribute { $attribute } of `<{ $componentType }>`.\n\n# $children is the list of child types that did not match, already joined.\nchildren-invalid = Invalid children for `<{ $componentType }>`: Found invalid children: { $children }\n\n## Falling back to a default\n\nattribute-value-invalid-using-default = Invalid value `{ $value }` for attribute `{ $attribute }`, using value `{ $default }`\n\n## Loading a DoenetML version\n\n# $fallback is the version that will be used instead, or `none` when the\n# embedding page named a standalone bundle of its own.\ndoenetml-version-not-found =\n { $fallback ->\n [none] DoenetML version { $version } not found.\n *[other] DoenetML version { $version } not found. Falling back to version { $fallback }\n }\n\n## Reading the DoenetML\n\n# The parser\'s own diagnostics: what the author sees before anything runs, and\n# for a beginner usually the first Doenet message they ever read.\n#\n# The parser writes its English beside the code rather than rendering it from\n# here, because `@doenet/parser` is inside the language-server bundle and a\n# catalog there is dead weight on the editor\'s critical path\n# (`packages/lsp/scripts/check-server-bundle.mjs` fails if one arrives). The\n# two copies are held together by a test in that package, which parses a\n# corpus and asserts every coded error renders to exactly what the parser\n# wrote — so a message edited here without its counterpart fails there.\n#\n# $tag, $value, $attribute and their relatives quote the author\'s own source\n# back at them and stay exactly as written. The `Invalid DoenetML: ` opening is\n# repeated in each message instead of being a shared term: a term a locale\n# forgets to define renders as its own name, and a prefix on fifteen messages\n# is not worth that failure mode.\n\nparse-invalid-doenetml = Invalid DoenetML: { $content }\n\nparse-tag-missing-close-tag = Invalid DoenetML: The tag `{ $tag }` has no closing tag. Expected a self-closing tag or a `</{ $tagName }>` tag.\n\nparse-tag-error = Invalid DoenetML: Error in tag `<{ $tagName }>`\n\nparse-attribute-missing-value = Invalid DoenetML: Invalid attribute `{ $attribute }` appears to be missing a value.\n\nparse-attribute-invalid = Invalid DoenetML: Invalid attribute `{ $attribute }`\n\nparse-attribute-value-invalid = Invalid DoenetML: Invalid attribute value `{ $value }`\n\n# $quote is the quote character that would balance the pair: `"` or `\'`.\nparse-attribute-value-quote-mismatch = Invalid DoenetML: Invalid attribute value `{ $value }`. The quote marks do not match. You appear to be missing a `{ $quote }`\n\nparse-open-tag-name-missing = Invalid DoenetML: Found a tag without a tag name, e.g. `<`\n\nparse-tag-not-closed = Invalid DoenetML: Tag `{ $tag }` was not closed (a `>` appears to be missing).\n\nparse-self-closing-tag-name-missing = Invalid DoenetML: Found a tag without a tag name `<{ $content }>`\n\nparse-self-closing-tag-not-closed = Invalid DoenetML: Tag `{ $tag }` was not closed (`/>` appears to be missing).\n\nparse-tag-invalid-attributes = Invalid DoenetML: Tag `{ $tag }` is not valid. It may have incorrect attributes.\n\nparse-close-tag-name-missing = Invalid DoenetML: Found a closing tag without a tag name, e.g. `</`\n\n# $attribute is the attribute name and $value the unquoted token that followed\n# it, shown reassembled the way the author should have written it.\nparse-attribute-value-unquoted = Attribute values must be enclosed in quotes: `{ $attribute }="{ $value }"`\n\nparse-close-tag-without-open-tag = Invalid DoenetML: Found closing tag `{ $tag }`, but no corresponding opening tag\n\nparse-close-tag-mismatched = Invalid DoenetML: Mismatched closing tag. Expected `</{ $expected }>`. Found `{ $found }`\n\n# The conversion\'s fall-through: the syntax tree held a node shape it has no\n# case for. Reaching an author means the grammar and the conversion have gone\n# out of step, which is a bug in Doenet rather than in their document — hence\n# `parser-` rather than the `parse-` of every message above, which is about\n# what the author wrote. They are still the one looking at it, so it is\n# translated like any other error. $node is the node\'s own name and stays as\n# it is.\nparser-node-unconvertible = Could not convert node { $node } to Dast node.\n\n## Names\n\n# $reason says which rule the name broke, as a key rather than a phrase, so the\n# whole sentence is translatable rather than assembled from two halves.\nname-attribute-invalid =\n Invalid attribute name=\'{ $name }\'. { $reason ->\n [characters] Names can contain only letters, numbers, underscores or hyphens.\n *[start] Names must start with a letter.\n }\n\ncomponent-name-invalid-start = Invalid component name "{ $name }". Names must start with a letter.\n\n## `<answer>` sugar\n\nanswer-video-watched-missing-video = Answer with type videoWatched must have a video attribute\n\nanswer-video-watched-video-not-reference = Answer with type videoWatched must have video attribute that is a reference\n\nanswer-name-not-single-text = Answer name attribute must have a single text child\n\n## Referencing another document\n\n# $attribute is the attribute the URI was written in (`copyFrom`, `extend`, …)\n# and stays as written; $uri is the author\'s own value.\n\nexternal-doenetml-recursion-limit = Unable to retrieve external DoenetML due to too many levels of recursion. Is there a circular reference?\n\nexternal-doenetml-unavailable = Unable to retrieve DoenetML from { $attribute }="{ $uri }"\n\nexternal-doenetml-type-mismatch = Invalid DoenetML retrieved from { $attribute }="{ $uri }": it did not match the component type "{ $componentType }"\n\n## Deprecated syntax\n\n# $from and $to are attribute names and $component a tag name; all three stay\n# as written. $component is `none` for a rename that applies to every component\n# accepting the attribute, where naming one would be wrong.\n#\n# The `[deprecation]` opening is a literal marker shared by all three messages,\n# not a word: leave it as it is.\n\ndeprecated-attribute-renamed =\n { $component ->\n [none] [deprecation] Attribute `{ $from }` is deprecated; use `{ $to }` instead.\n *[other] [deprecation] Attribute `{ $from }` on `<{ $component }>` is deprecated; use `{ $to }` instead.\n }\n\ndeprecated-attribute-renamed-conflict =\n { $component ->\n [none] [deprecation] Attribute `{ $from }` is deprecated and ignored because `{ $to }` is also specified.\n *[other] [deprecation] Attribute `{ $from }` on `<{ $component }>` is deprecated and ignored because `{ $to }` is also specified.\n }\n\ndeprecated-attribute-ignored = [deprecation] Attribute `{ $attribute }` on `<{ $component }>` is deprecated and ignored.\n\n\n## Language coverage\n\n# `<pluralize>` runs an English part-of-speech model over its text and puts the\n# nouns in the plural. There is no equivalent for an arbitrary language — a\n# correct plural needs that language\'s own morphology, and often its\n# dictionary — so in a document written in anything else the word is left as\n# the author typed it, and this says so rather than silently doing nothing.\n#\n# Raised only when there is nothing else to fall back on: a `pluralForm` is the\n# author supplying their own language\'s plural, and that is honored in every\n# language, which is why this can recommend it.\n#\n# $locale is the document\'s language tag, as declared.\npluralize-english-only = `<pluralize>` can only pluralize English, so its text is left unchanged in a document written in { $locale }. Write the plural form directly, or set it with the `pluralForm` attribute.\n\n\n## Checking against the schema\n\n# What the editor draws a squiggle under: the language server\'s own check of\n# the document against the DoenetML schema, run on every keystroke and\n# answered before anything is evaluated. A beginner meets these first, and\n# usually only these, because a document that does not pass them rarely gets\n# as far as producing a diagnostic from the core.\n#\n# `@doenet/lsp-tools` writes its English beside the code rather than rendering\n# it from here, for the same reason `@doenet/parser` does: it is inside the\n# language-server bundle, which `@doenet/codemirror` embeds verbatim and\n# starts as a blob worker, and a catalog on the editor\'s critical path is what\n# `packages/lsp/scripts/check-server-bundle.mjs` exists to reject. The two\n# copies are held together by a test in that package, which runs the checker\n# over a corpus and asserts every coded violation renders to exactly what the\n# checker wrote — so a message edited here without its counterpart fails\n# there.\n#\n# $tag, $parent and $attribute quote the author\'s own source back at them and\n# stay exactly as written; the angle brackets and backticks around them are\n# punctuation this catalog supplies, not part of the name.\n\nschema-element-unrecognized = Element `<{ $tag }>` is not a recognized Doenet element.\n\nschema-element-not-allowed-at-root = Element `<{ $tag }>` is not allowed at the root of the document.\n\nschema-element-not-allowed-inside = Element `<{ $tag }>` is not allowed inside of `<{ $parent }>`.\n\nschema-attribute-unrecognized = Element `<{ $tag }>` doesn\'t have an attribute called `{ $attribute }`.\n\n# $allowed is the attribute\'s permitted values, each already in double quotes\n# and joined for the reader\'s language. $isList says whether the attribute\n# takes several of them at once: one situation, two sentences, because the\n# reader has to be told they are choosing a whole list rather than a value.\nschema-attribute-value-not-allowed =\n { $isList ->\n [true] Attribute `{ $attribute }` of element `<{ $tag }>` must be a list whose items are each one of: { $allowed }\n *[other] Attribute `{ $attribute }` of element `<{ $tag }>` must be one of: { $allowed }\n }\n\n\n## The `<select>` family\'s error boxes\n##\n## The messages that replace the whole component with a red box rather than\n## warning beside it: nothing can be selected, so there is nothing to render.\n## They were the last uncoded `_error` path in the worker (#1581).\n##\n## Counts arrive as numbers rather than as text, so a language that agrees a\n## noun with them can select on them. English does not agree here — it says\n## "1 options" today and these messages reproduce it exactly, because the box\'s\n## text is what the existing suites pin.\n##\n## Being numbers, they are grouped: a count of 1500 renders as "1,500" in\n## English where the concatenated sentence these replaced wrote "1500". That is\n## the one way the English moved, and it moved in the right direction — these\n## are quantities, not identifiers like a line or a section number, which is\n## the distinction that decides between a number and a string everywhere in\n## these catalogs.\n##\n## Translators: component and attribute names — `selectFromSequence`,\n## `selectPrimeNumbers`, `from`, `to`, `step` — are DoenetML identifiers, not\n## words. They are written into these messages as they stand and must be left\n## in English exactly as written.\n\nselect-variant-name-option-count-mismatch = Invalid variant name for select. Variant name { $variantName } appears in { $numOptions } options but number to select is { $numToSelect }.\n\nselect-variant-name-without-options = Some variants are specified for select but no options are specified for possible variant name: { $variantName }.\n\nselect-variant-name-not-possible = Variant name { $variantName } that is specified for select is not a possible variant name.\n\nselect-too-few-options = Cannot select { $numToSelect } components from only { $numOptions }.\n\nselect-from-sequence-too-few-values = Cannot select { $numToSelect } values from a sequence of length { $length }.\n\nselect-from-sequence-indices-count-mismatch = Number of indices specified for select must match number to select\n\nselect-from-sequence-indices-not-integers = All indices specified for select must be integers\n\nselect-from-sequence-index-excluded = Specified index of selectfromsequence that was excluded\n\nselect-from-sequence-indices-excluded-combination = Specified indices of selectfromsequence that was an excluded combination\n\nselect-from-sequence-coprime-not-positive-integers = Cannot select coprime combinations as not selecting positive integers.\n\n# Translators: from, to and step are attribute names. They are written into\n# the message rather than passed in because these three never vary — an\n# argument is for a name that changes from one call to the next.\nselect-from-sequence-coprime-common-factor = Cannot select coprime numbers. All possible values share a common factor. (Specified values of "from" or "to" must be coprime with "step".)\n\nselect-from-sequence-coprime-single-number = Cannot select coprime combinations from a single number that is not 1.\n\nselect-from-sequence-excluded-too-many-combinations = Excluded over 70% of combinations in selectFromSequence\n\n# The sibling of `select-from-sequence-coprime-common-factor`, and a different\n# situation rather than a rewording of it: that one is decided up front, from\n# the sequence\'s own arithmetic. This one is what is left after two hundred\n# draws found no coprime combination among values that could have supplied one.\nselect-from-sequence-coprime-none-found = Could not select coprime numbers. All possible values share a common factor.\n\nselect-from-sequence-too-few-unique-values = Cannot select { $numToSelect } unique values from sequence of length { $numPossibleValues }\n\nselect-prime-numbers-too-few-values = Cannot select { $numToSelect } values from a list of primes of length { $numValues }\n\nselect-prime-numbers-values-count-mismatch = Number of values specified for select must match number to select\n\nselect-prime-numbers-values-not-prime = All values specified for select prime number must be in the list of primes\n\nselect-prime-numbers-values-excluded-combination = Specified values of selectPrimeNumbers was an excluded combination\n\nselect-prime-numbers-excluded-too-many-combinations = Excluded over 70% of combinations in selectPrimeNumbers\n\n# Both flukes are shared by `<selectFromSequence>` and `<selectPrimeNumbers>`,\n# which say the same thing in the same words. Neither is reachable in practice\n# — each follows two hundred independent draws — but an unreachable box is\n# still a box, and it renders in whatever language the rest of the page does.\nselect-random-combination-fluke = By extremely unlikely fluke, couldn\'t select combination of random values\n\nselect-random-value-fluke = By extremely unlikely fluke, couldn\'t select random value\n';
1371
+ const diagnostics = '# Errors and warnings surfaced to the reader or author. Produced by the worker\n# but addressed to whoever is looking at the screen, so these are selected by\n# `uiLocale`, not `documentLocale`.\n#\n# Message ids are lower-kebab-case Fluent identifiers, optionally with a\n# single `.attribute` suffix (`invalid-attribute-value`).\n#\n# Reached by stable diagnostic code rather than by a literal `t("key")` call:\n# `DIAGNOSTIC_CODES` in `src/diagnostics.ts` maps `doenet-w0001` to the id\n# below, and `lint:i18n` treats that registry as the call site. Adding a\n# message here without registering a code for it fails the lint as an orphan.\n#\n# Translators: `through`, `endpoint`, `midpointOffset`, `numDimensions` and the\n# like are DoenetML attribute names. They are part of the language, not prose,\n# and must be left in English exactly as written.\n\n## `<lineSegment>`\n\n# $attributes is a list of attribute names; $attributesCount is its length.\nline-segment-attributes-ignored-with-endpoints =\n { $attributesCount ->\n [one] { $attributes } is ignored when two endpoints are specified\n *[other] { $attributes } are ignored when two endpoints are specified\n }\n\n# $attributes is a list of attribute names; $attributesCount is its length.\nline-segment-attributes-ignored-with-endpoint-and-midpoint =\n { $attributesCount ->\n [one] { $attributes } is ignored when an endpoint and a midpoint are both specified\n *[other] { $attributes } are ignored when an endpoint and a midpoint are both specified\n }\n\nline-segment-midpoint-offset-without-midpoint = midpointOffset has no effect without a midpoint\n\n## `<line>`\n\nline-points-undetermined-dimensions = Line through points of undetermined dimensions.\n\nline-points-too-few-dimensions = Line must be through points of at least two dimensions.\n\n# $variables is a bare enumeration of variable names, not an "and" list.\nline-points-depend-on-variables = Line is through points that depend on variables: { $variables }.\n\nline-equation-invalid-format = Invalid format for equation of line in variables { $variable1 } and { $variable2 }.\n\n## `<ray>`\n\nray-overprescribed-through = Ray is prescribed by through, endpoint, and direction. Ignoring specified through.\n\nray-dimension-mismatch = numDimensions mismatch in ray.\n\n## `<vector>`\n\nvector-overprescribed-head = Vector is prescribed by head, tail, and displacement. Ignoring specified head.\n\nvector-dimension-mismatch = numDimensions mismatch in vector.\n\n## Attracting and constraining\n\n# $component is the DoenetML tag of the child that was named, e.g. "polygon".\nattract-to-without-nearest-point = Cannot attract to a `<{ $component }>` as it doesn\'t have a nearestPoint state variable.\n\nconstrain-to-without-nearest-point = Cannot constrain to a `<{ $component }>` as it doesn\'t have a nearestPoint state variable.\n\nconstrain-to-interior-without-nearest-point = Cannot constrain to interior of a `<{ $component }>` as it doesn\'t have a nearestPoint state variable.\n\n## `<choiceInput>`\n\n# Translators: `labelPosition` is an attribute name and stays in English.\nchoice-input-label-position-ignored = labelPosition is ignored for non-inline choiceInput\n\n## Ordering children by index\n##\n## These name the component in prose rather than as a tag, matching how the\n## messages have always read. The component names stay in English; the nouns\n## around them are prose and should be translated.\n\nchoice-input-indices-count-mismatch = Ignoring indices specified for choiceInput as number of indices doesn\'t match number of choice children.\n\npretzel-indices-count-mismatch = Ignoring indices specified for problem as number of indices doesn\'t match number of problem children.\n\nshuffle-indices-count-mismatch = Ignoring indices specified for shuffle as number of indices doesn\'t match number of components.\n\n# $component is `choiceInput`, `pretzel` or `shuffle` — a DoenetML component\n# name, so it stays in English.\nindices-ignored-out-of-range = Ignoring indices specified for { $component } as some indices out of range.\n\npretzel-indices-repeated = Ignoring indices specified for pretzel as some indices are repeated.\n\npretzel-circuit-first-index = Ignoring indices specified for pretzel in circuit mode as the first index must be 1.\n\n## `<shuffle>` and `<sort>`\n\n# $component is `shuffle` or `sort`. These two components accept the same\n# children and fail the same ways, so they share their messages.\nstring-children-need-type = For `<{ $component }>` to work with string children, a `type` attribute must be specified.\n\n# $type is what the author wrote; math, text, number and boolean are attribute\n# values and stay in English.\ninvalid-type-defaulting-to-math = Invalid type { $type } for { $component } component. Must be one of math, text, number, or boolean. Defaulting to math.\n\n# $value is the string child that could not be used.\nstring-not-valid-component-to-arrange = String "{ $value }" is not a valid component to { $component }. Ignoring.\n\n## Types and variables\n\ninvalid-type-defaulting-to-number = Invalid type { $type }, setting type to number.\n\ninvalid-variable-value = Invalid value of a variable: `{ $value }`\n\n## Variants\n\n# $index is what the author wrote, reproduced verbatim rather than as a number:\n# it reached this message precisely because it was not one.\nvariant-index-must-be-number = Variant index { $index } must be a number\n\nvariant-index-must-be-integer = Variant index { $index } must be an integer\n\n## `<sideBySide>`\n\n# $component is `sideBySide` or `sbsGroup`.\nside-by-side-absolute-widths = `<{ $component }>` is not implemented for absolute measurements. Setting widths to relative.\n\nside-by-side-absolute-margins = `<{ $component }>` is not implemented for absolute measurements. Setting margins to relative.\n\nside-by-side-no-block-child = Invalid `<{ $component }>`: it must have at least one block child.\n\n## `<label>`\n\n# Translators: `for` is an attribute name and stays in English.\nlabel-for-ignored-on-graphical = The `for` attribute on graphical `<label>` is ignored.\n\nlabel-for-must-resolve-to-one = The `for` attribute on `<label>` must resolve to exactly one component.\n\nlabel-for-unresolved = The `for` attribute on `<label>` could not be resolved to a component.\n\nlabel-for-answer-with-authored-inputs = The `for` attribute on `<label>` references an `<answer>` with explicitly authored inputs; reference the input directly.\n\nlabel-for-answer-without-input = The `for` attribute on `<label>` references an `<answer>` without an input to label.\n\nlabel-for-must-reference-input-or-answer = The `for` attribute on `<label>` must reference an input or an answer.\n\n## Accessibility\n\n# $component is a DoenetML tag, e.g. "graph" or "image".\naccessibility-short-description-or-decorative = For accessibility, `<{ $component }>` must either have a short description or be specified as decorative.\n\naccessibility-video-short-description = For accessibility, `<video>` must have a short description.\n\naccessibility-input-short-description-or-label = For accessibility, `<{ $component }>` must have a short description or a label.\n\n# The companion to the message above, for the input an `<answer>` creates on the\n# author\'s behalf. Two messages rather than one with the subject passed in: the\n# subject is a phrase here, not a name, and a phrase handed over as an argument\n# would never reach a translator.\naccessibility-answer-input-short-description-or-label = For accessibility, an `<answer>` creating an input must have a short description or a label.\n\naccessibility-short-description-contains-math = Short descriptions should not contain math components such as `<{ $component }>`. Spell out any math with words.\n\n# $colorName is an attribute name and stays in English. $ratio and $threshold\n# are contrast ratios; $mode says which theme the shortfall was measured in,\n# and is `dark` or `light`.\naccessibility-section-title-insufficient-contrast =\n { $mode ->\n [dark] { $colorName } has insufficient contrast for the section heading text (dark mode) ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1).\n *[other] { $colorName } has insufficient contrast for the section heading text ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1).\n }\n\n## `<circle>`\n\n# $count is the number of through points.\ncircle-through-points-non-numerical = Haven\'t implemented `<circle>` through { $count } points in case where the points don\'t have numerical values.\n\ncircle-too-many-through-points = Cannot calculate circle through more than 3 points.\n\ncircle-overprescribed-radius-center-points = Cannot calculate circle with specified radius, center and through points.\n\ncircle-center-with-multiple-points = Cannot calculate circle with specified center through more than 1 point.\n\n# $distance and $radius arrive as strings, not numbers: $radius is the author\'s\n# own value echoed back for diagnosis, and formatting it as a quantity would\n# round a radius of 0.0001 away to 0.\ncircle-radius-too-small = Cannot calculate circle: given that the distance between the two points is { $distance }, the specified radius { $radius } is too small.\n\ncircle-radius-with-many-points = Cannot create circle through more than two points with a specified radius.\n\ncircle-invalid-center-or-through-points = Invalid center or through points of circle.\n\ncircle-radius-center-with-multiple-points = Cannot calculate radius of circle with specified center through more than 1 point.\n\ncircle-change-radius-non-numerical = Cannot change radius of circle with non-numerical through points\n\ncircle-radius-with-points-non-numerical = Cannot create circle through more than one point with specified radius when don\'t have numerical values.\n\ncircle-change-center-non-numerical = Haven\'t implemented changing center of circle through points with non numerical values.\n\n## `<function>`\n\n# Two independent counts in one sentence, so the variants multiply out. A\n# select\'s variants each need their own line, so the inner one spans lines too;\n# that is safe because newlines inside a placeable never reach the rendered\n# value. Only text continuing onto a further line would.\nfunction-domain-insufficient-dimensions =\n { $intervals ->\n [one] Insufficient dimensions for domain for function. Domain has { $intervals } interval but the function has { $inputs ->\n [one] { $inputs } input\n *[other] { $inputs } inputs\n }.\n *[other] Insufficient dimensions for domain for function. Domain has { $intervals } intervals but the function has { $inputs ->\n [one] { $inputs } input\n *[other] { $inputs } inputs\n }.\n }\n\nfunction-domain-invalid-format = Invalid format for domain for function.\n\n# $type is what was being read off the point. It selects the wording rather\n# than being substituted into it: "maximum", "slope" and the rest are English\n# nouns, and a noun handed over as an argument would never reach a translator.\n# The catch-all reproduces the pre-catalog behavior for a value not listed here.\nfunction-ignoring-non-numerical =\n { $type ->\n [maximum] Ignoring non-numerical maximum of function.\n [minimum] Ignoring non-numerical minimum of function.\n [extremum] Ignoring non-numerical extremum of function.\n [point] Ignoring non-numerical point of function.\n [slope] Ignoring non-numerical slope of function.\n *[other] Ignoring non-numerical { $type } of function.\n }\n\nfunction-ignoring-empty =\n { $type ->\n [maximum] Ignoring empty maximum of function.\n [minimum] Ignoring empty minimum of function.\n [extremum] Ignoring empty extremum of function.\n [point] Ignoring empty point of function.\n *[other] Ignoring empty { $type } of function.\n }\n\nfunction-points-too-close = Function contains two points with locations too close together. Can\'t define function.\n\nfunction-iterates-input-output-mismatch =\n { $inputs ->\n [one] Function iterates are possible only if the number of inputs of the function is equal to the number of outputs. This function has { $inputs } input and { $outputs ->\n [one] { $outputs } output\n *[other] { $outputs } outputs\n }.\n *[other] Function iterates are possible only if the number of inputs of the function is equal to the number of outputs. This function has { $inputs } inputs and { $outputs ->\n [one] { $outputs } output\n *[other] { $outputs } outputs\n }.\n }\n\n## `<sequence>`\n\nsequence-invalid-length = Invalid length of sequence. Must be a non-negative integer.\n\n# $type is a sequence type: number, letters, or math.\nsequence-invalid-step = Invalid step of sequence. Must be a number for sequence of type { $type }.\n\n# $attribute is `from` or `to` — an attribute name, so it stays in English.\nsequence-invalid-endpoint-number = Invalid "{ $attribute }" of number sequence. Must be a number.\n\nsequence-invalid-endpoint-letters = Invalid "{ $attribute }" of letters sequence. Must be a letter combination.\n\nsequence-invalid-endpoint = Invalid "{ $attribute }" of sequence.\n\nselect-from-sequence-coprime-not-numbers = coprime ignored since not selecting numbers\n\nselect-from-sequence-coprime-with-exclude-combinations = coprime ignored since excludeCombinations specified\n\n## Resolving a `target`\n##\n## Raised by the components that take a `target` attribute. They resolve it\n## through the same code and fail the same two ways, so they share these two\n## messages rather than spelling each one out per component: $source is the tag\n## of the component that raised it, part of the DoenetML language, so it stays\n## in English.\n\ntarget-not-found = Invalid target for `<{ $source }>`: cannot find target.\n\n# $property is the state variable that was looked for; $component is the tag it\n# was looked for on.\ntarget-state-variable-not-found = Invalid target for `<{ $source }>`: cannot find a state variable named "{ $property }" on a `<{ $component }>`.\n\n## `<odeSystem>`\n\node-system-variables-match-independent = Variables of `<odeSystem>` must be different than independent variable.\n\node-system-duplicate-variable-names = Can\'t define ODE RHS functions with duplicate dependent variable names.\n\node-system-rhs-function-error = Cannot define ODE RHS function. Error creating mathjs function.\n\n## `<angle>`, `<parabola>`, and `<intersection>`\n\n# $count is how many line children were found.\nangle-too-many-lines = Cannot define an angle between { $count } lines\n\nangle-invalid-through-point = Invalid point in through of `<angle>`\n\nparabola-vertex-too-many-points = Haven\'t implemented parabola with vertex through more than 1 point.\n\nparabola-too-many-points = Haven\'t implemented parabola through more than 3 points.\n\nintersection-too-many-items = Haven\'t implemented intersection for more than two items\n\n## Other math components\n\nionic-compound-not-two-ions = Have not implemented ionic compound for anything other than two ions.\n\nionic-compound-needs-cation-and-anion = Ionic compound implemented only for one cation and one anion.\n\n# $equation is the equation as the author wrote it.\nsolve-equations-cannot-evaluate = Cannot solve equation as could not evaluate equation: { $equation }\n\n# Translators: `operandNumber` is an attribute name and stays in English.\nmath-operators-operand-number-required = Must specify a operandNumber when extracting a math operand.\n\neigen-decomposition-failed = Could not calculate eigenvalues of matrix\n\n## `<matchesPattern>`\n\n# Translators: `parameters` is an attribute name and stays in English.\n# $parameters lists the parameters as the author wrote them;\n# $parametersCount is how many there were.\nmatches-pattern-parameter-not-in-pattern =\n { $parametersCount ->\n [one] `<matchesPattern>`: the parameter { $parameters } does not occur in the pattern, so it will always match a blank.\n *[other] `<matchesPattern>`: the parameters { $parameters } do not occur in the pattern, so they will always match a blank.\n }\n\n## `<graph>`\n\n# Translators: grid is an attribute name and none, medium and dense are its\n# values; all four stay in English, as does the example. $grid is the value the\n# author wrote, reproduced verbatim — it reached this message precisely because\n# it was not one of the forms listed.\ngraph-grid-invalid = `<graph>`: cannot interpret grid="{ $grid }". It must be none, medium, dense, or two positive numbers separated by a space, such as grid="1 0.5". No grid is drawn.\n\n## PreFigure renderer\n\n# Translators: xLabelPosition, yLabelPosition and their values are attribute\n# names and stay in English, as does the renderer\'s name.\nprefigure-x-label-position-unsupported = `<graph>`: xLabelPosition="left" is not supported in prefigure renderer; using right-position behavior.\n\nprefigure-y-label-position-unsupported = `<graph>`: yLabelPosition="bottom" is not supported in prefigure renderer; using top-position behavior.\n\nprefigure-invalid-axis-bounds = `<graph>`: invalid axis bounds for prefigure conversion; using default bbox (-10,-10,10,10).\n\nprefigure-invalid-width = `<graph>`: invalid width for prefigure conversion; using default diagram width 425.\n\nprefigure-invalid-aspect-ratio = `<graph>`: invalid aspectRatio for prefigure conversion; using default aspect ratio 1.\n\n# Translators: the renderer\'s name, prefigure, stays in English. "grid" here is\n# the coordinate grid itself rather than the attribute that asks for one, so it\n# is prose and is translated.\nprefigure-grid-spacing-too-fine = `<graph>`: the grid spacing is too fine for the axis limits; the grid is omitted in the prefigure renderer.\n\nprefigure-annotations-not-rendered = `<graph>`: annotations will not be rendered when not using the PreFigure renderer.\n\nmultiple-annotations-children = Multiple `<annotations>` children found in `<graph>`; all but the last one are ignored.\n\n## Referring to other components\n##\n## `<updateValue>`\'s own "cannot find target" messages are not here: it\n## resolves a target the same way `<animateFromSequence>` does and fails the\n## same ways, so the two share `target-not-found` and\n## `target-state-variable-not-found` above.\n\ncopy-unrecognized-component-type = Cannot extend or copy an unrecognized component type: { $type }.\n\ncopy-prop-not-found = Could not find prop { $property } on a component of type { $component }\n\ncollect-no-source = No source found for collect.\n\ncollect-invalid-component-type = Cannot collect components of type `<{ $component }>` as it is an invalid component type.\n\n# $reference is the reference exactly as the author wrote it, `$` and all —\n# the `$p.styleDescription[1]` of `<text extend="$p.styleDescription[1]" />`.\n# An index only means something applied to an array, and the thing named here\n# is not one. The reference is quoted back rather than explained because the\n# text in front of the author is the only part of this they can act on: the\n# state variable and component index the core knows about are its own business\n# and go to the console instead.\nreference-index-unavailable = Cannot reference index `{ $reference }`\n\n## `<callAction>`\n\n# $action is the `actionName` the author asked for, part of the DoenetML\n# language, so it stays in English. $reference is the `target` as written.\ncomponent-action-unavailable = Cannot call { $action } on component `{ $reference }`\n\n## `<dataFrame>`\n\n# $componentIdx is an internal index, passed as a string so it is not grouped\n# like a quantity; the odd spacing before the colon is reproduced from the\n# original message.\ndata-frame-inconsistent-row-lengths = Data has invalid shape. Rows has inconsistent lengths. Found in componentIdx :{ $componentIdx }\n\ndata-frame-duplicate-column-names = Data has duplicate column names. Found in componentIdx :{ $componentIdx }\n\ndata-frame-missing-column-name = Data is missing a column name. Found in componentIdx :{ $componentIdx }\n\n## `<answer>` and scoring\n\nanswer-award-depends-on-own-response = An award for this answer is based on the answer tag\'s own submitted response, which will lead to unexpected behavior.\n\n# Translators: maxNumAttempts and sectionWideCheckWork are attribute names.\nanswer-max-num-attempts-in-section-wide-check-work = Setting `maxNumAttempts` on an `<answer>` inside a container with `sectionWideCheckWork` has no effect, as the number of attempts is controlled by the container. Set `maxNumAttempts` on the container instead.\n\nnested-section-wide-check-work-max-num-attempts = Setting `maxNumAttempts` on a container with `sectionWideCheckWork` that is inside another container with `sectionWideCheckWork` has no effect, as the number of attempts is controlled by the outer container. Set `maxNumAttempts` on the outer container instead.\n\n# $attributes is a list of attribute names; $attributesCount is its length.\nanswer-attributes-need-symbolic-equality =\n { $attributesCount ->\n [one] The { $attributes } attribute will have no effect without symbolicEquality set.\n *[other] The { $attributes } attributes will have no effect without symbolicEquality set.\n }\n\nanswer-invalid-type = Invalid type for answer: { $type }\n\n## `<module>`, `<conditionalContent>`, `<slider>`, `<pretzel>`\n\nmodule-attribute-child-needs-name = Since the component `<{ $component }>` does not have a name, it cannot be used for a module attribute\n\nmodule-attribute-name-already-defined = The component `<{ $component } name="{ $name }">` cannot be used as an attribute for a module because the `<module>` component type already has a "{ $name }" attribute defined.\n\nconditional-content-condition-ignored = Attribute `condition` is ignored on a `<conditionalContent>` component with case or else children.\n\nslider-markers-type-mismatch = Markers type doesn\'t match slider type.\n\npretzel-problem-needs-statement-and-answer = Invalid pretzel: each `<problem>` must contain one `<statement>` and one `<answer>`.\n\npretzel-circuit-first-problem-distractor = Invalid pretzel: in mode="circuit", the first `<problem>` cannot be a distractor.\n\n## Attribute values\n\n# $values is a list of the values that were rejected, each already in\n# backticks; $valuesCount is how many there were.\nattribute-invalid-values =\n { $valuesCount ->\n [one] Invalid value { $values } for attribute `{ $attribute }`; ignoring.\n *[other] Invalid values { $values } for attribute `{ $attribute }`; ignoring.\n }\n\nattribute-must-be-references = Invalid value `{ $value }` for attribute `{ $attribute }`. Attribute must be composed of references that begin with a `$`.\n\n# $names is a list of the rejected names, each already in single quotes.\nmath-input-invalid-function-names = <mathInput>: ignored invalid function name(s) in { $attribute }: { $names }. Each name\'s display segment must be at least 2 characters (letters or dashes); an optional `|<mathspeak alternative>` suffix may follow.\n\n## Building components from the source\n\n# Raised while the source is being turned into components, by throwing rather\n# than by building a record: the thrower is caught, the component becomes an\n# `_error`, and the diagnostic is re-raised from it.\n\ncomponent-type-invalid = Invalid component type: `<{ $componentType }>`\n\nattribute-repeated = Cannot repeat attribute { $attribute }.\n\nattribute-invalid-for-component = Invalid attribute "{ $attribute }" for a component of type `<{ $componentType }>`.\n\n## Style definition contrast\n\n# $context names the pair being compared, $mode which colour scheme it was\n# rendered in. Both are symbolic — the phrase is chosen here so a translator\n# can rewrite it, rather than being handed over already in English.\nstyle-definition-insufficient-contrast =\n Style definition { $styleNumber } has insufficient contrast for { $context ->\n [text-on-background] text color against background color\n [high-contrast] high-contrast color against the canvas\n [line] line color against the canvas\n [marker] marker color against the canvas\n *[text-on-canvas] text color against the canvas\n }{ $mode ->\n [dark] { " (dark mode)" }\n *[light] { "" }\n } ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1).\n\n# $suggestion says whether a concrete replacement colour could be computed.\n# The attribute names and colour values in the `available` branch are\n# DoenetML source, not prose, and stay as they are in every language.\nstyle-definition-dark-mode-text-background-contrast =\n Although style definition { $styleNumber } has specified colors that provide sufficient contrast for light mode, the dark-mode colors derived from these values have insufficient contrast for the text color against the background color ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1). { $suggestion ->\n [available] To ensure sufficient contrast in dark mode, either increase the light-mode contrast (e.g., set { $lightAttribute }="{ $lightColor }") or override the dark-mode color (e.g., set { $darkAttribute }="{ $darkColor }").\n *[none] To ensure sufficient contrast in dark mode, increase the light-mode contrast or override the derived colors with textColorDarkMode and/or backgroundColorDarkMode.\n }\n\nstyle-definition-dark-mode-text-canvas-contrast =\n Although style definition { $styleNumber } has a specified text color that provides sufficient contrast for light mode, the dark-mode text color derived from this value has insufficient contrast against the canvas ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; requires at least { $threshold }:1). { $suggestion ->\n [available] To ensure sufficient contrast in dark mode, either increase the light-mode contrast (e.g., set textColor="{ $lightColor }") or override the dark-mode color (e.g., set textColorDarkMode="{ $darkColor }").\n *[none] To ensure sufficient contrast in dark mode, increase the light-mode contrast or override the derived color with textColorDarkMode.\n }\n\nsection-multiple-style-palettes = A section can select only one <stylePalette>; using the last one.\n\n## Unique variants\n\n# Explanations of why a component\'s unique variants could not be worked out.\n# $component is the tag that could not be analyzed and stays as written; the\n# reason is a separate message per situation, so a host can tell them apart by\n# code and a translator sees a whole sentence rather than a fragment.\n\nvariant-num-to-select-not-non-negative-integer = cannot determine unique variants of { $component } as numToSelect isn\'t a non-negative integer.\n\nvariant-num-to-select-not-constant-number = cannot determine unique variants of { $component } as numToSelect isn\'t constant number.\n\nvariant-with-replacement-not-constant-boolean = cannot determine unique variants of { $component } as withReplacement isn\'t constant boolean.\n\nvariant-select-weight-disables-unique = Unique variants for select disabled if have an option with selectWeight or selectForVariants specified\n\nvariant-coprime-undetermined = cannot determine unique variants of { $component } as cannot determine coprime is always false.\n\n# $attribute is an attribute name (`from`, `to`, `step`, `sort`, `length`) and\n# stays as written.\nvariant-attribute-not-constant = cannot determine unique variants of { $component } as { $attribute } isn\'t a constant.\n\nvariant-attribute-not-number = cannot determine unique variants of { $component } as { $attribute } isn\'t a number.\n\n# $type is the sequence type the component was declared with. $expected names\n# what the value had to be, symbolically, because which one applies depends on\n# both the type and the attribute.\nvariant-attribute-wrong-type-for-sequence =\n cannot determine unique variants of { $component } of { $type } type as { $attribute } isn\'t { $expected ->\n [letters-combination] a combination of letters\n [math-expression] a valid math expression\n [integer] an integer\n *[number] a number\n }.\n\nvariant-length-not-integer = cannot determine unique variants of { $component } as length isn\'t an integer.\n\nvariant-sort-not-implemented = have not implemented unique variants of a { $component } with sort\n\nvariant-exclude-combinations-not-implemented = have not implemented unique variants of a { $component } with excludeCombinations\n\nvariant-math-exclude-not-implemented = have not implemented unique variants of a { $component } of type math with exclude\n\nvariant-non-constant-exclude-not-implemented = have not implemented unique variants of a { $component } with non-constant exclude\n\n## PreFigure conversion\n\n# $subject identifies the component the warning is about, already written as\n# `<tag>` or `<tag> (name)`. It is composed in code rather than here because\n# Fluent terms cannot take a variable as an argument, so a shared subject\n# fragment cannot be parameterized from the catalog. It holds only a tag name,\n# a component name and punctuation — never a word — which is why a descendant\n# with no type reads `<?>` rather than `<unknown>`.\n\nprefigure-descendant-unsupported = { $subject }: unsupported in graph prefigure renderer; descendant skipped.\n\nprefigure-descendant-invalid-geometry = { $subject }: non-finite or incomplete geometry; descendant skipped.\n\nprefigure-curve-label-omitted = { $subject }: labels are not supported on converted curve elements; label omitted.\n\nprefigure-curve-unsupported-definition-type = { $subject }: unsupported curve function definition type \'{ $definitionType }\'; descendant skipped.\n\nprefigure-region-flip-functions-unsupported = { $subject }: unsupported flipFunctions attribute on regionBetweenCurves; descendant skipped.\n\nprefigure-region-non-formula-child = { $subject }: only formula-typed child functions are supported on regionBetweenCurves; descendant skipped.\n\n# $labelKind says which family of object carried the label, since the advice\n# is the same but the object is not.\nprefigure-label-position-unsupported =\n { $subject }: unsupported labelPosition \'{ $labelPosition }\' for { $labelKind ->\n [line-family] line-family label\n *[point] point label\n }; default PreFigure alignment used.\n\nprefigure-fill-style-unsupported = { $subject }: fill style \'{ $fillStyle }\' is unsupported by PreFigure; falling back to a solid fill.\n\nprefigure-line-style-unknown = { $subject }: unknown line style \'{ $lineStyle }\' omitted from PreFigure output.\n\nprefigure-marker-style-mapped-to-diamond = { $subject }: marker style \'{ $markerStyle }\' mapped to PreFigure style \'diamond\'.\n\nprefigure-marker-style-unsupported = { $subject }: marker style \'{ $markerStyle }\' is unsupported by PreFigure; default style used.\n\n## PreFigure annotations\n\nannotation-ref-unresolvable = `<annotation>`: invalid `ref`; cannot resolve target. Annotation omitted.\n\nannotation-ref-multiple-targets = `<annotation>`: `ref` resolved to multiple targets; using the first target.\n\nannotation-ref-outside-graph = `<annotation>`: invalid `ref`; target is outside the containing graph. Annotation omitted.\n\nannotation-ref-unsupported-target = `<annotation>`: invalid `ref`; target is not a supported graphical object in prefigure conversion. Annotation omitted.\n\nannotation-text-missing = `<annotation>`: missing or empty `text`; emitting empty text.\n\n## Composites and references\n\n# $componentType is the type the composite was asked to create, when it is\n# known; `none` when the composite did not say.\ncomposite-circular-dependency =\n { $componentType ->\n [none] Circular dependency detected.\n *[other] Circular dependency detected involving `<{ $componentType }>` component.\n }\n\n# $reference is the reference as the author wrote it, already carrying its `$`.\nreference-no-referent = No referent found for reference: `{ $reference }`\n\nreference-multiple-referents = Multiple referents found for reference: `{ $reference }`\n\n## Children that do not match\n\nchildren-invalid-attribute-format = Invalid format for attribute { $attribute } of `<{ $componentType }>`.\n\n# $children is the list of child types that did not match, already joined.\nchildren-invalid = Invalid children for `<{ $componentType }>`: Found invalid children: { $children }\n\n## Falling back to a default\n\nattribute-value-invalid-using-default = Invalid value `{ $value }` for attribute `{ $attribute }`, using value `{ $default }`\n\n## Loading a DoenetML version\n\n# $fallback is the version that will be used instead, or `none` when the\n# embedding page named a standalone bundle of its own.\ndoenetml-version-not-found =\n { $fallback ->\n [none] DoenetML version { $version } not found.\n *[other] DoenetML version { $version } not found. Falling back to version { $fallback }\n }\n\n## Reading the DoenetML\n\n# The parser\'s own diagnostics: what the author sees before anything runs, and\n# for a beginner usually the first Doenet message they ever read.\n#\n# The parser writes its English beside the code rather than rendering it from\n# here, because `@doenet/parser` is inside the language-server bundle and a\n# catalog there is dead weight on the editor\'s critical path\n# (`packages/lsp/scripts/check-server-bundle.mjs` fails if one arrives). The\n# two copies are held together by a test in that package, which parses a\n# corpus and asserts every coded error renders to exactly what the parser\n# wrote — so a message edited here without its counterpart fails there.\n#\n# $tag, $value, $attribute and their relatives quote the author\'s own source\n# back at them and stay exactly as written. The `Invalid DoenetML: ` opening is\n# repeated in each message instead of being a shared term: a term a locale\n# forgets to define renders as its own name, and a prefix on fifteen messages\n# is not worth that failure mode.\n\nparse-invalid-doenetml = Invalid DoenetML: { $content }\n\nparse-tag-missing-close-tag = Invalid DoenetML: The tag `{ $tag }` has no closing tag. Expected a self-closing tag or a `</{ $tagName }>` tag.\n\nparse-tag-error = Invalid DoenetML: Error in tag `<{ $tagName }>`\n\nparse-attribute-missing-value = Invalid DoenetML: Invalid attribute `{ $attribute }` appears to be missing a value.\n\nparse-attribute-invalid = Invalid DoenetML: Invalid attribute `{ $attribute }`\n\nparse-attribute-value-invalid = Invalid DoenetML: Invalid attribute value `{ $value }`\n\n# $quote is the quote character that would balance the pair: `"` or `\'`.\nparse-attribute-value-quote-mismatch = Invalid DoenetML: Invalid attribute value `{ $value }`. The quote marks do not match. You appear to be missing a `{ $quote }`\n\nparse-open-tag-name-missing = Invalid DoenetML: Found a tag without a tag name, e.g. `<`\n\nparse-tag-not-closed = Invalid DoenetML: Tag `{ $tag }` was not closed (a `>` appears to be missing).\n\nparse-self-closing-tag-name-missing = Invalid DoenetML: Found a tag without a tag name `<{ $content }>`\n\nparse-self-closing-tag-not-closed = Invalid DoenetML: Tag `{ $tag }` was not closed (`/>` appears to be missing).\n\nparse-tag-invalid-attributes = Invalid DoenetML: Tag `{ $tag }` is not valid. It may have incorrect attributes.\n\nparse-close-tag-name-missing = Invalid DoenetML: Found a closing tag without a tag name, e.g. `</`\n\n# $attribute is the attribute name and $value the unquoted token that followed\n# it, shown reassembled the way the author should have written it.\nparse-attribute-value-unquoted = Attribute values must be enclosed in quotes: `{ $attribute }="{ $value }"`\n\nparse-close-tag-without-open-tag = Invalid DoenetML: Found closing tag `{ $tag }`, but no corresponding opening tag\n\nparse-close-tag-mismatched = Invalid DoenetML: Mismatched closing tag. Expected `</{ $expected }>`. Found `{ $found }`\n\n# The conversion\'s fall-through: the syntax tree held a node shape it has no\n# case for. Reaching an author means the grammar and the conversion have gone\n# out of step, which is a bug in Doenet rather than in their document — hence\n# `parser-` rather than the `parse-` of every message above, which is about\n# what the author wrote. They are still the one looking at it, so it is\n# translated like any other error. $node is the node\'s own name and stays as\n# it is.\nparser-node-unconvertible = Could not convert node { $node } to Dast node.\n\n## Names\n\n# $reason says which rule the name broke, as a key rather than a phrase, so the\n# whole sentence is translatable rather than assembled from two halves.\nname-attribute-invalid =\n Invalid attribute name=\'{ $name }\'. { $reason ->\n [characters] Names can contain only letters, numbers, underscores or hyphens.\n *[start] Names must start with a letter.\n }\n\ncomponent-name-invalid-start = Invalid component name "{ $name }". Names must start with a letter.\n\n## `<answer>` sugar\n\nanswer-video-watched-missing-video = Answer with type videoWatched must have a video attribute\n\nanswer-video-watched-video-not-reference = Answer with type videoWatched must have video attribute that is a reference\n\nanswer-name-not-single-text = Answer name attribute must have a single text child\n\n## Referencing another document\n\n# $attribute is the attribute the URI was written in (`copyFrom`, `extend`, …)\n# and stays as written; $uri is the author\'s own value.\n\nexternal-doenetml-recursion-limit = Unable to retrieve external DoenetML due to too many levels of recursion. Is there a circular reference?\n\nexternal-doenetml-unavailable = Unable to retrieve DoenetML from { $attribute }="{ $uri }"\n\nexternal-doenetml-type-mismatch = Invalid DoenetML retrieved from { $attribute }="{ $uri }": it did not match the component type "{ $componentType }"\n\n## Deprecated syntax\n\n# $from and $to are attribute names and $component a tag name; all three stay\n# as written. $component is `none` for a rename that applies to every component\n# accepting the attribute, where naming one would be wrong.\n#\n# The `[deprecation]` opening is a literal marker shared by all three messages,\n# not a word: leave it as it is.\n\ndeprecated-attribute-renamed =\n { $component ->\n [none] [deprecation] Attribute `{ $from }` is deprecated; use `{ $to }` instead.\n *[other] [deprecation] Attribute `{ $from }` on `<{ $component }>` is deprecated; use `{ $to }` instead.\n }\n\ndeprecated-attribute-renamed-conflict =\n { $component ->\n [none] [deprecation] Attribute `{ $from }` is deprecated and ignored because `{ $to }` is also specified.\n *[other] [deprecation] Attribute `{ $from }` on `<{ $component }>` is deprecated and ignored because `{ $to }` is also specified.\n }\n\ndeprecated-attribute-ignored = [deprecation] Attribute `{ $attribute }` on `<{ $component }>` is deprecated and ignored.\n\n\n## Language coverage\n\n# `<pluralize>` runs an English part-of-speech model over its text and puts the\n# nouns in the plural. There is no equivalent for an arbitrary language — a\n# correct plural needs that language\'s own morphology, and often its\n# dictionary — so in a document written in anything else the word is left as\n# the author typed it, and this says so rather than silently doing nothing.\n#\n# Raised only when there is nothing else to fall back on: a `pluralForm` is the\n# author supplying their own language\'s plural, and that is honored in every\n# language, which is why this can recommend it.\n#\n# $locale is the document\'s language tag, as declared.\npluralize-english-only = `<pluralize>` can only pluralize English, so its text is left unchanged in a document written in { $locale }. Write the plural form directly, or set it with the `pluralForm` attribute.\n\n\n## Checking against the schema\n\n# What the editor draws a squiggle under: the language server\'s own check of\n# the document against the DoenetML schema, run on every keystroke and\n# answered before anything is evaluated. A beginner meets these first, and\n# usually only these, because a document that does not pass them rarely gets\n# as far as producing a diagnostic from the core.\n#\n# `@doenet/lsp-tools` writes its English beside the code rather than rendering\n# it from here, for the same reason `@doenet/parser` does: it is inside the\n# language-server bundle, which `@doenet/codemirror` embeds verbatim and\n# starts as a blob worker, and a catalog on the editor\'s critical path is what\n# `packages/lsp/scripts/check-server-bundle.mjs` exists to reject. The two\n# copies are held together by a test in that package, which runs the checker\n# over a corpus and asserts every coded violation renders to exactly what the\n# checker wrote — so a message edited here without its counterpart fails\n# there.\n#\n# $tag, $parent and $attribute quote the author\'s own source back at them and\n# stay exactly as written; the angle brackets and backticks around them are\n# punctuation this catalog supplies, not part of the name.\n\nschema-element-unrecognized = Element `<{ $tag }>` is not a recognized Doenet element.\n\nschema-element-not-allowed-at-root = Element `<{ $tag }>` is not allowed at the root of the document.\n\nschema-element-not-allowed-inside = Element `<{ $tag }>` is not allowed inside of `<{ $parent }>`.\n\nschema-attribute-unrecognized = Element `<{ $tag }>` doesn\'t have an attribute called `{ $attribute }`.\n\n# $allowed is the attribute\'s permitted values, each already in double quotes\n# and joined for the reader\'s language. $isList says whether the attribute\n# takes several of them at once: one situation, two sentences, because the\n# reader has to be told they are choosing a whole list rather than a value.\nschema-attribute-value-not-allowed =\n { $isList ->\n [true] Attribute `{ $attribute }` of element `<{ $tag }>` must be a list whose items are each one of: { $allowed }\n *[other] Attribute `{ $attribute }` of element `<{ $tag }>` must be one of: { $allowed }\n }\n\n\n## The `<select>` family\'s error boxes\n##\n## The messages that replace the whole component with a red box rather than\n## warning beside it: nothing can be selected, so there is nothing to render.\n## They were the last uncoded `_error` path in the worker (#1581).\n##\n## Counts arrive as numbers rather than as text, so a language that agrees a\n## noun with them can select on them. English does not agree here — it says\n## "1 options" today and these messages reproduce it exactly, because the box\'s\n## text is what the existing suites pin.\n##\n## Being numbers, they are grouped: a count of 1500 renders as "1,500" in\n## English where the concatenated sentence these replaced wrote "1500". That is\n## the one way the English moved, and it moved in the right direction — these\n## are quantities, not identifiers like a line or a section number, which is\n## the distinction that decides between a number and a string everywhere in\n## these catalogs.\n##\n## Translators: component and attribute names — `selectFromSequence`,\n## `selectPrimeNumbers`, `from`, `to`, `step` — are DoenetML identifiers, not\n## words. They are written into these messages as they stand and must be left\n## in English exactly as written.\n\nselect-variant-name-option-count-mismatch = Invalid variant name for select. Variant name { $variantName } appears in { $numOptions } options but number to select is { $numToSelect }.\n\nselect-variant-name-without-options = Some variants are specified for select but no options are specified for possible variant name: { $variantName }.\n\nselect-variant-name-not-possible = Variant name { $variantName } that is specified for select is not a possible variant name.\n\nselect-too-few-options = Cannot select { $numToSelect } components from only { $numOptions }.\n\nselect-from-sequence-too-few-values = Cannot select { $numToSelect } values from a sequence of length { $length }.\n\nselect-from-sequence-indices-count-mismatch = Number of indices specified for select must match number to select\n\nselect-from-sequence-indices-not-integers = All indices specified for select must be integers\n\nselect-from-sequence-index-excluded = Specified index of selectfromsequence that was excluded\n\nselect-from-sequence-indices-excluded-combination = Specified indices of selectfromsequence that was an excluded combination\n\nselect-from-sequence-coprime-not-positive-integers = Cannot select coprime combinations as not selecting positive integers.\n\n# Translators: from, to and step are attribute names. They are written into\n# the message rather than passed in because these three never vary — an\n# argument is for a name that changes from one call to the next.\nselect-from-sequence-coprime-common-factor = Cannot select coprime numbers. All possible values share a common factor. (Specified values of "from" or "to" must be coprime with "step".)\n\nselect-from-sequence-coprime-single-number = Cannot select coprime combinations from a single number that is not 1.\n\nselect-from-sequence-excluded-too-many-combinations = Excluded over 70% of combinations in selectFromSequence\n\n# The sibling of `select-from-sequence-coprime-common-factor`, and a different\n# situation rather than a rewording of it: that one is decided up front, from\n# the sequence\'s own arithmetic. This one is what is left after two hundred\n# draws found no coprime combination among values that could have supplied one.\nselect-from-sequence-coprime-none-found = Could not select coprime numbers. All possible values share a common factor.\n\nselect-from-sequence-too-few-unique-values = Cannot select { $numToSelect } unique values from sequence of length { $numPossibleValues }\n\nselect-prime-numbers-too-few-values = Cannot select { $numToSelect } values from a list of primes of length { $numValues }\n\nselect-prime-numbers-values-count-mismatch = Number of values specified for select must match number to select\n\nselect-prime-numbers-values-not-prime = All values specified for select prime number must be in the list of primes\n\nselect-prime-numbers-values-excluded-combination = Specified values of selectPrimeNumbers was an excluded combination\n\nselect-prime-numbers-excluded-too-many-combinations = Excluded over 70% of combinations in selectPrimeNumbers\n\n# Both flukes are shared by `<selectFromSequence>` and `<selectPrimeNumbers>`,\n# which say the same thing in the same words. Neither is reachable in practice\n# — each follows two hundred independent draws — but an unreachable box is\n# still a box, and it renders in whatever language the rest of the page does.\nselect-random-combination-fluke = By extremely unlikely fluke, couldn\'t select combination of random values\n\nselect-random-value-fluke = By extremely unlikely fluke, couldn\'t select random value\n';
1372
1372
  const editor = '# Editor and language-server surfaces: the footer, the diagnostics panel, the\n# variant picker, the accessibility button, and the context-help panel beside\n# them. Selected by `uiLocale`.\n#\n# The editor binds to *one* language, and it is the one the viewer below it\n# resolved rather than the one the surrounding host chrome uses: the panel\n# lists diagnostics rendered down there, where an authored `<document lang>` is\n# known, and a footer in one language above a panel in another reads worse than\n# either choice on its own (#1580).\n#\n# The LSP ships bundled with its DoenetML version, so these catalogs are\n# version-correct rather than always-latest.\n#\n# Message ids are lower-kebab-case Fluent identifiers, optionally with a\n# single `.attribute` suffix (`format-document`).\n\n\n## The viewer\'s controls\n##\n## `editor-update-viewer` names the button that recompiles the document. Its\n## word depends on whether the source changed or only the document\'s state\n## did, which is a distinction the code makes and a `$action` says: the button\n## is otherwise identical, and splitting it into two messages would let the two\n## drift.\n##\n## The keyboard hint is a separate branch rather than text appended after the\n## title, because where a shortcut sits in a sentence is not the same in every\n## language. `$shortcut` is a key combination and stays as written.\n##\n## The tooltip takes the word as `$word` rather than referencing the message\n## above it: a message reference resolves only inside its own bundle, so a\n## locale that translated the tooltip but not the word would render the\n## reference literally instead of falling back to English. This is the shape\n## `paginator-page-status` already uses.\n\neditor-update-viewer =\n { $action ->\n [reset] Reset\n *[update] Update\n }\n\neditor-update-viewer-title =\n { $shortcut ->\n [none] { $word } Viewer\n *[other] { $word } Viewer { $shortcut }\n }\n\n\n## The variant picker\n\neditor-variant = Variant\neditor-variant-filter = Filter...\neditor-variant-next = Select next variant\neditor-variant-previous = Select previous variant\n\n\n## The accessibility status button\n##\n## `WCAG AA` is the name of the standard and is not translated, the way\n## `accessibility-heading-level-1` already leaves it.\n##\n## The tooltip and the label are separate messages rather than one with an\n## extra clause: the label counts the violations and the tooltip does not, and\n## a screen reader and a hover are different audiences.\n##\n## `$action` is whether clicking opens or closes the report — an interpolated\n## English verb before this, which no locale could reach and which no language\n## has to place where English does.\n\neditor-accessibility-title =\n { $status ->\n [violations] WCAG AA accessibility violation identified. Click to { $action ->\n [close] close\n *[open] open\n } accessibility report.\n [advisories] Click to { $action ->\n [close] close\n *[open] open\n } accessibility report. No WCAG AA violations were found, but additional accessibility recommendations are available.\n *[clean] Click to { $action ->\n [close] close\n *[open] open\n } accessibility report. No accessibility issues were found.\n }\n\neditor-accessibility-label =\n { $status ->\n [violations] WCAG AA accessibility violation identified. { $count ->\n [one] { $count } WCAG AA violation\n *[other] { $count } WCAG AA violations\n } found. Click to { $action ->\n [close] close\n *[open] open\n } accessibility report.\n [advisories] No WCAG AA violations identified. { $count ->\n [one] { $count } additional accessibility recommendation\n *[other] { $count } additional accessibility recommendations\n } found. Click to { $action ->\n [close] close\n *[open] open\n } accessibility report.\n *[clean] No WCAG AA violations identified. Click to { $action ->\n [close] close\n *[open] open\n } accessibility report.\n }\n\n# The word on the button itself, beside the icon, when there are violations.\neditor-accessibility-badge = WCAG\n\n\n## The footer\n##\n## `$version` is a version number and stays as written.\n\neditor-version-title = DoenetML version { $version }\n\neditor-tab-help = Context-sensitive help\n# The word beside the icon on that tab, which has room for one word.\neditor-tab-help-short = Context\neditor-tab-errors = Errors\neditor-tab-warnings = Warnings\neditor-tab-info = Info\neditor-tab-accessibility = Accessibility\neditor-tab-responses = Submitted responses\n\n# A tab\'s accessible name when it carries a count: "Errors: 3".\neditor-tab-with-count = { $label }: { $count }\n\neditor-options = Editor options\neditor-format-as-doenetml = Format as DoenetML\neditor-format-as-xml = Format as XML\n\n\n## The diagnostics panel\n\n# Where in the source a diagnostic was found. `$line` arrives as text, not as a\n# number: it identifies the line, so line 1234 is "#1234" and not "#1,234".\neditor-diagnostic-line = Line #{ $line }\n\neditor-no-errors = No Errors\neditor-no-warnings = No Warnings\neditor-no-info = No Info Diagnostics\n\neditor-show-info-annotations = Show info diagnostics in editor\neditor-show-accessibility-annotations = Show accessibility diagnostics in editor\n\n# Links into the documentation, which has no translated pages yet. The words\n# move; where they point does not (#1580).\neditor-accessibility-learn-more = Learn how Doenet approaches accessibility\n\n# The heading over the WCAG AA failures. The standard\'s name is a link, so it\n# arrives as an argument rather than being written into the sentence — the\n# brackets around it are this catalog\'s punctuation, and the link is the code\'s.\neditor-accessibility-violations-heading = Accessibility violations ({ $standard })\n\neditor-accessibility-other-heading = Other accessibility issues\neditor-none-found = None found\n\n\n## Submitted responses\n\neditor-no-responses = No submitted responses yet\neditor-response-answer-id = Answer Id\neditor-response-response = Response\neditor-response-credit = Credit\neditor-response-submitted = Submitted\n\n\n## The context-help panel\n##\n## The panel beside the diagnostics, which explains whatever the cursor is on.\n## It is the last of the surfaces the header above names.\n##\n## Several of these sentences have marked-up fragments in them — an element\n## name in `<code>`, a link, a rendered piece of inline markdown. Those arrive\n## as arguments and are put back as React nodes after the message is formatted,\n## so a translation owns the whole sentence including where each fragment sits\n## and the punctuation around it. A translation that drops one simply renders\n## without it rather than losing the sentence.\n##\n## Element names, attribute names and `styleNumber` are DoenetML identifiers\n## and stay as written. The descriptions and summaries the panel shows come\n## from the schema, which is generated from the documentation and is not\n## translated, and the values it resolves — a color\'s derived word, a\n## function name, a type — come from the language server in the same state.\n## What is here is the panel\'s own prose around them (#1580).\n\nhelp-placeholder = Place cursor on a tag name, attribute, or { $ref } for documentation.\n\nhelp-unsupported-ref-chain = Help for multi-part references like { $example } is not yet supported.\n\nhelp-unresolved-ref =\n { $reason ->\n [notFound] No referent found for reference: { $ref }.\n [multiple] Multiple referents found for reference: { $ref }.\n *[indeterminate] A referent for { $ref } could not be determined.\n }\n\n# Both links end in an arrow, which is direction rather than punctuation and is\n# the same in every language this ships in — but it is inside the message, so a\n# language written right to left can turn it around.\nhelp-learn-about-references = Learn about references →\nhelp-reference-page = Reference page →\n\n# What can go where the cursor is. Two selectors joined: where the cursor sits,\n# and what the schema allows there.\nhelp-suggestions-header =\n { $location ->\n [inside] Inside { $element }\n *[top] At the top level\n }{ $allowed ->\n [none] { " — nothing goes here." }\n [text] { " — type text here." }\n [text-and-components] { " — type text here, or try:" }\n *[components] { " — things to try:" }\n }\n\n# `$shortcut` is a key combination and stays as written. `$total` is a real\n# count, so a language that agrees a noun with it can select on it.\nhelp-suggestions-footer = Press { $shortcut } to see all { $total } components.\n\n# An element\'s name joined to its one-line summary. `$name` is empty where the\n# panel has already printed the name beside this — a suggestion in the list —\n# and only the separator is wanted, so the message has to read as punctuation\n# on its own.\nhelp-name-summary = { $name } — { $summary }\n\n# `$line` is text, not a number: it identifies a line, so line 1234 is "1234"\n# and not "1,234". `none` is how a position that is not known selects a\n# sentence without one rather than substituting an empty parenthesis.\nhelp-ref-is-reference =\n { $line ->\n [none] { $ref } is a reference to { $target }.\n *[other] { $ref } is a reference to { $target } (line { $line }).\n }\n\nhelp-ref-derived-from =\n { $line ->\n [none] Introduced by { $owner } as { $role }.\n *[other] Introduced by { $owner } on line { $line } as { $role }.\n }\n\nhelp-property-is-reference =\n { $line ->\n [none] { $ref } is a reference to the { $property } property of { $element }.\n *[other] { $ref } is a reference to the { $property } property of { $element } (line { $line }).\n }\n\n# The badge on the title row saying what kind of thing the panel is explaining.\nhelp-kind-attribute = attribute\nhelp-kind-snippet = snippet\nhelp-kind-array-entry = array entry\n\nhelp-default = Default:\nhelp-active-default = Active default:\n\n# Appended after the active default\'s value. `styleNumber` is the attribute\'s\n# own name and stays as written; the space and brackets around it do not.\nhelp-style-number-annotation = { " " }(styleNumber { $styleNumber })\n\nhelp-allowed-values =\n { $perItem ->\n [true] Allowed values (one per item):\n *[other] Allowed values:\n }\n\n# Heading for values the editor offers without requiring: the attribute accepts\n# others too, and nothing warns about them. Distinct from `help-allowed-values`\n# so a translation can pick a word that suggests rather than constrains.\nhelp-suggested-values = Suggested values:\n\nhelp-inserts = Inserts:\n\nhelp-coordinates =\n { $count ->\n [one] Coordinate:\n *[other] Coordinates:\n }\n\nhelp-type = Type:\n\nhelp-resolved-style = Resolved style (styleNumber { $styleNumber }):\n\nhelp-resolved-function-names = Resolved function names:\nhelp-reset-list = Reset list on this input:\nhelp-added-on-input = Added on this input:\nhelp-removed-on-input = Removed on this input:\n\n# The three names are attributes an author writes, so they stay as written.\nhelp-reset-overrides = { $reset } overrides { $additional } and { $removed }.\n';
1373
1373
  const CATALOG_NAMESPACES = [
1374
1374
  "chrome",
@@ -1476,7 +1476,7 @@ function createTranslator(locales, resources, options = {}) {
1476
1476
  }
1477
1477
  const esChrome = "# Spanish viewer chrome. Translated from `locales/en/chrome.ftl`, which is the\n# source of truth: `lint:i18n` rejects a key that does not exist there, and\n# reports a key that exists there but not here as missing coverage.\n#\n# Message ids are never translated — only the text to the right of `=`.\n#\n# Register: impersonal throughout — infinitives and bare nouns, never a `tú`\n# or `usted` verb form. The viewer does not know how formally a deployment\n# addresses its readers, and an impersonal label is correct for both.\n\n\n## Answer submission\n\nanswer-checking = Comprobando...\nanswer-submitting = Enviando...\n\nanswer-checking-status = Comprobando la respuesta\nanswer-submitting-status = Enviando la respuesta\n\nanswer-correct = Correcto\nanswer-incorrect = Incorrecto\n\nanswer-response-saved = Respuesta guardada\n\n# Spanish typographic convention puts a space before the percent sign.\nanswer-percent-credit = { $percent } % de crédito\nanswer-percent-correct = { $percent } % correcto\nanswer-percent-short = { $percent } %\n\nmax-credit-available = Crédito máximo disponible: { $percent } %\n\nattempts-remaining =\n { $count ->\n [0] no quedan intentos\n [one] queda { $count } intento\n *[other] quedan { $count } intentos\n }\n\nvalidation-correct = (Correcto)\nvalidation-incorrect = (Incorrecto)\nvalidation-partially-correct = (Parcialmente correcto)\n\n# `Mostrar` is the infinitive, per the register note above.\nanswer-show-responses =\n { $count ->\n [one] Mostrar { $count } respuesta a { $answerId }\n *[other] Mostrar { $count } respuestas a { $answerId }\n }\n\n\n## Disclosure panels\n\nfeedback-heading = Comentarios\n\ncollapsible-click-to-open = (clic para abrir)\ncollapsible-click-to-close = (clic para cerrar)\ncollapsible-initializing = Inicializando...\n\nfootnote-show = Mostrar la nota al pie\nfootnote-hide = Ocultar la nota al pie\n\ndescription-more-information = más información\n\n\n## Controls\n\nslider-previous = Anterior\nslider-next = Siguiente\n\nkeyboard-open = Abrir el teclado\nkeyboard-close = Cerrar el teclado\n\nmatrix-remove-row = Eliminar fila\nmatrix-add-row = Añadir fila\nmatrix-remove-column = Eliminar columna\nmatrix-add-column = Añadir columna\n\nsubset-add-remove-points = Añadir/Eliminar puntos\nsubset-toggle-points-intervals = Alternar puntos e intervalos\nsubset-move-points = Mover puntos\nsubset-clear = Borrar\n\norbital-add-row = Añadir fila\norbital-remove-row = Eliminar fila\norbital-add-box = Añadir casilla\norbital-remove-box = Eliminar casilla\norbital-add-up-arrow = Añadir flecha hacia arriba\norbital-add-down-arrow = Añadir flecha hacia abajo\norbital-remove-arrow = Eliminar flecha\n\norbital-row-label = Etiqueta de la fila { $row }\n\npretzel-answer = Respuesta\n\nsummary-statistics-caption = Resumen estadístico de { $column }\n\n\n## Math input\n\nmath-input-preview-region = vista previa de la expresión matemática\nmath-input-preview = Vista previa\nmath-input-invalid-expression = Expresión no válida:\n\n\n## Document status\n\nviewer-initializing = Inicializando...\n\n\n## Errors\n\nerror-heading = Error\n\n# $startLine y $endLine son números de línea y llegan como texto, no como\n# números, para que no se agrupen los millares.\nerror-found-at =\n { $span ->\n [line] Encontrado en la línea { $startLine }.\n *[lines] Encontrado en las líneas { $startLine } a { $endLine }.\n }\n\ndocument-contains-errors = ¡Este documento contiene errores!\n\n# Encabezados del globo que muestra el editor sobre un subrayado.\ndiagnostic-heading-error = Error\ndiagnostic-heading-warning = Advertencia\ndiagnostic-heading-information = Información\ndiagnostic-heading-hint = Sugerencia\n\n# «WCAG AA» es el nombre propio de la norma y no se traduce.\naccessibility-heading-level-1 = Incumplimiento de accesibilidad WCAG AA\naccessibility-heading-level-2 = Aviso de accesibilidad\n\nsomething-went-wrong = Algo salió mal.\n\n# Follows `error-heading` and a colon, so it begins in lower case, as in\n# English. The instruction is an infinitive, per the register note above.\nrenderer-load-failed = no se pudo cargar un componente. Recargar la página.\n\ncore-start-failed = No se pudo iniciar el visor del documento. Recargar la página.\n";
1478
1478
  const esContent = '# Spanish content catalog: the prose the core computes into the document.\n# Selected by `documentLocale` — the language the activity was written in.\n#\n# Spanish inflects. Adjectives follow their noun and agree with it in gender,\n# so every adjective below selects on `$gender`, the gender of the noun it\n# describes, and the composition messages put the noun first. Neither is\n# expressible by substituting into the English word order, which is why the\n# catalog controls the order and not the code.\n\n\n## Vocabulario de estilos\n\ncolor =\n .black =\n { $gender ->\n [f] negra\n *[m] negro\n }\n .white =\n { $gender ->\n [f] blanca\n *[m] blanco\n }\n .gray = gris\n .red =\n { $gender ->\n [f] roja\n *[m] rojo\n }\n .orange = naranja\n .yellow =\n { $gender ->\n [f] amarilla\n *[m] amarillo\n }\n .green = verde\n .cyan = cian\n .blue = azul\n .purple =\n { $gender ->\n [f] morada\n *[m] morado\n }\n .pink = rosa\n .brown = marrón\n\nline-width =\n .thick =\n { $gender ->\n [f] gruesa\n *[m] grueso\n }\n .thin =\n { $gender ->\n [f] delgada\n *[m] delgado\n }\n\nline-style =\n .dashed =\n { $gender ->\n [f] discontinua\n *[m] discontinuo\n }\n .dotted =\n { $gender ->\n [f] punteada\n *[m] punteado\n }\n\n# Sintagmas nominales: van detrás de «con» y no concuerdan con nada.\nfill-style =\n .horizontal = líneas horizontales\n .vertical = líneas verticales\n .diagonal = líneas diagonales\n .backdiagonal = líneas diagonales inversas\n .dots = puntos\n .diamonds = rombos\n\nnoun =\n .line = línea\n .line-segment = segmento\n .ray = semirrecta\n .vector = vector\n .curve = curva\n .function = función\n .parabola = parábola\n .polyline = polilínea\n .polygon = polígono\n .triangle = triángulo\n .rectangle = rectángulo\n .circle = círculo\n .region = región\n .point = punto\n .square = cuadrado\n .diamond = rombo\n .cross = cruz\n .plus = signo más\n\n# El nombre se parte: «polígono regular» lleva los adjetivos y «de 5 lados»\n# cierra el sintagma detrás de ellos. Si el complemento fuera delante, los\n# adjetivos quedarían separados del nombre con el que concuerdan («polígono\n# regular de 5 lados grueso rojo»).\nnoun-regular-polygon =\n { $part ->\n [tail] de { $numSides } lados\n *[head] polígono regular\n }\n\n# Además de los nombres de arriba, `$noun` puede ser «regular-polygon» (el\n# nombre que compone `noun-regular-polygon`) o el núcleo de un sintagma que no\n# se nombra en la descripción: «border», «fill», «text» y «background». Todos\n# ellos son masculinos en español —polígono, borde, relleno, texto, fondo—, así\n# que caen en el caso por defecto.\nnoun-gender =\n { $noun ->\n [line] f\n [ray] f\n [curve] f\n [function] f\n [parabola] f\n [polyline] f\n [region] f\n [cross] f\n *[other] m\n }\n\n\n## Composición de estilos\n\nstyle-stroke =\n { $parts ->\n [width-style-color] { $lineStyle } { $width } { $color }\n [width-color] { $width } { $color }\n [style-color] { $lineStyle } { $color }\n [width-style] { $lineStyle } { $width }\n [width] { $width }\n [style] { $lineStyle }\n *[color] { $color }\n }\n\n# El nombre va delante y los adjetivos detrás: «línea discontinua gruesa roja».\n# El complemento del nombre, si lo hay, cierra el sintagma: «polígono regular\n# grueso rojo de 5 lados».\nstyle-with-noun =\n { $parts ->\n [noun-tail] { $noun } { $description } { $nounTail }\n *[noun] { $noun } { $description }\n }\n\nstyle-filled-word =\n { $gender ->\n [f] rellena\n *[m] relleno\n }\n\nstyle-filled =\n { $parts ->\n [pattern] { $color } { $filled } con { $pattern }\n *[plain] { $color } { $filled }\n }\n\n# Aquí el complemento va pegado al nombre, y no al final como en\n# `style-with-noun`: «relleno de …» se lee como «lleno de …», así que «relleno\n# de 5 lados» diría otra cosa. «Polígono regular de 5 lados azul relleno».\nstyle-filled-with-noun =\n { $parts ->\n [pattern] { $noun } { $color } { $filled } con { $pattern }\n [plain-tail] { $noun } { $nounTail } { $color } { $filled }\n [pattern-tail] { $noun } { $nounTail } { $color } { $filled } con { $pattern }\n *[plain] { $noun } { $color } { $filled }\n }\n\n# «borde» es masculino, así que los adjetivos del borde concuerdan con él y no\n# con la figura que rodea.\nstyle-border-clause =\n { $parts ->\n [with-article] con un borde { $border }\n [and] y borde { $border }\n [and-article] y un borde { $border }\n *[with] con borde { $border }\n }\n\n# «de color» evita tener que concordar el color con un patrón en plural.\nstyle-fill =\n { $parts ->\n [pattern] { $pattern } de color { $color }\n *[plain] { $color }\n }\n\nstyle-unfilled = sin relleno\n\nstyle-text =\n { $parts ->\n [background] { $color } con un fondo { $background }\n *[plain] { $color }\n }\n\nstyle-background-none = ninguno\n\n\n## Palabras booleanas\n##\n## `true` y `false` siguen siendo sintaxis de DoenetML y no se traducen; aquí\n## solo se traduce la palabra que lee quien usa el documento.\n\nboolean-true = verdadero\nboolean-false = falso\n\n\n## Botones de respuesta\n\nanswer-submit-label = Revisar\nanswer-submit-label-no-correctness = Enviar respuesta\n\n\n## Bloques seccionales\n\nsection-name =\n .activity = Actividad\n .aside = Nota al margen\n .cascade = Cascada\n .definition = Definición\n .example = Ejemplo\n .exercise = Ejercicio\n .exercises = Ejercicios\n .given-answer = Respuesta\n .note = Nota\n .objectives = Objetivos\n .paragraphs = Párrafos\n .part = Parte\n .problem = Problema\n .problems = Problemas\n .proof = Demostración\n .question = Pregunta\n .section = Sección\n .solution = Solución\n .task = Tarea\n .theorem = Teorema\n\n# El español separa el título con un punto tras un número solo, igual que el\n# inglés, y con dos puntos cuando la palabra encabeza.\nsection-title-prefix =\n { $parts ->\n [name] { $sectionName }\n [number] { $sectionNumber }\n [name-title] { $sectionName }{ ": " }\n [number-title] { $sectionNumber }{ ". " }\n [name-number-title] { $sectionName } { $sectionNumber }{ ": " }\n *[name-number] { $sectionName } { $sectionNumber }\n }\n\nhint-title = Pista\n\n\n## Tablas y figuras\n\ntable-name =\n { $parts ->\n [numbered] Tabla { $enumeration }\n [numbered-title] Tabla { $enumeration }{ ": " }\n [unnumbered-title] Tabla{ ": " }\n *[unnumbered] Tabla\n }\n\nfigure-name =\n { $parts ->\n [numbered] Figura { $enumeration }\n [numbered-caption] Figura { $enumeration }{ ": " }\n [unnumbered-caption] Figura{ ": " }\n *[unnumbered] Figura\n }\n\n\n## Controles de paginación\n\npaginator-previous = Anterior\npaginator-next = Siguiente\npaginator-page = Página\n\npaginator-page-status = { $pageLabel } { $currentPage } de { $numPages }\n\n\n## Funciones definidas a trozos\n\npiecewise-condition-or = o\npiecewise-condition-if = si\npiecewise-condition-otherwise = en otro caso\n\n\n## Química\n##\n## Los símbolos, las fórmulas y todo aquello con lo que un `<award>` compara no\n## se traducen; aquí solo están las palabras que se leen.\n\nelement-name =\n .h = Hidrógeno\n .he = Helio\n .li = Litio\n .be = Berilio\n .b = Boro\n .c = Carbono\n .n = Nitrógeno\n .o = Oxígeno\n .f = Flúor\n .ne = Neón\n .na = Sodio\n .mg = Magnesio\n .al = Aluminio\n .si = Silicio\n .p = Fósforo\n .s = Azufre\n .cl = Cloro\n .ar = Argón\n .k = Potasio\n .ca = Calcio\n .sc = Escandio\n .ti = Titanio\n .v = Vanadio\n .cr = Cromo\n .mn = Manganeso\n .fe = Hierro\n .co = Cobalto\n .ni = Níquel\n .cu = Cobre\n .zn = Zinc\n .ga = Galio\n .ge = Germanio\n .as = Arsénico\n .se = Selenio\n .br = Bromo\n .kr = Kriptón\n .rb = Rubidio\n .sr = Estroncio\n .y = Itrio\n .zr = Circonio\n .nb = Niobio\n .mo = Molibdeno\n .tc = Tecnecio\n .ru = Rutenio\n .rh = Rodio\n .pd = Paladio\n .ag = Plata\n .cd = Cadmio\n .in = Indio\n .sn = Estaño\n .sb = Antimonio\n .te = Telurio\n .i = Yodo\n .xe = Xenón\n .cs = Cesio\n .ba = Bario\n .la = Lantano\n .ce = Cerio\n .pr = Praseodimio\n .nd = Neodimio\n .pm = Prometio\n .sm = Samario\n .eu = Europio\n .gd = Gadolinio\n .tb = Terbio\n .dy = Disprosio\n .ho = Holmio\n .er = Erbio\n .tm = Tulio\n .yb = Iterbio\n .lu = Lutecio\n .hf = Hafnio\n .ta = Tantalio\n .w = Wolframio\n .re = Renio\n .os = Osmio\n .ir = Iridio\n .pt = Platino\n .au = Oro\n .hg = Mercurio\n .tl = Talio\n .pb = Plomo\n .bi = Bismuto\n .po = Polonio\n .at = Astato\n .rn = Radón\n .fr = Francio\n .ra = Radio\n .ac = Actinio\n .th = Torio\n .pa = Protactinio\n .u = Uranio\n .np = Neptunio\n .pu = Plutonio\n .am = Americio\n .cm = Curio\n .bk = Berkelio\n .cf = Californio\n .es = Einsteinio\n .fm = Fermio\n .md = Mendelevio\n .no = Nobelio\n .lr = Lawrencio\n .rf = Rutherfordio\n .db = Dubnio\n .sg = Seaborgio\n .bh = Bohrio\n .hs = Hasio\n .mt = Meitnerio\n .ds = Darmstadtio\n .rg = Roentgenio\n .cn = Copernicio\n .nh = Nihonio\n .fl = Flerovio\n .mc = Moscovio\n .lv = Livermorio\n .ts = Teneso\n .og = Oganesón\n\nelement-anion-name =\n .h = Hidruro\n .c = Carburo\n .n = Nitruro\n .o = Óxido\n .f = Fluoruro\n .p = Fosfuro\n .s = Sulfuro\n .cl = Cloruro\n .br = Bromuro\n .i = Yoduro\n .at = Astaturo\n .ts = Tenesuro\n\nion-name-oxidation-state = { $name } ({ $numeral })\n\nchemistry-invalid-symbol = Símbolo químico no válido\nchemistry-invalid-ionic-compound = Compuesto iónico no válido\n';
1479
- const esDiagnostics = '# Advertencias y errores mostrados a quien lee o escribe el documento.\n# Seleccionados por `uiLocale`.\n#\n# Los nombres de atributos y componentes de DoenetML (`through`, `endpoint`,\n# `numDimensions`, …) forman parte del lenguaje y se dejan en inglés.\n\n## `<lineSegment>`\n\nline-segment-attributes-ignored-with-endpoints =\n { $attributesCount ->\n [one] { $attributes } se ignora cuando se especifican los dos extremos\n *[other] { $attributes } se ignoran cuando se especifican los dos extremos\n }\n\nline-segment-attributes-ignored-with-endpoint-and-midpoint =\n { $attributesCount ->\n [one] { $attributes } se ignora cuando se especifican un extremo y el punto medio\n *[other] { $attributes } se ignoran cuando se especifican un extremo y el punto medio\n }\n\nline-segment-midpoint-offset-without-midpoint = midpointOffset no tiene efecto sin un punto medio\n\n## `<line>`\n\n# «Recta», no «línea», aunque `noun.line` en content.ftl diga «línea»: no es\n# una incoherencia, sino la diferencia entre describir el trazo dibujado («una\n# línea azul gruesa») y hablar del objeto geométrico, que en matemáticas es\n# una recta —de ahí «la ecuación de la recta».\n\nline-points-undetermined-dimensions = La recta pasa por puntos de dimensiones indeterminadas.\n\nline-points-too-few-dimensions = La recta debe pasar por puntos de al menos dos dimensiones.\n\nline-points-depend-on-variables = La recta pasa por puntos que dependen de las variables: { $variables }.\n\n# Enumeradas con coma en vez de «y»: las variables de <line> son `x` e `y` por\n# omisión, y «en las variables x y y» sería a la vez incorrecto (ante el sonido\n# /i/ la conjunción es «e») e ilegible. La coma es correcta sea cual sea el\n# nombre de la variable, que aquí no se conoce de antemano.\nline-equation-invalid-format = Formato no válido para la ecuación de la recta en las variables { $variable1 }, { $variable2 }.\n\n## `<ray>`\n\nray-overprescribed-through = La semirrecta está determinada por through, endpoint y direction. Se ignora el through especificado.\n\nray-dimension-mismatch = Discrepancia de numDimensions en la semirrecta.\n\n## `<vector>`\n\nvector-overprescribed-head = El vector está determinado por head, tail y displacement. Se ignora el head especificado.\n\nvector-dimension-mismatch = Discrepancia de numDimensions en el vector.\n\n## Atraer y restringir\n\nattract-to-without-nearest-point = No se puede atraer a un `<{ $component }>` porque no tiene la variable de estado nearestPoint.\n\nconstrain-to-without-nearest-point = No se puede restringir a un `<{ $component }>` porque no tiene la variable de estado nearestPoint.\n\nconstrain-to-interior-without-nearest-point = No se puede restringir al interior de un `<{ $component }>` porque no tiene la variable de estado nearestPoint.\n\n## `<choiceInput>`\n\nchoice-input-label-position-ignored = labelPosition se ignora en un choiceInput que no es inline\n\n## Ordenar hijos por índice\n\nchoice-input-indices-count-mismatch = Se ignoran los índices especificados para choiceInput porque su cantidad no coincide con la cantidad de hijos choice.\n\npretzel-indices-count-mismatch = Se ignoran los índices especificados para problem porque su cantidad no coincide con la cantidad de hijos problem.\n\nshuffle-indices-count-mismatch = Se ignoran los índices especificados para shuffle porque su cantidad no coincide con la cantidad de componentes.\n\nindices-ignored-out-of-range = Se ignoran los índices especificados para { $component } porque algunos están fuera de rango.\n\npretzel-indices-repeated = Se ignoran los índices especificados para pretzel porque algunos están repetidos.\n\npretzel-circuit-first-index = Se ignoran los índices especificados para pretzel en modo circuit porque el primer índice debe ser 1.\n\n## `<shuffle>` y `<sort>`\n\nstring-children-need-type = Para que `<{ $component }>` funcione con hijos de texto, se debe especificar el atributo `type`.\n\ninvalid-type-defaulting-to-math = Tipo no válido { $type } para el componente { $component }. Debe ser math, text, number o boolean. Se usa math.\n\nstring-not-valid-component-to-arrange = La cadena "{ $value }" no es un componente válido para { $component }. Se ignora.\n\n## Tipos y variables\n\ninvalid-type-defaulting-to-number = Tipo no válido { $type }, se establece el tipo en number.\n\ninvalid-variable-value = Valor no válido de una variable: `{ $value }`\n\n## Variantes\n\nvariant-index-must-be-number = El índice de variante { $index } debe ser un número\n\nvariant-index-must-be-integer = El índice de variante { $index } debe ser un número entero\n\n## `<sideBySide>`\n\nside-by-side-absolute-widths = `<{ $component }>` no está implementado para medidas absolutas. Los anchos se establecen como relativos.\n\nside-by-side-absolute-margins = `<{ $component }>` no está implementado para medidas absolutas. Los márgenes se establecen como relativos.\n\nside-by-side-no-block-child = `<{ $component }>` no es válido: debe tener al menos un hijo de bloque.\n\n## `<label>`\n\nlabel-for-ignored-on-graphical = Se ignora el atributo `for` en un `<label>` gráfico.\n\nlabel-for-must-resolve-to-one = El atributo `for` de `<label>` debe corresponder exactamente a un componente.\n\nlabel-for-unresolved = No se pudo resolver el atributo `for` de `<label>` a un componente.\n\nlabel-for-answer-with-authored-inputs = El atributo `for` de `<label>` hace referencia a un `<answer>` con entradas escritas explícitamente; haz referencia a la entrada directamente.\n\nlabel-for-answer-without-input = El atributo `for` de `<label>` hace referencia a un `<answer>` que no tiene ninguna entrada que etiquetar.\n\nlabel-for-must-reference-input-or-answer = El atributo `for` de `<label>` debe hacer referencia a una entrada o a un `<answer>`.\n\n## Accesibilidad\n\naccessibility-short-description-or-decorative = Por accesibilidad, `<{ $component }>` debe tener una descripción breve o estar marcado como decorativo.\n\naccessibility-video-short-description = Por accesibilidad, `<video>` debe tener una descripción breve.\n\naccessibility-input-short-description-or-label = Por accesibilidad, `<{ $component }>` debe tener una descripción breve o una etiqueta.\n\naccessibility-answer-input-short-description-or-label = Por accesibilidad, la entrada creada por un `<answer>` debe tener una descripción breve o una etiqueta.\n\naccessibility-short-description-contains-math = Las descripciones breves no deben contener componentes matemáticos como `<{ $component }>`. Expresa las matemáticas con palabras.\n\naccessibility-section-title-insufficient-contrast =\n { $mode ->\n [dark] { $colorName } no tiene suficiente contraste con el texto del encabezado de sección (modo oscuro) ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1).\n *[other] { $colorName } no tiene suficiente contraste con el texto del encabezado de sección ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1).\n }\n\n## `<circle>`\n\ncircle-through-points-non-numerical = No está implementado un `<circle>` que pase por { $count } puntos cuando los puntos no tienen valores numéricos.\n\ncircle-too-many-through-points = No se puede calcular una circunferencia que pase por más de 3 puntos.\n\ncircle-overprescribed-radius-center-points = No se puede calcular una circunferencia con radio, centro y puntos de paso especificados a la vez.\n\ncircle-center-with-multiple-points = No se puede calcular una circunferencia con centro especificado que pase por más de 1 punto.\n\ncircle-radius-too-small = No se puede calcular la circunferencia: dado que la distancia entre los dos puntos es { $distance }, el radio especificado { $radius } es demasiado pequeño.\n\ncircle-radius-with-many-points = No se puede crear una circunferencia que pase por más de dos puntos con un radio especificado.\n\ncircle-invalid-center-or-through-points = El centro o los puntos de paso de la circunferencia no son válidos.\n\ncircle-radius-center-with-multiple-points = No se puede calcular el radio de una circunferencia con centro especificado que pase por más de 1 punto.\n\ncircle-change-radius-non-numerical = No se puede cambiar el radio de una circunferencia con puntos de paso no numéricos\n\ncircle-radius-with-points-non-numerical = No se puede crear una circunferencia que pase por más de un punto con un radio especificado cuando no hay valores numéricos.\n\ncircle-change-center-non-numerical = No está implementado cambiar el centro de una circunferencia que pasa por puntos con valores no numéricos.\n\n## `<function>`\n\nfunction-domain-insufficient-dimensions =\n { $intervals ->\n [one] Dimensiones insuficientes para el dominio de la función. El dominio tiene { $intervals } intervalo pero la función tiene { $inputs ->\n [one] { $inputs } entrada\n *[other] { $inputs } entradas\n }.\n *[other] Dimensiones insuficientes para el dominio de la función. El dominio tiene { $intervals } intervalos pero la función tiene { $inputs ->\n [one] { $inputs } entrada\n *[other] { $inputs } entradas\n }.\n }\n\nfunction-domain-invalid-format = Formato no válido para el dominio de la función.\n\nfunction-ignoring-non-numerical =\n { $type ->\n [maximum] Se ignora el máximo no numérico de la función.\n [minimum] Se ignora el mínimo no numérico de la función.\n [extremum] Se ignora el extremo no numérico de la función.\n [point] Se ignora el punto no numérico de la función.\n [slope] Se ignora la pendiente no numérica de la función.\n *[other] Se ignora { $type } no numérico de la función.\n }\n\nfunction-ignoring-empty =\n { $type ->\n [maximum] Se ignora el máximo vacío de la función.\n [minimum] Se ignora el mínimo vacío de la función.\n [extremum] Se ignora el extremo vacío de la función.\n [point] Se ignora el punto vacío de la función.\n *[other] Se ignora { $type } vacío de la función.\n }\n\nfunction-points-too-close = La función contiene dos puntos demasiado próximos entre sí. No se puede definir la función.\n\nfunction-iterates-input-output-mismatch =\n { $inputs ->\n [one] Las iteraciones de una función solo son posibles si el número de entradas es igual al número de salidas. Esta función tiene { $inputs } entrada y { $outputs ->\n [one] { $outputs } salida\n *[other] { $outputs } salidas\n }.\n *[other] Las iteraciones de una función solo son posibles si el número de entradas es igual al número de salidas. Esta función tiene { $inputs } entradas y { $outputs ->\n [one] { $outputs } salida\n *[other] { $outputs } salidas\n }.\n }\n\n## `<sequence>`\n\nsequence-invalid-length = Longitud de la secuencia no válida. Debe ser un entero no negativo.\n\nsequence-invalid-step = Paso de la secuencia no válido. Debe ser un número para una secuencia de tipo { $type }.\n\nsequence-invalid-endpoint-number = El valor de "{ $attribute }" de la secuencia numérica no es válido. Debe ser un número.\n\nsequence-invalid-endpoint-letters = El valor de "{ $attribute }" de la secuencia de letras no es válido. Debe ser una combinación de letras.\n\nsequence-invalid-endpoint = El valor de "{ $attribute }" de la secuencia no es válido.\n\nselect-from-sequence-coprime-not-numbers = Se ignora coprime porque no se están seleccionando números\n\nselect-from-sequence-coprime-with-exclude-combinations = Se ignora coprime porque se especificó excludeCombinations\n\n## Resolución de `target`\n\ntarget-not-found = Destino no válido para `<{ $source }>`: no se encuentra el destino.\n\ntarget-state-variable-not-found = Destino no válido para `<{ $source }>`: no se encuentra una variable de estado llamada "{ $property }" en un `<{ $component }>`.\n\n## `<odeSystem>`\n\node-system-variables-match-independent = Las variables de `<odeSystem>` deben ser distintas de la variable independiente.\n\node-system-duplicate-variable-names = No se pueden definir las funciones del lado derecho de la EDO con nombres de variables dependientes repetidos.\n\node-system-rhs-function-error = No se puede definir la función del lado derecho de la EDO. Error al crear la función de mathjs.\n\n## `<angle>`, `<parabola>` e `<intersection>`\n\nangle-too-many-lines = No se puede definir un ángulo entre { $count } rectas\n\nangle-invalid-through-point = Punto no válido en through de `<angle>`\n\nparabola-vertex-too-many-points = No está implementada una parábola con vértice que pase por más de 1 punto.\n\nparabola-too-many-points = No está implementada una parábola que pase por más de 3 puntos.\n\nintersection-too-many-items = No está implementada la intersección de más de dos objetos\n\n## Otros componentes matemáticos\n\nionic-compound-not-two-ions = No está implementado el compuesto iónico para algo distinto de dos iones.\n\nionic-compound-needs-cation-and-anion = El compuesto iónico solo está implementado para un catión y un anión.\n\nsolve-equations-cannot-evaluate = No se puede resolver la ecuación porque no se pudo evaluar: { $equation }\n\nmath-operators-operand-number-required = Se debe especificar operandNumber al extraer un operando matemático.\n\neigen-decomposition-failed = No se pudieron calcular los valores propios de la matriz\n\n## `<matchesPattern>`\n\nmatches-pattern-parameter-not-in-pattern =\n { $parametersCount ->\n [one] `<matchesPattern>`: el parámetro { $parameters } no aparece en el patrón, por lo que siempre coincidirá con un espacio en blanco.\n *[other] `<matchesPattern>`: los parámetros { $parameters } no aparecen en el patrón, por lo que siempre coincidirán con un espacio en blanco.\n }\n\n## Renderizador PreFigure\n\nprefigure-x-label-position-unsupported = `<graph>`: xLabelPosition="left" no es compatible con el renderizador prefigure; se usa el comportamiento de posición derecha.\n\nprefigure-y-label-position-unsupported = `<graph>`: yLabelPosition="bottom" no es compatible con el renderizador prefigure; se usa el comportamiento de posición superior.\n\nprefigure-invalid-axis-bounds = `<graph>`: los límites de los ejes no son válidos para la conversión a prefigure; se usa el bbox predeterminado (-10,-10,10,10).\n\nprefigure-invalid-width = `<graph>`: el ancho no es válido para la conversión a prefigure; se usa el ancho de diagrama predeterminado 425.\n\nprefigure-invalid-aspect-ratio = `<graph>`: aspectRatio no es válido para la conversión a prefigure; se usa la relación de aspecto predeterminada 1.\n\nprefigure-grid-spacing-too-fine = `<graph>`: el espaciado de la cuadrícula es demasiado fino para los límites de los ejes; se omite la cuadrícula en el renderizador prefigure.\n\nprefigure-annotations-not-rendered = `<graph>`: las anotaciones no se representan si no se usa el renderizador PreFigure.\n\nmultiple-annotations-children = Se encontraron varios hijos `<annotations>` en `<graph>`; se ignoran todos menos el último.\n\n## Referencias a otros componentes\n\ncopy-unrecognized-component-type = No se puede extender ni copiar un tipo de componente desconocido: { $type }.\n\ncopy-prop-not-found = No se encontró la propiedad { $property } en un componente de tipo { $component }\n\ncollect-no-source = No se encontró ninguna fuente para collect.\n\ncollect-invalid-component-type = No se pueden recolectar componentes de tipo `<{ $component }>` porque no es un tipo de componente válido.\n\nreference-index-unavailable = No se puede referenciar el índice `{ $reference }`\n\n## `<callAction>`\n\ncomponent-action-unavailable = No se puede llamar a { $action } en el componente `{ $reference }`\n\n## `<dataFrame>`\n\ndata-frame-inconsistent-row-lengths = Los datos tienen una forma no válida. Las filas tienen longitudes distintas. Encontrado en componentIdx :{ $componentIdx }\n\ndata-frame-duplicate-column-names = Los datos tienen nombres de columna repetidos. Encontrado en componentIdx :{ $componentIdx }\n\ndata-frame-missing-column-name = A los datos les falta el nombre de una columna. Encontrado en componentIdx :{ $componentIdx }\n\n## `<answer>` y puntuación\n\nanswer-award-depends-on-own-response = Un award de esta respuesta depende de la respuesta enviada por el propio answer, lo que provocará un comportamiento inesperado.\n\nanswer-max-num-attempts-in-section-wide-check-work = Establecer `maxNumAttempts` en un `<answer>` dentro de un contenedor con `sectionWideCheckWork` no tiene efecto, porque el número de intentos lo controla el contenedor. Establece `maxNumAttempts` en el contenedor.\n\nnested-section-wide-check-work-max-num-attempts = Establecer `maxNumAttempts` en un contenedor con `sectionWideCheckWork` que está dentro de otro contenedor con `sectionWideCheckWork` no tiene efecto, porque el número de intentos lo controla el contenedor exterior. Establece `maxNumAttempts` en el contenedor exterior.\n\nanswer-attributes-need-symbolic-equality =\n { $attributesCount ->\n [one] El atributo { $attributes } no tendrá efecto si no se establece symbolicEquality.\n *[other] Los atributos { $attributes } no tendrán efecto si no se establece symbolicEquality.\n }\n\nanswer-invalid-type = Tipo no válido para answer: { $type }\n\n## `<module>`, `<conditionalContent>`, `<slider>` y pretzel\n\nmodule-attribute-child-needs-name = Como el componente `<{ $component }>` no tiene nombre, no se puede usar como atributo de módulo\n\nmodule-attribute-name-already-defined = El componente `<{ $component } name="{ $name }">` no se puede usar como atributo de un módulo porque el tipo de componente `<module>` ya tiene definido un atributo "{ $name }".\n\nconditional-content-condition-ignored = Se ignora el atributo `condition` en un `<conditionalContent>` que tiene hijos case o else.\n\nslider-markers-type-mismatch = El tipo de los marcadores no coincide con el tipo del slider.\n\npretzel-problem-needs-statement-and-answer = Pretzel no válido: cada `<problem>` debe contener un `<statement>` y un `<answer>`.\n\npretzel-circuit-first-problem-distractor = Pretzel no válido: en mode="circuit", el primer `<problem>` no puede ser un distractor.\n\n## Valores de atributos\n\nattribute-invalid-values =\n { $valuesCount ->\n [one] Valor no válido { $values } para el atributo `{ $attribute }`; se ignora.\n *[other] Valores no válidos { $values } para el atributo `{ $attribute }`; se ignoran.\n }\n\nattribute-must-be-references = Valor no válido `{ $value }` para el atributo `{ $attribute }`. El atributo debe estar compuesto de referencias que empiecen por `$`.\n\nmath-input-invalid-function-names = <mathInput>: se ignoran nombres de función no válidos en { $attribute }: { $names }. El segmento visible de cada nombre debe tener al menos 2 caracteres (letras o guiones); puede añadirse un sufijo opcional `|<alternativa de mathspeak>`.\n\n## Construcción de componentes a partir del código fuente\n\ncomponent-type-invalid = Tipo de componente no válido: `<{ $componentType }>`\n\nattribute-repeated = No se puede repetir el atributo { $attribute }.\n\nattribute-invalid-for-component = Atributo "{ $attribute }" no válido para un componente de tipo `<{ $componentType }>`.\n\n## Contraste de las definiciones de estilo\n\nstyle-definition-insufficient-contrast =\n La definición de estilo { $styleNumber } no tiene suficiente contraste para { $context ->\n [text-on-background] el color del texto sobre el color de fondo\n [high-contrast] el color de alto contraste sobre el lienzo\n [line] el color de las líneas sobre el lienzo\n [marker] el color de los marcadores sobre el lienzo\n *[text-on-canvas] el color del texto sobre el lienzo\n }{ $mode ->\n [dark] { " (modo oscuro)" }\n *[light] { "" }\n } ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1).\n\nstyle-definition-dark-mode-text-background-contrast =\n Aunque la definición de estilo { $styleNumber } especifica colores con suficiente contraste en modo claro, los colores de modo oscuro derivados de esos valores no tienen suficiente contraste entre el color del texto y el color de fondo ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1). { $suggestion ->\n [available] Para lograr suficiente contraste en modo oscuro, aumenta el contraste en modo claro (por ejemplo, con { $lightAttribute }="{ $lightColor }") o define el color de modo oscuro (por ejemplo, con { $darkAttribute }="{ $darkColor }").\n *[none] Para lograr suficiente contraste en modo oscuro, aumenta el contraste en modo claro o sustituye los colores derivados mediante textColorDarkMode o backgroundColorDarkMode.\n }\n\nstyle-definition-dark-mode-text-canvas-contrast =\n Aunque la definición de estilo { $styleNumber } especifica un color de texto con suficiente contraste en modo claro, el color de texto de modo oscuro derivado de ese valor no tiene suficiente contraste sobre el lienzo ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1). { $suggestion ->\n [available] Para lograr suficiente contraste en modo oscuro, aumenta el contraste en modo claro (por ejemplo, con textColor="{ $lightColor }") o define el color de modo oscuro (por ejemplo, con textColorDarkMode="{ $darkColor }").\n *[none] Para lograr suficiente contraste en modo oscuro, aumenta el contraste en modo claro o sustituye el color derivado mediante textColorDarkMode.\n }\n\nsection-multiple-style-palettes = Una sección solo puede seleccionar un <stylePalette>; se usará el último.\n\n## Variantes únicas\n\nvariant-num-to-select-not-non-negative-integer = no se pueden determinar las variantes únicas de { $component } porque numToSelect no es un entero no negativo.\n\nvariant-num-to-select-not-constant-number = no se pueden determinar las variantes únicas de { $component } porque numToSelect no es un número constante.\n\nvariant-with-replacement-not-constant-boolean = no se pueden determinar las variantes únicas de { $component } porque withReplacement no es un booleano constante.\n\nvariant-select-weight-disables-unique = Las variantes únicas quedan desactivadas en select si alguna opción especifica selectWeight o selectForVariants\n\nvariant-coprime-undetermined = no se pueden determinar las variantes únicas de { $component } porque no se puede determinar si coprime es siempre falso.\n\nvariant-attribute-not-constant = no se pueden determinar las variantes únicas de { $component } porque { $attribute } no es constante.\n\nvariant-attribute-not-number = no se pueden determinar las variantes únicas de { $component } porque { $attribute } no es un número.\n\nvariant-attribute-wrong-type-for-sequence =\n no se pueden determinar las variantes únicas de { $component } de tipo { $type } porque { $attribute } no es { $expected ->\n [letters-combination] una combinación de letras\n [math-expression] una expresión matemática válida\n [integer] un entero\n *[number] un número\n }.\n\nvariant-length-not-integer = no se pueden determinar las variantes únicas de { $component } porque length no es un entero.\n\nvariant-sort-not-implemented = no se han implementado las variantes únicas de un { $component } con sort\n\nvariant-exclude-combinations-not-implemented = no se han implementado las variantes únicas de un { $component } con excludeCombinations\n\nvariant-math-exclude-not-implemented = no se han implementado las variantes únicas de un { $component } de tipo math con exclude\n\nvariant-non-constant-exclude-not-implemented = no se han implementado las variantes únicas de un { $component } con exclude no constante\n\n## Conversión a PreFigure\n\nprefigure-descendant-unsupported = { $subject }: no se admite en el renderizador prefigure de gráficos; se omite el descendiente.\n\nprefigure-descendant-invalid-geometry = { $subject }: geometría no finita o incompleta; se omite el descendiente.\n\nprefigure-curve-label-omitted = { $subject }: las etiquetas no se admiten en los elementos de curva convertidos; se omite la etiqueta.\n\nprefigure-curve-unsupported-definition-type = { $subject }: tipo de definición de función de curva no admitido \'{ $definitionType }\'; se omite el descendiente.\n\nprefigure-region-flip-functions-unsupported = { $subject }: atributo flipFunctions no admitido en regionBetweenCurves; se omite el descendiente.\n\nprefigure-region-non-formula-child = { $subject }: en regionBetweenCurves solo se admiten funciones hijas de tipo fórmula; se omite el descendiente.\n\nprefigure-label-position-unsupported =\n { $subject }: labelPosition \'{ $labelPosition }\' no admitido para { $labelKind ->\n [line-family] una etiqueta de la familia de líneas\n *[point] una etiqueta de punto\n }; se usa la alineación predeterminada de PreFigure.\n\nprefigure-fill-style-unsupported = { $subject }: PreFigure no admite el estilo de relleno \'{ $fillStyle }\'; se usa un relleno sólido.\n\nprefigure-line-style-unknown = { $subject }: estilo de línea desconocido \'{ $lineStyle }\'; se omite de la salida de PreFigure.\n\nprefigure-marker-style-mapped-to-diamond = { $subject }: el estilo de marcador \'{ $markerStyle }\' se asigna al estilo \'diamond\' de PreFigure.\n\nprefigure-marker-style-unsupported = { $subject }: PreFigure no admite el estilo de marcador \'{ $markerStyle }\'; se usa el estilo predeterminado.\n\n## Anotaciones de PreFigure\n\nannotation-ref-unresolvable = `<annotation>`: `ref` no válido; no se puede resolver el destino. Se omite la anotación.\n\nannotation-ref-multiple-targets = `<annotation>`: `ref` se resolvió a varios destinos; se usa el primero.\n\nannotation-ref-outside-graph = `<annotation>`: `ref` no válido; el destino está fuera del gráfico que lo contiene. Se omite la anotación.\n\nannotation-ref-unsupported-target = `<annotation>`: `ref` no válido; el destino no es un objeto gráfico admitido en la conversión a prefigure. Se omite la anotación.\n\nannotation-text-missing = `<annotation>`: falta `text` o está vacío; se emite texto vacío.\n\n## Composites y referencias\n\ncomposite-circular-dependency =\n { $componentType ->\n [none] Se detectó una dependencia circular.\n *[other] Se detectó una dependencia circular en la que participa un componente `<{ $componentType }>`.\n }\n\nreference-no-referent = No se encontró ningún referente para la referencia: `{ $reference }`\n\nreference-multiple-referents = Se encontraron varios referentes para la referencia: `{ $reference }`\n\n## Hijos que no coinciden\n\nchildren-invalid-attribute-format = Formato no válido para el atributo { $attribute } de `<{ $componentType }>`.\n\nchildren-invalid = Hijos no válidos para `<{ $componentType }>`: se encontraron hijos no válidos: { $children }\n\n## Se recurre a un valor predeterminado\n\nattribute-value-invalid-using-default = Valor no válido `{ $value }` para el atributo `{ $attribute }`; se usa el valor `{ $default }`\n\n## Carga de una versión de DoenetML\n\ndoenetml-version-not-found =\n { $fallback ->\n [none] No se encontró la versión { $version } de DoenetML.\n *[other] No se encontró la versión { $version } de DoenetML. Se recurrirá a la versión { $fallback }\n }\n\n## Lectura del DoenetML\n\n# Estos mensajes citan el propio texto del autor —`$tag`, `$value`,\n# `$attribute`…—, que se reproduce tal cual.\n\nparse-invalid-doenetml = DoenetML no válido: { $content }\n\nparse-tag-missing-close-tag = DoenetML no válido: la etiqueta `{ $tag }` no tiene etiqueta de cierre. Se esperaba una etiqueta autocerrada o una etiqueta `</{ $tagName }>`.\n\nparse-tag-error = DoenetML no válido: error en la etiqueta `<{ $tagName }>`\n\nparse-attribute-missing-value = DoenetML no válido: parece que al atributo `{ $attribute }` le falta un valor.\n\nparse-attribute-invalid = DoenetML no válido: atributo no válido `{ $attribute }`\n\nparse-attribute-value-invalid = DoenetML no válido: valor de atributo no válido `{ $value }`\n\n# $quote es la comilla que cerraría el par: `"` o `\'`.\nparse-attribute-value-quote-mismatch = DoenetML no válido: valor de atributo no válido `{ $value }`. Las comillas no coinciden. Parece que falta una `{ $quote }`\n\nparse-open-tag-name-missing = DoenetML no válido: se encontró una etiqueta sin nombre, por ejemplo `<`\n\nparse-tag-not-closed = DoenetML no válido: la etiqueta `{ $tag }` no se cerró (parece que falta un `>`).\n\nparse-self-closing-tag-name-missing = DoenetML no válido: se encontró una etiqueta sin nombre `<{ $content }>`\n\nparse-self-closing-tag-not-closed = DoenetML no válido: la etiqueta `{ $tag }` no se cerró (parece que falta `/>`).\n\nparse-tag-invalid-attributes = DoenetML no válido: la etiqueta `{ $tag }` no es válida. Puede que tenga atributos incorrectos.\n\nparse-close-tag-name-missing = DoenetML no válido: se encontró una etiqueta de cierre sin nombre, por ejemplo `</`\n\nparse-attribute-value-unquoted = Los valores de los atributos deben ir entre comillas: `{ $attribute }="{ $value }"`\n\nparse-close-tag-without-open-tag = DoenetML no válido: se encontró la etiqueta de cierre `{ $tag }`, pero no hay ninguna etiqueta de apertura que le corresponda\n\nparse-close-tag-mismatched = DoenetML no válido: la etiqueta de cierre no coincide. Se esperaba `</{ $expected }>`. Se encontró `{ $found }`\n\nparser-node-unconvertible = No se pudo convertir el nodo { $node } en un nodo Dast.\n\n## Nombres\n\nname-attribute-invalid =\n Atributo name=\'{ $name }\' no válido. { $reason ->\n [characters] Los nombres solo pueden contener letras, números, guiones bajos o guiones.\n *[start] Los nombres deben empezar por una letra.\n }\n\ncomponent-name-invalid-start = Nombre de componente "{ $name }" no válido. Los nombres deben empezar por una letra.\n\n## Azúcar sintáctico de `<answer>`\n\nanswer-video-watched-missing-video = Un `<answer>` de tipo videoWatched debe tener un atributo video\n\nanswer-video-watched-video-not-reference = Un `<answer>` de tipo videoWatched debe tener un atributo video que sea una referencia\n\nanswer-name-not-single-text = El atributo name de `<answer>` debe tener un único hijo de texto\n\n## Referencias a otro documento\n\nexternal-doenetml-recursion-limit = No se pudo obtener el DoenetML externo por exceso de niveles de recursión. ¿Hay alguna referencia circular?\n\nexternal-doenetml-unavailable = No se pudo obtener el DoenetML de { $attribute }="{ $uri }"\n\nexternal-doenetml-type-mismatch = El DoenetML obtenido de { $attribute }="{ $uri }" no es válido: no coincide con el tipo de componente "{ $componentType }"\n\n## Sintaxis obsoleta\n\n# `[deprecation]` es una marca literal que abre los tres mensajes; se deja\n# igual. $component es `none` cuando el cambio de nombre vale para todos los\n# componentes que aceptan el atributo y nombrar uno sería engañoso.\n\ndeprecated-attribute-renamed =\n { $component ->\n [none] [deprecation] El atributo `{ $from }` está obsoleto; usa `{ $to }` en su lugar.\n *[other] [deprecation] El atributo `{ $from }` de `<{ $component }>` está obsoleto; usa `{ $to }` en su lugar.\n }\n\ndeprecated-attribute-renamed-conflict =\n { $component ->\n [none] [deprecation] El atributo `{ $from }` está obsoleto y se ignora porque también se especificó `{ $to }`.\n *[other] [deprecation] El atributo `{ $from }` de `<{ $component }>` está obsoleto y se ignora porque también se especificó `{ $to }`.\n }\n\ndeprecated-attribute-ignored = [deprecation] El atributo `{ $attribute }` de `<{ $component }>` está obsoleto y se ignora.\n\n\n## Cobertura de idiomas\n\n# $locale es la etiqueta de idioma del documento, tal como se declaró.\npluralize-english-only = `<pluralize>` solo puede pluralizar en inglés, así que su texto queda sin cambios en un documento escrito en { $locale }. Escribe el plural directamente o indícalo con el atributo `pluralForm`.\n\n\n## Comprobación del esquema\n\n# $tag, $parent y $attribute reproducen lo que escribió quien redacta el\n# documento y se dejan tal cual; los signos `<`, `>` y las comillas invertidas\n# que los rodean son puntuación de este catálogo, no parte del nombre.\n\nschema-element-unrecognized = El elemento `<{ $tag }>` no es un elemento de Doenet reconocido.\n\nschema-element-not-allowed-at-root = El elemento `<{ $tag }>` no se permite en la raíz del documento.\n\nschema-element-not-allowed-inside = El elemento `<{ $tag }>` no se permite dentro de `<{ $parent }>`.\n\nschema-attribute-unrecognized = El elemento `<{ $tag }>` no tiene ningún atributo llamado `{ $attribute }`.\n\n# $allowed son los valores admitidos, cada uno ya entre comillas dobles y\n# enumerados según el idioma de quien lee. $isList indica si el atributo acepta\n# varios a la vez.\nschema-attribute-value-not-allowed =\n { $isList ->\n [true] El atributo `{ $attribute }` del elemento `<{ $tag }>` debe ser una lista en la que cada elemento sea uno de: { $allowed }\n *[other] El atributo `{ $attribute }` del elemento `<{ $tag }>` debe ser uno de: { $allowed }\n }\n\n\n## Los cuadros de error de la familia `<select>`\n##\n## Los recuentos llegan como números, de modo que una lengua que concuerde con\n## ellos puede seleccionar sobre ellos. Los nombres de componentes y atributos\n## (`selectFromSequence`, `selectPrimeNumbers`, `from`, `to`, `step`) son\n## identificadores de DoenetML y se dejan tal cual.\n\nselect-variant-name-option-count-mismatch = Nombre de variante no válido para select. El nombre de variante { $variantName } aparece en { $numOptions } opciones, pero el número a seleccionar es { $numToSelect }.\n\nselect-variant-name-without-options = Se especifican variantes para select, pero no se especifica ninguna opción para el posible nombre de variante: { $variantName }.\n\nselect-variant-name-not-possible = El nombre de variante { $variantName } especificado para select no es un nombre de variante posible.\n\nselect-too-few-options = No se pueden seleccionar { $numToSelect } componentes de solo { $numOptions }.\n\nselect-from-sequence-too-few-values = No se pueden seleccionar { $numToSelect } valores de una secuencia de longitud { $length }.\n\nselect-from-sequence-indices-count-mismatch = El número de índices especificados para select debe coincidir con el número a seleccionar\n\nselect-from-sequence-indices-not-integers = Todos los índices especificados para select deben ser enteros\n\nselect-from-sequence-index-excluded = Se especificó un índice de selectfromsequence que estaba excluido\n\nselect-from-sequence-indices-excluded-combination = Se especificaron índices de selectfromsequence que formaban una combinación excluida\n\nselect-from-sequence-coprime-not-positive-integers = No se pueden seleccionar combinaciones coprimas porque no se están seleccionando enteros positivos.\n\nselect-from-sequence-coprime-common-factor = No se pueden seleccionar números coprimos. Todos los valores posibles comparten un factor común. (Los valores especificados de "from" o "to" deben ser coprimos con "step".)\n\nselect-from-sequence-coprime-single-number = No se pueden seleccionar combinaciones coprimas a partir de un único número que no sea 1.\n\nselect-from-sequence-excluded-too-many-combinations = Se excluyó más del 70 % de las combinaciones en selectFromSequence\n\nselect-from-sequence-coprime-none-found = No se pudieron seleccionar números coprimos. Todos los valores posibles comparten un factor común.\n\nselect-from-sequence-too-few-unique-values = No se pueden seleccionar { $numToSelect } valores únicos de una secuencia de longitud { $numPossibleValues }\n\nselect-prime-numbers-too-few-values = No se pueden seleccionar { $numToSelect } valores de una lista de primos de longitud { $numValues }\n\nselect-prime-numbers-values-count-mismatch = El número de valores especificados para select debe coincidir con el número a seleccionar\n\nselect-prime-numbers-values-not-prime = Todos los valores especificados para select prime number deben estar en la lista de primos\n\nselect-prime-numbers-values-excluded-combination = Se especificaron valores de selectPrimeNumbers que formaban una combinación excluida\n\nselect-prime-numbers-excluded-too-many-combinations = Se excluyó más del 70 % de las combinaciones en selectPrimeNumbers\n\nselect-random-combination-fluke = Por una casualidad extremadamente improbable, no se pudo seleccionar una combinación de valores aleatorios\n\nselect-random-value-fluke = Por una casualidad extremadamente improbable, no se pudo seleccionar un valor aleatorio\n';
1479
+ const esDiagnostics = '# Advertencias y errores mostrados a quien lee o escribe el documento.\n# Seleccionados por `uiLocale`.\n#\n# Los nombres de atributos y componentes de DoenetML (`through`, `endpoint`,\n# `numDimensions`, …) forman parte del lenguaje y se dejan en inglés.\n\n## `<lineSegment>`\n\nline-segment-attributes-ignored-with-endpoints =\n { $attributesCount ->\n [one] { $attributes } se ignora cuando se especifican los dos extremos\n *[other] { $attributes } se ignoran cuando se especifican los dos extremos\n }\n\nline-segment-attributes-ignored-with-endpoint-and-midpoint =\n { $attributesCount ->\n [one] { $attributes } se ignora cuando se especifican un extremo y el punto medio\n *[other] { $attributes } se ignoran cuando se especifican un extremo y el punto medio\n }\n\nline-segment-midpoint-offset-without-midpoint = midpointOffset no tiene efecto sin un punto medio\n\n## `<line>`\n\n# «Recta», no «línea», aunque `noun.line` en content.ftl diga «línea»: no es\n# una incoherencia, sino la diferencia entre describir el trazo dibujado («una\n# línea azul gruesa») y hablar del objeto geométrico, que en matemáticas es\n# una recta —de ahí «la ecuación de la recta».\n\nline-points-undetermined-dimensions = La recta pasa por puntos de dimensiones indeterminadas.\n\nline-points-too-few-dimensions = La recta debe pasar por puntos de al menos dos dimensiones.\n\nline-points-depend-on-variables = La recta pasa por puntos que dependen de las variables: { $variables }.\n\n# Enumeradas con coma en vez de «y»: las variables de <line> son `x` e `y` por\n# omisión, y «en las variables x y y» sería a la vez incorrecto (ante el sonido\n# /i/ la conjunción es «e») e ilegible. La coma es correcta sea cual sea el\n# nombre de la variable, que aquí no se conoce de antemano.\nline-equation-invalid-format = Formato no válido para la ecuación de la recta en las variables { $variable1 }, { $variable2 }.\n\n## `<ray>`\n\nray-overprescribed-through = La semirrecta está determinada por through, endpoint y direction. Se ignora el through especificado.\n\nray-dimension-mismatch = Discrepancia de numDimensions en la semirrecta.\n\n## `<vector>`\n\nvector-overprescribed-head = El vector está determinado por head, tail y displacement. Se ignora el head especificado.\n\nvector-dimension-mismatch = Discrepancia de numDimensions en el vector.\n\n## Atraer y restringir\n\nattract-to-without-nearest-point = No se puede atraer a un `<{ $component }>` porque no tiene la variable de estado nearestPoint.\n\nconstrain-to-without-nearest-point = No se puede restringir a un `<{ $component }>` porque no tiene la variable de estado nearestPoint.\n\nconstrain-to-interior-without-nearest-point = No se puede restringir al interior de un `<{ $component }>` porque no tiene la variable de estado nearestPoint.\n\n## `<choiceInput>`\n\nchoice-input-label-position-ignored = labelPosition se ignora en un choiceInput que no es inline\n\n## Ordenar hijos por índice\n\nchoice-input-indices-count-mismatch = Se ignoran los índices especificados para choiceInput porque su cantidad no coincide con la cantidad de hijos choice.\n\npretzel-indices-count-mismatch = Se ignoran los índices especificados para problem porque su cantidad no coincide con la cantidad de hijos problem.\n\nshuffle-indices-count-mismatch = Se ignoran los índices especificados para shuffle porque su cantidad no coincide con la cantidad de componentes.\n\nindices-ignored-out-of-range = Se ignoran los índices especificados para { $component } porque algunos están fuera de rango.\n\npretzel-indices-repeated = Se ignoran los índices especificados para pretzel porque algunos están repetidos.\n\npretzel-circuit-first-index = Se ignoran los índices especificados para pretzel en modo circuit porque el primer índice debe ser 1.\n\n## `<shuffle>` y `<sort>`\n\nstring-children-need-type = Para que `<{ $component }>` funcione con hijos de texto, se debe especificar el atributo `type`.\n\ninvalid-type-defaulting-to-math = Tipo no válido { $type } para el componente { $component }. Debe ser math, text, number o boolean. Se usa math.\n\nstring-not-valid-component-to-arrange = La cadena "{ $value }" no es un componente válido para { $component }. Se ignora.\n\n## Tipos y variables\n\ninvalid-type-defaulting-to-number = Tipo no válido { $type }, se establece el tipo en number.\n\ninvalid-variable-value = Valor no válido de una variable: `{ $value }`\n\n## Variantes\n\nvariant-index-must-be-number = El índice de variante { $index } debe ser un número\n\nvariant-index-must-be-integer = El índice de variante { $index } debe ser un número entero\n\n## `<sideBySide>`\n\nside-by-side-absolute-widths = `<{ $component }>` no está implementado para medidas absolutas. Los anchos se establecen como relativos.\n\nside-by-side-absolute-margins = `<{ $component }>` no está implementado para medidas absolutas. Los márgenes se establecen como relativos.\n\nside-by-side-no-block-child = `<{ $component }>` no es válido: debe tener al menos un hijo de bloque.\n\n## `<label>`\n\nlabel-for-ignored-on-graphical = Se ignora el atributo `for` en un `<label>` gráfico.\n\nlabel-for-must-resolve-to-one = El atributo `for` de `<label>` debe corresponder exactamente a un componente.\n\nlabel-for-unresolved = No se pudo resolver el atributo `for` de `<label>` a un componente.\n\nlabel-for-answer-with-authored-inputs = El atributo `for` de `<label>` hace referencia a un `<answer>` con entradas escritas explícitamente; haz referencia a la entrada directamente.\n\nlabel-for-answer-without-input = El atributo `for` de `<label>` hace referencia a un `<answer>` que no tiene ninguna entrada que etiquetar.\n\nlabel-for-must-reference-input-or-answer = El atributo `for` de `<label>` debe hacer referencia a una entrada o a un `<answer>`.\n\n## Accesibilidad\n\naccessibility-short-description-or-decorative = Por accesibilidad, `<{ $component }>` debe tener una descripción breve o estar marcado como decorativo.\n\naccessibility-video-short-description = Por accesibilidad, `<video>` debe tener una descripción breve.\n\naccessibility-input-short-description-or-label = Por accesibilidad, `<{ $component }>` debe tener una descripción breve o una etiqueta.\n\naccessibility-answer-input-short-description-or-label = Por accesibilidad, la entrada creada por un `<answer>` debe tener una descripción breve o una etiqueta.\n\naccessibility-short-description-contains-math = Las descripciones breves no deben contener componentes matemáticos como `<{ $component }>`. Expresa las matemáticas con palabras.\n\naccessibility-section-title-insufficient-contrast =\n { $mode ->\n [dark] { $colorName } no tiene suficiente contraste con el texto del encabezado de sección (modo oscuro) ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1).\n *[other] { $colorName } no tiene suficiente contraste con el texto del encabezado de sección ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1).\n }\n\n## `<circle>`\n\ncircle-through-points-non-numerical = No está implementado un `<circle>` que pase por { $count } puntos cuando los puntos no tienen valores numéricos.\n\ncircle-too-many-through-points = No se puede calcular una circunferencia que pase por más de 3 puntos.\n\ncircle-overprescribed-radius-center-points = No se puede calcular una circunferencia con radio, centro y puntos de paso especificados a la vez.\n\ncircle-center-with-multiple-points = No se puede calcular una circunferencia con centro especificado que pase por más de 1 punto.\n\ncircle-radius-too-small = No se puede calcular la circunferencia: dado que la distancia entre los dos puntos es { $distance }, el radio especificado { $radius } es demasiado pequeño.\n\ncircle-radius-with-many-points = No se puede crear una circunferencia que pase por más de dos puntos con un radio especificado.\n\ncircle-invalid-center-or-through-points = El centro o los puntos de paso de la circunferencia no son válidos.\n\ncircle-radius-center-with-multiple-points = No se puede calcular el radio de una circunferencia con centro especificado que pase por más de 1 punto.\n\ncircle-change-radius-non-numerical = No se puede cambiar el radio de una circunferencia con puntos de paso no numéricos\n\ncircle-radius-with-points-non-numerical = No se puede crear una circunferencia que pase por más de un punto con un radio especificado cuando no hay valores numéricos.\n\ncircle-change-center-non-numerical = No está implementado cambiar el centro de una circunferencia que pasa por puntos con valores no numéricos.\n\n## `<function>`\n\nfunction-domain-insufficient-dimensions =\n { $intervals ->\n [one] Dimensiones insuficientes para el dominio de la función. El dominio tiene { $intervals } intervalo pero la función tiene { $inputs ->\n [one] { $inputs } entrada\n *[other] { $inputs } entradas\n }.\n *[other] Dimensiones insuficientes para el dominio de la función. El dominio tiene { $intervals } intervalos pero la función tiene { $inputs ->\n [one] { $inputs } entrada\n *[other] { $inputs } entradas\n }.\n }\n\nfunction-domain-invalid-format = Formato no válido para el dominio de la función.\n\nfunction-ignoring-non-numerical =\n { $type ->\n [maximum] Se ignora el máximo no numérico de la función.\n [minimum] Se ignora el mínimo no numérico de la función.\n [extremum] Se ignora el extremo no numérico de la función.\n [point] Se ignora el punto no numérico de la función.\n [slope] Se ignora la pendiente no numérica de la función.\n *[other] Se ignora { $type } no numérico de la función.\n }\n\nfunction-ignoring-empty =\n { $type ->\n [maximum] Se ignora el máximo vacío de la función.\n [minimum] Se ignora el mínimo vacío de la función.\n [extremum] Se ignora el extremo vacío de la función.\n [point] Se ignora el punto vacío de la función.\n *[other] Se ignora { $type } vacío de la función.\n }\n\nfunction-points-too-close = La función contiene dos puntos demasiado próximos entre sí. No se puede definir la función.\n\nfunction-iterates-input-output-mismatch =\n { $inputs ->\n [one] Las iteraciones de una función solo son posibles si el número de entradas es igual al número de salidas. Esta función tiene { $inputs } entrada y { $outputs ->\n [one] { $outputs } salida\n *[other] { $outputs } salidas\n }.\n *[other] Las iteraciones de una función solo son posibles si el número de entradas es igual al número de salidas. Esta función tiene { $inputs } entradas y { $outputs ->\n [one] { $outputs } salida\n *[other] { $outputs } salidas\n }.\n }\n\n## `<sequence>`\n\nsequence-invalid-length = Longitud de la secuencia no válida. Debe ser un entero no negativo.\n\nsequence-invalid-step = Paso de la secuencia no válido. Debe ser un número para una secuencia de tipo { $type }.\n\nsequence-invalid-endpoint-number = El valor de "{ $attribute }" de la secuencia numérica no es válido. Debe ser un número.\n\nsequence-invalid-endpoint-letters = El valor de "{ $attribute }" de la secuencia de letras no es válido. Debe ser una combinación de letras.\n\nsequence-invalid-endpoint = El valor de "{ $attribute }" de la secuencia no es válido.\n\nselect-from-sequence-coprime-not-numbers = Se ignora coprime porque no se están seleccionando números\n\nselect-from-sequence-coprime-with-exclude-combinations = Se ignora coprime porque se especificó excludeCombinations\n\n## Resolución de `target`\n\ntarget-not-found = Destino no válido para `<{ $source }>`: no se encuentra el destino.\n\ntarget-state-variable-not-found = Destino no válido para `<{ $source }>`: no se encuentra una variable de estado llamada "{ $property }" en un `<{ $component }>`.\n\n## `<odeSystem>`\n\node-system-variables-match-independent = Las variables de `<odeSystem>` deben ser distintas de la variable independiente.\n\node-system-duplicate-variable-names = No se pueden definir las funciones del lado derecho de la EDO con nombres de variables dependientes repetidos.\n\node-system-rhs-function-error = No se puede definir la función del lado derecho de la EDO. Error al crear la función de mathjs.\n\n## `<angle>`, `<parabola>` e `<intersection>`\n\nangle-too-many-lines = No se puede definir un ángulo entre { $count } rectas\n\nangle-invalid-through-point = Punto no válido en through de `<angle>`\n\nparabola-vertex-too-many-points = No está implementada una parábola con vértice que pase por más de 1 punto.\n\nparabola-too-many-points = No está implementada una parábola que pase por más de 3 puntos.\n\nintersection-too-many-items = No está implementada la intersección de más de dos objetos\n\n## Otros componentes matemáticos\n\nionic-compound-not-two-ions = No está implementado el compuesto iónico para algo distinto de dos iones.\n\nionic-compound-needs-cation-and-anion = El compuesto iónico solo está implementado para un catión y un anión.\n\nsolve-equations-cannot-evaluate = No se puede resolver la ecuación porque no se pudo evaluar: { $equation }\n\nmath-operators-operand-number-required = Se debe especificar operandNumber al extraer un operando matemático.\n\neigen-decomposition-failed = No se pudieron calcular los valores propios de la matriz\n\n## `<matchesPattern>`\n\nmatches-pattern-parameter-not-in-pattern =\n { $parametersCount ->\n [one] `<matchesPattern>`: el parámetro { $parameters } no aparece en el patrón, por lo que siempre coincidirá con un espacio en blanco.\n *[other] `<matchesPattern>`: los parámetros { $parameters } no aparecen en el patrón, por lo que siempre coincidirán con un espacio en blanco.\n }\n\n## `<graph>`\n\ngraph-grid-invalid = `<graph>`: no se puede interpretar grid="{ $grid }". Debe ser none, medium, dense o dos números positivos separados por un espacio, como grid="1 0.5". No se dibuja ninguna cuadrícula.\n\n## Renderizador PreFigure\n\nprefigure-x-label-position-unsupported = `<graph>`: xLabelPosition="left" no es compatible con el renderizador prefigure; se usa el comportamiento de posición derecha.\n\nprefigure-y-label-position-unsupported = `<graph>`: yLabelPosition="bottom" no es compatible con el renderizador prefigure; se usa el comportamiento de posición superior.\n\nprefigure-invalid-axis-bounds = `<graph>`: los límites de los ejes no son válidos para la conversión a prefigure; se usa el bbox predeterminado (-10,-10,10,10).\n\nprefigure-invalid-width = `<graph>`: el ancho no es válido para la conversión a prefigure; se usa el ancho de diagrama predeterminado 425.\n\nprefigure-invalid-aspect-ratio = `<graph>`: aspectRatio no es válido para la conversión a prefigure; se usa la relación de aspecto predeterminada 1.\n\nprefigure-grid-spacing-too-fine = `<graph>`: el espaciado de la cuadrícula es demasiado fino para los límites de los ejes; se omite la cuadrícula en el renderizador prefigure.\n\nprefigure-annotations-not-rendered = `<graph>`: las anotaciones no se representan si no se usa el renderizador PreFigure.\n\nmultiple-annotations-children = Se encontraron varios hijos `<annotations>` en `<graph>`; se ignoran todos menos el último.\n\n## Referencias a otros componentes\n\ncopy-unrecognized-component-type = No se puede extender ni copiar un tipo de componente desconocido: { $type }.\n\ncopy-prop-not-found = No se encontró la propiedad { $property } en un componente de tipo { $component }\n\ncollect-no-source = No se encontró ninguna fuente para collect.\n\ncollect-invalid-component-type = No se pueden recolectar componentes de tipo `<{ $component }>` porque no es un tipo de componente válido.\n\nreference-index-unavailable = No se puede referenciar el índice `{ $reference }`\n\n## `<callAction>`\n\ncomponent-action-unavailable = No se puede llamar a { $action } en el componente `{ $reference }`\n\n## `<dataFrame>`\n\ndata-frame-inconsistent-row-lengths = Los datos tienen una forma no válida. Las filas tienen longitudes distintas. Encontrado en componentIdx :{ $componentIdx }\n\ndata-frame-duplicate-column-names = Los datos tienen nombres de columna repetidos. Encontrado en componentIdx :{ $componentIdx }\n\ndata-frame-missing-column-name = A los datos les falta el nombre de una columna. Encontrado en componentIdx :{ $componentIdx }\n\n## `<answer>` y puntuación\n\nanswer-award-depends-on-own-response = Un award de esta respuesta depende de la respuesta enviada por el propio answer, lo que provocará un comportamiento inesperado.\n\nanswer-max-num-attempts-in-section-wide-check-work = Establecer `maxNumAttempts` en un `<answer>` dentro de un contenedor con `sectionWideCheckWork` no tiene efecto, porque el número de intentos lo controla el contenedor. Establece `maxNumAttempts` en el contenedor.\n\nnested-section-wide-check-work-max-num-attempts = Establecer `maxNumAttempts` en un contenedor con `sectionWideCheckWork` que está dentro de otro contenedor con `sectionWideCheckWork` no tiene efecto, porque el número de intentos lo controla el contenedor exterior. Establece `maxNumAttempts` en el contenedor exterior.\n\nanswer-attributes-need-symbolic-equality =\n { $attributesCount ->\n [one] El atributo { $attributes } no tendrá efecto si no se establece symbolicEquality.\n *[other] Los atributos { $attributes } no tendrán efecto si no se establece symbolicEquality.\n }\n\nanswer-invalid-type = Tipo no válido para answer: { $type }\n\n## `<module>`, `<conditionalContent>`, `<slider>` y pretzel\n\nmodule-attribute-child-needs-name = Como el componente `<{ $component }>` no tiene nombre, no se puede usar como atributo de módulo\n\nmodule-attribute-name-already-defined = El componente `<{ $component } name="{ $name }">` no se puede usar como atributo de un módulo porque el tipo de componente `<module>` ya tiene definido un atributo "{ $name }".\n\nconditional-content-condition-ignored = Se ignora el atributo `condition` en un `<conditionalContent>` que tiene hijos case o else.\n\nslider-markers-type-mismatch = El tipo de los marcadores no coincide con el tipo del slider.\n\npretzel-problem-needs-statement-and-answer = Pretzel no válido: cada `<problem>` debe contener un `<statement>` y un `<answer>`.\n\npretzel-circuit-first-problem-distractor = Pretzel no válido: en mode="circuit", el primer `<problem>` no puede ser un distractor.\n\n## Valores de atributos\n\nattribute-invalid-values =\n { $valuesCount ->\n [one] Valor no válido { $values } para el atributo `{ $attribute }`; se ignora.\n *[other] Valores no válidos { $values } para el atributo `{ $attribute }`; se ignoran.\n }\n\nattribute-must-be-references = Valor no válido `{ $value }` para el atributo `{ $attribute }`. El atributo debe estar compuesto de referencias que empiecen por `$`.\n\nmath-input-invalid-function-names = <mathInput>: se ignoran nombres de función no válidos en { $attribute }: { $names }. El segmento visible de cada nombre debe tener al menos 2 caracteres (letras o guiones); puede añadirse un sufijo opcional `|<alternativa de mathspeak>`.\n\n## Construcción de componentes a partir del código fuente\n\ncomponent-type-invalid = Tipo de componente no válido: `<{ $componentType }>`\n\nattribute-repeated = No se puede repetir el atributo { $attribute }.\n\nattribute-invalid-for-component = Atributo "{ $attribute }" no válido para un componente de tipo `<{ $componentType }>`.\n\n## Contraste de las definiciones de estilo\n\nstyle-definition-insufficient-contrast =\n La definición de estilo { $styleNumber } no tiene suficiente contraste para { $context ->\n [text-on-background] el color del texto sobre el color de fondo\n [high-contrast] el color de alto contraste sobre el lienzo\n [line] el color de las líneas sobre el lienzo\n [marker] el color de los marcadores sobre el lienzo\n *[text-on-canvas] el color del texto sobre el lienzo\n }{ $mode ->\n [dark] { " (modo oscuro)" }\n *[light] { "" }\n } ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1).\n\nstyle-definition-dark-mode-text-background-contrast =\n Aunque la definición de estilo { $styleNumber } especifica colores con suficiente contraste en modo claro, los colores de modo oscuro derivados de esos valores no tienen suficiente contraste entre el color del texto y el color de fondo ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1). { $suggestion ->\n [available] Para lograr suficiente contraste en modo oscuro, aumenta el contraste en modo claro (por ejemplo, con { $lightAttribute }="{ $lightColor }") o define el color de modo oscuro (por ejemplo, con { $darkAttribute }="{ $darkColor }").\n *[none] Para lograr suficiente contraste en modo oscuro, aumenta el contraste en modo claro o sustituye los colores derivados mediante textColorDarkMode o backgroundColorDarkMode.\n }\n\nstyle-definition-dark-mode-text-canvas-contrast =\n Aunque la definición de estilo { $styleNumber } especifica un color de texto con suficiente contraste en modo claro, el color de texto de modo oscuro derivado de ese valor no tiene suficiente contraste sobre el lienzo ({ NUMBER($ratio, minimumFractionDigits: 2, maximumFractionDigits: 2) }:1; se requiere al menos { $threshold }:1). { $suggestion ->\n [available] Para lograr suficiente contraste en modo oscuro, aumenta el contraste en modo claro (por ejemplo, con textColor="{ $lightColor }") o define el color de modo oscuro (por ejemplo, con textColorDarkMode="{ $darkColor }").\n *[none] Para lograr suficiente contraste en modo oscuro, aumenta el contraste en modo claro o sustituye el color derivado mediante textColorDarkMode.\n }\n\nsection-multiple-style-palettes = Una sección solo puede seleccionar un <stylePalette>; se usará el último.\n\n## Variantes únicas\n\nvariant-num-to-select-not-non-negative-integer = no se pueden determinar las variantes únicas de { $component } porque numToSelect no es un entero no negativo.\n\nvariant-num-to-select-not-constant-number = no se pueden determinar las variantes únicas de { $component } porque numToSelect no es un número constante.\n\nvariant-with-replacement-not-constant-boolean = no se pueden determinar las variantes únicas de { $component } porque withReplacement no es un booleano constante.\n\nvariant-select-weight-disables-unique = Las variantes únicas quedan desactivadas en select si alguna opción especifica selectWeight o selectForVariants\n\nvariant-coprime-undetermined = no se pueden determinar las variantes únicas de { $component } porque no se puede determinar si coprime es siempre falso.\n\nvariant-attribute-not-constant = no se pueden determinar las variantes únicas de { $component } porque { $attribute } no es constante.\n\nvariant-attribute-not-number = no se pueden determinar las variantes únicas de { $component } porque { $attribute } no es un número.\n\nvariant-attribute-wrong-type-for-sequence =\n no se pueden determinar las variantes únicas de { $component } de tipo { $type } porque { $attribute } no es { $expected ->\n [letters-combination] una combinación de letras\n [math-expression] una expresión matemática válida\n [integer] un entero\n *[number] un número\n }.\n\nvariant-length-not-integer = no se pueden determinar las variantes únicas de { $component } porque length no es un entero.\n\nvariant-sort-not-implemented = no se han implementado las variantes únicas de un { $component } con sort\n\nvariant-exclude-combinations-not-implemented = no se han implementado las variantes únicas de un { $component } con excludeCombinations\n\nvariant-math-exclude-not-implemented = no se han implementado las variantes únicas de un { $component } de tipo math con exclude\n\nvariant-non-constant-exclude-not-implemented = no se han implementado las variantes únicas de un { $component } con exclude no constante\n\n## Conversión a PreFigure\n\nprefigure-descendant-unsupported = { $subject }: no se admite en el renderizador prefigure de gráficos; se omite el descendiente.\n\nprefigure-descendant-invalid-geometry = { $subject }: geometría no finita o incompleta; se omite el descendiente.\n\nprefigure-curve-label-omitted = { $subject }: las etiquetas no se admiten en los elementos de curva convertidos; se omite la etiqueta.\n\nprefigure-curve-unsupported-definition-type = { $subject }: tipo de definición de función de curva no admitido \'{ $definitionType }\'; se omite el descendiente.\n\nprefigure-region-flip-functions-unsupported = { $subject }: atributo flipFunctions no admitido en regionBetweenCurves; se omite el descendiente.\n\nprefigure-region-non-formula-child = { $subject }: en regionBetweenCurves solo se admiten funciones hijas de tipo fórmula; se omite el descendiente.\n\nprefigure-label-position-unsupported =\n { $subject }: labelPosition \'{ $labelPosition }\' no admitido para { $labelKind ->\n [line-family] una etiqueta de la familia de líneas\n *[point] una etiqueta de punto\n }; se usa la alineación predeterminada de PreFigure.\n\nprefigure-fill-style-unsupported = { $subject }: PreFigure no admite el estilo de relleno \'{ $fillStyle }\'; se usa un relleno sólido.\n\nprefigure-line-style-unknown = { $subject }: estilo de línea desconocido \'{ $lineStyle }\'; se omite de la salida de PreFigure.\n\nprefigure-marker-style-mapped-to-diamond = { $subject }: el estilo de marcador \'{ $markerStyle }\' se asigna al estilo \'diamond\' de PreFigure.\n\nprefigure-marker-style-unsupported = { $subject }: PreFigure no admite el estilo de marcador \'{ $markerStyle }\'; se usa el estilo predeterminado.\n\n## Anotaciones de PreFigure\n\nannotation-ref-unresolvable = `<annotation>`: `ref` no válido; no se puede resolver el destino. Se omite la anotación.\n\nannotation-ref-multiple-targets = `<annotation>`: `ref` se resolvió a varios destinos; se usa el primero.\n\nannotation-ref-outside-graph = `<annotation>`: `ref` no válido; el destino está fuera del gráfico que lo contiene. Se omite la anotación.\n\nannotation-ref-unsupported-target = `<annotation>`: `ref` no válido; el destino no es un objeto gráfico admitido en la conversión a prefigure. Se omite la anotación.\n\nannotation-text-missing = `<annotation>`: falta `text` o está vacío; se emite texto vacío.\n\n## Composites y referencias\n\ncomposite-circular-dependency =\n { $componentType ->\n [none] Se detectó una dependencia circular.\n *[other] Se detectó una dependencia circular en la que participa un componente `<{ $componentType }>`.\n }\n\nreference-no-referent = No se encontró ningún referente para la referencia: `{ $reference }`\n\nreference-multiple-referents = Se encontraron varios referentes para la referencia: `{ $reference }`\n\n## Hijos que no coinciden\n\nchildren-invalid-attribute-format = Formato no válido para el atributo { $attribute } de `<{ $componentType }>`.\n\nchildren-invalid = Hijos no válidos para `<{ $componentType }>`: se encontraron hijos no válidos: { $children }\n\n## Se recurre a un valor predeterminado\n\nattribute-value-invalid-using-default = Valor no válido `{ $value }` para el atributo `{ $attribute }`; se usa el valor `{ $default }`\n\n## Carga de una versión de DoenetML\n\ndoenetml-version-not-found =\n { $fallback ->\n [none] No se encontró la versión { $version } de DoenetML.\n *[other] No se encontró la versión { $version } de DoenetML. Se recurrirá a la versión { $fallback }\n }\n\n## Lectura del DoenetML\n\n# Estos mensajes citan el propio texto del autor —`$tag`, `$value`,\n# `$attribute`…—, que se reproduce tal cual.\n\nparse-invalid-doenetml = DoenetML no válido: { $content }\n\nparse-tag-missing-close-tag = DoenetML no válido: la etiqueta `{ $tag }` no tiene etiqueta de cierre. Se esperaba una etiqueta autocerrada o una etiqueta `</{ $tagName }>`.\n\nparse-tag-error = DoenetML no válido: error en la etiqueta `<{ $tagName }>`\n\nparse-attribute-missing-value = DoenetML no válido: parece que al atributo `{ $attribute }` le falta un valor.\n\nparse-attribute-invalid = DoenetML no válido: atributo no válido `{ $attribute }`\n\nparse-attribute-value-invalid = DoenetML no válido: valor de atributo no válido `{ $value }`\n\n# $quote es la comilla que cerraría el par: `"` o `\'`.\nparse-attribute-value-quote-mismatch = DoenetML no válido: valor de atributo no válido `{ $value }`. Las comillas no coinciden. Parece que falta una `{ $quote }`\n\nparse-open-tag-name-missing = DoenetML no válido: se encontró una etiqueta sin nombre, por ejemplo `<`\n\nparse-tag-not-closed = DoenetML no válido: la etiqueta `{ $tag }` no se cerró (parece que falta un `>`).\n\nparse-self-closing-tag-name-missing = DoenetML no válido: se encontró una etiqueta sin nombre `<{ $content }>`\n\nparse-self-closing-tag-not-closed = DoenetML no válido: la etiqueta `{ $tag }` no se cerró (parece que falta `/>`).\n\nparse-tag-invalid-attributes = DoenetML no válido: la etiqueta `{ $tag }` no es válida. Puede que tenga atributos incorrectos.\n\nparse-close-tag-name-missing = DoenetML no válido: se encontró una etiqueta de cierre sin nombre, por ejemplo `</`\n\nparse-attribute-value-unquoted = Los valores de los atributos deben ir entre comillas: `{ $attribute }="{ $value }"`\n\nparse-close-tag-without-open-tag = DoenetML no válido: se encontró la etiqueta de cierre `{ $tag }`, pero no hay ninguna etiqueta de apertura que le corresponda\n\nparse-close-tag-mismatched = DoenetML no válido: la etiqueta de cierre no coincide. Se esperaba `</{ $expected }>`. Se encontró `{ $found }`\n\nparser-node-unconvertible = No se pudo convertir el nodo { $node } en un nodo Dast.\n\n## Nombres\n\nname-attribute-invalid =\n Atributo name=\'{ $name }\' no válido. { $reason ->\n [characters] Los nombres solo pueden contener letras, números, guiones bajos o guiones.\n *[start] Los nombres deben empezar por una letra.\n }\n\ncomponent-name-invalid-start = Nombre de componente "{ $name }" no válido. Los nombres deben empezar por una letra.\n\n## Azúcar sintáctico de `<answer>`\n\nanswer-video-watched-missing-video = Un `<answer>` de tipo videoWatched debe tener un atributo video\n\nanswer-video-watched-video-not-reference = Un `<answer>` de tipo videoWatched debe tener un atributo video que sea una referencia\n\nanswer-name-not-single-text = El atributo name de `<answer>` debe tener un único hijo de texto\n\n## Referencias a otro documento\n\nexternal-doenetml-recursion-limit = No se pudo obtener el DoenetML externo por exceso de niveles de recursión. ¿Hay alguna referencia circular?\n\nexternal-doenetml-unavailable = No se pudo obtener el DoenetML de { $attribute }="{ $uri }"\n\nexternal-doenetml-type-mismatch = El DoenetML obtenido de { $attribute }="{ $uri }" no es válido: no coincide con el tipo de componente "{ $componentType }"\n\n## Sintaxis obsoleta\n\n# `[deprecation]` es una marca literal que abre los tres mensajes; se deja\n# igual. $component es `none` cuando el cambio de nombre vale para todos los\n# componentes que aceptan el atributo y nombrar uno sería engañoso.\n\ndeprecated-attribute-renamed =\n { $component ->\n [none] [deprecation] El atributo `{ $from }` está obsoleto; usa `{ $to }` en su lugar.\n *[other] [deprecation] El atributo `{ $from }` de `<{ $component }>` está obsoleto; usa `{ $to }` en su lugar.\n }\n\ndeprecated-attribute-renamed-conflict =\n { $component ->\n [none] [deprecation] El atributo `{ $from }` está obsoleto y se ignora porque también se especificó `{ $to }`.\n *[other] [deprecation] El atributo `{ $from }` de `<{ $component }>` está obsoleto y se ignora porque también se especificó `{ $to }`.\n }\n\ndeprecated-attribute-ignored = [deprecation] El atributo `{ $attribute }` de `<{ $component }>` está obsoleto y se ignora.\n\n\n## Cobertura de idiomas\n\n# $locale es la etiqueta de idioma del documento, tal como se declaró.\npluralize-english-only = `<pluralize>` solo puede pluralizar en inglés, así que su texto queda sin cambios en un documento escrito en { $locale }. Escribe el plural directamente o indícalo con el atributo `pluralForm`.\n\n\n## Comprobación del esquema\n\n# $tag, $parent y $attribute reproducen lo que escribió quien redacta el\n# documento y se dejan tal cual; los signos `<`, `>` y las comillas invertidas\n# que los rodean son puntuación de este catálogo, no parte del nombre.\n\nschema-element-unrecognized = El elemento `<{ $tag }>` no es un elemento de Doenet reconocido.\n\nschema-element-not-allowed-at-root = El elemento `<{ $tag }>` no se permite en la raíz del documento.\n\nschema-element-not-allowed-inside = El elemento `<{ $tag }>` no se permite dentro de `<{ $parent }>`.\n\nschema-attribute-unrecognized = El elemento `<{ $tag }>` no tiene ningún atributo llamado `{ $attribute }`.\n\n# $allowed son los valores admitidos, cada uno ya entre comillas dobles y\n# enumerados según el idioma de quien lee. $isList indica si el atributo acepta\n# varios a la vez.\nschema-attribute-value-not-allowed =\n { $isList ->\n [true] El atributo `{ $attribute }` del elemento `<{ $tag }>` debe ser una lista en la que cada elemento sea uno de: { $allowed }\n *[other] El atributo `{ $attribute }` del elemento `<{ $tag }>` debe ser uno de: { $allowed }\n }\n\n\n## Los cuadros de error de la familia `<select>`\n##\n## Los recuentos llegan como números, de modo que una lengua que concuerde con\n## ellos puede seleccionar sobre ellos. Los nombres de componentes y atributos\n## (`selectFromSequence`, `selectPrimeNumbers`, `from`, `to`, `step`) son\n## identificadores de DoenetML y se dejan tal cual.\n\nselect-variant-name-option-count-mismatch = Nombre de variante no válido para select. El nombre de variante { $variantName } aparece en { $numOptions } opciones, pero el número a seleccionar es { $numToSelect }.\n\nselect-variant-name-without-options = Se especifican variantes para select, pero no se especifica ninguna opción para el posible nombre de variante: { $variantName }.\n\nselect-variant-name-not-possible = El nombre de variante { $variantName } especificado para select no es un nombre de variante posible.\n\nselect-too-few-options = No se pueden seleccionar { $numToSelect } componentes de solo { $numOptions }.\n\nselect-from-sequence-too-few-values = No se pueden seleccionar { $numToSelect } valores de una secuencia de longitud { $length }.\n\nselect-from-sequence-indices-count-mismatch = El número de índices especificados para select debe coincidir con el número a seleccionar\n\nselect-from-sequence-indices-not-integers = Todos los índices especificados para select deben ser enteros\n\nselect-from-sequence-index-excluded = Se especificó un índice de selectfromsequence que estaba excluido\n\nselect-from-sequence-indices-excluded-combination = Se especificaron índices de selectfromsequence que formaban una combinación excluida\n\nselect-from-sequence-coprime-not-positive-integers = No se pueden seleccionar combinaciones coprimas porque no se están seleccionando enteros positivos.\n\nselect-from-sequence-coprime-common-factor = No se pueden seleccionar números coprimos. Todos los valores posibles comparten un factor común. (Los valores especificados de "from" o "to" deben ser coprimos con "step".)\n\nselect-from-sequence-coprime-single-number = No se pueden seleccionar combinaciones coprimas a partir de un único número que no sea 1.\n\nselect-from-sequence-excluded-too-many-combinations = Se excluyó más del 70 % de las combinaciones en selectFromSequence\n\nselect-from-sequence-coprime-none-found = No se pudieron seleccionar números coprimos. Todos los valores posibles comparten un factor común.\n\nselect-from-sequence-too-few-unique-values = No se pueden seleccionar { $numToSelect } valores únicos de una secuencia de longitud { $numPossibleValues }\n\nselect-prime-numbers-too-few-values = No se pueden seleccionar { $numToSelect } valores de una lista de primos de longitud { $numValues }\n\nselect-prime-numbers-values-count-mismatch = El número de valores especificados para select debe coincidir con el número a seleccionar\n\nselect-prime-numbers-values-not-prime = Todos los valores especificados para select prime number deben estar en la lista de primos\n\nselect-prime-numbers-values-excluded-combination = Se especificaron valores de selectPrimeNumbers que formaban una combinación excluida\n\nselect-prime-numbers-excluded-too-many-combinations = Se excluyó más del 70 % de las combinaciones en selectPrimeNumbers\n\nselect-random-combination-fluke = Por una casualidad extremadamente improbable, no se pudo seleccionar una combinación de valores aleatorios\n\nselect-random-value-fluke = Por una casualidad extremadamente improbable, no se pudo seleccionar un valor aleatorio\n';
1480
1480
  const esEditor = '# Superficies del editor: el pie, el panel de diagnósticos, el selector de\n# variantes, el botón de accesibilidad y el panel de ayuda contextual.\n# Se selecciona con `uiLocale`.\n#\n# `WCAG AA` es el nombre de la norma y no se traduce.\n\n\n## Los controles del visor\n\neditor-update-viewer =\n { $action ->\n [reset] Reiniciar\n *[update] Actualizar\n }\n\neditor-update-viewer-title =\n { $shortcut ->\n [none] { $word } el visor\n *[other] { $word } el visor { $shortcut }\n }\n\n\n## El selector de variantes\n\neditor-variant = Variante\neditor-variant-filter = Filtrar...\neditor-variant-next = Seleccionar la variante siguiente\neditor-variant-previous = Seleccionar la variante anterior\n\n\n## El botón de estado de accesibilidad\n\neditor-accessibility-title =\n { $status ->\n [violations] Se detectó una infracción de accesibilidad WCAG AA. Pulse para { $action ->\n [close] cerrar\n *[open] abrir\n } el informe de accesibilidad.\n [advisories] Pulse para { $action ->\n [close] cerrar\n *[open] abrir\n } el informe de accesibilidad. No se detectaron infracciones WCAG AA, pero hay recomendaciones adicionales de accesibilidad.\n *[clean] Pulse para { $action ->\n [close] cerrar\n *[open] abrir\n } el informe de accesibilidad. No se detectó ningún problema de accesibilidad.\n }\n\neditor-accessibility-label =\n { $status ->\n [violations] Se detectó una infracción de accesibilidad WCAG AA. Se { $count ->\n [one] encontró { $count } infracción WCAG AA\n *[other] encontraron { $count } infracciones WCAG AA\n }. Pulse para { $action ->\n [close] cerrar\n *[open] abrir\n } el informe de accesibilidad.\n [advisories] No se detectaron infracciones WCAG AA. Se { $count ->\n [one] encontró { $count } recomendación adicional de accesibilidad\n *[other] encontraron { $count } recomendaciones adicionales de accesibilidad\n }. Pulse para { $action ->\n [close] cerrar\n *[open] abrir\n } el informe de accesibilidad.\n *[clean] No se detectaron infracciones WCAG AA. Pulse para { $action ->\n [close] cerrar\n *[open] abrir\n } el informe de accesibilidad.\n }\n\neditor-accessibility-badge = WCAG\n\n\n## El pie\n\neditor-version-title = Versión de DoenetML { $version }\n\neditor-tab-help = Ayuda contextual\neditor-tab-help-short = Contexto\neditor-tab-errors = Errores\neditor-tab-warnings = Advertencias\neditor-tab-info = Información\neditor-tab-accessibility = Accesibilidad\neditor-tab-responses = Respuestas enviadas\n\neditor-tab-with-count = { $label }: { $count }\n\neditor-options = Opciones del editor\neditor-format-as-doenetml = Formatear como DoenetML\neditor-format-as-xml = Formatear como XML\n\n\n## El panel de diagnósticos\n\neditor-diagnostic-line = Línea n.º { $line }\n\neditor-no-errors = Sin errores\neditor-no-warnings = Sin advertencias\neditor-no-info = Sin diagnósticos informativos\n\neditor-show-info-annotations = Mostrar los diagnósticos informativos en el editor\neditor-show-accessibility-annotations = Mostrar los diagnósticos de accesibilidad en el editor\n\neditor-accessibility-learn-more = Descubra cómo Doenet aborda la accesibilidad\n\neditor-accessibility-violations-heading = Infracciones de accesibilidad ({ $standard })\n\neditor-accessibility-other-heading = Otros problemas de accesibilidad\neditor-none-found = No se encontró ninguno\n\n\n## Respuestas enviadas\n\neditor-no-responses = Todavía no hay respuestas enviadas\neditor-response-answer-id = Id. de respuesta\neditor-response-response = Respuesta\neditor-response-credit = Puntuación\neditor-response-submitted = Enviada\n\n\n## El panel de ayuda contextual\n##\n## Los fragmentos con formato — un nombre de elemento en `<code>`, un enlace —\n## llegan como argumentos y se vuelven a insertar después de formatear el\n## mensaje, de modo que la traducción decide dónde va cada uno.\n\nhelp-placeholder = Coloque el cursor sobre el nombre de una etiqueta, un atributo o { $ref } para ver la documentación.\n\nhelp-unsupported-ref-chain = Todavía no hay ayuda para las referencias de varias partes como { $example }.\n\nhelp-unresolved-ref =\n { $reason ->\n [notFound] No se encontró ningún referente para la referencia: { $ref }.\n [multiple] Se encontraron varios referentes para la referencia: { $ref }.\n *[indeterminate] No se pudo determinar un referente para { $ref }.\n }\n\nhelp-learn-about-references = Más información sobre las referencias →\nhelp-reference-page = Página de referencia →\n\nhelp-suggestions-header =\n { $location ->\n [inside] Dentro de { $element }\n *[top] En el nivel superior\n }{ $allowed ->\n [none] { " — aquí no va nada." }\n [text] { " — escriba texto aquí." }\n [text-and-components] { " — escriba texto aquí o pruebe con:" }\n *[components] { " — puede probar con:" }\n }\n\nhelp-suggestions-footer = Pulse { $shortcut } para ver los { $total } componentes.\n\nhelp-name-summary = { $name } — { $summary }\n\nhelp-ref-is-reference =\n { $line ->\n [none] { $ref } es una referencia a { $target }.\n *[other] { $ref } es una referencia a { $target } (línea { $line }).\n }\n\nhelp-ref-derived-from =\n { $line ->\n [none] Introducida por { $owner } como { $role }.\n *[other] Introducida por { $owner } en la línea { $line } como { $role }.\n }\n\nhelp-property-is-reference =\n { $line ->\n [none] { $ref } es una referencia a la propiedad { $property } de { $element }.\n *[other] { $ref } es una referencia a la propiedad { $property } de { $element } (línea { $line }).\n }\n\nhelp-kind-attribute = atributo\nhelp-kind-snippet = fragmento\nhelp-kind-array-entry = entrada de arreglo\n\nhelp-default = Valor predeterminado:\nhelp-active-default = Valor predeterminado activo:\n\nhelp-style-number-annotation = { " " }(styleNumber { $styleNumber })\n\nhelp-allowed-values =\n { $perItem ->\n [true] Valores admitidos (uno por elemento):\n *[other] Valores admitidos:\n }\n\nhelp-suggested-values = Valores sugeridos:\n\nhelp-inserts = Inserta:\n\nhelp-coordinates =\n { $count ->\n [one] Coordenada:\n *[other] Coordenadas:\n }\n\nhelp-type = Tipo:\n\nhelp-resolved-style = Estilo resuelto (styleNumber { $styleNumber }):\n\nhelp-resolved-function-names = Nombres de función resueltos:\nhelp-reset-list = Lista restablecida en esta entrada:\nhelp-added-on-input = Añadidos en esta entrada:\nhelp-removed-on-input = Eliminados en esta entrada:\n\nhelp-reset-overrides = { $reset } prevalece sobre { $additional } y { $removed }.\n';
1481
1481
  const BUNDLED_TRANSLATIONS = {
1482
1482
  es: {
@@ -1486,6 +1486,10 @@ const BUNDLED_TRANSLATIONS = {
1486
1486
  editor: esEditor
1487
1487
  }
1488
1488
  };
1489
+ [
1490
+ DEFAULT_LOCALE,
1491
+ ...Object.keys(BUNDLED_TRANSLATIONS)
1492
+ ];
1489
1493
  function bundledResources(namespaces, { includeEnglish = false } = {}) {
1490
1494
  const resources = {};
1491
1495
  if (includeEnglish) {
@@ -1507,6 +1511,40 @@ bundledResources(
1507
1511
  CHROME_NAMESPACES,
1508
1512
  { includeEnglish: true }
1509
1513
  );
1514
+ const CODE_SPLIT_CATALOGS = typeof __DOENET_CODE_SPLIT_CATALOGS__ === "undefined" || __DOENET_CODE_SPLIT_CATALOGS__;
1515
+ const LAZY_CATALOG_MODULES = CODE_SPLIT_CATALOGS ? /* @__PURE__ */ Object.assign({}) : {};
1516
+ const CATALOG_PATH_PATTERN = /\/locales\/([^/]+)\/([^/]+)\.ftl$/;
1517
+ function isCatalogNamespace(name2) {
1518
+ return CATALOG_NAMESPACES.includes(name2);
1519
+ }
1520
+ function loadersFromModules(modules) {
1521
+ const byLocale = {};
1522
+ for (const [modulePath, importModule] of Object.entries(modules)) {
1523
+ const match2 = CATALOG_PATH_PATTERN.exec(modulePath);
1524
+ if (!match2 || !isCatalogNamespace(match2[2])) {
1525
+ continue;
1526
+ }
1527
+ (byLocale[match2[1]] ??= {})[match2[2]] = importModule;
1528
+ }
1529
+ const loaders = {};
1530
+ for (const [locale, importers] of Object.entries(byLocale)) {
1531
+ loaders[locale] = async (namespaces) => {
1532
+ const wanted = namespaces.filter(
1533
+ (namespace) => Boolean(importers[namespace])
1534
+ );
1535
+ const sources = await Promise.all(
1536
+ wanted.map((namespace) => importers[namespace]())
1537
+ );
1538
+ const catalogs = {};
1539
+ wanted.forEach((namespace, index2) => {
1540
+ catalogs[namespace] = sources[index2];
1541
+ });
1542
+ return catalogs;
1543
+ };
1544
+ }
1545
+ return loaders;
1546
+ }
1547
+ loadersFromModules(LAZY_CATALOG_MODULES);
1510
1548
  bundledResources(WORKER_NAMESPACES);
1511
1549
  const DIAGNOSTIC_CODES = {
1512
1550
  "doenet-i0001": "line-segment-attributes-ignored-with-endpoints",
@@ -1660,6 +1698,7 @@ const DIAGNOSTIC_CODES = {
1660
1698
  "doenet-w0116": "schema-attribute-value-not-allowed",
1661
1699
  "doenet-w0117": "matches-pattern-parameter-not-in-pattern",
1662
1700
  "doenet-w0118": "prefigure-grid-spacing-too-fine",
1701
+ "doenet-w0119": "graph-grid-invalid",
1663
1702
  "doenet-e0001": "pretzel-circuit-first-problem-distractor",
1664
1703
  "doenet-e0002": "component-type-invalid",
1665
1704
  "doenet-e0003": "attribute-repeated",
@@ -28015,9 +28054,336 @@ function requireCssesc$1() {
28015
28054
  return cssesc_1$1;
28016
28055
  }
28017
28056
  requireCssesc$1();
28018
- const viewerIframeJsSource = '(function() {\n "use strict";\n let lastAugmentedProps = null;\n let currentFunctionProps = {};\n const functionPropDispatchers = {};\n function getFunctionPropDispatcher(key) {\n let dispatcher = functionPropDispatchers[key];\n if (!dispatcher) {\n if (key === "reportScoreAndStateCallback" && typeof doenetWindowedViewer !== "undefined" && doenetWindowedViewer) {\n dispatcher = (report) => messageParentFromViewer({\n type: "reportScoreAndState",\n report\n });\n } else {\n dispatcher = (...callArgs) => currentFunctionProps[key]?.(...callArgs);\n }\n functionPropDispatchers[key] = dispatcher;\n }\n return dispatcher;\n }\n function functionPropArgsToMap(args) {\n const map = {};\n for (let i = 0; i < args.length; i += 2) {\n const key = args[i];\n const fn = args[i + 1];\n if (typeof key === "string" && typeof fn === "function") {\n map[key] = fn;\n }\n }\n return map;\n }\n function releaseFunctionProxy(fn) {\n try {\n fn?.[ComlinkViewer.releaseProxy]?.();\n } catch (e) {\n console.warn(\n "iframe DoenetViewer: failed to release stale Comlink proxy",\n e\n );\n }\n }\n function setCurrentFunctionProps(incoming) {\n for (const [key, fn] of Object.entries(currentFunctionProps)) {\n if (incoming[key] !== fn) {\n releaseFunctionProxy(fn);\n }\n }\n currentFunctionProps = incoming;\n }\n function defaultRequestScrollTo(offset) {\n messageParentFromViewer({ type: "scrollTo", offset });\n }\n function syncAugmentedFunctionProps() {\n if (!lastAugmentedProps) {\n return;\n }\n const next = {};\n for (const [key, val] of Object.entries(lastAugmentedProps)) {\n if (typeof val !== "function") {\n next[key] = val;\n }\n }\n for (const key of Object.keys(currentFunctionProps)) {\n next[key] = getFunctionPropDispatcher(key);\n }\n if (!("requestScrollTo" in next)) {\n next.requestScrollTo = defaultRequestScrollTo;\n }\n lastAugmentedProps = next;\n }\n let currentDoenetMLSource = null;\n function resolveDoenetMLSource(root) {\n if (currentDoenetMLSource !== null) {\n return currentDoenetMLSource;\n }\n const scriptTag = root.querySelector(\'script[type="text/doenetml"]\');\n currentDoenetMLSource = scriptTag?.innerHTML ?? "";\n return currentDoenetMLSource;\n }\n async function waitForStandaloneBundle(timeoutMs) {\n if (typeof window.renderDoenetViewerToContainer === "function") {\n return true;\n }\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, 50));\n if (typeof window.renderDoenetViewerToContainer === "function") {\n return true;\n }\n }\n return false;\n }\n ComlinkViewer.expose(\n {\n renderViewerWithFunctionProps,\n updateViewerProps(updatedSerializableProps) {\n if (!lastAugmentedProps) {\n console.warn(\n "iframe DoenetViewer: updateViewerProps arrived before renderViewerWithFunctionProps completed — likely a bug in the iframe wrapper\'s queue/replay sequencing."\n );\n return;\n }\n const { doenetML, ...rest } = updatedSerializableProps;\n if (typeof doenetML === "string") {\n currentDoenetMLSource = doenetML;\n }\n lastAugmentedProps = {\n ...lastAugmentedProps,\n ...rest\n };\n renderWithLastAugmentedProps();\n },\n updateViewerFunctionProps(...args) {\n if (!lastAugmentedProps) {\n console.warn(\n "iframe DoenetViewer: updateViewerFunctionProps arrived before renderViewerWithFunctionProps completed — likely a bug in the iframe wrapper\'s queue/replay sequencing."\n );\n return;\n }\n const incoming = functionPropArgsToMap(args);\n const prevKeys = Object.keys(currentFunctionProps).sort();\n const nextKeys = Object.keys(incoming).sort();\n const keysChanged = prevKeys.length !== nextKeys.length || prevKeys.some((key, i) => key !== nextKeys[i]);\n setCurrentFunctionProps(incoming);\n if (keysChanged) {\n syncAugmentedFunctionProps();\n renderWithLastAugmentedProps();\n }\n }\n },\n ComlinkViewer.windowEndpoint(globalThis.parent)\n );\n function renderViewerWithFunctionProps(...args) {\n setCurrentFunctionProps(functionPropArgsToMap(args));\n const augmentedDoenetViewerProps = { ...doenetViewerProps };\n augmentedDoenetViewerProps.externalVirtualKeyboardProvided = true;\n for (const propName of doenetViewerPropsSpecified) {\n if (!(propName in doenetViewerProps) && propName in currentFunctionProps) {\n augmentedDoenetViewerProps[propName] = getFunctionPropDispatcher(propName);\n }\n }\n if (!doenetViewerPropsSpecified.includes("requestScrollTo")) {\n augmentedDoenetViewerProps.requestScrollTo = defaultRequestScrollTo;\n }\n lastAugmentedProps = augmentedDoenetViewerProps;\n renderWithLastAugmentedProps();\n }\n function renderWithLastAugmentedProps() {\n const root = document.getElementById("root");\n window.renderDoenetViewerToContainer(\n root,\n resolveDoenetMLSource(root),\n lastAugmentedProps\n );\n }\n function installSharedCorePortProvider() {\n let coreCounter = 0;\n window.doenetGlobalConfig.createExternalCoreWorkerPort = () => {\n const coreId = `${viewerId}-core-${++coreCounter}`;\n const channel = new MessageChannel();\n window.parent.postMessage(\n { origin: viewerId, data: { type: "createSharedCore", coreId } },\n window.parent.origin,\n [channel.port2]\n );\n return {\n port: channel.port1,\n destroy: (suspectWedge) => {\n messageParentFromViewer({\n type: "destroySharedCore",\n coreId,\n suspectWedge: Boolean(suspectWedge)\n });\n }\n };\n };\n }\n (async () => {\n if (await waitForStandaloneBundle(6e4)) {\n if (typeof doenetSharedCoreWorker !== "undefined" && doenetSharedCoreWorker) {\n installSharedCorePortProvider();\n }\n messageParentFromViewer({\n iframeReady: true,\n stylePalettes: readStylePalettesFromBundle()\n });\n } else {\n messageParentFromViewer({\n error: "Invalid DoenetML version or DoenetML package not found"\n });\n }\n })().catch((err) => {\n console.error(\n "iframe DoenetViewer: unexpected failure while signalling iframeReady",\n err\n );\n try {\n messageParentFromViewer({\n error: "iframe viewer failed to initialize"\n });\n } catch {\n }\n });\n function readStylePalettesFromBundle() {\n try {\n return window.getDoenetStylePalettes?.() ?? null;\n } catch (err) {\n console.error(\n "iframe DoenetML: failed to read style palettes from the standalone bundle",\n err\n );\n return null;\n }\n }\n function messageParentFromViewer(data) {\n window.parent.postMessage(\n {\n origin: viewerId,\n data\n },\n window.parent.origin\n );\n }\n})();\n';
28057
+ const viewerIframeJsSource = '(function() {\n "use strict";\n const proxyMarker = /* @__PURE__ */ Symbol("Comlink.proxy");\n const createEndpoint = /* @__PURE__ */ Symbol("Comlink.endpoint");\n const releaseProxy = /* @__PURE__ */ Symbol("Comlink.releaseProxy");\n const finalizer = /* @__PURE__ */ Symbol("Comlink.finalizer");\n const throwMarker = /* @__PURE__ */ Symbol("Comlink.thrown");\n const isObject = (val) => typeof val === "object" && val !== null || typeof val === "function";\n const proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n }\n };\n const throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack\n }\n };\n } else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n }\n };\n const transferHandlers = /* @__PURE__ */ new Map([\n ["proxy", proxyTransferHandler],\n ["throw", throwTransferHandler]\n ]);\n function isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === "*") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n }\n function expose(obj, ep = globalThis, allowedOrigins = ["*"]) {\n ep.addEventListener("message", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin \'${ev.origin}\' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj2, prop) => obj2[prop], obj);\n const rawValue = path.reduce((obj2, prop) => obj2[prop], obj);\n switch (type) {\n case "GET":\n {\n returnValue = rawValue;\n }\n break;\n case "SET":\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case "APPLY":\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case "CONSTRUCT":\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case "ENDPOINT":\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case "RELEASE":\n {\n returnValue = void 0;\n }\n break;\n default:\n return;\n }\n } catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue).catch((value) => {\n return { value, [throwMarker]: 0 };\n }).then((returnValue2) => {\n const [wireValue, transferables] = toWireValue(returnValue2);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === "RELEASE") {\n ep.removeEventListener("message", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === "function") {\n obj[finalizer]();\n }\n }\n }).catch((error) => {\n const [wireValue, transferables] = toWireValue({\n value: new TypeError("Unserializable return value"),\n [throwMarker]: 0\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n }\n function isMessagePort(endpoint) {\n return endpoint.constructor.name === "MessagePort";\n }\n function closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n }\n function wrap(ep, target) {\n const pendingListeners = /* @__PURE__ */ new Map();\n ep.addEventListener("message", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n } finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], target);\n }\n function throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error("Proxy has been released and is not useable");\n }\n }\n function releaseEndpoint(ep) {\n return requestResponseMessage(ep, /* @__PURE__ */ new Map(), {\n type: "RELEASE"\n }).then(() => {\n closeEndPoint(ep);\n });\n }\n const proxyCounter = /* @__PURE__ */ new WeakMap();\n const proxyFinalizers = "FinalizationRegistry" in globalThis && new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\n function registerProxy(proxy2, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy2, ep, proxy2);\n }\n }\n function unregisterProxy(proxy2) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy2);\n }\n }\n function createProxy(ep, pendingListeners, path = [], target = function() {\n }) {\n let isProxyReleased = false;\n const proxy2 = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy2);\n releaseEndpoint(ep);\n pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === "then") {\n if (path.length === 0) {\n return { then: () => proxy2 };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\n type: "GET",\n path: path.map((p) => p.toString())\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, pendingListeners, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, pendingListeners, {\n type: "SET",\n path: [...path, prop].map((p) => p.toString()),\n value\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, pendingListeners, {\n type: "ENDPOINT"\n }).then(fromWireValue);\n }\n if (last === "bind") {\n return createProxy(ep, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: "APPLY",\n path: path.map((p) => p.toString()),\n argumentList\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: "CONSTRUCT",\n path: path.map((p) => p.toString()),\n argumentList\n }, transferables).then(fromWireValue);\n }\n });\n registerProxy(proxy2, ep);\n return proxy2;\n }\n function myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n }\n function processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n }\n const transferCache = /* @__PURE__ */ new WeakMap();\n function transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n }\n function proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n }\n function windowEndpoint(w, context = globalThis, targetOrigin = "*") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context)\n };\n }\n function toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: "HANDLER",\n name,\n value: serializedValue\n },\n transferables\n ];\n }\n }\n return [\n {\n type: "RAW",\n value\n },\n transferCache.get(value) || []\n ];\n }\n function fromWireValue(value) {\n switch (value.type) {\n case "HANDLER":\n return transferHandlers.get(value.name).deserialize(value.value);\n case "RAW":\n return value.value;\n }\n }\n function requestResponseMessage(ep, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n }\n function generateUUID() {\n return new Array(4).fill(0).map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)).join("-");\n }\n let lastAugmentedProps = null;\n let currentFunctionProps = {};\n const functionPropDispatchers = {};\n function getFunctionPropDispatcher(key) {\n let dispatcher = functionPropDispatchers[key];\n if (!dispatcher) {\n if (key === "reportScoreAndStateCallback" && typeof doenetWindowedViewer !== "undefined" && doenetWindowedViewer) {\n dispatcher = (report) => messageParentFromViewer({\n type: "reportScoreAndState",\n report\n });\n } else {\n dispatcher = (...callArgs) => currentFunctionProps[key]?.(...callArgs);\n }\n functionPropDispatchers[key] = dispatcher;\n }\n return dispatcher;\n }\n function functionPropArgsToMap(args) {\n const map = {};\n for (let i = 0; i < args.length; i += 2) {\n const key = args[i];\n const fn = args[i + 1];\n if (typeof key === "string" && typeof fn === "function") {\n map[key] = fn;\n }\n }\n return map;\n }\n function releaseFunctionProxy(fn) {\n try {\n fn?.[releaseProxy]?.();\n } catch (e) {\n console.warn(\n "iframe DoenetViewer: failed to release stale Comlink proxy",\n e\n );\n }\n }\n function setCurrentFunctionProps(incoming) {\n for (const [key, fn] of Object.entries(currentFunctionProps)) {\n if (incoming[key] !== fn) {\n releaseFunctionProxy(fn);\n }\n }\n currentFunctionProps = incoming;\n }\n function defaultRequestScrollTo(offset) {\n messageParentFromViewer({ type: "scrollTo", offset });\n }\n function syncAugmentedFunctionProps() {\n if (!lastAugmentedProps) {\n return;\n }\n const next = {};\n for (const [key, val] of Object.entries(lastAugmentedProps)) {\n if (typeof val !== "function") {\n next[key] = val;\n }\n }\n for (const key of Object.keys(currentFunctionProps)) {\n next[key] = getFunctionPropDispatcher(key);\n }\n if (!("requestScrollTo" in next)) {\n next.requestScrollTo = defaultRequestScrollTo;\n }\n lastAugmentedProps = next;\n }\n let currentDoenetMLSource = null;\n function resolveDoenetMLSource(root) {\n if (currentDoenetMLSource !== null) {\n return currentDoenetMLSource;\n }\n const scriptTag = root.querySelector(\'script[type="text/doenetml"]\');\n currentDoenetMLSource = scriptTag?.innerHTML ?? "";\n return currentDoenetMLSource;\n }\n async function waitForStandaloneBundle(timeoutMs) {\n if (typeof window.renderDoenetViewerToContainer === "function") {\n return true;\n }\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n await new Promise((resolve) => setTimeout(resolve, 50));\n if (typeof window.renderDoenetViewerToContainer === "function") {\n return true;\n }\n }\n return false;\n }\n expose(\n {\n renderViewerWithFunctionProps,\n updateViewerProps(updatedSerializableProps) {\n if (!lastAugmentedProps) {\n console.warn(\n "iframe DoenetViewer: updateViewerProps arrived before renderViewerWithFunctionProps completed — likely a bug in the iframe wrapper\'s queue/replay sequencing."\n );\n return;\n }\n const { doenetML, ...rest } = updatedSerializableProps;\n if (typeof doenetML === "string") {\n currentDoenetMLSource = doenetML;\n }\n lastAugmentedProps = {\n ...lastAugmentedProps,\n ...rest\n };\n renderWithLastAugmentedProps();\n },\n updateViewerFunctionProps(...args) {\n if (!lastAugmentedProps) {\n console.warn(\n "iframe DoenetViewer: updateViewerFunctionProps arrived before renderViewerWithFunctionProps completed — likely a bug in the iframe wrapper\'s queue/replay sequencing."\n );\n return;\n }\n const incoming = functionPropArgsToMap(args);\n const prevKeys = Object.keys(currentFunctionProps).sort();\n const nextKeys = Object.keys(incoming).sort();\n const keysChanged = prevKeys.length !== nextKeys.length || prevKeys.some((key, i) => key !== nextKeys[i]);\n setCurrentFunctionProps(incoming);\n if (keysChanged) {\n syncAugmentedFunctionProps();\n renderWithLastAugmentedProps();\n }\n }\n },\n windowEndpoint(globalThis.parent)\n );\n function renderViewerWithFunctionProps(...args) {\n setCurrentFunctionProps(functionPropArgsToMap(args));\n const augmentedDoenetViewerProps = { ...doenetViewerProps };\n augmentedDoenetViewerProps.externalVirtualKeyboardProvided = true;\n for (const propName of doenetViewerPropsSpecified) {\n if (!(propName in doenetViewerProps) && propName in currentFunctionProps) {\n augmentedDoenetViewerProps[propName] = getFunctionPropDispatcher(propName);\n }\n }\n if (!doenetViewerPropsSpecified.includes("requestScrollTo")) {\n augmentedDoenetViewerProps.requestScrollTo = defaultRequestScrollTo;\n }\n lastAugmentedProps = augmentedDoenetViewerProps;\n renderWithLastAugmentedProps();\n }\n function renderWithLastAugmentedProps() {\n const root = document.getElementById("root");\n window.renderDoenetViewerToContainer(\n root,\n resolveDoenetMLSource(root),\n lastAugmentedProps\n );\n }\n function installSharedCorePortProvider() {\n let coreCounter = 0;\n window.doenetGlobalConfig.createExternalCoreWorkerPort = () => {\n const coreId = `${viewerId}-core-${++coreCounter}`;\n const channel = new MessageChannel();\n window.parent.postMessage(\n { origin: viewerId, data: { type: "createSharedCore", coreId } },\n window.parent.origin,\n [channel.port2]\n );\n return {\n port: channel.port1,\n destroy: (suspectWedge) => {\n messageParentFromViewer({\n type: "destroySharedCore",\n coreId,\n suspectWedge: Boolean(suspectWedge)\n });\n }\n };\n };\n }\n (async () => {\n if (await waitForStandaloneBundle(6e4)) {\n if (typeof doenetSharedCoreWorker !== "undefined" && doenetSharedCoreWorker) {\n installSharedCorePortProvider();\n }\n messageParentFromViewer({\n iframeReady: true,\n stylePalettes: readStylePalettesFromBundle()\n });\n } else {\n messageParentFromViewer({\n error: "Invalid DoenetML version or DoenetML package not found"\n });\n }\n })().catch((err) => {\n console.error(\n "iframe DoenetViewer: unexpected failure while signalling iframeReady",\n err\n );\n try {\n messageParentFromViewer({\n error: "iframe viewer failed to initialize"\n });\n } catch {\n }\n });\n function readStylePalettesFromBundle() {\n try {\n return window.getDoenetStylePalettes?.() ?? null;\n } catch (err) {\n console.error(\n "iframe DoenetML: failed to read style palettes from the standalone bundle",\n err\n );\n return null;\n }\n }\n function messageParentFromViewer(data) {\n window.parent.postMessage(\n {\n origin: viewerId,\n data\n },\n window.parent.origin\n );\n }\n})();\n';
28019
28058
  const editorIframeJsSource = `(function() {
28020
28059
  "use strict";
28060
+ const proxyMarker = /* @__PURE__ */ Symbol("Comlink.proxy");
28061
+ const createEndpoint = /* @__PURE__ */ Symbol("Comlink.endpoint");
28062
+ const releaseProxy = /* @__PURE__ */ Symbol("Comlink.releaseProxy");
28063
+ const finalizer = /* @__PURE__ */ Symbol("Comlink.finalizer");
28064
+ const throwMarker = /* @__PURE__ */ Symbol("Comlink.thrown");
28065
+ const isObject = (val) => typeof val === "object" && val !== null || typeof val === "function";
28066
+ const proxyTransferHandler = {
28067
+ canHandle: (val) => isObject(val) && val[proxyMarker],
28068
+ serialize(obj) {
28069
+ const { port1, port2 } = new MessageChannel();
28070
+ expose(obj, port1);
28071
+ return [port2, [port2]];
28072
+ },
28073
+ deserialize(port) {
28074
+ port.start();
28075
+ return wrap(port);
28076
+ }
28077
+ };
28078
+ const throwTransferHandler = {
28079
+ canHandle: (value) => isObject(value) && throwMarker in value,
28080
+ serialize({ value }) {
28081
+ let serialized;
28082
+ if (value instanceof Error) {
28083
+ serialized = {
28084
+ isError: true,
28085
+ value: {
28086
+ message: value.message,
28087
+ name: value.name,
28088
+ stack: value.stack
28089
+ }
28090
+ };
28091
+ } else {
28092
+ serialized = { isError: false, value };
28093
+ }
28094
+ return [serialized, []];
28095
+ },
28096
+ deserialize(serialized) {
28097
+ if (serialized.isError) {
28098
+ throw Object.assign(new Error(serialized.value.message), serialized.value);
28099
+ }
28100
+ throw serialized.value;
28101
+ }
28102
+ };
28103
+ const transferHandlers = /* @__PURE__ */ new Map([
28104
+ ["proxy", proxyTransferHandler],
28105
+ ["throw", throwTransferHandler]
28106
+ ]);
28107
+ function isAllowedOrigin(allowedOrigins, origin) {
28108
+ for (const allowedOrigin of allowedOrigins) {
28109
+ if (origin === allowedOrigin || allowedOrigin === "*") {
28110
+ return true;
28111
+ }
28112
+ if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {
28113
+ return true;
28114
+ }
28115
+ }
28116
+ return false;
28117
+ }
28118
+ function expose(obj, ep = globalThis, allowedOrigins = ["*"]) {
28119
+ ep.addEventListener("message", function callback(ev) {
28120
+ if (!ev || !ev.data) {
28121
+ return;
28122
+ }
28123
+ if (!isAllowedOrigin(allowedOrigins, ev.origin)) {
28124
+ console.warn(\`Invalid origin '\${ev.origin}' for comlink proxy\`);
28125
+ return;
28126
+ }
28127
+ const { id, type, path } = Object.assign({ path: [] }, ev.data);
28128
+ const argumentList = (ev.data.argumentList || []).map(fromWireValue);
28129
+ let returnValue;
28130
+ try {
28131
+ const parent = path.slice(0, -1).reduce((obj2, prop) => obj2[prop], obj);
28132
+ const rawValue = path.reduce((obj2, prop) => obj2[prop], obj);
28133
+ switch (type) {
28134
+ case "GET":
28135
+ {
28136
+ returnValue = rawValue;
28137
+ }
28138
+ break;
28139
+ case "SET":
28140
+ {
28141
+ parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);
28142
+ returnValue = true;
28143
+ }
28144
+ break;
28145
+ case "APPLY":
28146
+ {
28147
+ returnValue = rawValue.apply(parent, argumentList);
28148
+ }
28149
+ break;
28150
+ case "CONSTRUCT":
28151
+ {
28152
+ const value = new rawValue(...argumentList);
28153
+ returnValue = proxy(value);
28154
+ }
28155
+ break;
28156
+ case "ENDPOINT":
28157
+ {
28158
+ const { port1, port2 } = new MessageChannel();
28159
+ expose(obj, port2);
28160
+ returnValue = transfer(port1, [port1]);
28161
+ }
28162
+ break;
28163
+ case "RELEASE":
28164
+ {
28165
+ returnValue = void 0;
28166
+ }
28167
+ break;
28168
+ default:
28169
+ return;
28170
+ }
28171
+ } catch (value) {
28172
+ returnValue = { value, [throwMarker]: 0 };
28173
+ }
28174
+ Promise.resolve(returnValue).catch((value) => {
28175
+ return { value, [throwMarker]: 0 };
28176
+ }).then((returnValue2) => {
28177
+ const [wireValue, transferables] = toWireValue(returnValue2);
28178
+ ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
28179
+ if (type === "RELEASE") {
28180
+ ep.removeEventListener("message", callback);
28181
+ closeEndPoint(ep);
28182
+ if (finalizer in obj && typeof obj[finalizer] === "function") {
28183
+ obj[finalizer]();
28184
+ }
28185
+ }
28186
+ }).catch((error) => {
28187
+ const [wireValue, transferables] = toWireValue({
28188
+ value: new TypeError("Unserializable return value"),
28189
+ [throwMarker]: 0
28190
+ });
28191
+ ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
28192
+ });
28193
+ });
28194
+ if (ep.start) {
28195
+ ep.start();
28196
+ }
28197
+ }
28198
+ function isMessagePort(endpoint) {
28199
+ return endpoint.constructor.name === "MessagePort";
28200
+ }
28201
+ function closeEndPoint(endpoint) {
28202
+ if (isMessagePort(endpoint))
28203
+ endpoint.close();
28204
+ }
28205
+ function wrap(ep, target) {
28206
+ const pendingListeners = /* @__PURE__ */ new Map();
28207
+ ep.addEventListener("message", function handleMessage(ev) {
28208
+ const { data } = ev;
28209
+ if (!data || !data.id) {
28210
+ return;
28211
+ }
28212
+ const resolver = pendingListeners.get(data.id);
28213
+ if (!resolver) {
28214
+ return;
28215
+ }
28216
+ try {
28217
+ resolver(data);
28218
+ } finally {
28219
+ pendingListeners.delete(data.id);
28220
+ }
28221
+ });
28222
+ return createProxy(ep, pendingListeners, [], target);
28223
+ }
28224
+ function throwIfProxyReleased(isReleased) {
28225
+ if (isReleased) {
28226
+ throw new Error("Proxy has been released and is not useable");
28227
+ }
28228
+ }
28229
+ function releaseEndpoint(ep) {
28230
+ return requestResponseMessage(ep, /* @__PURE__ */ new Map(), {
28231
+ type: "RELEASE"
28232
+ }).then(() => {
28233
+ closeEndPoint(ep);
28234
+ });
28235
+ }
28236
+ const proxyCounter = /* @__PURE__ */ new WeakMap();
28237
+ const proxyFinalizers = "FinalizationRegistry" in globalThis && new FinalizationRegistry((ep) => {
28238
+ const newCount = (proxyCounter.get(ep) || 0) - 1;
28239
+ proxyCounter.set(ep, newCount);
28240
+ if (newCount === 0) {
28241
+ releaseEndpoint(ep);
28242
+ }
28243
+ });
28244
+ function registerProxy(proxy2, ep) {
28245
+ const newCount = (proxyCounter.get(ep) || 0) + 1;
28246
+ proxyCounter.set(ep, newCount);
28247
+ if (proxyFinalizers) {
28248
+ proxyFinalizers.register(proxy2, ep, proxy2);
28249
+ }
28250
+ }
28251
+ function unregisterProxy(proxy2) {
28252
+ if (proxyFinalizers) {
28253
+ proxyFinalizers.unregister(proxy2);
28254
+ }
28255
+ }
28256
+ function createProxy(ep, pendingListeners, path = [], target = function() {
28257
+ }) {
28258
+ let isProxyReleased = false;
28259
+ const proxy2 = new Proxy(target, {
28260
+ get(_target, prop) {
28261
+ throwIfProxyReleased(isProxyReleased);
28262
+ if (prop === releaseProxy) {
28263
+ return () => {
28264
+ unregisterProxy(proxy2);
28265
+ releaseEndpoint(ep);
28266
+ pendingListeners.clear();
28267
+ isProxyReleased = true;
28268
+ };
28269
+ }
28270
+ if (prop === "then") {
28271
+ if (path.length === 0) {
28272
+ return { then: () => proxy2 };
28273
+ }
28274
+ const r = requestResponseMessage(ep, pendingListeners, {
28275
+ type: "GET",
28276
+ path: path.map((p) => p.toString())
28277
+ }).then(fromWireValue);
28278
+ return r.then.bind(r);
28279
+ }
28280
+ return createProxy(ep, pendingListeners, [...path, prop]);
28281
+ },
28282
+ set(_target, prop, rawValue) {
28283
+ throwIfProxyReleased(isProxyReleased);
28284
+ const [value, transferables] = toWireValue(rawValue);
28285
+ return requestResponseMessage(ep, pendingListeners, {
28286
+ type: "SET",
28287
+ path: [...path, prop].map((p) => p.toString()),
28288
+ value
28289
+ }, transferables).then(fromWireValue);
28290
+ },
28291
+ apply(_target, _thisArg, rawArgumentList) {
28292
+ throwIfProxyReleased(isProxyReleased);
28293
+ const last = path[path.length - 1];
28294
+ if (last === createEndpoint) {
28295
+ return requestResponseMessage(ep, pendingListeners, {
28296
+ type: "ENDPOINT"
28297
+ }).then(fromWireValue);
28298
+ }
28299
+ if (last === "bind") {
28300
+ return createProxy(ep, pendingListeners, path.slice(0, -1));
28301
+ }
28302
+ const [argumentList, transferables] = processArguments(rawArgumentList);
28303
+ return requestResponseMessage(ep, pendingListeners, {
28304
+ type: "APPLY",
28305
+ path: path.map((p) => p.toString()),
28306
+ argumentList
28307
+ }, transferables).then(fromWireValue);
28308
+ },
28309
+ construct(_target, rawArgumentList) {
28310
+ throwIfProxyReleased(isProxyReleased);
28311
+ const [argumentList, transferables] = processArguments(rawArgumentList);
28312
+ return requestResponseMessage(ep, pendingListeners, {
28313
+ type: "CONSTRUCT",
28314
+ path: path.map((p) => p.toString()),
28315
+ argumentList
28316
+ }, transferables).then(fromWireValue);
28317
+ }
28318
+ });
28319
+ registerProxy(proxy2, ep);
28320
+ return proxy2;
28321
+ }
28322
+ function myFlat(arr) {
28323
+ return Array.prototype.concat.apply([], arr);
28324
+ }
28325
+ function processArguments(argumentList) {
28326
+ const processed = argumentList.map(toWireValue);
28327
+ return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];
28328
+ }
28329
+ const transferCache = /* @__PURE__ */ new WeakMap();
28330
+ function transfer(obj, transfers) {
28331
+ transferCache.set(obj, transfers);
28332
+ return obj;
28333
+ }
28334
+ function proxy(obj) {
28335
+ return Object.assign(obj, { [proxyMarker]: true });
28336
+ }
28337
+ function windowEndpoint(w, context = globalThis, targetOrigin = "*") {
28338
+ return {
28339
+ postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),
28340
+ addEventListener: context.addEventListener.bind(context),
28341
+ removeEventListener: context.removeEventListener.bind(context)
28342
+ };
28343
+ }
28344
+ function toWireValue(value) {
28345
+ for (const [name, handler] of transferHandlers) {
28346
+ if (handler.canHandle(value)) {
28347
+ const [serializedValue, transferables] = handler.serialize(value);
28348
+ return [
28349
+ {
28350
+ type: "HANDLER",
28351
+ name,
28352
+ value: serializedValue
28353
+ },
28354
+ transferables
28355
+ ];
28356
+ }
28357
+ }
28358
+ return [
28359
+ {
28360
+ type: "RAW",
28361
+ value
28362
+ },
28363
+ transferCache.get(value) || []
28364
+ ];
28365
+ }
28366
+ function fromWireValue(value) {
28367
+ switch (value.type) {
28368
+ case "HANDLER":
28369
+ return transferHandlers.get(value.name).deserialize(value.value);
28370
+ case "RAW":
28371
+ return value.value;
28372
+ }
28373
+ }
28374
+ function requestResponseMessage(ep, pendingListeners, msg, transfers) {
28375
+ return new Promise((resolve) => {
28376
+ const id = generateUUID();
28377
+ pendingListeners.set(id, resolve);
28378
+ if (ep.start) {
28379
+ ep.start();
28380
+ }
28381
+ ep.postMessage(Object.assign({ id }, msg), transfers);
28382
+ });
28383
+ }
28384
+ function generateUUID() {
28385
+ return new Array(4).fill(0).map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)).join("-");
28386
+ }
28021
28387
  let editorControlHandle = null;
28022
28388
  let lastAugmentedProps = null;
28023
28389
  let currentFunctionProps = {};
@@ -28043,7 +28409,7 @@ const editorIframeJsSource = `(function() {
28043
28409
  }
28044
28410
  function releaseFunctionProxy(fn) {
28045
28411
  try {
28046
- fn?.[ComlinkEditor.releaseProxy]?.();
28412
+ fn?.[releaseProxy]?.();
28047
28413
  } catch (e) {
28048
28414
  console.warn(
28049
28415
  "iframe DoenetEditor: failed to release stale Comlink proxy",
@@ -28096,7 +28462,7 @@ const editorIframeJsSource = `(function() {
28096
28462
  }
28097
28463
  return false;
28098
28464
  }
28099
- ComlinkEditor.expose(
28465
+ expose(
28100
28466
  {
28101
28467
  renderEditorWithFunctionProps,
28102
28468
  updateEditorProps(updatedSerializableProps) {
@@ -28157,7 +28523,7 @@ const editorIframeJsSource = `(function() {
28157
28523
  editorControlHandle.updateRenderedView();
28158
28524
  }
28159
28525
  },
28160
- ComlinkEditor.windowEndpoint(globalThis.parent)
28526
+ windowEndpoint(globalThis.parent)
28161
28527
  );
28162
28528
  function renderEditorWithFunctionProps(...args) {
28163
28529
  setCurrentFunctionProps(functionPropArgsToMap(args));
@@ -28267,6 +28633,13 @@ function createIframeHead(standaloneUrl, cssUrl) {
28267
28633
  function createIframeBodyOpenTag(darkMode) {
28268
28634
  return `<body style="margin:0" ${BODY_BACKGROUND_ATTRIBUTE}="${bodyBackgroundMode(darkMode)}">`;
28269
28635
  }
28636
+ function createBootScript(boundConsts, compiledEntryPoint) {
28637
+ const declarations = Object.entries(boundConsts).map(([name2, value]) => `const ${name2} = ${JSON.stringify(value)};`).join("\n ");
28638
+ return `<script type="module">
28639
+ ${declarations}
28640
+ ${compiledEntryPoint}
28641
+ <\/script>`;
28642
+ }
28270
28643
  function createHtmlForDoenetViewer(id2, doenetML, doenetViewerProps, standaloneUrl, cssUrl, useSharedCoreWorker = false, windowed = false) {
28271
28644
  const doenetViewerPropsSpecified = Object.keys(doenetViewerProps);
28272
28645
  if (!doenetViewerPropsSpecified.includes("initializedCallback")) {
@@ -28276,18 +28649,16 @@ function createHtmlForDoenetViewer(id2, doenetML, doenetViewerProps, standaloneU
28276
28649
  <html style="overflow:hidden">
28277
28650
  ${createIframeHead(standaloneUrl, cssUrl)}
28278
28651
  ${createIframeBodyOpenTag(doenetViewerProps.darkMode)}
28279
- <script type="module">
28280
- const viewerId = "${id2}";
28281
- const doenetViewerProps = ${JSON.stringify(doenetViewerProps)};
28282
- const doenetViewerPropsSpecified = ${JSON.stringify(doenetViewerPropsSpecified)};
28283
- const doenetSharedCoreWorker = ${JSON.stringify(!!useSharedCoreWorker)};
28284
- const doenetWindowedViewer = ${JSON.stringify(!!windowed)};
28285
- import * as ComlinkViewer from "https://unpkg.com/comlink/dist/esm/comlink.mjs";
28286
-
28287
- // This source code has been compiled by vite and should be directly included.
28288
- // It assumes that viewerId, doenetViewerProps, doenetViewerPropsSpecified, and ComlinkViewer are defined in the global scope.
28289
- ${viewerIframeJsSource}
28290
- <\/script>
28652
+ ${createBootScript(
28653
+ {
28654
+ viewerId: id2,
28655
+ doenetViewerProps,
28656
+ doenetViewerPropsSpecified,
28657
+ doenetSharedCoreWorker: !!useSharedCoreWorker,
28658
+ doenetWindowedViewer: !!windowed
28659
+ },
28660
+ viewerIframeJsSource
28661
+ )}
28291
28662
  <div id="root" data-doenet-message-parent="true" data-doenet-send-resize-events="true">
28292
28663
  <div class="doenet-loading" style="text-align:center">
28293
28664
  <p><img src="https://www.doenet.org/Doenet_Logo_Frontpage.png"/></p>
@@ -28306,16 +28677,14 @@ function createHtmlForDoenetEditor(id2, doenetML, width, doenetEditorProps, stan
28306
28677
  <html style="overflow:hidden">
28307
28678
  ${createIframeHead(standaloneUrl, cssUrl)}
28308
28679
  ${createIframeBodyOpenTag(doenetEditorProps.darkMode)}
28309
- <script type="module">
28310
- const editorId = "${id2}";
28311
- const doenetEditorProps = ${JSON.stringify(augmentedProps)};
28312
- const doenetEditorPropsSpecified = ${JSON.stringify(doenetEditorPropsSpecified)};
28313
- import * as ComlinkEditor from "https://unpkg.com/comlink/dist/esm/comlink.mjs";
28314
-
28315
- // This source code has been compiled by vite and should be directly included.
28316
- // It assumes that editorId, doenetEditorProps, doenetEditorPropsSpecified, and ComlinkEditor are defined in the global scope.
28317
- ${editorIframeJsSource}
28318
- <\/script>
28680
+ ${createBootScript(
28681
+ {
28682
+ editorId: id2,
28683
+ doenetEditorProps: augmentedProps,
28684
+ doenetEditorPropsSpecified
28685
+ },
28686
+ editorIframeJsSource
28687
+ )}
28319
28688
  <div id="root" data-doenet-message-parent="true">
28320
28689
  <script type="text/doenetml">${doenetML}<\/script>
28321
28690
  </div>
@@ -66900,7 +67269,7 @@ function ExternalVirtualKeyboard({
66900
67269
  }
66901
67270
  );
66902
67271
  }
66903
- const version = "0.7.21-dev.406";
67272
+ const version = "0.7.21-dev.409";
66904
67273
  const latestDoenetmlVersion = version;
66905
67274
  function subscribeToPinnedTheme() {
66906
67275
  return () => {