{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openeik.org/schemas/0.4/drawings/svg-profile.json",
  "$comment": "OpenEik 0.2: folded by tools/fold-schemas.mjs from the proposal drawings, which 0.2 makes a rule (decision D5). Written by hand from the text, not generated.",
  "title": "OpenEik drawing SVG 0.1",
  "description": "The profile of an issued drawing's SVG (Part XIV, section 6) as data: the elements and attributes it allows, what it forbids, the forms of its values and references, and its limits. A validator and a host's parser share it. It is a schema that asserts nothing: its member x-eik-svg-profile holds the profile. Safety comes from this allowlist and a validator, not from sanitising: anything it does not allow is refused. The rules that read it are XIV.6.12, rules 1 to 27.",
  "x-eik-svg-profile": {
    "profile": "openeik-drawing-svg/0.1",
    "namespace": "http://www.w3.org/2000/svg",
    "root": "svg",
    "paperUnit": "mm",
    "limits": {
      "bytes": 67108864,
      "elements": 2000000,
      "depth": 32,
      "expanded": 1000000
    },
    "numbers": {
      "pattern": "^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]*[1-9])?$",
      "negativeZero": false,
      "decimals": 3,
      "viewportMatrixDecimals": 9,
      "note": "Fixed decimals: no exponent, no +, no leading zeros, no trailing zeros after the point, -0 written 0, an integer part always (0.5, never .5). At most three decimals, but for the numbers of a viewport group's transform (the derivation's matrix), at most nine. No unit but the root's mm. Lists of numbers are separated by white space, a comma, or both."
    },
    "elements": {
      "svg": {
        "attributes": [
          "xmlns",
          "width",
          "height",
          "viewBox"
        ],
        "root": true
      },
      "g": {
        "attributes": []
      },
      "defs": {
        "attributes": [],
        "hidden": true
      },
      "title": {
        "attributes": [
          "lang"
        ],
        "hidden": true
      },
      "desc": {
        "attributes": [
          "lang"
        ],
        "hidden": true
      },
      "metadata": {
        "attributes": [
          "id"
        ],
        "hidden": true
      },
      "path": {
        "attributes": [
          "d"
        ],
        "drawn": true
      },
      "rect": {
        "attributes": [
          "x",
          "y",
          "width",
          "height",
          "rx",
          "ry"
        ],
        "drawn": true
      },
      "circle": {
        "attributes": [
          "cx",
          "cy",
          "r"
        ],
        "drawn": true
      },
      "ellipse": {
        "attributes": [
          "cx",
          "cy",
          "rx",
          "ry"
        ],
        "drawn": true
      },
      "line": {
        "attributes": [
          "x1",
          "y1",
          "x2",
          "y2"
        ],
        "drawn": true
      },
      "polyline": {
        "attributes": [
          "points"
        ],
        "drawn": true
      },
      "polygon": {
        "attributes": [
          "points"
        ],
        "drawn": true
      },
      "text": {
        "attributes": [
          "x",
          "y",
          "dx",
          "dy",
          "xml:space"
        ],
        "drawn": true
      },
      "tspan": {
        "attributes": [
          "x",
          "y",
          "dx",
          "dy",
          "xml:space"
        ]
      },
      "use": {
        "attributes": [
          "href",
          "x",
          "y"
        ],
        "drawn": true
      },
      "image": {
        "attributes": [
          "href",
          "x",
          "y",
          "width",
          "height",
          "preserveAspectRatio"
        ],
        "drawn": true,
        "picture": true
      },
      "pattern": {
        "attributes": [
          "x",
          "y",
          "width",
          "height",
          "patternUnits",
          "patternContentUnits",
          "patternTransform",
          "viewBox"
        ],
        "hidden": true
      },
      "clipPath": {
        "attributes": [
          "clipPathUnits"
        ],
        "hidden": true
      },
      "marker": {
        "attributes": [
          "markerWidth",
          "markerHeight",
          "markerUnits",
          "refX",
          "refY",
          "orient",
          "viewBox"
        ],
        "hidden": true
      }
    },
    "anyElement": [
      "id",
      "class",
      "role",
      "aria-label",
      "transform",
      "clip-path",
      "opacity",
      "fill",
      "fill-opacity",
      "fill-rule",
      "stroke",
      "stroke-width",
      "stroke-opacity",
      "stroke-linecap",
      "stroke-linejoin",
      "stroke-miterlimit",
      "stroke-dasharray",
      "stroke-dashoffset",
      "marker-start",
      "marker-mid",
      "marker-end",
      "font-family",
      "font-size",
      "font-weight",
      "font-style",
      "text-anchor"
    ],
    "notOnRoot": [
      "transform"
    ],
    "modelLink": [
      "data-eik-layer",
      "data-eik-viewport",
      "data-eik-view",
      "data-eik-id",
      "data-eik-part",
      "data-eik-record",
      "data-eik-role",
      "data-eik-feature",
      "data-eik-hash",
      "data-eik-item",
      "data-eik-ref",
      "data-eik-origin",
      "data-eik-anchor",
      "data-eik-rev",
      "data-eik-change",
      "data-eik-code"
    ],
    "extensionData": {
      "form": "data-<prefix>-<name>",
      "note": "A data attribute under an extension prefix registered in the extension registry (Part I, 11.1) is allowed and ignored (outline, section D, item 10). The prefix must be registered: a validator that is not given the registered prefixes allows none. Every other data-* attribute is refused."
    },
    "forbiddenElements": {
      "script": "script runs",
      "foreignObject": "it carries HTML, which can run script",
      "style": "CSS: imports, fetches and rules a renderer applies differently",
      "symbol": "SVG 1.1 and SVG 2 size it differently: use a g and use",
      "filter": "a filter; engines draw them differently",
      "mask": "a mask",
      "linearGradient": "a gradient",
      "radialGradient": "a gradient",
      "meshgradient": "a gradient",
      "hatch": "an SVG 2 hatch, deferred by the SVG working group: use a pattern",
      "hatchpath": "an SVG 2 hatch, deferred by the SVG working group: use a pattern",
      "solidcolor": "an SVG 2 paint server",
      "animate": "animation",
      "animateMotion": "animation",
      "animateTransform": "animation",
      "animateColor": "animation",
      "set": "animation",
      "mpath": "animation",
      "discard": "animation",
      "a": "a link",
      "switch": "a switch: what is drawn depends on the renderer",
      "view": "a view of the file, a link target",
      "textPath": "text on a path, which engines lay out differently",
      "font": "an SVG font, which SVG 2 removed",
      "font-face": "an SVG font, which SVG 2 removed",
      "cursor": "interactivity",
      "iframe": "embedded content",
      "video": "embedded content",
      "audio": "embedded content",
      "canvas": "embedded content",
      "svg": "a nested svg: only the root is an svg"
    },
    "picture": {
      "element": "image",
      "layer": "derived",
      "viewKinds": [
        "3d"
      ],
      "role": "picture",
      "sheetLayer": "sheet",
      "sheetMediaTypes": [
        "image/png",
        "image/jpeg"
      ],
      "note": "By the steward's decision of 16 October 2026 (outline, section E, item 7), image is allowed as the picture of a 3D view: the one child of the derived layer of the viewport group of a view whose kind is one of viewKinds (the derivation's viewport gives it), its href data of image/png in base64 (references, image/href). By the steward's decision of 19 October 2026, image is also allowed anywhere in the sheet layer (sheetLayer): a title block's logo, or a picture placed on the sheet, its href data of one of sheetMediaTypes in base64. Either carries data-eik-role picture and no data-eik-id, data-eik-record or data-eik-item, never a file or a URL. An image anywhere else, a second picture of a 3D view and anything beside it in its layer are refused (rule 8). A picture names no element, which rule 19 does not ask of it, and counts towards the 64 MiB."
    },
    "forbiddenElementPrefixes": {
      "fe": "a filter primitive"
    },
    "forbiddenAttributes": {
      "on*": "an event handler: script",
      "style": "CSS",
      "vector-effect": "it ties widths to the screen, not the paper",
      "xlink:*": "SVG 1.1's links: the profile writes href",
      "xml:base": "a base for references outside the file",
      "display": "hides or shows by CSS",
      "visibility": "hides or shows by CSS",
      "pointer-events": "interactivity",
      "data-*": "a data attribute that is not one of the model link (6.8) nor under a registered extension prefix",
      "<prefix>:*": "an attribute in another namespace"
    },
    "values": {
      "xmlns": {
        "type": "namespace",
        "rule": 5
      },
      "svg/width": {
        "type": "paper",
        "rule": 6
      },
      "svg/height": {
        "type": "paper",
        "rule": 6
      },
      "viewBox": {
        "type": "viewBox"
      },
      "id": {
        "type": "nonEmpty"
      },
      "class": {
        "type": "text"
      },
      "role": {
        "type": "text"
      },
      "aria-label": {
        "type": "text"
      },
      "lang": {
        "type": "text"
      },
      "transform": {
        "type": "transform"
      },
      "patternTransform": {
        "type": "transform"
      },
      "clip-path": {
        "type": "url",
        "kinds": [
          "clipPath"
        ],
        "none": true
      },
      "marker-start": {
        "type": "url",
        "kinds": [
          "marker"
        ],
        "none": true
      },
      "marker-mid": {
        "type": "url",
        "kinds": [
          "marker"
        ],
        "none": true
      },
      "marker-end": {
        "type": "url",
        "kinds": [
          "marker"
        ],
        "none": true
      },
      "fill": {
        "type": "paint",
        "kinds": [
          "pattern"
        ]
      },
      "stroke": {
        "type": "paint",
        "kinds": [
          "pattern"
        ]
      },
      "opacity": {
        "type": "number",
        "min": 0,
        "max": 1
      },
      "fill-opacity": {
        "type": "number",
        "min": 0,
        "max": 1
      },
      "stroke-opacity": {
        "type": "number",
        "min": 0,
        "max": 1
      },
      "fill-rule": {
        "type": "enum",
        "values": [
          "nonzero",
          "evenodd"
        ]
      },
      "stroke-width": {
        "type": "number",
        "min": 0
      },
      "stroke-linecap": {
        "type": "enum",
        "values": [
          "butt",
          "round",
          "square"
        ]
      },
      "stroke-linejoin": {
        "type": "enum",
        "values": [
          "miter",
          "round",
          "bevel"
        ]
      },
      "stroke-miterlimit": {
        "type": "number",
        "min": 1
      },
      "stroke-dasharray": {
        "type": "dasharray"
      },
      "stroke-dashoffset": {
        "type": "number"
      },
      "font-family": {
        "type": "family",
        "rule": 16
      },
      "font-size": {
        "type": "number",
        "min": 0
      },
      "font-weight": {
        "type": "enum",
        "values": [
          "normal",
          "bold",
          "100",
          "200",
          "300",
          "400",
          "500",
          "600",
          "700",
          "800",
          "900"
        ]
      },
      "font-style": {
        "type": "enum",
        "values": [
          "normal",
          "italic",
          "oblique"
        ]
      },
      "text-anchor": {
        "type": "enum",
        "values": [
          "start",
          "middle",
          "end"
        ]
      },
      "x": {
        "type": "number"
      },
      "y": {
        "type": "number"
      },
      "width": {
        "type": "number",
        "min": 0
      },
      "height": {
        "type": "number",
        "min": 0
      },
      "rx": {
        "type": "number",
        "min": 0
      },
      "ry": {
        "type": "number",
        "min": 0
      },
      "cx": {
        "type": "number"
      },
      "cy": {
        "type": "number"
      },
      "r": {
        "type": "number",
        "min": 0
      },
      "x1": {
        "type": "number"
      },
      "y1": {
        "type": "number"
      },
      "x2": {
        "type": "number"
      },
      "y2": {
        "type": "number"
      },
      "points": {
        "type": "numbers",
        "even": true,
        "least": 2
      },
      "d": {
        "type": "path"
      },
      "text/x": {
        "type": "numbers",
        "least": 1
      },
      "text/y": {
        "type": "numbers",
        "least": 1
      },
      "text/dx": {
        "type": "numbers",
        "least": 1
      },
      "text/dy": {
        "type": "numbers",
        "least": 1
      },
      "tspan/x": {
        "type": "numbers",
        "least": 1
      },
      "tspan/y": {
        "type": "numbers",
        "least": 1
      },
      "tspan/dx": {
        "type": "numbers",
        "least": 1
      },
      "tspan/dy": {
        "type": "numbers",
        "least": 1
      },
      "xml:space": {
        "type": "enum",
        "values": [
          "preserve"
        ]
      },
      "use/href": {
        "type": "reference",
        "rule": 12
      },
      "image/href": {
        "type": "reference",
        "rule": 12
      },
      "patternUnits": {
        "type": "enum",
        "values": [
          "userSpaceOnUse",
          "objectBoundingBox"
        ]
      },
      "patternContentUnits": {
        "type": "enum",
        "values": [
          "userSpaceOnUse",
          "objectBoundingBox"
        ]
      },
      "clipPathUnits": {
        "type": "enum",
        "values": [
          "userSpaceOnUse",
          "objectBoundingBox"
        ]
      },
      "markerUnits": {
        "type": "enum",
        "values": [
          "strokeWidth",
          "userSpaceOnUse"
        ]
      },
      "markerWidth": {
        "type": "number",
        "min": 0
      },
      "markerHeight": {
        "type": "number",
        "min": 0
      },
      "refX": {
        "type": "number"
      },
      "refY": {
        "type": "number"
      },
      "orient": {
        "type": "orient"
      },
      "preserveAspectRatio": {
        "type": "enum",
        "values": [
          "none",
          "xMidYMid meet",
          "xMidYMid slice"
        ]
      },
      "data-eik-layer": {
        "type": "enum",
        "values": [
          "sheet",
          "derived",
          "drafted",
          "agent",
          "revisions"
        ],
        "rule": 17
      },
      "data-eik-viewport": {
        "type": "nonEmpty",
        "rule": 24
      },
      "data-eik-view": {
        "type": "nonEmpty",
        "rule": 24
      },
      "data-eik-id": {
        "type": "ids",
        "ascending": true
      },
      "data-eik-part": {
        "type": "pattern",
        "pattern": "^(?:0|[1-9][0-9]*)$",
        "rule": 20
      },
      "data-eik-record": {
        "type": "pattern",
        "pattern": "^[a-z][A-Za-z0-9]*/[^/]+$"
      },
      "data-eik-role": {
        "type": "enum",
        "values": [
          "cut",
          "poche",
          "projection",
          "hidden",
          "overhead",
          "beyond",
          "hatch",
          "symbol",
          "text",
          "picture"
        ]
      },
      "data-eik-feature": {
        "type": "pattern",
        "pattern": "^(?:layer|face|edge):\\S+$"
      },
      "data-eik-hash": {
        "type": "pattern",
        "pattern": "^[0-9a-f]{64}$",
        "rule": 22
      },
      "data-eik-item": {
        "type": "nonEmpty",
        "rule": 23
      },
      "data-eik-ref": {
        "type": "ids"
      },
      "data-eik-origin": {
        "type": "enum",
        "values": [
          "derived",
          "person",
          "agent"
        ],
        "rule": 23
      },
      "data-eik-anchor": {
        "type": "enum",
        "values": [
          "attached",
          "moved",
          "elementOnly",
          "orphaned"
        ],
        "rule": 27
      },
      "data-eik-rev": {
        "type": "text"
      },
      "data-eik-change": {
        "type": "ids"
      },
      "data-eik-code": {
        "type": "pattern",
        "pattern": "^[0-9a-f]{64}$"
      }
    },
    "references": {
      "use/href": {
        "form": "fragment",
        "kinds": [
          "g",
          "path",
          "rect",
          "circle",
          "ellipse",
          "line",
          "polyline",
          "polygon",
          "text",
          "use"
        ],
        "note": "href is only on use, as #<id> of an element of these kinds; nothing outside the file. A reference of the form data names data of one of mediaTypes in base64 instead, which no element of profile 0.1 takes."
      },
      "image/href": {
        "form": "data",
        "mediaTypes": [
          "image/png"
        ],
        "signatures": {
          "image/png": "89504e470d0a1a0a",
          "image/jpeg": "ffd8ff"
        },
        "note": "a picture (picture): the picture of a 3D view data:image/png;base64, and one of the sheet layer also data:image/jpeg;base64 (picture, sheetMediaTypes), with valid base64 of a PNG or a JPEG (its first bytes the format's signature, in hexadecimal here); never a file, a URL or another media type"
      },
      "url()": {
        "form": "url",
        "note": "url(#<id>) only in clip-path, marker-start, marker-mid, marker-end, fill and stroke, each naming an element of the kinds its entry in values gives; nothing outside the file"
      }
    },
    "transforms": [
      "matrix",
      "translate",
      "scale",
      "rotate"
    ],
    "colours": {
      "keywords": [
        "none"
      ],
      "pattern": "^#[0-9a-f]{6}$",
      "note": "none, #rrggbb in lower case, or url(#<id>) of a pattern"
    },
    "layers": {
      "root": [
        "title",
        "desc",
        "metadata",
        "defs",
        "sheet",
        "viewport",
        "sheet",
        "revisions"
      ],
      "once": [
        "title",
        "desc",
        "metadata",
        "defs",
        "sheet",
        "revisions"
      ],
      "required": [
        "title",
        "metadata",
        "sheet"
      ],
      "note": "root lists the root's children in their order (6.7). A kind listed twice stands at either of its places, and a kind of once occurs at most once: so the sheet layer comes before the viewport groups, or after them and before the revisions layer, by the steward's decision of 17 October 2026, and never twice. viewport lists a viewport group's layers in their order. Where the derivation's generator.order is paint, an element may have several groups in a derived layer, its parts, each with data-eik-part numbered from 0 in the order of the file (6.7; 6.12, rule 20).",
      "viewport": [
        "derived",
        "drafted",
        "agent"
      ],
      "origins": {
        "derived": "derived",
        "drafted": "person",
        "agent": "agent"
      },
      "anchors": [
        "attached",
        "moved",
        "elementOnly",
        "orphaned"
      ]
    },
    "derivation": {
      "metadataId": "openeik-derivation",
      "format": "openeik-drawing-derivation/0.1",
      "orders": [
        "id",
        "paint"
      ],
      "viewKinds": [
        "plan",
        "section",
        "elevation",
        "3d",
        "drafting"
      ],
      "unscaled": [
        "3d"
      ]
    }
  }
}
