@monimesl/dot-simulator 0.1.0-alpha.4 → 0.1.0-alpha.5

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/README.md CHANGED
@@ -18,3 +18,8 @@ simulator.error('view.dml:3:7: ...'); // show a build error over the device
18
18
  (`NavigationStack` from core) and announce it with `stack`.
19
19
  - `src/client/`: the browser scripts. `simulator.js` is the page, and `webview-bridge.js` and
20
20
  `service-bridge.js` install `__hostTransport` in each layer.
21
+
22
+ The simulator defaults to **Touch** input mode. It activates the mini-app's own
23
+ `@media (pointer: coarse)` rules inside the phone frame so touch targets can be reviewed from a
24
+ desktop browser. Choose **Browser** to use the browser's real pointer capabilities instead. Input
25
+ mode is independent from the iOS/Android platform context.
@@ -278,6 +278,7 @@
278
278
  });
279
279
  const List = defineComponent({
280
280
  name: "List",
281
+ props: { size: ["sm", "md"] },
281
282
  children: "elements"
282
283
  });
283
284
  const ListItem = defineComponent({
@@ -296,7 +297,8 @@
296
297
  name: "Sheet",
297
298
  props: {
298
299
  open: "boolean",
299
- title: "string"
300
+ title: "string",
301
+ showCloseIcon: "boolean"
300
302
  },
301
303
  events: ["close"],
302
304
  children: "elements"
@@ -1 +1 @@
1
- {"version":3,"file":"service-bridge.js","names":[],"sources":["../../../../core/dist/index.js","../../src/paths.ts","../../src/client/hot-reload.ts","../../src/client/wire.ts","../../src/client/service-bridge.ts"],"sourcesContent":["//#region src/view/component.ts\nfunction defineComponent(manifest) {\n\treturn {\n\t\tprops: {},\n\t\tevents: [],\n\t\t...manifest\n\t};\n}\nfunction eventProp(event) {\n\treturn `on${event.charAt(0).toUpperCase()}${event.slice(1)}`;\n}\nfunction isEventProp(name) {\n\tconst letterAfterOn = name.charAt(2);\n\treturn name.startsWith(\"on\") && letterAfterOn >= \"A\" && letterAfterOn <= \"Z\";\n}\nfunction eventName(prop) {\n\tconst name = prop.slice(2);\n\treturn name.charAt(0).toLowerCase() + name.slice(1);\n}\nfunction componentRegistry(manifests) {\n\tconst registry = {};\n\tfor (const manifest of manifests) {\n\t\tif (manifest.name in registry) throw new Error(`Component <${manifest.name}> is defined twice`);\n\t\tregistry[manifest.name] = manifest;\n\t}\n\treturn registry;\n}\n//#endregion\n//#region src/view/values.ts\nfunction toText(value) {\n\tswitch (typeof value) {\n\t\tcase \"string\": return value;\n\t\tcase \"number\":\n\t\tcase \"boolean\":\n\t\tcase \"bigint\": return String(value);\n\t\tcase \"object\": return value === null ? \"\" : JSON.stringify(value);\n\t\tdefault: return \"\";\n\t}\n}\nfunction toList(value) {\n\tif (Array.isArray(value)) return value;\n\tif (typeof value === \"object\" && value !== null && Symbol.iterator in value) return Array.from(value);\n\treturn [];\n}\n//#endregion\n//#region src/source/location.ts\nfunction createLocator(source) {\n\tconst lineStarts = [0];\n\tfor (let index = 0; index < source.length; index++) if (source[index] === \"\\n\") lineStarts.push(index + 1);\n\treturn (offset) => {\n\t\tlet low = 0;\n\t\tlet high = lineStarts.length - 1;\n\t\twhile (low < high) {\n\t\t\tconst middle = Math.floor((low + high + 1) / 2);\n\t\t\tif (lineStarts[middle] <= offset) low = middle;\n\t\t\telse high = middle - 1;\n\t\t}\n\t\treturn {\n\t\t\tline: low + 1,\n\t\t\tcolumn: offset - lineStarts[low] + 1,\n\t\t\toffset\n\t\t};\n\t};\n}\nfunction locationAt(source, offset) {\n\treturn createLocator(source)(offset);\n}\nfunction locatedMessage(message, file, location) {\n\tconst where = [\n\t\tfile,\n\t\tlocation?.line,\n\t\tlocation?.column\n\t].filter((part) => part !== void 0).join(\":\");\n\treturn where ? `${where}: ${message}` : message;\n}\n//#endregion\n//#region src/source/error.ts\nvar SourceError = class extends Error {\n\treason;\n\tfile;\n\tloc;\n\tconstructor(reason, file, location) {\n\t\tsuper(locatedMessage(reason, file, location));\n\t\tthis.reason = reason;\n\t\tthis.file = file;\n\t\tthis.loc = location;\n\t}\n};\n//#endregion\n//#region src/view/components/amount-input.ts\nconst AmountInput = defineComponent({\n\tname: \"AmountInput\",\n\tprops: {\n\t\tvalue: \"number\",\n\t\tcurrency: \"string\",\n\t\tdecimals: \"number\",\n\t\tlabel: \"string\",\n\t\tplaceholder: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/button.ts\nconst Button = defineComponent({\n\tname: \"Button\",\n\tprops: {\n\t\tvariant: [\"primary\", \"secondary\"],\n\t\tdisabled: \"boolean\",\n\t\tloading: \"boolean\"\n\t},\n\tevents: [\"click\"],\n\tchildren: \"text\"\n});\n//#endregion\n//#region src/view/components/options.ts\nconst SIZES = [\n\t\"small\",\n\t\"medium\",\n\t\"large\"\n];\nconst SPACES = [\n\t\"none\",\n\t\"small\",\n\t\"medium\",\n\t\"large\"\n];\nconst TONES = [\n\t\"default\",\n\t\"muted\",\n\t\"info\",\n\t\"success\",\n\t\"warning\",\n\t\"danger\"\n];\nconst STATUS_TONES = [\n\t\"default\",\n\t\"info\",\n\t\"success\",\n\t\"warning\",\n\t\"danger\"\n];\nconst ICON_NAMES = [\n\t\"arrow-down\",\n\t\"arrow-left\",\n\t\"arrow-right\",\n\t\"arrow-up\",\n\t\"bank\",\n\t\"bell\",\n\t\"bolt\",\n\t\"calendar\",\n\t\"card\",\n\t\"cart\",\n\t\"cash\",\n\t\"check\",\n\t\"chevron-down\",\n\t\"chevron-left\",\n\t\"chevron-right\",\n\t\"chevron-up\",\n\t\"clock\",\n\t\"close\",\n\t\"copy\",\n\t\"download\",\n\t\"edit\",\n\t\"error\",\n\t\"eye\",\n\t\"eye-off\",\n\t\"file\",\n\t\"gift\",\n\t\"grid\",\n\t\"heart\",\n\t\"help\",\n\t\"history\",\n\t\"home\",\n\t\"image\",\n\t\"info\",\n\t\"list\",\n\t\"location\",\n\t\"lock\",\n\t\"logout\",\n\t\"mail\",\n\t\"minus\",\n\t\"mobile\",\n\t\"more\",\n\t\"phone\",\n\t\"plus\",\n\t\"qr-code\",\n\t\"receipt\",\n\t\"refresh\",\n\t\"search\",\n\t\"send\",\n\t\"settings\",\n\t\"share\",\n\t\"star\",\n\t\"success\",\n\t\"trash\",\n\t\"upload\",\n\t\"user\",\n\t\"users\",\n\t\"wallet\",\n\t\"warning\",\n\t\"water\",\n\t\"wifi\"\n];\n//#endregion\n//#region src/view/components/carousel.ts\nconst Carousel = defineComponent({\n\tname: \"Carousel\",\n\tprops: {\n\t\tautoplay: \"boolean\",\n\t\tinterval: \"number\",\n\t\tloop: \"boolean\",\n\t\tindicator: [\"dots\", \"none\"],\n\t\tgap: SPACES,\n\t\teffect: [\"slide\", \"scale\"],\n\t\tindex: \"number\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/chip.ts\nconst Chip = defineComponent({\n\tname: \"Chip\",\n\tprops: {\n\t\tlabel: \"string\",\n\t\ticon: ICON_NAMES,\n\t\tselected: \"boolean\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"tap\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/code-input.ts\nconst CodeInput = defineComponent({\n\tname: \"CodeInput\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlength: \"number\",\n\t\tlabel: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\tsecure: \"boolean\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\", \"complete\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/divider.ts\nconst Divider = defineComponent({\n\tname: \"Divider\",\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/empty-state.ts\nconst EmptyState = defineComponent({\n\tname: \"EmptyState\",\n\tprops: {\n\t\ticon: ICON_NAMES,\n\t\ttitle: \"string\",\n\t\ttext: \"string\"\n\t},\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/feedback.ts\nconst Spinner = defineComponent({\n\tname: \"Spinner\",\n\tprops: { size: SIZES },\n\tchildren: \"none\"\n});\nconst ProgressBar = defineComponent({\n\tname: \"ProgressBar\",\n\tprops: { value: \"number\" },\n\tchildren: \"none\"\n});\nconst Notice = defineComponent({\n\tname: \"Notice\",\n\tprops: {\n\t\ttone: STATUS_TONES,\n\t\ttitle: \"string\"\n\t},\n\tchildren: \"text\"\n});\nconst Badge = defineComponent({\n\tname: \"Badge\",\n\tprops: { tone: STATUS_TONES },\n\tchildren: \"text\"\n});\n//#endregion\n//#region src/view/components/footer.ts\nconst Footer = defineComponent({\n\tname: \"Footer\",\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/grid.ts\nconst Grid = defineComponent({\n\tname: \"Grid\",\n\tprops: {\n\t\tcolumns: \"number\",\n\t\tgap: SPACES\n\t},\n\tchildren: \"elements\"\n});\nconst GridItem = defineComponent({\n\tname: \"GridItem\",\n\tprops: {\n\t\tlabel: \"string\",\n\t\ticon: ICON_NAMES,\n\t\timage: \"string\",\n\t\tbadge: \"string\"\n\t},\n\tevents: [\"tap\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/icon.ts\nconst Icon = defineComponent({\n\tname: \"Icon\",\n\tprops: {\n\t\tname: ICON_NAMES,\n\t\tsize: SIZES,\n\t\ttone: TONES\n\t},\n\tchildren: \"none\",\n\tinline: true\n});\n//#endregion\n//#region src/view/components/image.ts\nconst Image = defineComponent({\n\tname: \"Image\",\n\tprops: {\n\t\tsrc: \"string\",\n\t\talt: \"string\",\n\t\twidth: \"number\",\n\t\theight: \"number\",\n\t\tfit: [\"cover\", \"contain\"],\n\t\tshape: [\n\t\t\t\"rounded\",\n\t\t\t\"square\",\n\t\t\t\"circle\"\n\t\t]\n\t},\n\tevents: [\"load\", \"error\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/input.ts\nconst Input = defineComponent({\n\tname: \"Input\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tplaceholder: \"string\",\n\t\tlabel: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\tprefix: \"string\",\n\t\tsuffix: \"string\",\n\t\ttype: [\n\t\t\t\"text\",\n\t\t\t\"number\",\n\t\t\t\"email\",\n\t\t\t\"phone\",\n\t\t\t\"password\"\n\t\t],\n\t\tmaxLength: \"number\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\", \"submit\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/list.ts\nconst List = defineComponent({\n\tname: \"List\",\n\tchildren: \"elements\"\n});\nconst ListItem = defineComponent({\n\tname: \"ListItem\",\n\tprops: {\n\t\ttitle: \"string\",\n\t\tsubtitle: \"string\",\n\t\tvalue: \"string\",\n\t\ticon: ICON_NAMES,\n\t\timage: \"string\"\n\t},\n\tevents: [\"tap\"],\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/overlays.ts\nconst Sheet = defineComponent({\n\tname: \"Sheet\",\n\tprops: {\n\t\topen: \"boolean\",\n\t\ttitle: \"string\"\n\t},\n\tevents: [\"close\"],\n\tchildren: \"elements\"\n});\nconst Toast = defineComponent({\n\tname: \"Toast\",\n\tprops: {\n\t\tmessage: \"string\",\n\t\ttone: STATUS_TONES,\n\t\tduration: \"number\"\n\t},\n\tevents: [\"hide\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/qr-code.ts\nconst QRCode = defineComponent({\n\tname: \"QRCode\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tsize: \"number\",\n\t\tlabel: \"string\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/select.ts\nconst Select = defineComponent({\n\tname: \"Select\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\",\n\t\tplaceholder: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"elements\"\n});\nconst Option = defineComponent({\n\tname: \"Option\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/skeleton.ts\nconst Skeleton = defineComponent({\n\tname: \"Skeleton\",\n\tprops: {\n\t\tshape: [\n\t\t\t\"text\",\n\t\t\t\"circle\",\n\t\t\t\"box\"\n\t\t],\n\t\tlines: \"number\",\n\t\theight: \"number\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/tabs.ts\nconst Tabs = defineComponent({\n\tname: \"Tabs\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tvariant: [\"underline\", \"segmented\"]\n\t},\n\tevents: [\"change\"],\n\tchildren: \"elements\"\n});\nconst Tab = defineComponent({\n\tname: \"Tab\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\",\n\t\tbadge: \"number\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/text.ts\nconst Text = defineComponent({\n\tname: \"Text\",\n\tprops: {\n\t\tvariant: [\n\t\t\t\"title\",\n\t\t\t\"body\",\n\t\t\t\"caption\"\n\t\t],\n\t\ttone: TONES,\n\t\tweight: [\n\t\t\t\"regular\",\n\t\t\t\"medium\",\n\t\t\t\"bold\"\n\t\t],\n\t\talign: [\n\t\t\t\"start\",\n\t\t\t\"center\",\n\t\t\t\"end\"\n\t\t],\n\t\tmaxLines: \"number\"\n\t},\n\tchildren: \"text\",\n\tinline: true\n});\n//#endregion\n//#region src/view/components/text-area.ts\nconst TextArea = defineComponent({\n\tname: \"TextArea\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tplaceholder: \"string\",\n\t\tlabel: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\trows: \"number\",\n\t\tmaxLength: \"number\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/toggles.ts\nconst Switch = defineComponent({\n\tname: \"Switch\",\n\tprops: {\n\t\tchecked: \"boolean\",\n\t\tlabel: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"none\"\n});\nconst Checkbox = defineComponent({\n\tname: \"Checkbox\",\n\tprops: {\n\t\tchecked: \"boolean\",\n\t\tlabel: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"none\"\n});\nconst RadioGroup = defineComponent({\n\tname: \"RadioGroup\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"elements\"\n});\nconst Radio = defineComponent({\n\tname: \"Radio\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/view.ts\nconst View = defineComponent({\n\tname: \"View\",\n\tprops: {\n\t\tgap: SPACES,\n\t\tdirection: [\"column\", \"row\"],\n\t\talign: [\n\t\t\t\"stretch\",\n\t\t\t\"start\",\n\t\t\t\"center\",\n\t\t\t\"end\"\n\t\t],\n\t\tjustify: [\n\t\t\t\"start\",\n\t\t\t\"center\",\n\t\t\t\"end\",\n\t\t\t\"between\"\n\t\t],\n\t\twrap: \"boolean\",\n\t\tgrow: \"boolean\",\n\t\tpadding: SPACES,\n\t\tpaddingTop: SPACES,\n\t\tpaddingStart: SPACES,\n\t\tpaddingEnd: SPACES,\n\t\tpaddingBottom: SPACES,\n\t\tvariant: [\"plain\", \"card\"]\n\t},\n\tevents: [\"tap\"],\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/index.ts\nconst builtinComponents = {\n\tAmountInput,\n\tBadge,\n\tButton,\n\tCarousel,\n\tCheckbox,\n\tChip,\n\tCodeInput,\n\tDivider,\n\tEmptyState,\n\tFooter,\n\tGrid,\n\tGridItem,\n\tIcon,\n\tImage,\n\tInput,\n\tList,\n\tListItem,\n\tNotice,\n\tOption,\n\tProgressBar,\n\tQRCode,\n\tRadio,\n\tRadioGroup,\n\tSelect,\n\tSheet,\n\tSkeleton,\n\tSpinner,\n\tSwitch,\n\tTab,\n\tTabs,\n\tText,\n\tTextArea,\n\tToast,\n\tView\n};\nconst builtinRegistry = componentRegistry(Object.values(builtinComponents));\n//#endregion\n//#region src/event/emitter.ts\nvar EventEmitter = class {\n\t#listeners = /* @__PURE__ */ new Map();\n\ton(name, listener) {\n\t\tconst listeners = this.#listeners.get(name) ?? /* @__PURE__ */ new Set();\n\t\tthis.#listeners.set(name, listeners);\n\t\tlisteners.add(listener);\n\t\treturn () => listeners.delete(listener);\n\t}\n\temit(name, ...args) {\n\t\tthis.#listeners.get(name)?.forEach((listener) => listener(...args));\n\t}\n};\n//#endregion\n//#region src/event/core.ts\nfunction createEvent(type, detail = {}, data = {}) {\n\treturn {\n\t\ttype,\n\t\tdetail,\n\t\tdata\n\t};\n}\n//#endregion\n//#region src/host/host.ts\nfunction hostTransport() {\n\tconst transport = globalThis.__hostTransport;\n\tif (!transport) throw new Error(\"No Dot host found: expected `globalThis.__hostTransport` to be available at runtime. Dots run inside the Dash App, or a simulator via `dotctl dev`.\");\n\treturn transport;\n}\n//#endregion\n//#region src/host/context.ts\nconst DEFAULT_SYSTEM_CONTEXT = {\n\tscheme: \"light\",\n\tappState: \"active\"\n};\n//#endregion\n//#region src/host/calls.ts\nvar HostError = class extends Error {\n\tname = \"HostError\";\n\tcode;\n\tconstructor(code, message) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n};\nlet connectedCaller = null;\nfunction connectHost(caller) {\n\tconnectedCaller = caller;\n}\nfunction callHost(method, params, options = {}) {\n\tif (!connectedCaller) {\n\t\tconst error = new HostError(\"unsupported\", `No host to run \"${method}\": host calls run in the service`);\n\t\treturn createHostRequest(Promise.reject(error));\n\t}\n\treturn connectedCaller(method, params, options);\n}\nfunction createHostRequest(promise, cancel = () => {}) {\n\tconst request = promise;\n\trequest.cancel = cancel;\n\treturn request;\n}\n//#endregion\n//#region src/host/permissions.ts\nconst PERMISSIONS = [\"account\"];\nfunction isPermission(value) {\n\treturn PERMISSIONS.includes(value);\n}\n//#endregion\n//#region src/host/files.ts\nconst DOT_FILE_PATH_MAX_LENGTH = 512;\nconst MAX_NAME_LENGTH = 255;\nfunction dotFilePathProblem(path, { allowRoot = false } = {}) {\n\tif (path === \"\") return allowRoot ? null : \"A path is needed, such as \\\"receipts/42.pdf\\\"\";\n\tif (path.length > 512) return `\"${path.slice(0, 40)}…\" is longer than 512 characters`;\n\tif (path.startsWith(\"/\")) return `\"${path}\" starts with \"/\": paths are relative to the dot's storage, such as \"receipts/42.pdf\"`;\n\tif ([...path].some((char) => char === \"\\\\\" || char.charCodeAt(0) < 32)) return `\"${path}\" has a backslash or a control character`;\n\tfor (const name of path.split(\"/\")) {\n\t\tif (name === \"\" || name === \".\" || name === \"..\") return `\"${path}\" has an empty, \".\" or \"..\" part: write each folder once, such as \"receipts/42.pdf\"`;\n\t\tif (name.length > MAX_NAME_LENGTH) return `\"${path}\" has a name longer than ${MAX_NAME_LENGTH} characters`;\n\t}\n\treturn null;\n}\n//#endregion\n//#region src/host/network.ts\nconst LABEL = \"[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\";\nconst NETWORK_HOST_PATTERN = new RegExp(`^(?:\\\\*\\\\.${LABEL}(?:\\\\.${LABEL})+|${LABEL}(?:\\\\.${LABEL})*)$`);\nconst NETWORK_HOST_MAX_LENGTH = 253;\nfunction isNetworkHost(value) {\n\treturn value.length <= 253 && NETWORK_HOST_PATTERN.test(value);\n}\nfunction allowsHost(hosts, host) {\n\tconst name = host.toLowerCase().replace(/\\.$/, \"\");\n\treturn hosts.some((pattern) => pattern.startsWith(\"*.\") ? name.endsWith(pattern.slice(1)) : name === pattern);\n}\n//#endregion\n//#region src/version/semantic-version.ts\nconst SEMVER_PATTERN = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\nfunction isSemanticVersion(value) {\n\treturn typeof value === \"string\" && SEMVER_PATTERN.test(value);\n}\nfunction majorVersion(version) {\n\treturn parseVersion(version).major;\n}\nfunction isVersionAtLeast(version, minimum) {\n\treturn compareVersions(version, minimum) >= 0;\n}\nfunction compareVersions(left, right) {\n\tconst leftVersion = parseVersion(left);\n\tconst rightVersion = parseVersion(right);\n\tconst differences = [\n\t\tleftVersion.major - rightVersion.major,\n\t\tleftVersion.minor - rightVersion.minor,\n\t\tleftVersion.patch - rightVersion.patch\n\t];\n\tfor (const difference of differences) if (difference !== 0) return difference;\n\treturn comparePrereleases(leftVersion.prerelease, rightVersion.prerelease);\n}\nfunction parseVersion(version) {\n\tconst match = SEMVER_PATTERN.exec(version);\n\tif (!match) throw new Error(`\"${version}\" is not a semantic version`);\n\tconst [, major, minor, patch, prerelease] = match;\n\treturn {\n\t\tmajor: Number(major),\n\t\tminor: Number(minor),\n\t\tpatch: Number(patch),\n\t\tprerelease: prerelease === void 0 ? [] : prerelease.split(\".\")\n\t};\n}\nfunction comparePrereleases(left, right) {\n\tif (left.length === 0 || right.length === 0) return right.length - left.length;\n\tconst shared = Math.min(left.length, right.length);\n\tfor (let index = 0; index < shared; index++) {\n\t\tconst order = compareIdentifiers(left[index], right[index]);\n\t\tif (order !== 0) return order;\n\t}\n\treturn left.length - right.length;\n}\nfunction compareIdentifiers(left, right) {\n\tconst leftIsNumber = /^\\d+$/.test(left);\n\tconst rightIsNumber = /^\\d+$/.test(right);\n\tif (leftIsNumber && rightIsNumber) return Number(left) - Number(right);\n\tif (leftIsNumber) return -1;\n\tif (rightIsNumber) return 1;\n\tif (left < right) return -1;\n\tif (left > right) return 1;\n\treturn 0;\n}\n//#endregion\n//#region src/host/react.ts\nconst REACT_HOST_PATH = \"/__dot/react/\";\nconst REACT_HOST_MODULES = {\n\treact: \"react.js\",\n\t\"react/jsx-runtime\": \"react-jsx-runtime.js\",\n\t\"react-dom/client\": \"react-dom-client.js\"\n};\nfunction reactHostUrl(dotReactVersion, file) {\n\treturn `${REACT_HOST_PATH}${majorVersion(dotReactVersion)}/${file}`;\n}\nfunction isReactCompatible(hostVersion, dotVersion) {\n\treturn majorVersion(hostVersion) === majorVersion(dotVersion) && isVersionAtLeast(hostVersion, dotVersion);\n}\nfunction newestReactOfMajor(versions, major) {\n\treturn versions.filter((version) => majorVersion(version) === major).sort(compareVersions).at(-1);\n}\n//#endregion\n//#region src/protocol/transport.ts\nfunction createAdaptorTransport(adapter) {\n\treturn {\n\t\tpost: (message) => adapter.postMessage(message),\n\t\tlisten(listener) {\n\t\t\tconst onMessage = (event) => listener(event.data);\n\t\t\tadapter.addEventListener(\"message\", onMessage);\n\t\t\treturn () => adapter.removeEventListener(\"message\", onMessage);\n\t\t}\n\t};\n}\nfunction createTransportPair() {\n\tconst firstListeners = /* @__PURE__ */ new Set();\n\tconst secondListeners = /* @__PURE__ */ new Set();\n\tconst createSide = (ownListeners, otherListeners) => ({\n\t\tpost: (message) => {\n\t\t\tconst copy = JSON.parse(JSON.stringify(message));\n\t\t\totherListeners.forEach((listener) => listener(copy));\n\t\t},\n\t\tlisten(listener) {\n\t\t\townListeners.add(listener);\n\t\t\treturn () => ownListeners.delete(listener);\n\t\t}\n\t});\n\treturn [createSide(firstListeners, secondListeners), createSide(secondListeners, firstListeners)];\n}\nconst PAGE_HOOKS = Object.keys({\n\tonLoad: true,\n\tonShow: true,\n\tonHide: true,\n\tonUnload: true\n});\n//#endregion\n//#region src/page/navigation.ts\nconst MAX_STACK_DEPTH = 8;\nconst PAGE_ID = /^[A-Za-z0-9_-]+(?:\\/[A-Za-z0-9_-]+)*$/;\nfunction isPageId(value) {\n\treturn PAGE_ID.test(value);\n}\nvar NavigationStack = class {\n\tlimit;\n\t#pages = [];\n\t#nextInstanceId = 1;\n\tconstructor(limit = 8) {\n\t\tthis.limit = limit;\n\t}\n\tget pages() {\n\t\treturn this.#pages;\n\t}\n\tget top() {\n\t\treturn this.#pages.at(-1);\n\t}\n\t/**\n\t* Applies a navigation, or refuses it and returns false: a push onto a full stack, or going back\n\t* from the first page (which the host handles itself, e.g. by closing the dot).\n\t*/\n\tapply(navigation) {\n\t\tswitch (navigation.action) {\n\t\t\tcase \"push\":\n\t\t\t\tif (this.#pages.length >= this.limit) return false;\n\t\t\t\tbreak;\n\t\t\tcase \"replace\":\n\t\t\t\tthis.#pages.pop();\n\t\t\t\tbreak;\n\t\t\tcase \"reset\":\n\t\t\t\tthis.#pages = [];\n\t\t\t\tbreak;\n\t\t\tcase \"back\": {\n\t\t\t\tconst count = Math.min(navigation.delta, this.#pages.length - 1);\n\t\t\t\tif (count < 1) return false;\n\t\t\t\tthis.#pages = this.#pages.slice(0, -count);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tconst { page, options } = navigation;\n\t\tthis.#pages = [...this.#pages, {\n\t\t\tinstanceId: this.#nextInstanceId++,\n\t\t\tpage,\n\t\t\toptions\n\t\t}];\n\t\treturn true;\n\t}\n};\n//#endregion\n//#region src/page/state.ts\nfunction applyChanges(state, changes) {\n\tconst next = { ...state };\n\tfor (const [key, value] of Object.entries(changes)) if (value !== void 0) next[key] = value;\n\treturn next;\n}\n//#endregion\n//#region src/page/bars.ts\nconst HEX_COLOR = /^#[0-9a-fA-F]{6}$/;\nfunction checkNavigationBar(options) {\n\tconst { title, hidden, backgroundColor, textColor } = options;\n\tif (title !== void 0 && typeof title !== \"string\") throw new TypeError(\"The navigation bar's title must be text\");\n\tif (hidden !== void 0 && typeof hidden !== \"boolean\") throw new TypeError(\"The navigation bar's `hidden` must be true or false\");\n\tfor (const [name, color] of Object.entries({\n\t\tbackgroundColor,\n\t\ttextColor\n\t})) if (color !== void 0 && (typeof color !== \"string\" || !HEX_COLOR.test(color))) throw new TypeError(`The navigation bar's ${name} must be a color such as \"#1A73E8\"`);\n}\nfunction checkTabBar(options) {\n\tif (options.hidden !== void 0 && typeof options.hidden !== \"boolean\") throw new TypeError(\"The tab bar's `hidden` must be true or false\");\n}\nfunction checkConfigs(configs) {\n\tcheckNavigationBar(configs.navigationBar ?? {});\n\tcheckTabBar(configs.tabBar ?? {});\n}\nfunction mergeConfigs(...configs) {\n\tconst bars = {\n\t\tnavigationBar: {},\n\t\ttabBar: {}\n\t};\n\tfor (const config of configs) {\n\t\tbars.navigationBar = {\n\t\t\t...bars.navigationBar,\n\t\t\t...config?.navigationBar\n\t\t};\n\t\tbars.tabBar = {\n\t\t\t...bars.tabBar,\n\t\t\t...config?.tabBar\n\t\t};\n\t}\n\treturn bars;\n}\n//#endregion\n//#region src/messageChannel.ts\nvar MessageChannel = class {\n\t#transport;\n\t#handlers = /* @__PURE__ */ new Map();\n\tconstructor(transport) {\n\t\tthis.#transport = transport;\n\t}\n\tsend(type, payload) {\n\t\tthis.#transport.post({\n\t\t\ttype,\n\t\t\tpayload\n\t\t});\n\t}\n\thandle(type, handler) {\n\t\tconst previous = this.#handlers.get(type);\n\t\tthis.#handlers.set(type, handler);\n\t\treturn previous;\n\t}\n\tlisten(onError) {\n\t\treturn this.#transport.listen((rawMessage) => {\n\t\t\tconst message = rawMessage;\n\t\t\tconst handler = this.#handlers.get(message.type);\n\t\t\tif (!handler) {\n\t\t\t\tonError(/* @__PURE__ */ new Error(`No handler registered for message \"${message.type}\"`), message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\thandler(message.payload);\n\t\t\t} catch (error) {\n\t\t\t\tonError(error, message);\n\t\t\t}\n\t\t});\n\t}\n};\n//#endregion\nexport { AmountInput, Badge, Button, Carousel, Checkbox, Chip, CodeInput, DEFAULT_SYSTEM_CONTEXT, DOT_FILE_PATH_MAX_LENGTH, Divider, EmptyState, EventEmitter, Footer, Grid, GridItem, HostError, ICON_NAMES, Icon, Image, Input, List, ListItem, MAX_STACK_DEPTH, MessageChannel, NETWORK_HOST_MAX_LENGTH, NETWORK_HOST_PATTERN, NavigationStack, Notice, Option, PAGE_HOOKS, PERMISSIONS, ProgressBar, QRCode, REACT_HOST_MODULES, REACT_HOST_PATH, Radio, RadioGroup, SEMVER_PATTERN, SIZES, STATUS_TONES, Select, Sheet, Skeleton, SourceError, Spinner, Switch, TONES, Tab, Tabs, Text, TextArea, Toast, View, allowsHost, applyChanges, builtinComponents, builtinRegistry, callHost, checkConfigs, checkNavigationBar, checkTabBar, compareVersions, componentRegistry, connectHost, createAdaptorTransport, createEvent, createHostRequest, createLocator, createTransportPair, defineComponent, dotFilePathProblem, eventName, eventProp, hostTransport, isEventProp, isNetworkHost, isPageId, isPermission, isReactCompatible, isSemanticVersion, isVersionAtLeast, locatedMessage, locationAt, majorVersion, mergeConfigs, newestReactOfMajor, reactHostUrl, toList, toText };\n\n//# sourceMappingURL=index.js.map","export const CLIENT_PATH = '/__dot/';\nexport const EVENTS_PATH = `${CLIENT_PATH}events`;\nexport const HTTP_PATH = `${CLIENT_PATH}network/http/`;\nexport const FILE_PATH = `${CLIENT_PATH}file/`;\n\nexport const DOT_PATH = '/dot/';\nexport const WEBVIEW_URL = `${DOT_PATH}ui/index.html`;\nexport const WEBVIEW_SCRIPT_URL = `${DOT_PATH}ui/dot.js`;\nexport const SERVICE_URL = `${DOT_PATH}logic/dot.js`;\nexport const MANIFEST_URL = `${DOT_PATH}manifest.json`;\n","// What the simulator page posts to the dot's worker and web view to run its new build in place.\nexport interface HotReload {\n readonly dotHotReload: number;\n}\n\nexport function hotReloadIn(data: unknown): number | undefined {\n const reload = (data as Partial<HotReload> | null)?.dotHotReload;\n return typeof reload === 'number' ? reload : undefined;\n}\n","import type { Transport } from '@monimesl/dot-core';\n\n// Native bridges only carry strings, so JSON-encoding here makes state that a device could not\n// carry fail in the simulator too.\ninterface Wire {\n readonly dot: string;\n}\n\nfunction isWire(data: unknown): data is Wire {\n return typeof (data as Partial<Wire> | null)?.dot === 'string';\n}\n\nexport function wireTransport(channel: Transport): Transport {\n return {\n post: (message) => channel.post({ dot: JSON.stringify(message) } satisfies Wire),\n listen: (listener) =>\n channel.listen((data) => {\n if (isWire(data)) {\n listener(JSON.parse(data.dot));\n }\n }),\n };\n}\n\n// The simulator page and the webview's iframe, each accepting messages only from the other.\nexport function windowChannel(other: () => Window | null): Transport {\n return {\n post: (message) => other()?.postMessage(message, location.origin),\n listen(listener) {\n const onMessage = (event: MessageEvent) => {\n if (event.source === other()) {\n listener(event.data);\n }\n };\n window.addEventListener('message', onMessage);\n return () => window.removeEventListener('message', onMessage);\n },\n };\n}\n","import type { TransportAdapter } from '@monimesl/dot-core';\nimport { createAdaptorTransport } from '@monimesl/dot-core';\n\nimport { SERVICE_URL } from '../paths';\nimport { hotReloadIn } from './hot-reload';\nimport { wireTransport } from './wire';\n\ninterface WorkerScope extends TransportAdapter {\n importScripts(...urls: string[]): void;\n}\n\nconst scope = globalThis as unknown as WorkerScope;\n\nglobalThis.__hostTransport = wireTransport(createAdaptorTransport(scope));\n\nscope.importScripts(SERVICE_URL);\n\n// The new build hands its pages to the service already running here.\nscope.addEventListener('message', ({ data }) => {\n const reload = hotReloadIn(data);\n if (reload !== undefined) {\n scope.importScripts(`${SERVICE_URL}?hot=${reload}`);\n }\n});\n"],"mappings":";;CACA,SAAS,gBAAgB,UAAU;EAClC,OAAO;GACN,OAAO,CAAC;GACR,QAAQ,CAAC;GACT,GAAG;EACJ;CACD;CAYA,SAAS,kBAAkB,WAAW;EACrC,MAAM,WAAW,CAAC;EAClB,KAAK,MAAM,YAAY,WAAW;GACjC,IAAI,SAAS,QAAQ,UAAU,MAAM,IAAI,MAAM,cAAc,SAAS,KAAK,mBAAmB;GAC9F,SAAS,SAAS,QAAQ;EAC3B;EACA,OAAO;CACR;CAgEA,MAAM,cAAc,gBAAgB;EACnC,MAAM;EACN,OAAO;GACN,OAAO;GACP,UAAU;GACV,UAAU;GACV,OAAO;GACP,aAAa;GACb,MAAM;GACN,OAAO;GACP,UAAU;EACX;EACA,QAAQ,CAAC,QAAQ;EACjB,UAAU;CACX,CAAC;CAGD,MAAM,SAAS,gBAAgB;EAC9B,MAAM;EACN,OAAO;GACN,SAAS,CAAC,WAAW,WAAW;GAChC,UAAU;GACV,SAAS;EACV;EACA,QAAQ,CAAC,OAAO;EAChB,UAAU;CACX,CAAC;CAGD,MAAM,QAAQ;EACb;EACA;EACA;CACD;CACA,MAAM,SAAS;EACd;EACA;EACA;EACA;CACD;CACA,MAAM,QAAQ;EACb;EACA;EACA;EACA;EACA;EACA;CACD;CACA,MAAM,eAAe;EACpB;EACA;EACA;EACA;EACA;CACD;CACA,MAAM,aAAa;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD;CAGA,MAAM,WAAW,gBAAgB;EAChC,MAAM;EACN,OAAO;GACN,UAAU;GACV,UAAU;GACV,MAAM;GACN,WAAW,CAAC,QAAQ,MAAM;GAC1B,KAAK;GACL,QAAQ,CAAC,SAAS,OAAO;GACzB,OAAO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"}
1
+ {"version":3,"file":"service-bridge.js","names":[],"sources":["../../../../core/dist/index.js","../../src/paths.ts","../../src/client/hot-reload.ts","../../src/client/wire.ts","../../src/client/service-bridge.ts"],"sourcesContent":["//#region src/view/component.ts\nfunction defineComponent(manifest) {\n\treturn {\n\t\tprops: {},\n\t\tevents: [],\n\t\t...manifest\n\t};\n}\nfunction eventProp(event) {\n\treturn `on${event.charAt(0).toUpperCase()}${event.slice(1)}`;\n}\nfunction isEventProp(name) {\n\tconst letterAfterOn = name.charAt(2);\n\treturn name.startsWith(\"on\") && letterAfterOn >= \"A\" && letterAfterOn <= \"Z\";\n}\nfunction eventName(prop) {\n\tconst name = prop.slice(2);\n\treturn name.charAt(0).toLowerCase() + name.slice(1);\n}\nfunction componentRegistry(manifests) {\n\tconst registry = {};\n\tfor (const manifest of manifests) {\n\t\tif (manifest.name in registry) throw new Error(`Component <${manifest.name}> is defined twice`);\n\t\tregistry[manifest.name] = manifest;\n\t}\n\treturn registry;\n}\n//#endregion\n//#region src/view/values.ts\nfunction toText(value) {\n\tswitch (typeof value) {\n\t\tcase \"string\": return value;\n\t\tcase \"number\":\n\t\tcase \"boolean\":\n\t\tcase \"bigint\": return String(value);\n\t\tcase \"object\": return value === null ? \"\" : JSON.stringify(value);\n\t\tdefault: return \"\";\n\t}\n}\nfunction toList(value) {\n\tif (Array.isArray(value)) return value;\n\tif (typeof value === \"object\" && value !== null && Symbol.iterator in value) return Array.from(value);\n\treturn [];\n}\n//#endregion\n//#region src/source/location.ts\nfunction createLocator(source) {\n\tconst lineStarts = [0];\n\tfor (let index = 0; index < source.length; index++) if (source[index] === \"\\n\") lineStarts.push(index + 1);\n\treturn (offset) => {\n\t\tlet low = 0;\n\t\tlet high = lineStarts.length - 1;\n\t\twhile (low < high) {\n\t\t\tconst middle = Math.floor((low + high + 1) / 2);\n\t\t\tif (lineStarts[middle] <= offset) low = middle;\n\t\t\telse high = middle - 1;\n\t\t}\n\t\treturn {\n\t\t\tline: low + 1,\n\t\t\tcolumn: offset - lineStarts[low] + 1,\n\t\t\toffset\n\t\t};\n\t};\n}\nfunction locationAt(source, offset) {\n\treturn createLocator(source)(offset);\n}\nfunction locatedMessage(message, file, location) {\n\tconst where = [\n\t\tfile,\n\t\tlocation?.line,\n\t\tlocation?.column\n\t].filter((part) => part !== void 0).join(\":\");\n\treturn where ? `${where}: ${message}` : message;\n}\n//#endregion\n//#region src/source/error.ts\nvar SourceError = class extends Error {\n\treason;\n\tfile;\n\tloc;\n\tconstructor(reason, file, location) {\n\t\tsuper(locatedMessage(reason, file, location));\n\t\tthis.reason = reason;\n\t\tthis.file = file;\n\t\tthis.loc = location;\n\t}\n};\n//#endregion\n//#region src/view/components/amount-input.ts\nconst AmountInput = defineComponent({\n\tname: \"AmountInput\",\n\tprops: {\n\t\tvalue: \"number\",\n\t\tcurrency: \"string\",\n\t\tdecimals: \"number\",\n\t\tlabel: \"string\",\n\t\tplaceholder: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/button.ts\nconst Button = defineComponent({\n\tname: \"Button\",\n\tprops: {\n\t\tvariant: [\"primary\", \"secondary\"],\n\t\tdisabled: \"boolean\",\n\t\tloading: \"boolean\"\n\t},\n\tevents: [\"click\"],\n\tchildren: \"text\"\n});\n//#endregion\n//#region src/view/components/options.ts\nconst SIZES = [\n\t\"small\",\n\t\"medium\",\n\t\"large\"\n];\nconst SPACES = [\n\t\"none\",\n\t\"small\",\n\t\"medium\",\n\t\"large\"\n];\nconst TONES = [\n\t\"default\",\n\t\"muted\",\n\t\"info\",\n\t\"success\",\n\t\"warning\",\n\t\"danger\"\n];\nconst STATUS_TONES = [\n\t\"default\",\n\t\"info\",\n\t\"success\",\n\t\"warning\",\n\t\"danger\"\n];\nconst ICON_NAMES = [\n\t\"arrow-down\",\n\t\"arrow-left\",\n\t\"arrow-right\",\n\t\"arrow-up\",\n\t\"bank\",\n\t\"bell\",\n\t\"bolt\",\n\t\"calendar\",\n\t\"card\",\n\t\"cart\",\n\t\"cash\",\n\t\"check\",\n\t\"chevron-down\",\n\t\"chevron-left\",\n\t\"chevron-right\",\n\t\"chevron-up\",\n\t\"clock\",\n\t\"close\",\n\t\"copy\",\n\t\"download\",\n\t\"edit\",\n\t\"error\",\n\t\"eye\",\n\t\"eye-off\",\n\t\"file\",\n\t\"gift\",\n\t\"grid\",\n\t\"heart\",\n\t\"help\",\n\t\"history\",\n\t\"home\",\n\t\"image\",\n\t\"info\",\n\t\"list\",\n\t\"location\",\n\t\"lock\",\n\t\"logout\",\n\t\"mail\",\n\t\"minus\",\n\t\"mobile\",\n\t\"more\",\n\t\"phone\",\n\t\"plus\",\n\t\"qr-code\",\n\t\"receipt\",\n\t\"refresh\",\n\t\"search\",\n\t\"send\",\n\t\"settings\",\n\t\"share\",\n\t\"star\",\n\t\"success\",\n\t\"trash\",\n\t\"upload\",\n\t\"user\",\n\t\"users\",\n\t\"wallet\",\n\t\"warning\",\n\t\"water\",\n\t\"wifi\"\n];\n//#endregion\n//#region src/view/components/carousel.ts\nconst Carousel = defineComponent({\n\tname: \"Carousel\",\n\tprops: {\n\t\tautoplay: \"boolean\",\n\t\tinterval: \"number\",\n\t\tloop: \"boolean\",\n\t\tindicator: [\"dots\", \"none\"],\n\t\tgap: SPACES,\n\t\teffect: [\"slide\", \"scale\"],\n\t\tindex: \"number\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/chip.ts\nconst Chip = defineComponent({\n\tname: \"Chip\",\n\tprops: {\n\t\tlabel: \"string\",\n\t\ticon: ICON_NAMES,\n\t\tselected: \"boolean\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"tap\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/code-input.ts\nconst CodeInput = defineComponent({\n\tname: \"CodeInput\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlength: \"number\",\n\t\tlabel: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\tsecure: \"boolean\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\", \"complete\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/divider.ts\nconst Divider = defineComponent({\n\tname: \"Divider\",\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/empty-state.ts\nconst EmptyState = defineComponent({\n\tname: \"EmptyState\",\n\tprops: {\n\t\ticon: ICON_NAMES,\n\t\ttitle: \"string\",\n\t\ttext: \"string\"\n\t},\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/feedback.ts\nconst Spinner = defineComponent({\n\tname: \"Spinner\",\n\tprops: { size: SIZES },\n\tchildren: \"none\"\n});\nconst ProgressBar = defineComponent({\n\tname: \"ProgressBar\",\n\tprops: { value: \"number\" },\n\tchildren: \"none\"\n});\nconst Notice = defineComponent({\n\tname: \"Notice\",\n\tprops: {\n\t\ttone: STATUS_TONES,\n\t\ttitle: \"string\"\n\t},\n\tchildren: \"text\"\n});\nconst Badge = defineComponent({\n\tname: \"Badge\",\n\tprops: { tone: STATUS_TONES },\n\tchildren: \"text\"\n});\n//#endregion\n//#region src/view/components/footer.ts\nconst Footer = defineComponent({\n\tname: \"Footer\",\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/grid.ts\nconst Grid = defineComponent({\n\tname: \"Grid\",\n\tprops: {\n\t\tcolumns: \"number\",\n\t\tgap: SPACES\n\t},\n\tchildren: \"elements\"\n});\nconst GridItem = defineComponent({\n\tname: \"GridItem\",\n\tprops: {\n\t\tlabel: \"string\",\n\t\ticon: ICON_NAMES,\n\t\timage: \"string\",\n\t\tbadge: \"string\"\n\t},\n\tevents: [\"tap\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/icon.ts\nconst Icon = defineComponent({\n\tname: \"Icon\",\n\tprops: {\n\t\tname: ICON_NAMES,\n\t\tsize: SIZES,\n\t\ttone: TONES\n\t},\n\tchildren: \"none\",\n\tinline: true\n});\n//#endregion\n//#region src/view/components/image.ts\nconst Image = defineComponent({\n\tname: \"Image\",\n\tprops: {\n\t\tsrc: \"string\",\n\t\talt: \"string\",\n\t\twidth: \"number\",\n\t\theight: \"number\",\n\t\tfit: [\"cover\", \"contain\"],\n\t\tshape: [\n\t\t\t\"rounded\",\n\t\t\t\"square\",\n\t\t\t\"circle\"\n\t\t]\n\t},\n\tevents: [\"load\", \"error\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/input.ts\nconst Input = defineComponent({\n\tname: \"Input\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tplaceholder: \"string\",\n\t\tlabel: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\tprefix: \"string\",\n\t\tsuffix: \"string\",\n\t\ttype: [\n\t\t\t\"text\",\n\t\t\t\"number\",\n\t\t\t\"email\",\n\t\t\t\"phone\",\n\t\t\t\"password\"\n\t\t],\n\t\tmaxLength: \"number\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\", \"submit\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/list.ts\nconst List = defineComponent({\n\tname: \"List\",\n\tprops: { size: [\"sm\", \"md\"] },\n\tchildren: \"elements\"\n});\nconst ListItem = defineComponent({\n\tname: \"ListItem\",\n\tprops: {\n\t\ttitle: \"string\",\n\t\tsubtitle: \"string\",\n\t\tvalue: \"string\",\n\t\ticon: ICON_NAMES,\n\t\timage: \"string\"\n\t},\n\tevents: [\"tap\"],\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/overlays.ts\nconst Sheet = defineComponent({\n\tname: \"Sheet\",\n\tprops: {\n\t\topen: \"boolean\",\n\t\ttitle: \"string\",\n\t\tshowCloseIcon: \"boolean\"\n\t},\n\tevents: [\"close\"],\n\tchildren: \"elements\"\n});\nconst Toast = defineComponent({\n\tname: \"Toast\",\n\tprops: {\n\t\tmessage: \"string\",\n\t\ttone: STATUS_TONES,\n\t\tduration: \"number\"\n\t},\n\tevents: [\"hide\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/qr-code.ts\nconst QRCode = defineComponent({\n\tname: \"QRCode\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tsize: \"number\",\n\t\tlabel: \"string\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/select.ts\nconst Select = defineComponent({\n\tname: \"Select\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\",\n\t\tplaceholder: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"elements\"\n});\nconst Option = defineComponent({\n\tname: \"Option\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/skeleton.ts\nconst Skeleton = defineComponent({\n\tname: \"Skeleton\",\n\tprops: {\n\t\tshape: [\n\t\t\t\"text\",\n\t\t\t\"circle\",\n\t\t\t\"box\"\n\t\t],\n\t\tlines: \"number\",\n\t\theight: \"number\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/tabs.ts\nconst Tabs = defineComponent({\n\tname: \"Tabs\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tvariant: [\"underline\", \"segmented\"]\n\t},\n\tevents: [\"change\"],\n\tchildren: \"elements\"\n});\nconst Tab = defineComponent({\n\tname: \"Tab\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\",\n\t\tbadge: \"number\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/text.ts\nconst Text = defineComponent({\n\tname: \"Text\",\n\tprops: {\n\t\tvariant: [\n\t\t\t\"title\",\n\t\t\t\"body\",\n\t\t\t\"caption\"\n\t\t],\n\t\ttone: TONES,\n\t\tweight: [\n\t\t\t\"regular\",\n\t\t\t\"medium\",\n\t\t\t\"bold\"\n\t\t],\n\t\talign: [\n\t\t\t\"start\",\n\t\t\t\"center\",\n\t\t\t\"end\"\n\t\t],\n\t\tmaxLines: \"number\"\n\t},\n\tchildren: \"text\",\n\tinline: true\n});\n//#endregion\n//#region src/view/components/text-area.ts\nconst TextArea = defineComponent({\n\tname: \"TextArea\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tplaceholder: \"string\",\n\t\tlabel: \"string\",\n\t\thint: \"string\",\n\t\terror: \"string\",\n\t\trows: \"number\",\n\t\tmaxLength: \"number\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/toggles.ts\nconst Switch = defineComponent({\n\tname: \"Switch\",\n\tprops: {\n\t\tchecked: \"boolean\",\n\t\tlabel: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"none\"\n});\nconst Checkbox = defineComponent({\n\tname: \"Checkbox\",\n\tprops: {\n\t\tchecked: \"boolean\",\n\t\tlabel: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"none\"\n});\nconst RadioGroup = defineComponent({\n\tname: \"RadioGroup\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tevents: [\"change\"],\n\tchildren: \"elements\"\n});\nconst Radio = defineComponent({\n\tname: \"Radio\",\n\tprops: {\n\t\tvalue: \"string\",\n\t\tlabel: \"string\",\n\t\tdisabled: \"boolean\"\n\t},\n\tchildren: \"none\"\n});\n//#endregion\n//#region src/view/components/view.ts\nconst View = defineComponent({\n\tname: \"View\",\n\tprops: {\n\t\tgap: SPACES,\n\t\tdirection: [\"column\", \"row\"],\n\t\talign: [\n\t\t\t\"stretch\",\n\t\t\t\"start\",\n\t\t\t\"center\",\n\t\t\t\"end\"\n\t\t],\n\t\tjustify: [\n\t\t\t\"start\",\n\t\t\t\"center\",\n\t\t\t\"end\",\n\t\t\t\"between\"\n\t\t],\n\t\twrap: \"boolean\",\n\t\tgrow: \"boolean\",\n\t\tpadding: SPACES,\n\t\tpaddingTop: SPACES,\n\t\tpaddingStart: SPACES,\n\t\tpaddingEnd: SPACES,\n\t\tpaddingBottom: SPACES,\n\t\tvariant: [\"plain\", \"card\"]\n\t},\n\tevents: [\"tap\"],\n\tchildren: \"elements\"\n});\n//#endregion\n//#region src/view/components/index.ts\nconst builtinComponents = {\n\tAmountInput,\n\tBadge,\n\tButton,\n\tCarousel,\n\tCheckbox,\n\tChip,\n\tCodeInput,\n\tDivider,\n\tEmptyState,\n\tFooter,\n\tGrid,\n\tGridItem,\n\tIcon,\n\tImage,\n\tInput,\n\tList,\n\tListItem,\n\tNotice,\n\tOption,\n\tProgressBar,\n\tQRCode,\n\tRadio,\n\tRadioGroup,\n\tSelect,\n\tSheet,\n\tSkeleton,\n\tSpinner,\n\tSwitch,\n\tTab,\n\tTabs,\n\tText,\n\tTextArea,\n\tToast,\n\tView\n};\nconst builtinRegistry = componentRegistry(Object.values(builtinComponents));\n//#endregion\n//#region src/event/emitter.ts\nvar EventEmitter = class {\n\t#listeners = /* @__PURE__ */ new Map();\n\ton(name, listener) {\n\t\tconst listeners = this.#listeners.get(name) ?? /* @__PURE__ */ new Set();\n\t\tthis.#listeners.set(name, listeners);\n\t\tlisteners.add(listener);\n\t\treturn () => listeners.delete(listener);\n\t}\n\temit(name, ...args) {\n\t\tthis.#listeners.get(name)?.forEach((listener) => listener(...args));\n\t}\n};\n//#endregion\n//#region src/event/core.ts\nfunction createEvent(type, detail = {}, data = {}) {\n\treturn {\n\t\ttype,\n\t\tdetail,\n\t\tdata\n\t};\n}\n//#endregion\n//#region src/host/host.ts\nfunction hostTransport() {\n\tconst transport = globalThis.__hostTransport;\n\tif (!transport) throw new Error(\"No Dot host found: expected `globalThis.__hostTransport` to be available at runtime. Dots run inside the Dash App, or a simulator via `dotctl dev`.\");\n\treturn transport;\n}\n//#endregion\n//#region src/host/context.ts\nconst DEFAULT_SYSTEM_CONTEXT = {\n\tplatform: \"ios\",\n\tscheme: \"light\",\n\tappState: \"active\"\n};\n//#endregion\n//#region src/host/calls.ts\nvar HostError = class extends Error {\n\tname = \"HostError\";\n\tcode;\n\tconstructor(code, message) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n};\nlet connectedCaller = null;\nfunction connectHost(caller) {\n\tconnectedCaller = caller;\n}\nfunction callHost(method, params, options = {}) {\n\tif (!connectedCaller) {\n\t\tconst error = new HostError(\"unsupported\", `No host to run \"${method}\": host calls run in the service`);\n\t\treturn createHostRequest(Promise.reject(error));\n\t}\n\treturn connectedCaller(method, params, options);\n}\nfunction createHostRequest(promise, cancel = () => {}) {\n\tconst request = promise;\n\trequest.cancel = cancel;\n\treturn request;\n}\n//#endregion\n//#region src/host/permissions.ts\nconst PERMISSIONS = [\"account\"];\nfunction isPermission(value) {\n\treturn PERMISSIONS.includes(value);\n}\n//#endregion\n//#region src/host/files.ts\nconst DOT_FILE_PATH_MAX_LENGTH = 512;\nconst MAX_NAME_LENGTH = 255;\nfunction dotFilePathProblem(path, { allowRoot = false } = {}) {\n\tif (path === \"\") return allowRoot ? null : \"A path is needed, such as \\\"receipts/42.pdf\\\"\";\n\tif (path.length > 512) return `\"${path.slice(0, 40)}…\" is longer than 512 characters`;\n\tif (path.startsWith(\"/\")) return `\"${path}\" starts with \"/\": paths are relative to the dot's storage, such as \"receipts/42.pdf\"`;\n\tif ([...path].some((char) => char === \"\\\\\" || char.charCodeAt(0) < 32)) return `\"${path}\" has a backslash or a control character`;\n\tfor (const name of path.split(\"/\")) {\n\t\tif (name === \"\" || name === \".\" || name === \"..\") return `\"${path}\" has an empty, \".\" or \"..\" part: write each folder once, such as \"receipts/42.pdf\"`;\n\t\tif (name.length > MAX_NAME_LENGTH) return `\"${path}\" has a name longer than ${MAX_NAME_LENGTH} characters`;\n\t}\n\treturn null;\n}\n//#endregion\n//#region src/host/network.ts\nconst LABEL = \"[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\";\nconst NETWORK_HOST_PATTERN = new RegExp(`^(?:\\\\*\\\\.${LABEL}(?:\\\\.${LABEL})+|${LABEL}(?:\\\\.${LABEL})*)$`);\nconst NETWORK_HOST_MAX_LENGTH = 253;\nfunction isNetworkHost(value) {\n\treturn value.length <= 253 && NETWORK_HOST_PATTERN.test(value);\n}\nfunction allowsHost(hosts, host) {\n\tconst name = host.toLowerCase().replace(/\\.$/, \"\");\n\treturn hosts.some((pattern) => pattern.startsWith(\"*.\") ? name.endsWith(pattern.slice(1)) : name === pattern);\n}\n//#endregion\n//#region src/version/semantic-version.ts\nconst SEMVER_PATTERN = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\nfunction isSemanticVersion(value) {\n\treturn typeof value === \"string\" && SEMVER_PATTERN.test(value);\n}\nfunction majorVersion(version) {\n\treturn parseVersion(version).major;\n}\nfunction isVersionAtLeast(version, minimum) {\n\treturn compareVersions(version, minimum) >= 0;\n}\nfunction compareVersions(left, right) {\n\tconst leftVersion = parseVersion(left);\n\tconst rightVersion = parseVersion(right);\n\tconst differences = [\n\t\tleftVersion.major - rightVersion.major,\n\t\tleftVersion.minor - rightVersion.minor,\n\t\tleftVersion.patch - rightVersion.patch\n\t];\n\tfor (const difference of differences) if (difference !== 0) return difference;\n\treturn comparePrereleases(leftVersion.prerelease, rightVersion.prerelease);\n}\nfunction parseVersion(version) {\n\tconst match = SEMVER_PATTERN.exec(version);\n\tif (!match) throw new Error(`\"${version}\" is not a semantic version`);\n\tconst [, major, minor, patch, prerelease] = match;\n\treturn {\n\t\tmajor: Number(major),\n\t\tminor: Number(minor),\n\t\tpatch: Number(patch),\n\t\tprerelease: prerelease === void 0 ? [] : prerelease.split(\".\")\n\t};\n}\nfunction comparePrereleases(left, right) {\n\tif (left.length === 0 || right.length === 0) return right.length - left.length;\n\tconst shared = Math.min(left.length, right.length);\n\tfor (let index = 0; index < shared; index++) {\n\t\tconst order = compareIdentifiers(left[index], right[index]);\n\t\tif (order !== 0) return order;\n\t}\n\treturn left.length - right.length;\n}\nfunction compareIdentifiers(left, right) {\n\tconst leftIsNumber = /^\\d+$/.test(left);\n\tconst rightIsNumber = /^\\d+$/.test(right);\n\tif (leftIsNumber && rightIsNumber) return Number(left) - Number(right);\n\tif (leftIsNumber) return -1;\n\tif (rightIsNumber) return 1;\n\tif (left < right) return -1;\n\tif (left > right) return 1;\n\treturn 0;\n}\n//#endregion\n//#region src/host/react.ts\nconst REACT_HOST_PATH = \"/__dot/react/\";\nconst REACT_HOST_MODULES = {\n\treact: \"react.js\",\n\t\"react/jsx-runtime\": \"react-jsx-runtime.js\",\n\t\"react-dom\": \"react-dom.js\",\n\t\"react-dom/client\": \"react-dom-client.js\"\n};\nfunction reactHostUrl(dotReactVersion, file) {\n\treturn `${REACT_HOST_PATH}${majorVersion(dotReactVersion)}/${file}`;\n}\nfunction isReactCompatible(hostVersion, dotVersion) {\n\treturn majorVersion(hostVersion) === majorVersion(dotVersion) && isVersionAtLeast(hostVersion, dotVersion);\n}\nfunction newestReactOfMajor(versions, major) {\n\treturn versions.filter((version) => majorVersion(version) === major).sort(compareVersions).at(-1);\n}\n//#endregion\n//#region src/protocol/transport.ts\nfunction createAdaptorTransport(adapter) {\n\treturn {\n\t\tpost: (message) => adapter.postMessage(message),\n\t\tlisten(listener) {\n\t\t\tconst onMessage = (event) => listener(event.data);\n\t\t\tadapter.addEventListener(\"message\", onMessage);\n\t\t\treturn () => adapter.removeEventListener(\"message\", onMessage);\n\t\t}\n\t};\n}\nfunction createTransportPair() {\n\tconst firstListeners = /* @__PURE__ */ new Set();\n\tconst secondListeners = /* @__PURE__ */ new Set();\n\tconst createSide = (ownListeners, otherListeners) => ({\n\t\tpost: (message) => {\n\t\t\tconst copy = JSON.parse(JSON.stringify(message));\n\t\t\totherListeners.forEach((listener) => listener(copy));\n\t\t},\n\t\tlisten(listener) {\n\t\t\townListeners.add(listener);\n\t\t\treturn () => ownListeners.delete(listener);\n\t\t}\n\t});\n\treturn [createSide(firstListeners, secondListeners), createSide(secondListeners, firstListeners)];\n}\nconst PAGE_HOOKS = Object.keys({\n\tonLoad: true,\n\tonShow: true,\n\tonHide: true,\n\tonUnload: true\n});\n//#endregion\n//#region src/page/navigation.ts\nconst MAX_STACK_DEPTH = 8;\nconst PAGE_ID = /^[A-Za-z0-9_-]+(?:\\/[A-Za-z0-9_-]+)*$/;\nfunction isPageId(value) {\n\treturn PAGE_ID.test(value);\n}\nvar NavigationStack = class {\n\tlimit;\n\t#pages = [];\n\t#nextInstanceId = 1;\n\tconstructor(limit = 8) {\n\t\tthis.limit = limit;\n\t}\n\tget pages() {\n\t\treturn this.#pages;\n\t}\n\tget top() {\n\t\treturn this.#pages.at(-1);\n\t}\n\t/**\n\t* Applies a navigation, or refuses it and returns false: a push onto a full stack, or going back\n\t* from the first page (which the host handles itself, e.g. by closing the dot).\n\t*/\n\tapply(navigation) {\n\t\tswitch (navigation.action) {\n\t\t\tcase \"push\":\n\t\t\t\tif (this.#pages.length >= this.limit) return false;\n\t\t\t\tbreak;\n\t\t\tcase \"replace\":\n\t\t\t\tthis.#pages.pop();\n\t\t\t\tbreak;\n\t\t\tcase \"reset\":\n\t\t\t\tthis.#pages = [];\n\t\t\t\tbreak;\n\t\t\tcase \"back\": {\n\t\t\t\tconst count = Math.min(navigation.delta, this.#pages.length - 1);\n\t\t\t\tif (count < 1) return false;\n\t\t\t\tthis.#pages = this.#pages.slice(0, -count);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tconst { page, options } = navigation;\n\t\tthis.#pages = [...this.#pages, {\n\t\t\tinstanceId: this.#nextInstanceId++,\n\t\t\tpage,\n\t\t\toptions\n\t\t}];\n\t\treturn true;\n\t}\n};\n//#endregion\n//#region src/page/state.ts\nfunction applyChanges(state, changes) {\n\tconst next = { ...state };\n\tfor (const [key, value] of Object.entries(changes)) if (value !== void 0) next[key] = value;\n\treturn next;\n}\n//#endregion\n//#region src/page/bars.ts\nconst HEX_COLOR = /^#[0-9a-fA-F]{6}$/;\nfunction checkNavigationBar(options) {\n\tconst { title, hidden, backgroundColor, textColor } = options;\n\tif (title !== void 0 && typeof title !== \"string\") throw new TypeError(\"The navigation bar's title must be text\");\n\tif (hidden !== void 0 && typeof hidden !== \"boolean\") throw new TypeError(\"The navigation bar's `hidden` must be true or false\");\n\tfor (const [name, color] of Object.entries({\n\t\tbackgroundColor,\n\t\ttextColor\n\t})) if (color !== void 0 && (typeof color !== \"string\" || !HEX_COLOR.test(color))) throw new TypeError(`The navigation bar's ${name} must be a color such as \"#1A73E8\"`);\n}\nfunction checkTabBar(options) {\n\tif (options.hidden !== void 0 && typeof options.hidden !== \"boolean\") throw new TypeError(\"The tab bar's `hidden` must be true or false\");\n}\nfunction checkConfigs(configs) {\n\tcheckNavigationBar(configs.navigationBar ?? {});\n\tcheckTabBar(configs.tabBar ?? {});\n}\nfunction mergeConfigs(...configs) {\n\tconst bars = {\n\t\tnavigationBar: {},\n\t\ttabBar: {}\n\t};\n\tfor (const config of configs) {\n\t\tbars.navigationBar = {\n\t\t\t...bars.navigationBar,\n\t\t\t...config?.navigationBar\n\t\t};\n\t\tbars.tabBar = {\n\t\t\t...bars.tabBar,\n\t\t\t...config?.tabBar\n\t\t};\n\t}\n\treturn bars;\n}\n//#endregion\n//#region src/messageChannel.ts\nvar MessageChannel = class {\n\t#transport;\n\t#handlers = /* @__PURE__ */ new Map();\n\tconstructor(transport) {\n\t\tthis.#transport = transport;\n\t}\n\tsend(type, payload) {\n\t\tthis.#transport.post({\n\t\t\ttype,\n\t\t\tpayload\n\t\t});\n\t}\n\thandle(type, handler) {\n\t\tconst previous = this.#handlers.get(type);\n\t\tthis.#handlers.set(type, handler);\n\t\treturn previous;\n\t}\n\tlisten(onError) {\n\t\treturn this.#transport.listen((rawMessage) => {\n\t\t\tconst message = rawMessage;\n\t\t\tconst handler = this.#handlers.get(message.type);\n\t\t\tif (!handler) {\n\t\t\t\tonError(/* @__PURE__ */ new Error(`No handler registered for message \"${message.type}\"`), message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\thandler(message.payload);\n\t\t\t} catch (error) {\n\t\t\t\tonError(error, message);\n\t\t\t}\n\t\t});\n\t}\n};\n//#endregion\nexport { AmountInput, Badge, Button, Carousel, Checkbox, Chip, CodeInput, DEFAULT_SYSTEM_CONTEXT, DOT_FILE_PATH_MAX_LENGTH, Divider, EmptyState, EventEmitter, Footer, Grid, GridItem, HostError, ICON_NAMES, Icon, Image, Input, List, ListItem, MAX_STACK_DEPTH, MessageChannel, NETWORK_HOST_MAX_LENGTH, NETWORK_HOST_PATTERN, NavigationStack, Notice, Option, PAGE_HOOKS, PERMISSIONS, ProgressBar, QRCode, REACT_HOST_MODULES, REACT_HOST_PATH, Radio, RadioGroup, SEMVER_PATTERN, SIZES, STATUS_TONES, Select, Sheet, Skeleton, SourceError, Spinner, Switch, TONES, Tab, Tabs, Text, TextArea, Toast, View, allowsHost, applyChanges, builtinComponents, builtinRegistry, callHost, checkConfigs, checkNavigationBar, checkTabBar, compareVersions, componentRegistry, connectHost, createAdaptorTransport, createEvent, createHostRequest, createLocator, createTransportPair, defineComponent, dotFilePathProblem, eventName, eventProp, hostTransport, isEventProp, isNetworkHost, isPageId, isPermission, isReactCompatible, isSemanticVersion, isVersionAtLeast, locatedMessage, locationAt, majorVersion, mergeConfigs, newestReactOfMajor, reactHostUrl, toList, toText };\n\n//# sourceMappingURL=index.js.map","export const CLIENT_PATH = '/__dot/';\nexport const EVENTS_PATH = `${CLIENT_PATH}events`;\nexport const HTTP_PATH = `${CLIENT_PATH}network/http/`;\nexport const FILE_PATH = `${CLIENT_PATH}file/`;\n\nexport const DOT_PATH = '/dot/';\nexport const WEBVIEW_URL = `${DOT_PATH}ui/index.html`;\nexport const WEBVIEW_SCRIPT_URL = `${DOT_PATH}ui/dot.js`;\nexport const SERVICE_URL = `${DOT_PATH}logic/dot.js`;\nexport const MANIFEST_URL = `${DOT_PATH}manifest.json`;\n","// What the simulator page posts to the dot's worker and web view to run its new build in place.\nexport interface HotReload {\n readonly dotHotReload: number;\n}\n\nexport function hotReloadIn(data: unknown): number | undefined {\n const reload = (data as Partial<HotReload> | null)?.dotHotReload;\n return typeof reload === 'number' ? reload : undefined;\n}\n","import type { Transport } from '@monimesl/dot-core';\n\n// Native bridges only carry strings, so JSON-encoding here makes state that a device could not\n// carry fail in the simulator too.\ninterface Wire {\n readonly dot: string;\n}\n\nfunction isWire(data: unknown): data is Wire {\n return typeof (data as Partial<Wire> | null)?.dot === 'string';\n}\n\nexport function wireTransport(channel: Transport): Transport {\n return {\n post: (message) => channel.post({ dot: JSON.stringify(message) } satisfies Wire),\n listen: (listener) =>\n channel.listen((data) => {\n if (isWire(data)) {\n listener(JSON.parse(data.dot));\n }\n }),\n };\n}\n\n// The simulator page and the webview's iframe, each accepting messages only from the other.\nexport function windowChannel(other: () => Window | null): Transport {\n return {\n post: (message) => other()?.postMessage(message, location.origin),\n listen(listener) {\n const onMessage = (event: MessageEvent) => {\n if (event.source === other()) {\n listener(event.data);\n }\n };\n window.addEventListener('message', onMessage);\n return () => window.removeEventListener('message', onMessage);\n },\n };\n}\n","import type { TransportAdapter } from '@monimesl/dot-core';\nimport { createAdaptorTransport } from '@monimesl/dot-core';\n\nimport { SERVICE_URL } from '../paths';\nimport { hotReloadIn } from './hot-reload';\nimport { wireTransport } from './wire';\n\ninterface WorkerScope extends TransportAdapter {\n importScripts(...urls: string[]): void;\n}\n\nconst scope = globalThis as unknown as WorkerScope;\n\nglobalThis.__hostTransport = wireTransport(createAdaptorTransport(scope));\n\nscope.importScripts(SERVICE_URL);\n\n// The new build hands its pages to the service already running here.\nscope.addEventListener('message', ({ data }) => {\n const reload = hotReloadIn(data);\n if (reload !== undefined) {\n scope.importScripts(`${SERVICE_URL}?hot=${reload}`);\n }\n});\n"],"mappings":";;CACA,SAAS,gBAAgB,UAAU;EAClC,OAAO;GACN,OAAO,CAAC;GACR,QAAQ,CAAC;GACT,GAAG;EACJ;CACD;CAYA,SAAS,kBAAkB,WAAW;EACrC,MAAM,WAAW,CAAC;EAClB,KAAK,MAAM,YAAY,WAAW;GACjC,IAAI,SAAS,QAAQ,UAAU,MAAM,IAAI,MAAM,cAAc,SAAS,KAAK,mBAAmB;GAC9F,SAAS,SAAS,QAAQ;EAC3B;EACA,OAAO;CACR;CAgEA,MAAM,cAAc,gBAAgB;EACnC,MAAM;EACN,OAAO;GACN,OAAO;GACP,UAAU;GACV,UAAU;GACV,OAAO;GACP,aAAa;GACb,MAAM;GACN,OAAO;GACP,UAAU;EACX;EACA,QAAQ,CAAC,QAAQ;EACjB,UAAU;CACX,CAAC;CAGD,MAAM,SAAS,gBAAgB;EAC9B,MAAM;EACN,OAAO;GACN,SAAS,CAAC,WAAW,WAAW;GAChC,UAAU;GACV,SAAS;EACV;EACA,QAAQ,CAAC,OAAO;EAChB,UAAU;CACX,CAAC;CAGD,MAAM,QAAQ;EACb;EACA;EACA;CACD;CACA,MAAM,SAAS;EACd;EACA;EACA;EACA;CACD;CACA,MAAM,QAAQ;EACb;EACA;EACA;EACA;EACA;EACA;CACD;CACA,MAAM,eAAe;EACpB;EACA;EACA;EACA;EACA;CACD;CACA,MAAM,aAAa;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD;CAGA,MAAM,WAAW,gBAAgB;EAChC,MAAM;EACN,OAAO;GACN,UAAU;GACV,UAAU;GACV,MAAM;GACN,WAAW,CAAC,QAAQ,MAAM;GAC1B,KAAK;GACL,QAAQ,CAAC,SAAS,OAAO;GACzB,OAAO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"}
@@ -278,6 +278,7 @@
278
278
  });
279
279
  const List = defineComponent({
280
280
  name: "List",
281
+ props: { size: ["sm", "md"] },
281
282
  children: "elements"
282
283
  });
283
284
  const ListItem = defineComponent({
@@ -296,7 +297,8 @@
296
297
  name: "Sheet",
297
298
  props: {
298
299
  open: "boolean",
299
- title: "string"
300
+ title: "string",
301
+ showCloseIcon: "boolean"
300
302
  },
301
303
  events: ["close"],
302
304
  children: "elements"
@@ -1099,12 +1101,16 @@
1099
1101
  const log = element("#log");
1100
1102
  const errorBanner = element("#error");
1101
1103
  const phone = element(".phone");
1104
+ const platformSelect = element("#platform");
1105
+ const inputModeSelect = element("#input-mode");
1102
1106
  const schemeSelect = element("#scheme");
1103
1107
  const navigationBar = element(".navigation-bar");
1104
1108
  const navigationTitle = element("#navigation-title");
1105
1109
  const navigationBack = element("#navigation-back");
1106
1110
  const tabBar = element(".tab-bar");
1107
1111
  const browserDark = matchMedia("(prefers-color-scheme: dark)");
1112
+ const COARSE_POINTER_MEDIA = /\(\s*(?:any-)?pointer\s*:\s*coarse\s*\)/gi;
1113
+ const EMULATED_TOUCH_STYLE = "data-dot-simulator-touch";
1108
1114
  let runningApp = null;
1109
1115
  let launchCount = 0;
1110
1116
  let hotReloads = 0;
@@ -1218,6 +1224,7 @@
1218
1224
  }
1219
1225
  function systemContext() {
1220
1226
  return {
1227
+ platform: platformSelect.value,
1221
1228
  scheme: schemeSelect.value,
1222
1229
  appState: appState()
1223
1230
  };
@@ -1234,6 +1241,54 @@
1234
1241
  phone.dataset.scheme = scheme;
1235
1242
  runningApp?.host.setSystemContext(systemContext());
1236
1243
  }
1244
+ function changeInputMode(mode) {
1245
+ inputModeSelect.value = mode;
1246
+ phone.dataset.inputMode = mode;
1247
+ applyInputMode();
1248
+ }
1249
+ function applyInputMode() {
1250
+ const document = screen.contentDocument;
1251
+ if (!document) return;
1252
+ document.documentElement.dataset.dotSimulatorInput = inputModeSelect.value;
1253
+ document.querySelector(`style[${EMULATED_TOUCH_STYLE}]`)?.remove();
1254
+ if (inputModeSelect.value !== "touch") return;
1255
+ const css = coarsePointerCss(document);
1256
+ if (!css) return;
1257
+ const style = document.createElement("style");
1258
+ style.setAttribute(EMULATED_TOUCH_STYLE, "");
1259
+ style.textContent = css;
1260
+ document.head.append(style);
1261
+ }
1262
+ function coarsePointerCss(document) {
1263
+ let css = "";
1264
+ for (const sheet of document.styleSheets) try {
1265
+ css += coarsePointerRules(sheet.cssRules);
1266
+ } catch {}
1267
+ return css;
1268
+ }
1269
+ function coarsePointerRules(rules) {
1270
+ let css = "";
1271
+ for (const rule of rules) {
1272
+ const nestedRules = rule.cssRules;
1273
+ if (!nestedRules) continue;
1274
+ if (rule.type === CSSRule.MEDIA_RULE) {
1275
+ const media = rule;
1276
+ COARSE_POINTER_MEDIA.lastIndex = 0;
1277
+ if (COARSE_POINTER_MEDIA.test(media.conditionText)) {
1278
+ COARSE_POINTER_MEDIA.lastIndex = 0;
1279
+ const condition = media.conditionText.replace(COARSE_POINTER_MEDIA, "(min-width: 0px)");
1280
+ const contents = Array.from(media.cssRules, (child) => child.cssText).join("\n");
1281
+ css += condition === "(min-width: 0px)" ? contents : `@media ${condition}{${contents}}`;
1282
+ continue;
1283
+ }
1284
+ }
1285
+ const contents = coarsePointerRules(nestedRules);
1286
+ if (!contents) continue;
1287
+ const openingBrace = rule.cssText.indexOf("{");
1288
+ if (openingBrace !== -1) css += `${rule.cssText.slice(0, openingBrace)}{${contents}}`;
1289
+ }
1290
+ return css;
1291
+ }
1237
1292
  const events = new EventSource(EVENTS_PATH);
1238
1293
  events.addEventListener("reload", () => {
1239
1294
  showError(null);
@@ -1249,11 +1304,18 @@
1249
1304
  navigationBack.addEventListener("click", goBack);
1250
1305
  element("#clear").addEventListener("click", () => log.replaceChildren());
1251
1306
  schemeSelect.addEventListener("change", () => changeScheme(schemeSelect.value));
1307
+ inputModeSelect.addEventListener("change", () => changeInputMode(inputModeSelect.value));
1308
+ platformSelect.addEventListener("change", () => {
1309
+ phone.dataset.platform = platformSelect.value;
1310
+ runningApp?.host.setSystemContext(systemContext());
1311
+ });
1312
+ screen.addEventListener("load", applyInputMode);
1252
1313
  browserDark.addEventListener("change", () => changeScheme(browserScheme()));
1253
1314
  document.addEventListener("visibilitychange", () => {
1254
1315
  runningApp?.host.setSystemContext(systemContext());
1255
1316
  });
1256
1317
  changeScheme(browserScheme());
1318
+ changeInputMode("touch");
1257
1319
  syncLaunch();
1258
1320
  //#endregion
1259
1321
  })();