refactor(canvas): host A2UI via gateway
This commit is contained in:
1 parent
13ebbd1a2b
commit
ed001a5f55
28 files changed
+385
-354
No files matched your search
@@ -605,9 +605,17 @@ class NodeRuntime(context: Context) {
|
||||
BridgeSession.InvokeResult.ok("""{"format":"${snapshotParams.format.rawValue}","base64":"$base64"}""")
|
||||
}
|
||||
ClawdisCanvasA2UICommand.Reset.rawValue -> {
|
||||
val ready = ensureA2uiReady()
|
||||
val a2uiUrl = resolveA2uiHostUrl()
|
||||
?: return BridgeSession.InvokeResult.error(
|
||||
code = "A2UI_HOST_NOT_CONFIGURED",
|
||||
message = "A2UI_HOST_NOT_CONFIGURED: gateway did not advertise canvas host",
|
||||
)
|
||||
val ready = ensureA2uiReady(a2uiUrl)
|
||||
if (!ready) {
|
||||
return BridgeSession.InvokeResult.error(code = "A2UI_NOT_READY", message = "A2UI not ready")
|
||||
return BridgeSession.InvokeResult.error(
|
||||
code = "A2UI_HOST_UNAVAILABLE",
|
||||
message = "A2UI host not reachable",
|
||||
)
|
||||
}
|
||||
val res = canvas.eval(a2uiResetJS)
|
||||
BridgeSession.InvokeResult.ok(res)
|
||||
@@ -619,9 +627,17 @@ class NodeRuntime(context: Context) {
|
||||
} catch (err: Throwable) {
|
||||
return BridgeSession.InvokeResult.error(code = "INVALID_REQUEST", message = err.message ?: "invalid A2UI payload")
|
||||
}
|
||||
val ready = ensureA2uiReady()
|
||||
val a2uiUrl = resolveA2uiHostUrl()
|
||||
?: return BridgeSession.InvokeResult.error(
|
||||
code = "A2UI_HOST_NOT_CONFIGURED",
|
||||
message = "A2UI_HOST_NOT_CONFIGURED: gateway did not advertise canvas host",
|
||||
)
|
||||
val ready = ensureA2uiReady(a2uiUrl)
|
||||
if (!ready) {
|
||||
return BridgeSession.InvokeResult.error(code = "A2UI_NOT_READY", message = "A2UI not ready")
|
||||
return BridgeSession.InvokeResult.error(
|
||||
code = "A2UI_HOST_UNAVAILABLE",
|
||||
message = "A2UI host not reachable",
|
||||
)
|
||||
}
|
||||
val js = a2uiApplyMessagesJS(messages)
|
||||
val res = canvas.eval(js)
|
||||
@@ -707,7 +723,14 @@ class NodeRuntime(context: Context) {
|
||||
return code to "$code: $message"
|
||||
}
|
||||
|
||||
private suspend fun ensureA2uiReady(): Boolean {
|
||||
private fun resolveA2uiHostUrl(): String? {
|
||||
val raw = session.currentCanvasHostUrl()?.trim().orEmpty()
|
||||
if (raw.isBlank()) return null
|
||||
val base = raw.trimEnd('/')
|
||||
return "${base}/__clawdis__/a2ui/"
|
||||
}
|
||||
|
||||
private suspend fun ensureA2uiReady(a2uiUrl: String): Boolean {
|
||||
try {
|
||||
val already = canvas.eval(a2uiReadyCheckJS)
|
||||
if (already == "true") return true
|
||||
@@ -715,8 +738,7 @@ class NodeRuntime(context: Context) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// Ensure the default canvas scaffold is loaded; A2UI is now hosted there.
|
||||
canvas.navigate("")
|
||||
canvas.navigate(a2uiUrl)
|
||||
repeat(50) {
|
||||
try {
|
||||
val ready = canvas.eval(a2uiReadyCheckJS)
|
||||
|
||||
@@ -61,6 +61,7 @@ class BridgeSession(
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
private val writeLock = Mutex()
|
||||
private val pending = ConcurrentHashMap<String, CompletableDeferred<RpcResponse>>()
|
||||
@Volatile private var canvasHostUrl: String? = null
|
||||
|
||||
private var desired: Pair<BridgeEndpoint, Hello>? = null
|
||||
private var job: Job? = null
|
||||
@@ -77,10 +78,13 @@ class BridgeSession(
|
||||
scope.launch(Dispatchers.IO) {
|
||||
job?.cancelAndJoin()
|
||||
job = null
|
||||
canvasHostUrl = null
|
||||
onDisconnected("Offline")
|
||||
}
|
||||
}
|
||||
|
||||
fun currentCanvasHostUrl(): String? = canvasHostUrl
|
||||
|
||||
suspend fun sendEvent(event: String, payloadJson: String?) {
|
||||
val conn = currentConnection ?: return
|
||||
conn.sendJson(
|
||||
@@ -209,6 +213,7 @@ class BridgeSession(
|
||||
when (first["type"].asStringOrNull()) {
|
||||
"hello-ok" -> {
|
||||
val name = first["serverName"].asStringOrNull() ?: "Bridge"
|
||||
canvasHostUrl = first["canvasHostUrl"].asStringOrNull()?.trim()?.ifEmpty { null }
|
||||
onConnected(name, conn.remoteAddress)
|
||||
}
|
||||
"error" -> {
|
||||
|
||||
+2
-1
@@ -46,7 +46,7 @@ class BridgeSessionTest {
|
||||
|
||||
val hello = reader.readLine()
|
||||
assertTrue(hello.contains("\"type\":\"hello\""))
|
||||
writer.write("""{"type":"hello-ok","serverName":"Test Bridge"}""")
|
||||
writer.write("""{"type":"hello-ok","serverName":"Test Bridge","canvasHostUrl":"http://127.0.0.1:18793"}""")
|
||||
writer.write("\n")
|
||||
writer.flush()
|
||||
|
||||
@@ -77,6 +77,7 @@ class BridgeSessionTest {
|
||||
)
|
||||
|
||||
connected.await()
|
||||
assertEquals("http://127.0.0.1:18793", session.currentCanvasHostUrl())
|
||||
val payload = session.request(method = "health", paramsJson = null)
|
||||
assertEquals("""{"value":123}""", payload)
|
||||
server.await()
|
||||
|
||||
@@ -25,6 +25,11 @@ actor BridgeSession {
|
||||
private var serverEventSubscribers: [UUID: AsyncStream<BridgeEventFrame>.Continuation] = [:]
|
||||
|
||||
private(set) var state: State = .idle
|
||||
private var canvasHostUrl: String?
|
||||
|
||||
func currentCanvasHostUrl() -> String? {
|
||||
self.canvasHostUrl
|
||||
}
|
||||
|
||||
func currentRemoteAddress() -> String? {
|
||||
guard let endpoint = self.connection?.currentPath?.remoteEndpoint else { return nil }
|
||||
@@ -101,6 +106,7 @@ actor BridgeSession {
|
||||
if base.type == "hello-ok" {
|
||||
let ok = try self.decoder.decode(BridgeHelloOk.self, from: data)
|
||||
self.state = .connected(serverName: ok.serverName)
|
||||
self.canvasHostUrl = ok.canvasHostUrl?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
await onConnected?(ok.serverName)
|
||||
} else if base.type == "error" {
|
||||
let err = try self.decoder.decode(BridgeErrorFrame.self, from: data)
|
||||
@@ -210,6 +216,7 @@ actor BridgeSession {
|
||||
self.connection = nil
|
||||
self.queue = nil
|
||||
self.buffer = Data()
|
||||
self.canvasHostUrl = nil
|
||||
|
||||
let pending = self.pendingRPC.values
|
||||
self.pendingRPC.removeAll()
|
||||
|
||||
@@ -143,6 +143,13 @@ final class NodeAppModel {
|
||||
}
|
||||
}
|
||||
|
||||
private func resolveA2UIHostURL() async -> String? {
|
||||
guard let raw = await self.bridge.currentCanvasHostUrl() else { return nil }
|
||||
let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !trimmed.isEmpty, let base = URL(string: trimmed) else { return nil }
|
||||
return base.appendingPathComponent("__clawdis__/a2ui/").absoluteString
|
||||
}
|
||||
|
||||
func setScenePhase(_ phase: ScenePhase) {
|
||||
switch phase {
|
||||
case .background:
|
||||
@@ -436,12 +443,22 @@ final class NodeAppModel {
|
||||
return BridgeInvokeResponse(id: req.id, ok: true, payloadJSON: payload)
|
||||
|
||||
case ClawdisCanvasA2UICommand.reset.rawValue:
|
||||
self.screen.showDefaultCanvas()
|
||||
guard let a2uiUrl = await self.resolveA2UIHostURL() else {
|
||||
return BridgeInvokeResponse(
|
||||
id: req.id,
|
||||
ok: false,
|
||||
error: ClawdisNodeError(
|
||||
code: .unavailable,
|
||||
message: "A2UI_HOST_NOT_CONFIGURED: gateway did not advertise canvas host"))
|
||||
}
|
||||
self.screen.navigate(to: a2uiUrl)
|
||||
if await !self.screen.waitForA2UIReady(timeoutMs: 5000) {
|
||||
return BridgeInvokeResponse(
|
||||
id: req.id,
|
||||
ok: false,
|
||||
error: ClawdisNodeError(code: .unavailable, message: "A2UI not ready"))
|
||||
error: ClawdisNodeError(
|
||||
code: .unavailable,
|
||||
message: "A2UI_HOST_UNAVAILABLE: A2UI host not reachable"))
|
||||
}
|
||||
|
||||
let json = try await self.screen.eval(javaScript: """
|
||||
@@ -468,12 +485,22 @@ final class NodeAppModel {
|
||||
}
|
||||
}
|
||||
|
||||
self.screen.showDefaultCanvas()
|
||||
guard let a2uiUrl = await self.resolveA2UIHostURL() else {
|
||||
return BridgeInvokeResponse(
|
||||
id: req.id,
|
||||
ok: false,
|
||||
error: ClawdisNodeError(
|
||||
code: .unavailable,
|
||||
message: "A2UI_HOST_NOT_CONFIGURED: gateway did not advertise canvas host"))
|
||||
}
|
||||
self.screen.navigate(to: a2uiUrl)
|
||||
if await !self.screen.waitForA2UIReady(timeoutMs: 5000) {
|
||||
return BridgeInvokeResponse(
|
||||
id: req.id,
|
||||
ok: false,
|
||||
error: ClawdisNodeError(code: .unavailable, message: "A2UI not ready"))
|
||||
error: ClawdisNodeError(
|
||||
code: .unavailable,
|
||||
message: "A2UI_HOST_UNAVAILABLE: A2UI host not reachable"))
|
||||
}
|
||||
|
||||
let messagesJSON = try ClawdisCanvasA2UIJSONL.encodeMessagesJSONArray(messages)
|
||||
|
||||
@@ -199,11 +199,6 @@ final class ScreenController {
|
||||
name: "scaffold",
|
||||
ext: "html",
|
||||
subdirectory: "CanvasScaffold")
|
||||
private static let a2uiIndexURL: URL? = ScreenController.bundledResourceURL(
|
||||
name: "index",
|
||||
ext: "html",
|
||||
subdirectory: "CanvasA2UI")
|
||||
|
||||
func isTrustedCanvasUIURL(_ url: URL) -> Bool {
|
||||
guard url.isFileURL else { return false }
|
||||
let std = url.standardizedFileURL
|
||||
@@ -212,11 +207,6 @@ final class ScreenController {
|
||||
{
|
||||
return true
|
||||
}
|
||||
if let expected = Self.a2uiIndexURL,
|
||||
std == expected.standardizedFileURL
|
||||
{
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import AppKit
|
||||
import ClawdisIPC
|
||||
import ClawdisKit
|
||||
import Foundation
|
||||
import OSLog
|
||||
|
||||
@@ -192,12 +191,12 @@ final class CanvasManager {
|
||||
if path.hasPrefix("/") { path.removeFirst() }
|
||||
path = path.removingPercentEncoding ?? path
|
||||
|
||||
// Root special-case: built-in shell page when no index exists.
|
||||
// Root special-case: built-in scaffold page when no index exists.
|
||||
if path.isEmpty {
|
||||
let a = sessionDir.appendingPathComponent("index.html", isDirectory: false)
|
||||
let b = sessionDir.appendingPathComponent("index.htm", isDirectory: false)
|
||||
if fm.fileExists(atPath: a.path) || fm.fileExists(atPath: b.path) { return .ok }
|
||||
return Self.hasBundledA2UIShell() ? .a2uiShell : .welcome
|
||||
return .welcome
|
||||
}
|
||||
|
||||
// Direct file or directory.
|
||||
@@ -229,11 +228,5 @@ final class CanvasManager {
|
||||
return fm.fileExists(atPath: b.path)
|
||||
}
|
||||
|
||||
private static func hasBundledA2UIShell() -> Bool {
|
||||
let bundle = ClawdisKitResources.bundle
|
||||
if bundle.url(forResource: "index", withExtension: "html", subdirectory: "CanvasA2UI") != nil {
|
||||
return true
|
||||
}
|
||||
return bundle.url(forResource: "index", withExtension: "html") != nil
|
||||
}
|
||||
// no bundled A2UI shell; scaffold fallback is purely visual
|
||||
}
|
||||
@@ -8,8 +8,6 @@ private let canvasLogger = Logger(subsystem: "com.steipete.clawdis", category: "
|
||||
final class CanvasSchemeHandler: NSObject, WKURLSchemeHandler {
|
||||
private let root: URL
|
||||
|
||||
private static let builtinPrefix = "__clawdis__/a2ui"
|
||||
|
||||
init(root: URL) {
|
||||
self.root = root
|
||||
}
|
||||
@@ -67,10 +65,6 @@ final class CanvasSchemeHandler: NSObject, WKURLSchemeHandler {
|
||||
if path.hasPrefix("/") { path.removeFirst() }
|
||||
path = path.removingPercentEncoding ?? path
|
||||
|
||||
if let builtin = self.builtinResponse(requestPath: path) {
|
||||
return builtin
|
||||
}
|
||||
|
||||
// Special-case: welcome page when root index is missing.
|
||||
if path.isEmpty {
|
||||
let indexA = sessionRoot.appendingPathComponent("index.html", isDirectory: false)
|
||||
@@ -78,7 +72,7 @@ final class CanvasSchemeHandler: NSObject, WKURLSchemeHandler {
|
||||
if !FileManager.default.fileExists(atPath: indexA.path),
|
||||
!FileManager.default.fileExists(atPath: indexB.path)
|
||||
{
|
||||
return self.a2uiShellPage(sessionRoot: sessionRoot)
|
||||
return self.scaffoldPage(sessionRoot: sessionRoot)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +198,7 @@ final class CanvasSchemeHandler: NSObject, WKURLSchemeHandler {
|
||||
return self.html(body, title: "Canvas")
|
||||
}
|
||||
|
||||
private func a2uiShellPage(sessionRoot: URL) -> CanvasResponse {
|
||||
private func scaffoldPage(sessionRoot: URL) -> CanvasResponse {
|
||||
// Default Canvas UX: when no index exists, show the built-in scaffold page.
|
||||
if let data = self.loadBundledResourceData(relativePath: "CanvasScaffold/scaffold.html") {
|
||||
return CanvasResponse(mime: "text/html", data: data)
|
||||
@@ -214,35 +208,6 @@ final class CanvasSchemeHandler: NSObject, WKURLSchemeHandler {
|
||||
return self.welcomePage(sessionRoot: sessionRoot)
|
||||
}
|
||||
|
||||
private func builtinResponse(requestPath: String) -> CanvasResponse? {
|
||||
let trimmed = requestPath.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !trimmed.isEmpty else { return nil }
|
||||
|
||||
guard trimmed == Self.builtinPrefix
|
||||
|| trimmed == Self.builtinPrefix + "/"
|
||||
|| trimmed.hasPrefix(Self.builtinPrefix + "/")
|
||||
else { return nil }
|
||||
|
||||
let relative = if trimmed == Self.builtinPrefix || trimmed == Self.builtinPrefix + "/" {
|
||||
"index.html"
|
||||
} else {
|
||||
String(trimmed.dropFirst((Self.builtinPrefix + "/").count))
|
||||
}
|
||||
|
||||
if relative.isEmpty { return self.html("Not Found", title: "Canvas: 404") }
|
||||
if relative.contains("..") || relative.contains("\\") {
|
||||
return self.html("Forbidden", title: "Canvas: 403")
|
||||
}
|
||||
|
||||
guard let data = self.loadBundledResourceData(relativePath: "CanvasA2UI/\(relative)") else {
|
||||
return self.html("Not Found", title: "Canvas: 404")
|
||||
}
|
||||
|
||||
let ext = (relative as NSString).pathExtension
|
||||
let mime = CanvasScheme.mimeType(forExtension: ext)
|
||||
return CanvasResponse(mime: mime, data: data)
|
||||
}
|
||||
|
||||
private func loadBundledResourceData(relativePath: String) -> Data? {
|
||||
let trimmed = relativePath.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !trimmed.isEmpty else { return nil }
|
||||
|
||||
@@ -162,10 +162,7 @@ final class CanvasWindowController: NSWindowController, WKNavigationDelegate, NS
|
||||
// Only auto-reload when we are showing local canvas content.
|
||||
guard webView.url?.scheme == CanvasScheme.scheme else { return }
|
||||
|
||||
// Avoid reloading the built-in A2UI shell due to filesystem noise (it does not depend on session
|
||||
// files).
|
||||
let path = webView.url?.path ?? ""
|
||||
if path.hasPrefix("/__clawdis__/a2ui") { return }
|
||||
if path == "/" || path.isEmpty {
|
||||
let indexA = sessionDir.appendingPathComponent("index.html", isDirectory: false)
|
||||
let indexB = sessionDir.appendingPathComponent("index.htm", isDirectory: false)
|
||||
@@ -608,9 +605,14 @@ private final class CanvasA2UIActionMessageHandler: NSObject, WKScriptMessageHan
|
||||
guard message.name == Self.messageName else { return }
|
||||
|
||||
// Only accept actions from local Canvas content (not arbitrary web pages).
|
||||
guard let webView = message.webView,
|
||||
webView.url?.scheme == CanvasScheme.scheme
|
||||
else { return }
|
||||
guard let webView = message.webView, let url = webView.url else { return }
|
||||
if url.scheme == CanvasScheme.scheme {
|
||||
// ok
|
||||
} else if Self.isLocalNetworkCanvasURL(url) {
|
||||
// ok
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
let body: [String: Any] = {
|
||||
if let dict = message.body as? [String: Any] { return dict }
|
||||
@@ -693,6 +695,43 @@ private final class CanvasA2UIActionMessageHandler: NSObject, WKScriptMessageHan
|
||||
}
|
||||
}
|
||||
|
||||
private static func isLocalNetworkCanvasURL(_ url: URL) -> Bool {
|
||||
guard let scheme = url.scheme?.lowercased(), scheme == "http" || scheme == "https" else {
|
||||
return false
|
||||
}
|
||||
guard let host = url.host?.trimmingCharacters(in: .whitespacesAndNewlines), !host.isEmpty else {
|
||||
return false
|
||||
}
|
||||
if host == "localhost" { return true }
|
||||
if host.hasSuffix(".local") { return true }
|
||||
if host.hasSuffix(".ts.net") { return true }
|
||||
if host.hasSuffix(".tailscale.net") { return true }
|
||||
if !host.contains("."), !host.contains(":") { return true }
|
||||
if let ipv4 = Self.parseIPv4(host) {
|
||||
return Self.isLocalNetworkIPv4(ipv4)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private static func parseIPv4(_ host: String) -> (UInt8, UInt8, UInt8, UInt8)? {
|
||||
let parts = host.split(separator: ".", omittingEmptySubsequences: false)
|
||||
guard parts.count == 4 else { return nil }
|
||||
let bytes: [UInt8] = parts.compactMap { UInt8($0) }
|
||||
guard bytes.count == 4 else { return nil }
|
||||
return (bytes[0], bytes[1], bytes[2], bytes[3])
|
||||
}
|
||||
|
||||
private static func isLocalNetworkIPv4(_ ip: (UInt8, UInt8, UInt8, UInt8)) -> Bool {
|
||||
let (a, b, _, _) = ip
|
||||
if a == 10 { return true }
|
||||
if a == 172, (16...31).contains(Int(b)) { return true }
|
||||
if a == 192, b == 168 { return true }
|
||||
if a == 127 { return true }
|
||||
if a == 169, b == 254 { return true }
|
||||
if a == 100, (64...127).contains(Int(b)) { return true }
|
||||
return false
|
||||
}
|
||||
|
||||
// Formatting helpers live in ClawdisKit (`ClawdisCanvasA2UIAction`).
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,12 @@ actor GatewayConnection {
|
||||
self.lastSnapshot = nil
|
||||
}
|
||||
|
||||
func canvasHostUrl() async -> String? {
|
||||
guard let snapshot = self.lastSnapshot else { return nil }
|
||||
let trimmed = snapshot.canvashosturl?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||||
return trimmed.isEmpty ? nil : trimmed
|
||||
}
|
||||
|
||||
func subscribe(bufferingNewest: Int = 100) -> AsyncStream<GatewayPush> {
|
||||
let id = UUID()
|
||||
let snapshot = self.lastSnapshot
|
||||
|
||||
@@ -6,7 +6,6 @@ import Foundation
|
||||
actor MacNodeRuntime {
|
||||
private let cameraCapture = CameraCaptureService()
|
||||
@MainActor private let screenRecorder = ScreenRecordService()
|
||||
private static let a2uiShellPath = "/__clawdis__/a2ui/"
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func handleInvoke(_ req: BridgeInvokeRequest) async -> BridgeInvokeResponse {
|
||||
@@ -248,15 +247,27 @@ actor MacNodeRuntime {
|
||||
|
||||
private func ensureA2UIHost() async throws {
|
||||
if await self.isA2UIReady() { return }
|
||||
guard let a2uiUrl = await self.resolveA2UIHostUrl() else {
|
||||
throw NSError(domain: "Canvas", code: 30, userInfo: [
|
||||
NSLocalizedDescriptionKey: "A2UI_HOST_NOT_CONFIGURED: gateway did not advertise canvas host",
|
||||
])
|
||||
}
|
||||
_ = try await MainActor.run {
|
||||
try CanvasManager.shared.show(sessionKey: "main", path: Self.a2uiShellPath)
|
||||
try CanvasManager.shared.show(sessionKey: "main", path: a2uiUrl)
|
||||
}
|
||||
if await self.isA2UIReady(poll: true) { return }
|
||||
throw NSError(domain: "Canvas", code: 31, userInfo: [
|
||||
NSLocalizedDescriptionKey: "A2UI not ready",
|
||||
NSLocalizedDescriptionKey: "A2UI_HOST_UNAVAILABLE: A2UI host not reachable",
|
||||
])
|
||||
}
|
||||
|
||||
private func resolveA2UIHostUrl() async -> String? {
|
||||
guard let raw = await GatewayConnection.shared.canvasHostUrl() else { return nil }
|
||||
let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !trimmed.isEmpty, let baseUrl = URL(string: trimmed) else { return nil }
|
||||
return baseUrl.appendingPathComponent("__clawdis__/a2ui/").absoluteString
|
||||
}
|
||||
|
||||
private func isA2UIReady(poll: Bool = false) async -> Bool {
|
||||
let deadline = poll ? Date().addingTimeInterval(6.0) : Date()
|
||||
while true {
|
||||
|
||||
@@ -66,9 +66,7 @@ public enum CanvasShowStatus: String, Codable, Sendable {
|
||||
case ok
|
||||
/// Local canvas target did not resolve to a file (404 page).
|
||||
case notFound
|
||||
/// Local canvas root ("/") has no index, so the built-in A2UI shell is shown.
|
||||
case a2uiShell
|
||||
/// Legacy fallback when the built-in shell isn't available (dev misconfiguration).
|
||||
/// Local scaffold fallback (e.g., no index.html present).
|
||||
case welcome
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ public struct HelloOk: Codable {
|
||||
public let server: [String: AnyCodable]
|
||||
public let features: [String: AnyCodable]
|
||||
public let snapshot: Snapshot
|
||||
public let canvashosturl: String?
|
||||
public let policy: [String: AnyCodable]
|
||||
|
||||
public init(
|
||||
@@ -61,6 +62,7 @@ public struct HelloOk: Codable {
|
||||
server: [String: AnyCodable],
|
||||
features: [String: AnyCodable],
|
||||
snapshot: Snapshot,
|
||||
canvashosturl: String?,
|
||||
policy: [String: AnyCodable]
|
||||
) {
|
||||
self.type = type
|
||||
@@ -68,6 +70,7 @@ public struct HelloOk: Codable {
|
||||
self.server = server
|
||||
self.features = features
|
||||
self.snapshot = snapshot
|
||||
self.canvashosturl = canvashosturl
|
||||
self.policy = policy
|
||||
}
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
@@ -76,6 +79,7 @@ public struct HelloOk: Codable {
|
||||
case server
|
||||
case features
|
||||
case snapshot
|
||||
case canvashosturl = "canvasHostUrl"
|
||||
case policy
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,10 +99,12 @@ public struct BridgeHello: Codable, Sendable {
|
||||
public struct BridgeHelloOk: Codable, Sendable {
|
||||
public let type: String
|
||||
public let serverName: String
|
||||
public let canvasHostUrl: String?
|
||||
|
||||
public init(type: String = "hello-ok", serverName: String) {
|
||||
public init(type: String = "hello-ok", serverName: String, canvasHostUrl: String? = nil) {
|
||||
self.type = type
|
||||
self.serverName = serverName
|
||||
self.canvasHostUrl = canvasHostUrl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,16 +85,6 @@
|
||||
pointer-events: none;
|
||||
z-index: 3;
|
||||
}
|
||||
#clawdis-a2ui-wrap {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: none;
|
||||
z-index: 2;
|
||||
}
|
||||
#clawdis-a2ui-wrap clawdis-a2ui-host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
#clawdis-status .card {
|
||||
text-align: center;
|
||||
padding: 16px 18px;
|
||||
@@ -126,9 +116,6 @@
|
||||
<div class="subtitle" id="clawdis-status-subtitle">Waiting for agent</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="clawdis-a2ui-wrap">
|
||||
<clawdis-a2ui-host></clawdis-a2ui-host>
|
||||
</div>
|
||||
<script>
|
||||
(() => {
|
||||
const canvas = document.getElementById('clawdis-canvas');
|
||||
@@ -170,92 +157,6 @@
|
||||
};
|
||||
})();
|
||||
|
||||
(() => {
|
||||
const wrap = document.getElementById('clawdis-a2ui-wrap');
|
||||
if (!wrap) return;
|
||||
|
||||
const candidates = [
|
||||
// iOS (SwiftPM resources flattened)
|
||||
"a2ui.bundle.js",
|
||||
// Android (assets keep directory structure)
|
||||
"../CanvasA2UI/a2ui.bundle.js",
|
||||
"CanvasA2UI/a2ui.bundle.js",
|
||||
];
|
||||
|
||||
const loadScript = (src) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const el = document.createElement("script");
|
||||
el.src = src;
|
||||
el.async = true;
|
||||
el.onload = () => resolve();
|
||||
el.onerror = () => reject(new Error(`failed to load ${src}`));
|
||||
document.head.appendChild(el);
|
||||
});
|
||||
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
|
||||
const installVisibilityHooks = () => {
|
||||
const api = globalThis.clawdisA2UI;
|
||||
if (!api || typeof api.applyMessages !== "function") return false;
|
||||
if (globalThis.__clawdisA2UIVisibilityHooksInstalled) return true;
|
||||
globalThis.__clawdisA2UIVisibilityHooksInstalled = true;
|
||||
|
||||
const show = () => { wrap.style.display = "block"; };
|
||||
const hide = () => { wrap.style.display = "none"; };
|
||||
|
||||
const sync = () => {
|
||||
try {
|
||||
const surfaces =
|
||||
typeof api.getSurfaces === "function" ? api.getSurfaces() : [];
|
||||
if (Array.isArray(surfaces) && surfaces.length > 0) show();
|
||||
else hide();
|
||||
} catch {
|
||||
hide();
|
||||
}
|
||||
};
|
||||
|
||||
const origApply = api.applyMessages.bind(api);
|
||||
api.applyMessages = (messages) => {
|
||||
const res = origApply(messages);
|
||||
sync();
|
||||
return res;
|
||||
};
|
||||
const origReset = api.reset.bind(api);
|
||||
api.reset = () => {
|
||||
const res = origReset();
|
||||
hide();
|
||||
return res;
|
||||
};
|
||||
|
||||
hide();
|
||||
return true;
|
||||
};
|
||||
|
||||
(async () => {
|
||||
if (globalThis.clawdisA2UI) {
|
||||
installVisibilityHooks();
|
||||
return;
|
||||
}
|
||||
|
||||
let loaded = false;
|
||||
for (const src of candidates) {
|
||||
try {
|
||||
await loadScript(src);
|
||||
loaded = true;
|
||||
break;
|
||||
} catch {
|
||||
// try next
|
||||
}
|
||||
}
|
||||
if (!loaded) return;
|
||||
|
||||
// Wait for custom element upgrade + connectedCallback to publish globalThis.clawdisA2UI.
|
||||
for (let i = 0; i < 60; i += 1) {
|
||||
if (installVisibilityHooks()) return;
|
||||
await sleep(50);
|
||||
}
|
||||
})().catch(() => {});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -28,40 +28,4 @@ import Testing
|
||||
#expect(msg.contains("instance=ipad16_6 ctx={\"city\":\"Vienna\"}"))
|
||||
#expect(msg.hasSuffix(" default=update_canvas"))
|
||||
}
|
||||
|
||||
@Test func a2uiBundleSupportsAndroidBridgeFallback() throws {
|
||||
guard let url = ClawdisKitResources.bundle.url(forResource: "a2ui.bundle", withExtension: "js")
|
||||
else {
|
||||
throw NSError(domain: "Tests", code: 1, userInfo: [
|
||||
NSLocalizedDescriptionKey: "Missing resource a2ui.bundle.js",
|
||||
])
|
||||
}
|
||||
let js = try String(contentsOf: url, encoding: .utf8)
|
||||
#expect(js.contains("clawdisCanvasA2UIAction"))
|
||||
#expect(js.contains("globalThis.clawdisCanvasA2UIAction"))
|
||||
}
|
||||
|
||||
@Test func a2uiBundleWrapsDynamicCssValues() throws {
|
||||
guard let url = ClawdisKitResources.bundle.url(forResource: "a2ui.bundle", withExtension: "js")
|
||||
else {
|
||||
throw NSError(domain: "Tests", code: 1, userInfo: [
|
||||
NSLocalizedDescriptionKey: "Missing resource a2ui.bundle.js",
|
||||
])
|
||||
}
|
||||
let js = try String(contentsOf: url, encoding: .utf8)
|
||||
#expect(js.contains("blur(${r(statusBlur)})"))
|
||||
#expect(js.contains("box-shadow: ${r(statusShadow)}"))
|
||||
}
|
||||
|
||||
@Test func a2uiBundleStylesModalBackdrop() throws {
|
||||
guard let url = ClawdisKitResources.bundle.url(forResource: "a2ui.bundle", withExtension: "js")
|
||||
else {
|
||||
throw NSError(domain: "Tests", code: 1, userInfo: [
|
||||
NSLocalizedDescriptionKey: "Missing resource a2ui.bundle.js",
|
||||
])
|
||||
}
|
||||
let js = try String(contentsOf: url, encoding: .utf8)
|
||||
#expect(js.contains("::backdrop"))
|
||||
#expect(js.contains("backdrop-filter: blur(6px)"))
|
||||
}
|
||||
}
|
||||
+9
-6
@@ -8,14 +8,17 @@ import { themeContext } from "@clawdis/a2ui-theme-context";
|
||||
|
||||
const modalStyles = css`
|
||||
dialog {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 24px;
|
||||
border: none;
|
||||
background: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
max-width: calc(100vw - 32px);
|
||||
max-height: calc(100vh - 32px);
|
||||
background: rgba(5, 8, 16, 0.65);
|
||||
backdrop-filter: blur(6px);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
dialog::backdrop {
|
||||
|
||||
@@ -5,7 +5,14 @@ import { defineConfig } from "rolldown";
|
||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(here, "../../../../..");
|
||||
const fromHere = (p) => path.resolve(here, p);
|
||||
const outputFile = path.resolve(here, "../../Sources/ClawdisKit/Resources/CanvasA2UI/a2ui.bundle.js");
|
||||
const outputFile = path.resolve(
|
||||
here,
|
||||
"../../../../..",
|
||||
"src",
|
||||
"canvas-host",
|
||||
"a2ui",
|
||||
"a2ui.bundle.js",
|
||||
);
|
||||
|
||||
const a2uiLitDist = path.resolve(repoRoot, "vendor/a2ui/renderers/lit/dist/src");
|
||||
const a2uiThemeContext = path.resolve(a2uiLitDist, "0.8/ui/context/theme.js");
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
"indentWidth": 2,
|
||||
"indentStyle": "space"
|
||||
},
|
||||
"files": {
|
||||
"includes": [
|
||||
"src/**/*.ts"
|
||||
]
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
"scripts": {
|
||||
"dev": "tsx src/index.ts",
|
||||
"docs:list": "tsx scripts/docs-list.ts",
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"build": "pnpm canvas:a2ui:bundle && tsc -p tsconfig.json && tsx scripts/canvas-a2ui-copy.ts",
|
||||
"ui:install": "pnpm -C ui install",
|
||||
"ui:dev": "pnpm -C ui dev",
|
||||
"ui:build": "pnpm -C ui build",
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const srcDir = path.join(repoRoot, "src", "canvas-host", "a2ui");
|
||||
const outDir = path.join(repoRoot, "dist", "canvas-host", "a2ui");
|
||||
|
||||
async function main() {
|
||||
await fs.stat(path.join(srcDir, "index.html"));
|
||||
await fs.stat(path.join(srcDir, "a2ui.bundle.js"));
|
||||
await fs.mkdir(path.dirname(outDir), { recursive: true });
|
||||
await fs.cp(srcDir, outDir, { recursive: true });
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(String(err));
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -156,6 +156,10 @@ if [[ "${SKIP_GATEWAY_PACKAGE:-0}" != "1" ]]; then
|
||||
--define "__CLAWDIS_VERSION__=\\\"$PKG_VERSION\\\""
|
||||
chmod +x "$CLI_OUT"
|
||||
|
||||
echo "🎨 Copying gateway A2UI host assets"
|
||||
rm -rf "$RELAY_DIR/a2ui"
|
||||
cp -R "$ROOT_DIR/src/canvas-host/a2ui" "$RELAY_DIR/a2ui"
|
||||
|
||||
echo "📄 Writing embedded runtime package.json (Pi compatibility)"
|
||||
cat > "$RELAY_DIR/package.json" <<JSON
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ log "==> Killing existing Clawdis instances"
|
||||
kill_all_clawdis
|
||||
stop_launch_agent
|
||||
|
||||
# Bundle built-in Canvas A2UI shell (single-file JS, shipped in the app bundle).
|
||||
# Bundle Gateway-hosted Canvas A2UI assets.
|
||||
run_step "bundle canvas a2ui" bash -lc "cd '${ROOT_DIR}' && pnpm canvas:a2ui:bundle"
|
||||
|
||||
# 2) Rebuild into the same path the packager consumes (.build).
|
||||
|
||||
+127
-124
@@ -15,7 +15,7 @@ var __export = (all, symbols) => {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/css-tag.js
|
||||
//#region node_modules/@lit/reactive-element/css-tag.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC
|
||||
@@ -60,7 +60,7 @@ const r = (t$7) => new n$9("string" == typeof t$7 ? t$7 : t$7 + "", void 0, s$8)
|
||||
})(t$7) : t$7;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/reactive-element.js
|
||||
//#region node_modules/@lit/reactive-element/reactive-element.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -291,7 +291,7 @@ var y = class extends HTMLElement {
|
||||
y.elementStyles = [], y.shadowRootOptions = { mode: "open" }, y[d$2("elementProperties")] = new Map(), y[d$2("finalized")] = new Map(), p$2?.({ ReactiveElement: y }), (a$1.reactiveElementVersions ??= []).push("2.1.1");
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/lit-html.js
|
||||
//#region node_modules/lit-html/lit-html.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -559,7 +559,7 @@ const B = (t$7, i$10, s$9) => {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-element@4.2.1/node_modules/lit-element/lit-element.js
|
||||
//#region node_modules/lit-element/lit-element.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -599,7 +599,7 @@ const n$7 = {
|
||||
(s$6.litElementVersions ??= []).push("4.2.1");
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/is-server.js
|
||||
//#region node_modules/lit-html/is-server.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google LLC
|
||||
@@ -608,7 +608,7 @@ const n$7 = {
|
||||
const o$9 = !1;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directive.js
|
||||
//#region node_modules/lit-html/directive.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -642,7 +642,7 @@ var i$3 = class {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directive-helpers.js
|
||||
//#region node_modules/lit-html/directive-helpers.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
@@ -678,7 +678,7 @@ var i$3 = class {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directives/repeat.js
|
||||
//#region node_modules/lit-html/directives/repeat.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -739,7 +739,7 @@ const u$1 = (e$14, s$9, t$7) => {
|
||||
});
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/lib/context-request-event.js
|
||||
//#region node_modules/@lit/context/lib/context-request-event.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
@@ -755,7 +755,7 @@ var s$2 = class extends Event {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/lib/create-context.js
|
||||
//#region node_modules/@lit/context/lib/create-context.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
@@ -766,7 +766,7 @@ function n$3(n$11) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/lib/controllers/context-consumer.js
|
||||
//#region node_modules/@lit/context/lib/controllers/context-consumer.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
@@ -793,7 +793,7 @@ function n$3(n$11) {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/lib/value-notifier.js
|
||||
//#region node_modules/@lit/context/lib/value-notifier.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
@@ -832,7 +832,7 @@ var s$4 = class {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/lib/controllers/context-provider.js
|
||||
//#region node_modules/@lit/context/lib/controllers/context-provider.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
@@ -868,7 +868,7 @@ var i$2 = class extends s$4 {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/lib/context-root.js
|
||||
//#region node_modules/@lit/context/lib/context-root.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
@@ -908,7 +908,7 @@ var i$2 = class extends s$4 {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/lib/decorators/provide.js
|
||||
//#region node_modules/@lit/context/lib/decorators/provide.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -963,7 +963,7 @@ var i$2 = class extends s$4 {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/lib/decorators/consume.js
|
||||
//#region node_modules/@lit/context/lib/decorators/consume.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google LLC
|
||||
@@ -2260,7 +2260,7 @@ var A2uiMessageProcessor = class A2uiMessageProcessor {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/signal-polyfill@0.2.2/node_modules/signal-polyfill/dist/index.js
|
||||
//#region node_modules/signal-polyfill/dist/index.js
|
||||
var __defProp = Object.defineProperty;
|
||||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
||||
enumerable: true,
|
||||
@@ -2818,7 +2818,7 @@ var Signal;
|
||||
})(Signal || (Signal = {}));
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/signal-utils@0.21.1_signal-polyfill@0.2.2/node_modules/signal-utils/dist/-private/util.ts.js
|
||||
//#region node_modules/signal-utils/dist/-private/util.ts.js
|
||||
/**
|
||||
* equality check here is always false so that we can dirty the storage
|
||||
* via setting to _anything_
|
||||
@@ -2845,7 +2845,7 @@ function fnCacheFor(context) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/signal-utils@0.21.1_signal-polyfill@0.2.2/node_modules/signal-utils/dist/array.ts.js
|
||||
//#region node_modules/signal-utils/dist/array.ts.js
|
||||
const ARRAY_GETTER_METHODS = new Set([
|
||||
Symbol.iterator,
|
||||
"concat",
|
||||
@@ -2978,7 +2978,7 @@ function signalArray(x$1) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/signal-utils@0.21.1_signal-polyfill@0.2.2/node_modules/signal-utils/dist/map.ts.js
|
||||
//#region node_modules/signal-utils/dist/map.ts.js
|
||||
var SignalMap = class {
|
||||
collection = createStorage();
|
||||
storages = new Map();
|
||||
@@ -3056,7 +3056,7 @@ var SignalMap = class {
|
||||
Object.setPrototypeOf(SignalMap.prototype, Map.prototype);
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/signal-utils@0.21.1_signal-polyfill@0.2.2/node_modules/signal-utils/dist/object.ts.js
|
||||
//#region node_modules/signal-utils/dist/object.ts.js
|
||||
/**
|
||||
* Implementation based of tracked-built-ins' TrackedObject
|
||||
* https://github.com/tracked-tools/tracked-built-ins/blob/master/addon/src/-private/object.js
|
||||
@@ -3145,7 +3145,7 @@ function signalObject(obj) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/signal-utils@0.21.1_signal-polyfill@0.2.2/node_modules/signal-utils/dist/set.ts.js
|
||||
//#region node_modules/signal-utils/dist/set.ts.js
|
||||
var SignalSet = class {
|
||||
collection = createStorage();
|
||||
storages = new Map();
|
||||
@@ -3968,7 +3968,7 @@ const Data = {
|
||||
const Schemas = { A2UIClientEventMessage: server_to_client_with_standard_catalog_default };
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/custom-element.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/custom-element.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -3981,7 +3981,7 @@ const t = (t$7) => (e$14, o$14) => {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/property.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/property.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4024,7 +4024,7 @@ function n(t$7) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/state.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/state.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4038,7 +4038,7 @@ function n(t$7) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/event-options.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/event-options.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4052,7 +4052,7 @@ function t$2(t$7) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/base.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/base.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4061,7 +4061,7 @@ function t$2(t$7) {
|
||||
const e$6 = (e$14, t$7, c$7) => (c$7.configurable = !0, c$7.enumerable = !0, Reflect.decorate && "object" != typeof t$7 && Object.defineProperty(e$14, t$7, c$7), c$7);
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/query.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/query.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4093,7 +4093,7 @@ const e$6 = (e$14, t$7, c$7) => (c$7.configurable = !0, c$7.enumerable = !0, Ref
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/query-all.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/query-all.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4107,7 +4107,7 @@ function r$6(r$11) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/query-async.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/query-async.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4120,7 +4120,7 @@ function r$5(r$11) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/query-assigned-elements.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/query-assigned-elements.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
@@ -4136,7 +4136,7 @@ function r$5(r$11) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit+reactive-element@2.1.1/node_modules/@lit/reactive-element/decorators/query-assigned-nodes.js
|
||||
//#region node_modules/@lit/reactive-element/decorators/query-assigned-nodes.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4152,7 +4152,7 @@ function r$5(r$11) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit-labs+signals@0.1.3/node_modules/@lit-labs/signals/lib/signal-watcher.js
|
||||
//#region node_modules/@lit-labs/signals/lib/signal-watcher.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google LLC
|
||||
@@ -4215,7 +4215,7 @@ function e$5(e$14) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/async-directive.js
|
||||
//#region node_modules/lit-html/async-directive.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -4273,7 +4273,7 @@ var f = class extends i$3 {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit-labs+signals@0.1.3/node_modules/@lit-labs/signals/lib/watch.js
|
||||
//#region node_modules/@lit-labs/signals/lib/watch.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google LLC
|
||||
@@ -4318,7 +4318,7 @@ var f = class extends i$3 {
|
||||
const o$4 = e$1(h$1);
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit-labs+signals@0.1.3/node_modules/@lit-labs/signals/lib/html-tag.js
|
||||
//#region node_modules/@lit-labs/signals/lib/html-tag.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google LLC
|
||||
@@ -4326,7 +4326,7 @@ const o$4 = e$1(h$1);
|
||||
*/ const m = (o$14) => (t$7, ...m$3) => o$14(t$7, ...m$3.map(((o$15) => o$15 instanceof Signal.State || o$15 instanceof Signal.Computed ? o$4(o$15) : o$15))), l = m(x), r$2 = m(b);
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/@lit-labs+signals@0.1.3/node_modules/@lit-labs/signals/index.js
|
||||
//#region node_modules/@lit-labs/signals/index.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google LLC
|
||||
@@ -4334,7 +4334,7 @@ const o$4 = e$1(h$1);
|
||||
*/ const l$1 = Signal.State, o$5 = Signal.Computed, r$3 = (l$5, o$14) => new Signal.State(l$5, o$14), i$5 = (l$5, o$14) => new Signal.Computed(l$5, o$14);
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directives/map.js
|
||||
//#region node_modules/lit-html/directives/map.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
@@ -4348,7 +4348,7 @@ function* o$3(o$14, f$4) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/signal-utils@0.21.1_signal-polyfill@0.2.2/node_modules/signal-utils/dist/subtle/microtask-effect.ts.js
|
||||
//#region node_modules/signal-utils/dist/subtle/microtask-effect.ts.js
|
||||
let pending = false;
|
||||
let watcher = new Signal.subtle.Watcher(() => {
|
||||
if (!pending) {
|
||||
@@ -5084,7 +5084,7 @@ let Root = (() => {
|
||||
})();
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directives/class-map.js
|
||||
//#region node_modules/lit-html/directives/class-map.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
@@ -5113,7 +5113,7 @@ let Root = (() => {
|
||||
});
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directives/style-map.js
|
||||
//#region node_modules/lit-html/directives/style-map.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google LLC
|
||||
@@ -7160,7 +7160,7 @@ let MultipleChoice = (() => {
|
||||
})();
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directives/ref.js
|
||||
//#region node_modules/lit-html/directives/ref.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
@@ -8585,7 +8585,7 @@ let TextField = (() => {
|
||||
})();
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directives/unsafe-html.js
|
||||
//#region node_modules/lit-html/directives/unsafe-html.js
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google LLC
|
||||
@@ -8612,7 +8612,7 @@ e$2.directiveName = "unsafeHTML", e$2.resultType = 1;
|
||||
const o$1 = e$1(e$2);
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/decode.mjs
|
||||
//#region node_modules/mdurl/lib/decode.mjs
|
||||
const decodeCache = {};
|
||||
function getDecodeCache(exclude) {
|
||||
let cache = decodeCache[exclude];
|
||||
@@ -8696,7 +8696,7 @@ decode$2.componentChars = "";
|
||||
var decode_default = decode$2;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/encode.mjs
|
||||
//#region node_modules/mdurl/lib/encode.mjs
|
||||
const encodeCache = {};
|
||||
function getEncodeCache(exclude) {
|
||||
let cache = encodeCache[exclude];
|
||||
@@ -8761,7 +8761,7 @@ encode$2.componentChars = "-_.!~*'()";
|
||||
var encode_default = encode$2;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/format.mjs
|
||||
//#region node_modules/mdurl/lib/format.mjs
|
||||
function format(url) {
|
||||
let result = "";
|
||||
result += url.protocol || "";
|
||||
@@ -8781,7 +8781,7 @@ function format(url) {
|
||||
;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/parse.mjs
|
||||
//#region node_modules/mdurl/lib/parse.mjs
|
||||
function Url() {
|
||||
this.protocol = null;
|
||||
this.slashes = null;
|
||||
@@ -8990,7 +8990,7 @@ Url.prototype.parseHost = function(host) {
|
||||
var parse_default = urlParse;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/index.mjs
|
||||
//#region node_modules/mdurl/index.mjs
|
||||
var mdurl_exports = /* @__PURE__ */ __export({
|
||||
decode: () => decode_default,
|
||||
encode: () => encode_default,
|
||||
@@ -8999,31 +8999,31 @@ var mdurl_exports = /* @__PURE__ */ __export({
|
||||
});
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/properties/Any/regex.mjs
|
||||
//#region node_modules/uc.micro/properties/Any/regex.mjs
|
||||
var regex_default = /[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Cc/regex.mjs
|
||||
//#region node_modules/uc.micro/categories/Cc/regex.mjs
|
||||
var regex_default$1 = /[\0-\x1F\x7F-\x9F]/;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Cf/regex.mjs
|
||||
//#region node_modules/uc.micro/categories/Cf/regex.mjs
|
||||
var regex_default$4 = /[\xAD\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC3F]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/P/regex.mjs
|
||||
//#region node_modules/uc.micro/categories/P/regex.mjs
|
||||
var regex_default$3 = /[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDEAD\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]/;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/S/regex.mjs
|
||||
//#region node_modules/uc.micro/categories/S/regex.mjs
|
||||
var regex_default$5 = /[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC2\uFD40-\uFD4F\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF76\uDF7B-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDE53\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC5\uDECE-\uDEDB\uDEE0-\uDEE8\uDEF0-\uDEF8\uDF00-\uDF92\uDF94-\uDFCA]/;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Z/regex.mjs
|
||||
//#region node_modules/uc.micro/categories/Z/regex.mjs
|
||||
var regex_default$2 = /[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/index.mjs
|
||||
//#region node_modules/uc.micro/index.mjs
|
||||
var uc_exports = /* @__PURE__ */ __export({
|
||||
Any: () => regex_default,
|
||||
Cc: () => regex_default$1,
|
||||
@@ -9034,15 +9034,15 @@ var uc_exports = /* @__PURE__ */ __export({
|
||||
});
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/generated/decode-data-html.js
|
||||
//#region node_modules/entities/lib/esm/generated/decode-data-html.js
|
||||
var decode_data_html_default = new Uint16Array("ᵁ<Õıʊҝջאٵ۞ޢߖࠏઑඡ༉༦ረዡᐕᒝᓃᓟᔥ\0\0\0\0\0\0ᕫᛍᦍᰒᷝ↰⊍⏀⏻⑂⠤⤒ⴈ⹈⿎〖㊺㘹㞬㣾㨨㩱㫠㬮ࠀEMabcfglmnoprstu\\bfms¦³¹ÈÏlig耻Æ䃆P耻&䀦cute耻Á䃁reve;䄂Āiyx}rc耻Â䃂;䐐r;쀀𝔄rave耻À䃀pha;䎑acr;䄀d;橓Āgp¡on;䄄f;쀀𝔸plyFunction;恡ing耻Å䃅Ācs¾Ãr;쀀𝒜ign;扔ilde耻Ã䃃ml耻Ä䃄ЀaceforsuåûþėĜĢħĪĀcrêòkslash;或Ŷöø;櫧ed;挆y;䐑ƀcrtąċĔause;戵noullis;愬a;䎒r;쀀𝔅pf;쀀𝔹eve;䋘còēmpeq;扎܀HOacdefhilorsuōőŖƀƞƢƵƷƺǜȕɳɸɾcy;䐧PY耻©䂩ƀcpyŝŢźute;䄆Ā;iŧŨ拒talDifferentialD;慅leys;愭ȀaeioƉƎƔƘron;䄌dil耻Ç䃇rc;䄈nint;戰ot;䄊ĀdnƧƭilla;䂸terDot;䂷òſi;䎧rcleȀDMPTLJNjǑǖot;抙inus;抖lus;投imes;抗oĀcsǢǸkwiseContourIntegral;戲eCurlyĀDQȃȏoubleQuote;思uote;怙ȀlnpuȞȨɇɕonĀ;eȥȦ户;橴ƀgitȯȶȺruent;扡nt;戯ourIntegral;戮ĀfrɌɎ;愂oduct;成nterClockwiseContourIntegral;戳oss;樯cr;쀀𝒞pĀ;Cʄʅ拓ap;才րDJSZacefiosʠʬʰʴʸˋ˗ˡ˦̳ҍĀ;oŹʥtrahd;椑cy;䐂cy;䐅cy;䐏ƀgrsʿ˄ˇger;怡r;憡hv;櫤Āayː˕ron;䄎;䐔lĀ;t˝˞戇a;䎔r;쀀𝔇Āaf˫̧Ācm˰̢riticalȀADGT̖̜̀̆cute;䂴oŴ̋̍;䋙bleAcute;䋝rave;䁠ilde;䋜ond;拄ferentialD;慆Ѱ̽\0\0\0͔͂\0Ѕf;쀀𝔻ƀ;DE͈͉͍䂨ot;惜qual;扐blèCDLRUVͣͲϏϢϸontourIntegraìȹoɴ\0\0ͻ»͉nArrow;懓Āeo·ΤftƀARTΐΖΡrrow;懐ightArrow;懔eåˊngĀLRΫτeftĀARγιrrow;柸ightArrow;柺ightArrow;柹ightĀATϘϞrrow;懒ee;抨pɁϩ\0\0ϯrrow;懑ownArrow;懕erticalBar;戥ǹABLRTaВЪаўѿͼrrowƀ;BUНОТ憓ar;椓pArrow;懵reve;䌑eft˒к\0ц\0ѐightVector;楐eeVector;楞ectorĀ;Bљњ憽ar;楖ightǔѧ\0ѱeeVector;楟ectorĀ;BѺѻ懁ar;楗eeĀ;A҆҇护rrow;憧ĀctҒҗr;쀀𝒟rok;䄐ࠀNTacdfglmopqstuxҽӀӄӋӞӢӧӮӵԡԯԶՒ՝ՠեG;䅊H耻Ð䃐cute耻É䃉ƀaiyӒӗӜron;䄚rc耻Ê䃊;䐭ot;䄖r;쀀𝔈rave耻È䃈ement;戈ĀapӺӾcr;䄒tyɓԆ\0\0ԒmallSquare;旻erySmallSquare;斫ĀgpԦԪon;䄘f;쀀𝔼silon;䎕uĀaiԼՉlĀ;TՂՃ橵ilde;扂librium;懌Āci՚r;愰m;橳a;䎗ml耻Ë䃋Āipժկsts;戃onentialE;慇ʀcfiosօֈ֍ֲy;䐤r;쀀𝔉lledɓ֗\0\0֣mallSquare;旼erySmallSquare;斪Ͱֺ\0ֿ\0\0ׄf;쀀𝔽All;戀riertrf;愱còJTabcdfgorstרׯؒؖ؛؝أ٬ٲcy;䐃耻>䀾mmaĀ;d䎓;䏜reve;䄞ƀeiy؇،ؐdil;䄢rc;䄜;䐓ot;䄠r;쀀𝔊;拙pf;쀀𝔾eater̀EFGLSTصلَٖٛ٦qualĀ;Lؾؿ扥ess;招ullEqual;执reater;檢ess;扷lantEqual;橾ilde;扳cr;쀀𝒢;扫ЀAacfiosuڅڋږڛڞڪھۊRDcy;䐪Āctڐڔek;䋇;䁞irc;䄤r;愌lbertSpace;愋ǰگ\0ڲf;愍izontalLine;攀Āctۃۅòکrok;䄦mpńېۘownHumðįqual;扏܀EJOacdfgmnostuۺ۾܃܇ܚܞܡܨ݄ݸދޏޕcy;䐕lig;䄲cy;䐁cute耻Í䃍Āiyܓܘrc耻Î䃎;䐘ot;䄰r;愑rave耻Ì䃌ƀ;apܠܯܿĀcgܴܷr;䄪inaryI;慈lieóϝǴ݉\0ݢĀ;eݍݎ戬Āgrݓݘral;戫section;拂isibleĀCTݬݲomma;恣imes;恢ƀgptݿރވon;䄮f;쀀𝕀a;䎙cr;愐ilde;䄨ǫޚ\0ޞcy;䐆l耻Ï䃏ʀcfosuެ߂ߐĀiyޱrc;䄴;䐙r;쀀𝔍pf;쀀𝕁ǣ߇\0ߌr;쀀𝒥rcy;䐈kcy;䐄HJacfosߤߨ߽߬߱ࠂࠈcy;䐥cy;䐌ppa;䎚Āey߶dil;䄶;䐚r;쀀𝔎pf;쀀𝕂cr;쀀𝒦րJTaceflmostࠥࠩࠬࡐࡣসে্ੇcy;䐉耻<䀼ʀcmnpr࠷࠼ࡁࡄࡍute;䄹bda;䎛g;柪lacetrf;愒r;憞ƀaeyࡗࡡron;䄽dil;䄻;䐛Āfsࡨ॰tԀACDFRTUVarࡾࢩࢱࣦ࣠ࣼयज़ΐ४ĀnrࢃgleBracket;柨rowƀ;BR࢙࢚࢞憐ar;懤ightArrow;懆eiling;挈oǵࢷ\0ࣃbleBracket;柦nǔࣈ\0࣒eeVector;楡ectorĀ;Bࣛࣜ懃ar;楙loor;挊ightĀAV࣯ࣵrrow;憔ector;楎Āerँगeƀ;AVउऊऐ抣rrow;憤ector;楚iangleƀ;BEतथऩ抲ar;槏qual;抴pƀDTVषूौownVector;楑eeVector;楠ectorĀ;Bॖॗ憿ar;楘ectorĀ;B॥०憼ar;楒ightáΜs̀EFGLSTॾঋকঝঢভqualGreater;拚ullEqual;扦reater;扶ess;檡lantEqual;橽ilde;扲r;쀀𝔏Ā;eঽা拘ftarrow;懚idot;䄿ƀnpwਖਛgȀLRlr৷ਂਐeftĀAR০৬rrow;柵ightArrow;柷ightArrow;柶eftĀarγਊightáοightáϊf;쀀𝕃erĀLRਢਬeftArrow;憙ightArrow;憘ƀchtਾੀੂòࡌ;憰rok;䅁;扪Ѐacefiosuਗ਼અઋp;椅y;䐜Ādl੯iumSpace;恟lintrf;愳r;쀀𝔐nusPlus;戓pf;쀀𝕄cò੶;䎜ҀJacefostuણધભીଔଙඑඞcy;䐊cute;䅃ƀaeyહાron;䅇dil;䅅;䐝ƀgswે૰ativeƀMTV૨ediumSpace;怋hiĀcn૦ëeryThiîtedĀGLଆreaterGreateòٳessLesóੈLine;䀊r;쀀𝔑ȀBnptଢନଷreak;恠BreakingSpace;䂠f;愕ڀ;CDEGHLNPRSTV୕ୖ୪௫ఄ಄ದൡඅ櫬Āoungruent;扢pCap;扭oubleVerticalBar;戦ƀlqxஃஊement;戉ualĀ;Tஒஓ扠ilde;쀀≂̸ists;戄reater;EFGLSTஶஷ扯qual;扱ullEqual;쀀≧̸reater;쀀≫̸ess;批lantEqual;쀀⩾̸ilde;扵umpń௲ownHump;쀀≎̸qual;쀀≏̸eĀfsఊధtTriangleƀ;BEచఛడ拪ar;쀀⧏̸qual;括s̀;EGLSTవశ఼ౄోౘ扮qual;扰reater;扸ess;쀀≪̸lantEqual;쀀⩽̸ilde;扴estedĀGL౨౹reaterGreater;쀀⪢̸essLess;쀀⪡̸recedesƀ;ESಒಓಛ技qual;쀀⪯̸lantEqual;拠ĀeiಫಹveLine truncated
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/generated/decode-data-xml.js
|
||||
//#region node_modules/entities/lib/esm/generated/decode-data-xml.js
|
||||
var decode_data_xml_default = new Uint16Array("Ȁaglq \x1Bɭ\0\0p;䀦os;䀧t;䀾t;䀼uot;䀢".split("").map((c$7) => c$7.charCodeAt(0)));
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/decode_codepoint.js
|
||||
//#region node_modules/entities/lib/esm/decode_codepoint.js
|
||||
var _a;
|
||||
const decodeMap = new Map([
|
||||
[0, 65533],
|
||||
@@ -9111,7 +9111,7 @@ function decodeCodePoint(codePoint) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/decode.js
|
||||
//#region node_modules/entities/lib/esm/decode.js
|
||||
var CharCodes;
|
||||
(function(CharCodes$1) {
|
||||
CharCodes$1[CharCodes$1["NUM"] = 35] = "NUM";
|
||||
@@ -9545,7 +9545,7 @@ function decodeXML(str) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/generated/encode-html.js
|
||||
//#region node_modules/entities/lib/esm/generated/encode-html.js
|
||||
function restoreDiff(arr) {
|
||||
for (let i$10 = 1; i$10 < arr.length; i$10++) {
|
||||
arr[i$10][0] += arr[i$10 - 1][0] + 1;
|
||||
@@ -11254,7 +11254,7 @@ var encode_html_default = new Map(/* @__PURE__ */ restoreDiff([
|
||||
]));
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/escape.js
|
||||
//#region node_modules/entities/lib/esm/escape.js
|
||||
const xmlReplacer = /["&'<>$\x80-\uFFFF]/g;
|
||||
const xmlCodeMap = new Map([
|
||||
[34, """],
|
||||
@@ -11357,7 +11357,7 @@ const escapeText = getEscaper(/[&<>\u00A0]/g, new Map([
|
||||
]));
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/encode.js
|
||||
//#region node_modules/entities/lib/esm/encode.js
|
||||
const htmlReplacer = /[\t\n!-,./:-@[-`\f{-}$\x80-\uFFFF]/g;
|
||||
/**
|
||||
* Encodes all characters in the input using HTML entities. This includes
|
||||
@@ -11418,7 +11418,7 @@ function encodeHTMLTrieRe(regExp, str) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/index.js
|
||||
//#region node_modules/entities/lib/esm/index.js
|
||||
/** The level of entities to support. */
|
||||
var EntityLevel;
|
||||
(function(EntityLevel$1) {
|
||||
@@ -11504,7 +11504,7 @@ function encode$1(data, options = EntityLevel.XML) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/utils.mjs
|
||||
//#region node_modules/markdown-it/lib/common/utils.mjs
|
||||
var utils_exports$1 = /* @__PURE__ */ __export({
|
||||
arrayReplaceAt: () => arrayReplaceAt,
|
||||
assign: () => assign$1,
|
||||
@@ -11722,7 +11722,7 @@ const lib = {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_label.mjs
|
||||
//#region node_modules/markdown-it/lib/helpers/parse_link_label.mjs
|
||||
function parseLinkLabel(state, start, disableNested) {
|
||||
let level, found, marker, prevPos;
|
||||
const max = state.posMax;
|
||||
@@ -11758,7 +11758,7 @@ function parseLinkLabel(state, start, disableNested) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_destination.mjs
|
||||
//#region node_modules/markdown-it/lib/helpers/parse_link_destination.mjs
|
||||
function parseLinkDestination(str, start, max) {
|
||||
let code$1;
|
||||
let pos = start;
|
||||
@@ -11834,7 +11834,7 @@ function parseLinkDestination(str, start, max) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_title.mjs
|
||||
//#region node_modules/markdown-it/lib/helpers/parse_link_title.mjs
|
||||
function parseLinkTitle(str, start, max, prev_state) {
|
||||
let code$1;
|
||||
let pos = start;
|
||||
@@ -11883,7 +11883,7 @@ function parseLinkTitle(str, start, max, prev_state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/index.mjs
|
||||
//#region node_modules/markdown-it/lib/helpers/index.mjs
|
||||
var helpers_exports = /* @__PURE__ */ __export({
|
||||
parseLinkDestination: () => parseLinkDestination,
|
||||
parseLinkLabel: () => parseLinkLabel,
|
||||
@@ -11891,7 +11891,7 @@ var helpers_exports = /* @__PURE__ */ __export({
|
||||
});
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/renderer.mjs
|
||||
//#region node_modules/markdown-it/lib/renderer.mjs
|
||||
/**
|
||||
* class Renderer
|
||||
*
|
||||
@@ -12134,7 +12134,7 @@ Renderer.prototype.render = function(tokens, options, env) {
|
||||
var renderer_default = Renderer;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/ruler.mjs
|
||||
//#region node_modules/markdown-it/lib/ruler.mjs
|
||||
/**
|
||||
* class Ruler
|
||||
*
|
||||
@@ -12437,7 +12437,7 @@ Ruler.prototype.getRules = function(chainName) {
|
||||
var ruler_default = Ruler;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/token.mjs
|
||||
//#region node_modules/markdown-it/lib/token.mjs
|
||||
/**
|
||||
* class Token
|
||||
**/
|
||||
@@ -12610,7 +12610,7 @@ Token.prototype.attrJoin = function attrJoin(name, value) {
|
||||
var token_default = Token;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/state_core.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_core/state_core.mjs
|
||||
function StateCore(src, md, env) {
|
||||
this.src = src;
|
||||
this.env = env;
|
||||
@@ -12622,7 +12622,7 @@ StateCore.prototype.Token = token_default;
|
||||
var state_core_default = StateCore;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/normalize.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_core/normalize.mjs
|
||||
const NEWLINES_RE = /\r\n?|\n/g;
|
||||
const NULL_RE = /\0/g;
|
||||
function normalize(state) {
|
||||
@@ -12633,7 +12633,7 @@ function normalize(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/block.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_core/block.mjs
|
||||
function block(state) {
|
||||
let token;
|
||||
if (state.inlineMode) {
|
||||
@@ -12648,7 +12648,7 @@ function block(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/inline.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_core/inline.mjs
|
||||
function inline(state) {
|
||||
const tokens = state.tokens;
|
||||
for (let i$10 = 0, l$5 = tokens.length; i$10 < l$5; i$10++) {
|
||||
@@ -12660,7 +12660,7 @@ function inline(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/linkify.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_core/linkify.mjs
|
||||
function isLinkOpen$1(str) {
|
||||
return /^<a[>\s]/i.test(str);
|
||||
}
|
||||
@@ -12758,7 +12758,7 @@ function linkify$1(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/replacements.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_core/replacements.mjs
|
||||
const RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/;
|
||||
const SCOPED_ABBR_TEST_RE = /\((c|tm|r)\)/i;
|
||||
const SCOPED_ABBR_RE = /\((c|tm|r)\)/gi;
|
||||
@@ -12821,7 +12821,7 @@ function replace(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/smartquotes.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_core/smartquotes.mjs
|
||||
const QUOTE_TEST_RE = /['"]/;
|
||||
const QUOTE_RE = /['"]/g;
|
||||
const APOSTROPHE = "’";
|
||||
@@ -12967,7 +12967,7 @@ function smartquotes(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/text_join.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_core/text_join.mjs
|
||||
function text_join(state) {
|
||||
let curr, last;
|
||||
const blockTokens = state.tokens;
|
||||
@@ -12998,7 +12998,7 @@ function text_join(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_core.mjs
|
||||
//#region node_modules/markdown-it/lib/parser_core.mjs
|
||||
/** internal
|
||||
* class Core
|
||||
*
|
||||
@@ -13043,7 +13043,7 @@ Core.prototype.State = state_core_default;
|
||||
var parser_core_default = Core;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/state_block.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/state_block.mjs
|
||||
function StateBlock(src, md, env, tokens) {
|
||||
this.src = src;
|
||||
this.md = md;
|
||||
@@ -13201,7 +13201,7 @@ StateBlock.prototype.Token = token_default;
|
||||
var state_block_default = StateBlock;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/table.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/table.mjs
|
||||
const MAX_AUTOCOMPLETED_CELLS = 65536;
|
||||
function getLine(state, line) {
|
||||
const pos = state.bMarks[line] + state.tShift[line];
|
||||
@@ -13392,7 +13392,7 @@ function table(state, startLine, endLine, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/code.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/code.mjs
|
||||
function code(state, startLine, endLine) {
|
||||
if (state.sCount[startLine] - state.blkIndent < 4) {
|
||||
return false;
|
||||
@@ -13419,7 +13419,7 @@ function code(state, startLine, endLine) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/fence.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/fence.mjs
|
||||
function fence(state, startLine, endLine, silent) {
|
||||
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
||||
let max = state.eMarks[startLine];
|
||||
@@ -13489,7 +13489,7 @@ function fence(state, startLine, endLine, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/blockquote.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/blockquote.mjs
|
||||
function blockquote(state, startLine, endLine, silent) {
|
||||
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
||||
let max = state.eMarks[startLine];
|
||||
@@ -13615,7 +13615,7 @@ function blockquote(state, startLine, endLine, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/hr.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/hr.mjs
|
||||
function hr(state, startLine, endLine, silent) {
|
||||
const max = state.eMarks[startLine];
|
||||
if (state.sCount[startLine] - state.blkIndent >= 4) {
|
||||
@@ -13650,7 +13650,7 @@ function hr(state, startLine, endLine, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/list.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/list.mjs
|
||||
function skipBulletListMarker(state, startLine) {
|
||||
const max = state.eMarks[startLine];
|
||||
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
||||
@@ -13875,7 +13875,7 @@ function list(state, startLine, endLine, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/reference.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/reference.mjs
|
||||
function reference(state, startLine, _endLine, silent) {
|
||||
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
||||
let max = state.eMarks[startLine];
|
||||
@@ -14053,7 +14053,7 @@ function reference(state, startLine, _endLine, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/html_blocks.mjs
|
||||
//#region node_modules/markdown-it/lib/common/html_blocks.mjs
|
||||
var html_blocks_default = [
|
||||
"address",
|
||||
"article",
|
||||
@@ -14120,7 +14120,7 @@ var html_blocks_default = [
|
||||
];
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/html_re.mjs
|
||||
//#region node_modules/markdown-it/lib/common/html_re.mjs
|
||||
const attr_name = "[a-zA-Z_:][a-zA-Z0-9:._-]*";
|
||||
const unquoted = "[^\"'=<>`\\x00-\\x20]+";
|
||||
const single_quoted = "'[^']*'";
|
||||
@@ -14137,7 +14137,7 @@ const HTML_TAG_RE = new RegExp("^(?:" + open_tag + "|" + close_tag + "|" + comme
|
||||
const HTML_OPEN_CLOSE_TAG_RE = new RegExp("^(?:" + open_tag + "|" + close_tag + ")");
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/html_block.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/html_block.mjs
|
||||
const HTML_SEQUENCES = [
|
||||
[
|
||||
/^<(script|pre|style|textarea)(?=(\s|>|$))/i,
|
||||
@@ -14225,7 +14225,7 @@ function html_block(state, startLine, endLine, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/heading.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/heading.mjs
|
||||
function heading(state, startLine, endLine, silent) {
|
||||
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
||||
let max = state.eMarks[startLine];
|
||||
@@ -14267,7 +14267,7 @@ function heading(state, startLine, endLine, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/lheading.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/lheading.mjs
|
||||
function lheading(state, startLine, endLine) {
|
||||
const terminatorRules = state.md.block.ruler.getRules("paragraph");
|
||||
if (state.sCount[startLine] - state.blkIndent >= 4) {
|
||||
@@ -14330,7 +14330,7 @@ function lheading(state, startLine, endLine) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/paragraph.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_block/paragraph.mjs
|
||||
function paragraph(state, startLine, endLine) {
|
||||
const terminatorRules = state.md.block.ruler.getRules("paragraph");
|
||||
const oldParentType = state.parentType;
|
||||
@@ -14368,7 +14368,7 @@ function paragraph(state, startLine, endLine) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_block.mjs
|
||||
//#region node_modules/markdown-it/lib/parser_block.mjs
|
||||
/** internal
|
||||
* class ParserBlock
|
||||
*
|
||||
@@ -14514,7 +14514,7 @@ ParserBlock.prototype.State = state_block_default;
|
||||
var parser_block_default = ParserBlock;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/state_inline.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/state_inline.mjs
|
||||
function StateInline(src, md, env, outTokens) {
|
||||
this.src = src;
|
||||
this.env = env;
|
||||
@@ -14591,7 +14591,7 @@ StateInline.prototype.Token = token_default;
|
||||
var state_inline_default = StateInline;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/text.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/text.mjs
|
||||
function isTerminatorChar(ch) {
|
||||
switch (ch) {
|
||||
case 10:
|
||||
@@ -14636,7 +14636,7 @@ function text(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/linkify.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/linkify.mjs
|
||||
const SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i;
|
||||
function linkify(state, silent) {
|
||||
if (!state.md.options.linkify) return false;
|
||||
@@ -14674,7 +14674,7 @@ function linkify(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/newline.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/newline.mjs
|
||||
function newline(state, silent) {
|
||||
let pos = state.pos;
|
||||
if (state.src.charCodeAt(pos) !== 10) {
|
||||
@@ -14706,7 +14706,7 @@ function newline(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/escape.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/escape.mjs
|
||||
const ESCAPED = [];
|
||||
for (let i$10 = 0; i$10 < 256; i$10++) {
|
||||
ESCAPED.push(0);
|
||||
@@ -14758,7 +14758,7 @@ function escape(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/backticks.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/backticks.mjs
|
||||
function backtick(state, silent) {
|
||||
let pos = state.pos;
|
||||
const ch = state.src.charCodeAt(pos);
|
||||
@@ -14804,7 +14804,7 @@ function backtick(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/strikethrough.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/strikethrough.mjs
|
||||
function strikethrough_tokenize(state, silent) {
|
||||
const start = state.pos;
|
||||
const marker = state.src.charCodeAt(start);
|
||||
@@ -14900,7 +14900,7 @@ var strikethrough_default = {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/emphasis.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/emphasis.mjs
|
||||
function emphasis_tokenize(state, silent) {
|
||||
const start = state.pos;
|
||||
const marker = state.src.charCodeAt(start);
|
||||
@@ -14974,7 +14974,7 @@ var emphasis_default = {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/link.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/link.mjs
|
||||
function link(state, silent) {
|
||||
let code$1, label, res, ref;
|
||||
let href = "";
|
||||
@@ -15083,7 +15083,7 @@ function link(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/image.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/image.mjs
|
||||
function image(state, silent) {
|
||||
let code$1, content, label, pos, ref, res, title$1, start;
|
||||
let href = "";
|
||||
@@ -15192,7 +15192,7 @@ function image(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/autolink.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/autolink.mjs
|
||||
const EMAIL_RE = /^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/;
|
||||
const AUTOLINK_RE = /^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/;
|
||||
function autolink(state, silent) {
|
||||
@@ -15251,7 +15251,7 @@ function autolink(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/html_inline.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/html_inline.mjs
|
||||
function isLinkOpen(str) {
|
||||
return /^<a[>\s]/i.test(str);
|
||||
}
|
||||
@@ -15290,7 +15290,7 @@ function html_inline(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/entity.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/entity.mjs
|
||||
const DIGITAL_RE = /^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i;
|
||||
const NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i;
|
||||
function entity(state, silent) {
|
||||
@@ -15332,7 +15332,7 @@ function entity(state, silent) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/balance_pairs.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/balance_pairs.mjs
|
||||
function processDelimiters(delimiters) {
|
||||
const openersBottom = {};
|
||||
const max = delimiters.length;
|
||||
@@ -15404,7 +15404,7 @@ function link_pairs(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/fragments_join.mjs
|
||||
//#region node_modules/markdown-it/lib/rules_inline/fragments_join.mjs
|
||||
function fragments_join(state) {
|
||||
let curr, last;
|
||||
let level = 0;
|
||||
@@ -15429,7 +15429,7 @@ function fragments_join(state) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_inline.mjs
|
||||
//#region node_modules/markdown-it/lib/parser_inline.mjs
|
||||
/** internal
|
||||
* class ParserInline
|
||||
*
|
||||
@@ -15559,7 +15559,7 @@ ParserInline.prototype.State = state_inline_default;
|
||||
var parser_inline_default = ParserInline;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/linkify-it@5.0.0/node_modules/linkify-it/lib/re.mjs
|
||||
//#region node_modules/linkify-it/lib/re.mjs
|
||||
function re_default(opts) {
|
||||
const re = {};
|
||||
opts = opts || {};
|
||||
@@ -15600,7 +15600,7 @@ function re_default(opts) {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/linkify-it@5.0.0/node_modules/linkify-it/index.mjs
|
||||
//#region node_modules/linkify-it/index.mjs
|
||||
function assign(obj) {
|
||||
const sources = Array.prototype.slice.call(arguments, 1);
|
||||
sources.forEach(function(source) {
|
||||
@@ -16092,7 +16092,7 @@ LinkifyIt.prototype.onCompile = function onCompile() {};
|
||||
var linkify_it_default = LinkifyIt;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.es6.js
|
||||
//#region node_modules/punycode.js/punycode.es6.js
|
||||
/** Highest positive signed 32-bit float value */
|
||||
const maxInt = 2147483647;
|
||||
/** Bootstring parameters */
|
||||
@@ -16425,7 +16425,7 @@ const punycode = {
|
||||
var punycode_es6_default = punycode;
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/default.mjs
|
||||
//#region node_modules/markdown-it/lib/presets/default.mjs
|
||||
var default_default = {
|
||||
options: {
|
||||
html: false,
|
||||
@@ -16446,7 +16446,7 @@ var default_default = {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/zero.mjs
|
||||
//#region node_modules/markdown-it/lib/presets/zero.mjs
|
||||
var zero_default = {
|
||||
options: {
|
||||
html: false,
|
||||
@@ -16475,7 +16475,7 @@ var zero_default = {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/commonmark.mjs
|
||||
//#region node_modules/markdown-it/lib/presets/commonmark.mjs
|
||||
var commonmark_default = {
|
||||
options: {
|
||||
html: true,
|
||||
@@ -16530,7 +16530,7 @@ var commonmark_default = {
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/index.mjs
|
||||
//#region node_modules/markdown-it/lib/index.mjs
|
||||
const config = {
|
||||
default: default_default,
|
||||
zero: zero_default,
|
||||
@@ -17568,14 +17568,17 @@ function instanceOf(tagName) {
|
||||
//#region apps/shared/ClawdisKit/Tools/CanvasA2UI/bootstrap.js
|
||||
const modalStyles = i`
|
||||
dialog {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 24px;
|
||||
border: none;
|
||||
background: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
max-width: calc(100vw - 32px);
|
||||
max-height: calc(100vh - 32px);
|
||||
background: rgba(5, 8, 16, 0.65);
|
||||
backdrop-filter: blur(6px);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
dialog::backdrop {
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Canvas</title>
|
||||
<title>Clawdis Canvas</title>
|
||||
<style>
|
||||
:root { color-scheme: light dark; }
|
||||
html, body { height: 100%; margin: 0; }
|
||||
@@ -94,4 +94,36 @@ describe("canvas host", () => {
|
||||
await fs.rm(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("serves the gateway-hosted A2UI scaffold", async () => {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdis-canvas-"));
|
||||
|
||||
const server = await startCanvasHost({
|
||||
runtime: defaultRuntime,
|
||||
rootDir: dir,
|
||||
port: 0,
|
||||
listenHost: "127.0.0.1",
|
||||
allowInTests: true,
|
||||
});
|
||||
|
||||
try {
|
||||
const res = await fetch(
|
||||
`http://127.0.0.1:${server.port}/__clawdis__/a2ui/`,
|
||||
);
|
||||
const html = await res.text();
|
||||
expect(res.status).toBe(200);
|
||||
expect(html).toContain("clawdis-a2ui-host");
|
||||
expect(html).toContain("clawdisCanvasA2UIAction");
|
||||
|
||||
const bundleRes = await fetch(
|
||||
`http://127.0.0.1:${server.port}/__clawdis__/a2ui/a2ui.bundle.js`,
|
||||
);
|
||||
const js = await bundleRes.text();
|
||||
expect(bundleRes.status).toBe(200);
|
||||
expect(js).toContain("clawdisA2UI");
|
||||
} finally {
|
||||
await server.close();
|
||||
await fs.rm(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -108,6 +108,7 @@ export const HelloOkSchema = Type.Object(
|
||||
{ additionalProperties: false },
|
||||
),
|
||||
snapshot: SnapshotSchema,
|
||||
canvasHostUrl: Type.Optional(NonEmptyString),
|
||||
policy: Type.Object(
|
||||
{
|
||||
maxPayload: Type.Integer({ minimum: 1 }),
|
||||
|
||||
@@ -79,7 +79,11 @@ type BridgeInvokeResponseFrame = {
|
||||
error?: { code: string; message: string } | null;
|
||||
};
|
||||
|
||||
type BridgeHelloOkFrame = { type: "hello-ok"; serverName: string };
|
||||
type BridgeHelloOkFrame = {
|
||||
type: "hello-ok";
|
||||
serverName: string;
|
||||
canvasHostUrl?: string;
|
||||
};
|
||||
type BridgePairOkFrame = { type: "pair-ok"; token: string };
|
||||
type BridgeErrorFrame = { type: "error"; code: string; message: string };
|
||||
|
||||
@@ -132,6 +136,7 @@ export type NodeBridgeServerOpts = {
|
||||
host: string;
|
||||
port: number; // 0 = ephemeral
|
||||
pairingBaseDir?: string;
|
||||
canvasHostPort?: number;
|
||||
onEvent?: (nodeId: string, evt: BridgeEventFrame) => Promise<void> | void;
|
||||
onRequest?: (
|
||||
nodeId: string,
|
||||
@@ -180,6 +185,15 @@ export async function startNodeBridgeServer(
|
||||
? opts.serverName.trim()
|
||||
: os.hostname();
|
||||
|
||||
const buildCanvasHostUrl = (socket: net.Socket) => {
|
||||
const port = opts.canvasHostPort;
|
||||
if (!port) return undefined;
|
||||
const host = socket.localAddress?.trim();
|
||||
if (!host) return undefined;
|
||||
const formatted = host.includes(":") ? `[${host}]` : host;
|
||||
return `http://${formatted}:${port}`;
|
||||
};
|
||||
|
||||
type ConnectionState = {
|
||||
socket: net.Socket;
|
||||
nodeInfo: NodeBridgeClientInfo;
|
||||
@@ -356,7 +370,11 @@ export async function startNodeBridgeServer(
|
||||
opts.pairingBaseDir,
|
||||
);
|
||||
connections.set(nodeId, { socket, nodeInfo, invokeWaiters });
|
||||
send({ type: "hello-ok", serverName } satisfies BridgeHelloOkFrame);
|
||||
send({
|
||||
type: "hello-ok",
|
||||
serverName,
|
||||
canvasHostUrl: buildCanvasHostUrl(socket),
|
||||
} satisfies BridgeHelloOkFrame);
|
||||
await opts.onAuthenticated?.(nodeInfo);
|
||||
};
|
||||
|
||||
@@ -466,7 +484,11 @@ export async function startNodeBridgeServer(
|
||||
};
|
||||
connections.set(nodeId, { socket, nodeInfo, invokeWaiters });
|
||||
send({ type: "pair-ok", token: wait.token } satisfies BridgePairOkFrame);
|
||||
send({ type: "hello-ok", serverName } satisfies BridgeHelloOkFrame);
|
||||
send({
|
||||
type: "hello-ok",
|
||||
serverName,
|
||||
canvasHostUrl: buildCanvasHostUrl(socket),
|
||||
} satisfies BridgeHelloOkFrame);
|
||||
await opts.onAuthenticated?.(nodeInfo);
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user