From 5c6fec788f0ed1a61d353f5b60fe1f47f7b94630 Mon Sep 17 00:00:00 2001 From: Everett Date: Tue, 22 Sep 2026 09:33:17 -0700 Subject: [PATCH] Fix AI widget rendering and add visual quality regression --- Editor/editorfe/src/scriptWidgetAPI.js | 2 +- Scripts/ai-quality-images.swift | 46 +++++ Scripts/ai-quality-report.py | 29 +++ Scripts/ai-quality.sh | 34 ++++ .../AI/Eval/AIEvalRunner.swift | 2 +- .../AI/PromptBuilder.swift | 25 ++- .../API/ScriptWidgetRuntimeDevice.swift | 12 +- .../ScriptWidgetAttributeFrameModifier.swift | 10 +- .../Runtime/ScriptWidgetRunningState.swift | 5 +- .../Widget/Runtime/ScriptWidgetRuntime.swift | 5 +- .../AIGenerationTests.swift | 181 ++++++++++++++++++ .../RuntimeExecutionTests.swift | 8 + .../RuntimeUnitTests.swift | 21 ++ docs/README.md | 1 + docs/ai-generate.md | 2 + docs/ai-quality-testing.md | 43 +++++ docs/runtime-api.md | 6 + docs/scriptwidget-runtime-api.md | 58 +++--- .../App/Settings/SettingAIView.swift | 4 +- .../{index-CaXXMCSr.js => index-dCxXChRa.js} | 2 +- .../StudioEditor.bundle/index.html | 2 +- .../Settings/SettingAIView.swift | 4 +- .../{index-CaXXMCSr.js => index-dCxXChRa.js} | 2 +- .../StudioEditor.bundle/index.html | 2 +- 24 files changed, 458 insertions(+), 48 deletions(-) create mode 100644 Scripts/ai-quality-images.swift create mode 100644 Scripts/ai-quality-report.py create mode 100755 Scripts/ai-quality.sh create mode 100644 docs/ai-quality-testing.md rename iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/assets/{index-CaXXMCSr.js => index-dCxXChRa.js} (98%) rename macOS/ScriptWidgetMac/StudioEditor.bundle/assets/{index-CaXXMCSr.js => index-dCxXChRa.js} (98%) diff --git a/Editor/editorfe/src/scriptWidgetAPI.js b/Editor/editorfe/src/scriptWidgetAPI.js index 4755a7bf..2d65b210 100644 --- a/Editor/editorfe/src/scriptWidgetAPI.js +++ b/Editor/editorfe/src/scriptWidgetAPI.js @@ -16,7 +16,7 @@ export const scriptWidgetAPI = { "font": { "type": "enum", "values": ["largeTitle", "title", "title2", "title3", "headline", "subheadline", "body", "callout", "footnote", "caption", "caption2"], "documentation": "Semantic text style." }, "fontWeight": { "type": "enum", "values": ["ultraLight", "thin", "light", "regular", "medium", "semibold", "bold", "heavy", "black"], "documentation": "Font weight." }, "fontDesign": { "type": "enum", "values": ["default", "rounded", "serif", "monospaced"], "documentation": "Font design." }, - "frame": { "type": "number|string", "documentation": "Size or frame description." }, + "frame": { "type": "number|string", "documentation": "Square size (64 or \"64\"), width,height (\"64,48\"), or flexible frame (\"max\", \"max,48\")." }, "padding": { "type": "number|string", "documentation": "Padding amount or edge description." }, "corner": { "type": "number", "documentation": "Corner radius." }, "opacity": { "type": "number", "documentation": "Opacity from 0 through 1." }, diff --git a/Scripts/ai-quality-images.swift b/Scripts/ai-quality-images.swift new file mode 100644 index 00000000..a6b8deaf --- /dev/null +++ b/Scripts/ai-quality-images.swift @@ -0,0 +1,46 @@ +// Local screenshot inspection only. OCR is a review signal, not a visual-quality proof. +import Foundation +import Vision +import ImageIO + +struct Sample: Decodable { + let id: String + let attempt: Int + let expectedText: [String]? + let screenshots: [String] +} +struct Observation: Encodable { + let image: String + let recognizedText: String + let unrecognizedExpectedText: [String] +} +func normalized(_ text: String) -> String { + String(text.lowercased().unicodeScalars.filter { CharacterSet.alphanumerics.contains($0) }) +} +guard CommandLine.arguments.count == 2 else { + fatalError("Usage: swift Scripts/ai-quality-images.swift /absolute/artifact/directory") +} +let directory = URL(fileURLWithPath: CommandLine.arguments[1], isDirectory: true) +let samples = try JSONDecoder().decode([Sample].self, from: Data(contentsOf: directory.appendingPathComponent("quality.json"))) +var observations: [Observation] = [] +for sample in samples { + for filename in sample.screenshots { + // Only inspect locally generated flat PNG names, never arbitrary report paths. + guard filename == URL(fileURLWithPath: filename).lastPathComponent, + !filename.contains(".."), filename.hasSuffix(".png") else { fatalError("Invalid screenshot filename") } + let request = VNRecognizeTextRequest() + request.recognitionLevel = .accurate + let hasChinese = (sample.expectedText ?? []).joined().unicodeScalars.contains { (0x4E00...0x9FFF).contains($0.value) } + request.recognitionLanguages = hasChinese ? ["zh-Hans", "en-US"] : ["en-US"] + request.automaticallyDetectsLanguage = true + request.usesLanguageCorrection = false + try VNImageRequestHandler(url: directory.appendingPathComponent(filename)).perform([request]) + let text = (request.results ?? []).compactMap { $0.topCandidates(1).first?.string }.joined(separator: " ") + let absent = (sample.expectedText ?? []).filter { !normalized(text).contains(normalized($0)) } + observations.append(.init(image: filename, recognizedText: text, unrecognizedExpectedText: absent)) + } +} +let encoder = JSONEncoder() +encoder.outputFormatting = [.prettyPrinted, .sortedKeys] +try encoder.encode(observations).write(to: directory.appendingPathComponent("vision.json"), options: .atomic) +print("OCR inspected \(observations.count) screenshots; \(observations.filter { !$0.unrecognizedExpectedText.isEmpty }.count) need review.") diff --git a/Scripts/ai-quality-report.py b/Scripts/ai-quality-report.py new file mode 100644 index 00000000..36fbcc2d --- /dev/null +++ b/Scripts/ai-quality-report.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +"""Make an offline, inspectable visual report; no uploads or external resources.""" +import html +import json +import pathlib +import sys + +root = pathlib.Path(sys.argv[1]).resolve() +samples = json.loads((root / "quality.json").read_text()) +vision_path = root / "vision.json" +vision = {x["image"]: x for x in json.loads(vision_path.read_text())} if vision_path.exists() else {} +config_path = root / "config.json" +config = json.loads(config_path.read_text()) if config_path.exists() else {"status": "run incomplete"} +escape = lambda value: html.escape(str(value), quote=True) +cards = [] +for item in samples: + figures = [] + for filename in item["screenshots"]: + if pathlib.Path(filename).name != filename or ".." in filename or not filename.endswith(".png"): + raise ValueError("Invalid screenshot filename") + finding = vision.get(filename, {}) + missing = finding.get("unrecognizedExpectedText", []) + review = ", ".join(missing) or ("no missing expected text flagged" if finding else "not run") + figures.append(f'
{escape(filename)}
{escape(filename)}
OCR review: {escape(review)}
') + cards.append(f'

{escape(item["id"])} · attempt {item["attempt"]}

{escape(item["prompt"])}

Runtime: {item["runtimePassed"]} · Missing text: {escape(item["missingText"])} · Missing components: {escape(item.get("missingComponents", []))} · Tokens: {item["tokens"]}

{"".join(figures)}
') +page = '''ScriptWidget AI quality review

ScriptWidget AI quality review

Native macOS snapshots of synthetic offline prompts. Runtime/text checks do not prove readability. OCR flags require visual review; it can miss small text or punctuation. WidgetKit device behavior is not certified by this report.

''' +page += f'

Configuration: {escape(config)}

' + "".join(cards) + "
" +(root / "index.html").write_text(page) +print(root / "index.html") diff --git a/Scripts/ai-quality.sh b/Scripts/ai-quality.sh new file mode 100755 index 00000000..d0297295 --- /dev/null +++ b/Scripts/ai-quality.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# Opt-in, bounded live generation using synthetic offline prompts. +set -eu +ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) +cd "$ROOT" +if [ -z "${AI_QUALITY_REPLAY:-}" ]; then + : "${ROCKY_OPENAI_APIKEY:?Set ROCKY_OPENAI_APIKEY to your provider key}" + : "${ROCKY_OPENAI_BASEURL:?Set ROCKY_OPENAI_BASEURL to your provider base URL}" + : "${ROCKY_OPENAI_MODEL:?Set ROCKY_OPENAI_MODEL to a model returned by your server}" +fi +OUTPUT=${AI_QUALITY_OUTPUT:-"$ROOT/__Release/ai-quality/$(date +%Y%m%d-%H%M%S)"} +case "$OUTPUT" in /*) ;; *) echo 'AI_QUALITY_OUTPUT must be an absolute path' >&2; exit 2 ;; esac +export TEST_RUNNER_ROCKY_OPENAI_APIKEY="${ROCKY_OPENAI_APIKEY:-}" +export TEST_RUNNER_ROCKY_OPENAI_BASEURL="${ROCKY_OPENAI_BASEURL:-http://localhost}" +export TEST_RUNNER_ROCKY_OPENAI_MODEL="${ROCKY_OPENAI_MODEL:-replay}" +export TEST_RUNNER_AI_QUALITY=1 +export TEST_RUNNER_AI_QUALITY_ATTEMPTS=${AI_QUALITY_ATTEMPTS:-2} +export TEST_RUNNER_AI_QUALITY_OUTPUT="$OUTPUT" +if [ -n "${AI_QUALITY_REPLAY:-}" ]; then + export TEST_RUNNER_AI_QUALITY_REPLAY="$AI_QUALITY_REPLAY" +else + unset TEST_RUNNER_AI_QUALITY_REPLAY +fi +STATUS=0 +xcodebuild -quiet -project macOS/ScriptWidgetMac.xcodeproj -scheme ScriptWidgetRuntimeTests \ + -destination 'platform=macOS' -derivedDataPath "${SCRIPTWIDGET_DERIVED_DATA:-/tmp/scriptwidget-ai-quality}" \ + -only-testing:ScriptWidgetRuntimeTests/AIGenerationTests/testWidgetQualityMatrix \ + CODE_SIGNING_ALLOWED=NO test || STATUS=$? +if [ -f "$OUTPUT/quality.json" ]; then + swift Scripts/ai-quality-images.swift "$OUTPUT" + python3 Scripts/ai-quality-report.py "$OUTPUT" +fi +printf 'AI quality artifacts: %s\n' "$OUTPUT" +exit "$STATUS" diff --git a/Shared/ScriptWidgetRuntime/AI/Eval/AIEvalRunner.swift b/Shared/ScriptWidgetRuntime/AI/Eval/AIEvalRunner.swift index c6ab8c1c..7a5e296b 100644 --- a/Shared/ScriptWidgetRuntime/AI/Eval/AIEvalRunner.swift +++ b/Shared/ScriptWidgetRuntime/AI/Eval/AIEvalRunner.swift @@ -91,7 +91,7 @@ struct AIEvalRunnerProgress { /// composition is changed substantively. Reports get tagged with this /// so two reports against the same dataset can be diffed meaningfully. enum AIEvalPromptVersion { - static let current = "v1" + static let current = "v2" } actor AIEvalRunner { diff --git a/Shared/ScriptWidgetRuntime/AI/PromptBuilder.swift b/Shared/ScriptWidgetRuntime/AI/PromptBuilder.swift index 8ba9d901..ab032212 100644 --- a/Shared/ScriptWidgetRuntime/AI/PromptBuilder.swift +++ b/Shared/ScriptWidgetRuntime/AI/PromptBuilder.swift @@ -42,7 +42,7 @@ enum AIWidgetSize: String, CaseIterable, Identifiable, Codable { case .small: return CGSize(width: 170, height: 170) case .medium: return CGSize(width: 329, height: 170) case .large: return CGSize(width: 329, height: 345) - case .extraLarge: return CGSize(width: 345, height: 329) + case .extraLarge: return CGSize(width: 639, height: 345) case .extraLargePortrait: return CGSize(width: 345, height: 639) case .accessoryInline: return CGSize(width: 250, height: 30) case .accessoryCircular: return CGSize(width: 72, height: 72) @@ -55,9 +55,9 @@ enum AIWidgetSize: String, CaseIterable, Identifiable, Codable { var designHint: String { switch self { case .small: - return "Square, ~155x155 px. Keep it to one or two key pieces of information." + return "Square, ~170x170 px. Keep it to one or two key pieces of information." case .medium: - return "Wide rectangle, ~329x155 px. Room for a small grid or two columns." + return "Wide rectangle, ~329x170 px. Room for a small grid or two columns." case .large: return "Square, ~329x345 px. Multiple sections / richer layout." case .extraLarge: @@ -69,7 +69,7 @@ enum AIWidgetSize: String, CaseIterable, Identifiable, Codable { case .accessoryCircular: return "Very small round area (~72x72). Icon + a number at most." case .accessoryRectangular: - return "Small rectangle (~160x72). A few short lines of text." + return "Small rectangle (~170x72). A few short lines of text." } } } @@ -131,6 +131,23 @@ enum PromptBuilder { visual density to the declared widget size. 10. Keep the output self-contained — no external files, no image assets the user hasn't provided. + 11. Respect light and dark appearances. Prefer color="primary" + and color="secondary" for text. On accessory widgets use + primary/secondary monochrome content with no background; + never hardcode white text on a transparent background. + 12. Use frame="width,height" for explicit sizes, e.g. frame="60,60" + for a ring inside a 72x72 accessory widget. Leave room for + stroke thickness and padding. Do not apply frame="max" to + every row: it expands height too. Use frame="max,24" for a + full-width row with a fixed height when appropriate. + 13. Charts use data={$json([{label: "Mon", value: 3}])}, not JSX + child marks. Keep chart axes legible: avoid a fixed dark + background with default light-appearance axes. Prefer the + default background or select a matching background using + $device.isdarkmode(). + 14. Preserve the requested labels and values. Do not invent + meeting locations, extra events, or live data. For fixed + demo data do not call network, location or Health APIs. """ let reference = reference.combined return rules + "\n\n" + reference diff --git a/Shared/ScriptWidgetRuntime/Widget/API/ScriptWidgetRuntimeDevice.swift b/Shared/ScriptWidgetRuntime/Widget/API/ScriptWidgetRuntimeDevice.swift index f1e28f32..0855e087 100644 --- a/Shared/ScriptWidgetRuntime/Widget/API/ScriptWidgetRuntimeDevice.swift +++ b/Shared/ScriptWidgetRuntime/Widget/API/ScriptWidgetRuntimeDevice.swift @@ -52,8 +52,12 @@ import UIKit #if os(macOS) + static var systemIsDarkMode: Bool { + NSAppearance.currentDrawing().bestMatch(from: [.darkAqua, .aqua]) == .darkAqua + } + static func isdarkmode() -> Bool { - return true + JSContext.current()?.scriptWidgetRunningState?.isDarkMode ?? systemIsDarkMode } static func screen() -> [AnyHashable : Any]! { @@ -124,8 +128,12 @@ import UIKit #else + static var systemIsDarkMode: Bool { + UITraitCollection.current.userInterfaceStyle == .dark + } + static func isdarkmode() -> Bool { - return UITraitCollection.current.userInterfaceStyle == .dark + JSContext.current()?.scriptWidgetRunningState?.isDarkMode ?? systemIsDarkMode } static func screen() -> [AnyHashable : Any]! { diff --git a/Shared/ScriptWidgetRuntime/Widget/Component/Attributes/General/ScriptWidgetAttributeFrameModifier.swift b/Shared/ScriptWidgetRuntime/Widget/Component/Attributes/General/ScriptWidgetAttributeFrameModifier.swift index 20322922..dec4b7fe 100644 --- a/Shared/ScriptWidgetRuntime/Widget/Component/Attributes/General/ScriptWidgetAttributeFrameModifier.swift +++ b/Shared/ScriptWidgetRuntime/Widget/Component/Attributes/General/ScriptWidgetAttributeFrameModifier.swift @@ -63,12 +63,20 @@ struct ScriptWidgetAttributeFrameModifier: ViewModifier { var width: CGFloat = 0 var height: CGFloat = 0 - if let frameValue = element.getPropString("frame") { + let numericFrame = (element.getProps()["frame"] as? NSNumber).flatMap { value -> String? in + guard CFGetTypeID(value) != CFBooleanGetTypeID() else { return nil } + return String(value.doubleValue) + } + if let frameValue = element.getPropString("frame") ?? numericFrame { let parts = frameValue.split(separator: ",") if parts.count == 1 { // frame="max" if frameValue == "max" { frameMode = .max_alignment + } else if let side = Double(frameValue), side.isFinite, side >= 0 { + width = CGFloat(side) + height = CGFloat(side) + frameMode = .width_height_alignment } } else if parts.count == 2 { let part1 = String(parts[0]) diff --git a/Shared/ScriptWidgetRuntime/Widget/Runtime/ScriptWidgetRunningState.swift b/Shared/ScriptWidgetRuntime/Widget/Runtime/ScriptWidgetRunningState.swift index 2dc4171a..080cec91 100644 --- a/Shared/ScriptWidgetRuntime/Widget/Runtime/ScriptWidgetRunningState.swift +++ b/Shared/ScriptWidgetRuntime/Widget/Runtime/ScriptWidgetRunningState.swift @@ -102,9 +102,12 @@ class ScriptWidgetRunningState { var package: ScriptWidgetPackage let executionSession: ScriptWidgetExecutionSession + let isDarkMode: Bool? + var storageNamespace: String { "script.\(package.name)." } - init(package: ScriptWidgetPackage) { + init(package: ScriptWidgetPackage, isDarkMode: Bool? = nil) { + self.isDarkMode = isDarkMode self.logger = ScriptWidgetConsoleLogger() self.package = package self.executionSession = ScriptWidgetExecutionSession() diff --git a/Shared/ScriptWidgetRuntime/Widget/Runtime/ScriptWidgetRuntime.swift b/Shared/ScriptWidgetRuntime/Widget/Runtime/ScriptWidgetRuntime.swift index 35ccd2c0..87698a2b 100644 --- a/Shared/ScriptWidgetRuntime/Widget/Runtime/ScriptWidgetRuntime.swift +++ b/Shared/ScriptWidgetRuntime/Widget/Runtime/ScriptWidgetRuntime.swift @@ -334,7 +334,10 @@ class ScriptWidgetRuntime { self.environments = environments // APIs like $file/$console read per-execution state from the // owning JSContext. - runtimeContext.scriptWidgetRunningState = ScriptWidgetRunningState(package: package) + // Capture appearance before JavaScript moves to a worker queue. + runtimeContext.scriptWidgetRunningState = ScriptWidgetRunningState( + package: package, isDarkMode: ScriptWidgetRuntimeDevice.systemIsDarkMode + ) ScriptWidgetMemoryPressure.install() ScriptWidgetPrecompiler.install() } diff --git a/Tests/ScriptWidgetRuntimeTests/AIGenerationTests.swift b/Tests/ScriptWidgetRuntimeTests/AIGenerationTests.swift index 044b51e8..11f0baec 100644 --- a/Tests/ScriptWidgetRuntimeTests/AIGenerationTests.swift +++ b/Tests/ScriptWidgetRuntimeTests/AIGenerationTests.swift @@ -23,6 +23,10 @@ // import XCTest +#if os(macOS) +import SwiftUI +import AppKit +#endif @testable import ScriptWidget final class AIGenerationTests: XCTestCase { @@ -282,6 +286,183 @@ final class AIGenerationTests: XCTestCase { } } + #if os(macOS) + @MainActor + func testDeviceAppearanceIsCapturedPerRuntimeBeforeWorkerExecution() async throws { + let package = try AgentRuntimeBridge.shared.makeSandboxPackage(prefix: "appearance") + defer { AgentRuntimeBridge.shared.cleanupSandboxPackage(package) } + var runtimes: [(ScriptWidgetRuntime, String)] = [] + for (name, expected) in [(NSAppearance.Name.aqua, "light"), (.darkAqua, "dark")] { + try XCTUnwrap(NSAppearance(named: name)).performAsCurrentDrawingAppearance { + XCTAssertEqual(ScriptWidgetRuntimeDevice.isdarkmode(), expected == "dark") + runtimes.append((ScriptWidgetRuntime(package: package, environments: [:]), expected)) + } + } + for (runtime, expected) in runtimes { + let output = await Task.detached { + runtime.executeJSXSyncForWidget("$render({$device.isdarkmode() ? 'dark' : 'light'});") + }.value + XCTAssertNil(output.1) + XCTAssertEqual(Self.qualityText(try XCTUnwrap(output.0)), expected) + } + } + + private struct QualityCase { + let id: String + let size: AIWidgetSize + let prompt: String + let expectedText: [String] + var expectedTagGroups: [[String]] = [] + } + + private struct QualityResult: Codable { + let id: String + let size: String + let attempt: Int + let prompt: String + let runtimePassed: Bool + let expectedText: [String] + let missingText: [String] + let missingComponents: [String] + let error: String? + let tokens: Int + let duration: Double + let screenshots: [String] + } + + /// Opt-in visual/semantic regression suite. Synthetic, offline prompts only; + /// no user widgets, personal data or credentials are written to artifacts. + @MainActor + func testWidgetQualityMatrix() async throws { + let variables = ProcessInfo.processInfo.environment + guard variables["AI_QUALITY"] == "1" else { throw XCTSkip("AI_QUALITY != 1") } + let env = variables["AI_QUALITY_REPLAY"] == nil ? try resolveEnv() : Env(apiKey: "", baseURL: "http://localhost", model: "replay") + let path = try XCTUnwrap(variables["AI_QUALITY_OUTPUT"], "Set an explicit local artifact directory") + guard path.hasPrefix("/") else { return XCTFail("Artifact directory must be absolute") } + let directory = URL(fileURLWithPath: path, isDirectory: true) + try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true) + let attempts = max(1, min(3, Int(variables["AI_QUALITY_ATTEMPTS"] ?? "2") ?? 2)) + let cases: [QualityCase] = [ + .init(id: "hydration", size: .small, + prompt: "A hydration widget. Show the title Hydration, a ring or progress indicator for 6 of 8 glasses, and the text 6 / 8. Blue accent, readable in light and dark appearances. Use only this fixed data; no network.", expectedText: ["Hydration", "6", "8"], expectedTagGroups: [["ring", "progress"]]), + .init(id: "metrics", size: .medium, + prompt: "A compact business widget with two balanced columns: Revenue $2400 and Orders 32. Use stat components or native text, clear labels and values. Fixed demo data, no network.", expectedText: ["Revenue", "2400", "Orders", "32"]), + .init(id: "chinese-dashboard", size: .large, + prompt: "做一个中文日程 Widget,标题为今日安排,三项日程:09:00 团队会议、14:00 设计评审、18:00 跑步。清晰的时间列、分隔线、留白;浅色和深色都要易读。仅用这些固定数据,不联网。", expectedText: ["今日安排", "09:00", "团队会议", "14:00", "设计评审", "18:00", "跑步"]), + .init(id: "weekly-chart", size: .medium, + prompt: "A weekly steps widget titled Weekly Steps with a native bar chart for Mon 3000, Tue 5000, Wed 4000, Thu 6500, Fri 8000, Sat 7000, Sun 6000. Show Total 39500 as text. Use fixed data only, no HealthKit or network.", expectedText: ["Weekly Steps", "39500"], expectedTagGroups: [["chart"]]), + .init(id: "wide-dashboard", size: .extraLarge, + prompt: "An iPad wide dashboard, four evenly spaced columns titled Focus, Tasks, Water, Steps, with values 25 min, 3 left, 6 cups, 8000. Clear visual hierarchy, no hardcoded screen coordinates. Fixed data only, no network.", expectedText: ["Focus", "Tasks", "Water", "Steps", "25", "8000"]), + .init(id: "inline", size: .accessoryInline, + prompt: "A lock-screen inline widget displaying exactly Next meeting 14:30. Single text line; no background, no network.", expectedText: ["Next meeting 14:30"]), + .init(id: "circular", size: .accessoryCircular, + prompt: "A lock-screen circular widget displaying 75% with a simple progress ring. Monochrome, no background; avoid clipping within 72 by 72 points. Fixed data only.", expectedText: ["75"], expectedTagGroups: [["ring", "gauge"]]), + .init(id: "rectangular", size: .accessoryRectangular, + prompt: "A monochrome lock-screen rectangular widget: title Next train, time 08:45 and destination Central. No background, no network. Short readable lines within 170 by 72 points.", expectedText: ["Next train", "08:45", "Central"]) + ] + var results: [QualityResult] = [] + let settings = makeSettings(env, maxIterations: 4) + let encoder = JSONEncoder() + encoder.outputFormatting = [.prettyPrinted, .sortedKeys] + for sample in cases { + for attempt in 1...attempts { + let started = Date() + let outcome: AgentLoopOutcome + if let replay = variables["AI_QUALITY_REPLAY"] { + let code = try String(contentsOf: URL(fileURLWithPath: replay) + .appendingPathComponent("\(sample.id)-\(attempt).jsx"), encoding: .utf8) + let package = try AgentRuntimeBridge.shared.makeSandboxPackage(prefix: "quality-replay") + let run = await AgentRuntimeBridge.shared.run(jsx: code, in: package, size: sample.size) + AgentRuntimeBridge.shared.cleanupSandboxPackage(package) + if run.didSucceed, let root = run.element { outcome = .succeeded(jsx: code, element: root, usage: .zero) } + else { outcome = .exhausted(lastJSX: code, lastError: run.error?.summaryForPrompt, usage: .zero) } + } else { + outcome = await AgentLoop().run(.init(mode: .fresh(userDescription: sample.prompt), + size: sample.size, settings: settings, maxIterations: 4)) { _ in } + } + var jsx: String? + var element: ScriptWidgetRuntimeElement? + var error: String? + let tokens: Int + switch outcome { + case let .succeeded(code, root, usage): jsx = code; element = root; tokens = usage.totalTokens + case let .exhausted(code, message, usage): jsx = code; error = message ?? "exhausted"; tokens = usage.totalTokens + case let .failed(message, usage): error = message; tokens = usage.totalTokens + case let .cancelled(usage): error = "cancelled"; tokens = usage.totalTokens + } + let stem = "\(sample.id)-\(attempt)" + if let jsx { try jsx.write(to: directory.appendingPathComponent(stem + ".jsx"), atomically: true, encoding: .utf8) } + var screenshots: [String] = [] + var text = "" + if let element { + text = Self.qualityText(element) + for dark in [false, true] { + let filename = stem + (dark ? "-dark.png" : "-light.png") + try await saveQualityScreenshot(try XCTUnwrap(jsx), size: sample.size, dark: dark, + to: directory.appendingPathComponent(filename)) + screenshots.append(filename) + } + } + results.append(.init(id: sample.id, size: sample.size.rawValue, attempt: attempt, + prompt: sample.prompt, runtimePassed: element != nil, expectedText: sample.expectedText, missingText: sample.expectedText.filter { !text.localizedCaseInsensitiveContains($0) }, + missingComponents: sample.expectedTagGroups.filter { group in + guard let element else { return true } + return Set(group).isDisjoint(with: Self.qualityTags(element)) + }.map { $0.joined(separator: " or ") }, + error: error, tokens: tokens, duration: Date().timeIntervalSince(started), screenshots: screenshots)) + try encoder.encode(results).write(to: directory.appendingPathComponent("quality.json"), options: .atomic) + print("AI quality: \(stem), runtime=\(element != nil), missing=\(results.last!.missingText.count)") + } + } + let config = ["model": env.model, "host": URL(string: env.baseURL)?.host ?? "invalid", "promptVersion": AIEvalPromptVersion.current, + "attempts": String(attempts), "maxIterations": "4", "temperature": "0.2"] + try encoder.encode(config).write(to: directory.appendingPathComponent("config.json"), options: .atomic) + XCTAssertEqual(results.count, cases.count * attempts) + XCTAssertTrue(results.allSatisfy { $0.runtimePassed && $0.missingText.isEmpty && $0.missingComponents.isEmpty }, "Inspect quality.json and screenshots; render/semantic quality gate failed") + } + + private static func qualityText(_ element: ScriptWidgetRuntimeElement) -> String { + func strings(_ value: Any) -> [String] { + if let element = value as? ScriptWidgetRuntimeElement { return [qualityText(element)] } + if let values = value as? [Any] { return values.flatMap(strings) } + if let values = value as? [AnyHashable: Any] { return values.values.flatMap(strings) } + return [String(describing: value)] + } + return (element.getChildren().flatMap(strings) + element.getProps().values.flatMap(strings)).joined(separator: " ") + } + + private static func qualityTags(_ element: ScriptWidgetRuntimeElement) -> Set { + element.childrenAsElements().reduce(into: Set([element.tagAsString() ?? ""])) { $0.formUnion(qualityTags($1)) } + } + + @MainActor + private func saveQualityScreenshot(_ jsx: String, size: AIWidgetSize, dark: Bool, to url: URL) async throws { + guard #available(macOS 13.0, *) else { throw XCTSkip("ImageRenderer requires macOS 13") } + let package = try AgentRuntimeBridge.shared.makeSandboxPackage(prefix: "quality-snapshot") + defer { AgentRuntimeBridge.shared.cleanupSandboxPackage(package) } + var themedRuntime: ScriptWidgetRuntime? + let appearance = try XCTUnwrap(NSAppearance(named: dark ? .darkAqua : .aqua)) + appearance.performAsCurrentDrawingAppearance { + themedRuntime = ScriptWidgetRuntime(package: package, environments: ["widget-size": size.rawValue]) + } + let runtime = try XCTUnwrap(themedRuntime) + let result = await Task.detached { runtime.executeJSXSyncForWidget(jsx) }.value + XCTAssertNil(result.1, "Theme replay failed") + let element = try XCTUnwrap(result.0) + let view = ScriptWidgetElementView(element: element, context: .init(runtime: runtime, debugMode: false, + scriptName: "Quality", scriptParameter: "", package: package)) + .frame(width: size.previewSize.width, height: size.previewSize.height) + .background(dark ? Color.black : Color.white) + .environment(\.colorScheme, dark ? .dark : .light) + let renderer = ImageRenderer(content: view) + renderer.scale = 2 + let cgImage = try XCTUnwrap(renderer.cgImage, "Native snapshot failed") + let bitmap = NSBitmapImageRep(cgImage: cgImage) + let data = try XCTUnwrap(bitmap.representation(using: .png, properties: [:])) + try data.write(to: url, options: .atomic) + } + #endif + // MARK: - Full benchmark (opt-in: AI_EVAL_FULL=1) func testFullTemplateBenchmark() async throws { diff --git a/Tests/ScriptWidgetRuntimeTests/RuntimeExecutionTests.swift b/Tests/ScriptWidgetRuntimeTests/RuntimeExecutionTests.swift index 7b88f276..6051f001 100644 --- a/Tests/ScriptWidgetRuntimeTests/RuntimeExecutionTests.swift +++ b/Tests/ScriptWidgetRuntimeTests/RuntimeExecutionTests.swift @@ -60,6 +60,14 @@ final class RuntimeExecutionTests: XCTestCase { return out.joined(separator: " ") } + func testNumericSquareFrameSurvivesJSXBridge() throws { + let output = makeRuntime().executeJSXSyncForWidget("$render();") + XCTAssertNil(output.1) + let frame = ScriptWidgetAttributeFrameModifier(try XCTUnwrap(output.0)) + XCTAssertEqual(frame.width, 64) + XCTAssertEqual(frame.height, 64) + } + // MARK: - Happy path func testSimpleVStackRenders() { diff --git a/Tests/ScriptWidgetRuntimeTests/RuntimeUnitTests.swift b/Tests/ScriptWidgetRuntimeTests/RuntimeUnitTests.swift index e8ca4a1b..ea9fb95b 100644 --- a/Tests/ScriptWidgetRuntimeTests/RuntimeUnitTests.swift +++ b/Tests/ScriptWidgetRuntimeTests/RuntimeUnitTests.swift @@ -291,6 +291,27 @@ final class ScriptWidgetRuntimeElementTests: XCTestCase { } } +final class ScriptWidgetFrameTests: XCTestCase { + func testSquareFrameShorthandMatchesExplicitDimensions() { + for value: Any in ["64", 64, 64.0, NSNumber(value: 64)] { + let shorthand = ScriptWidgetAttributeFrameModifier(.init(tagString: "ring", props: ["frame": value], children: nil)) + let explicit = ScriptWidgetAttributeFrameModifier(.init(tagString: "ring", props: ["frame": "64,64"], children: nil)) + XCTAssertEqual(shorthand.frameMode, explicit.frameMode) + XCTAssertEqual(shorthand.width, 64) + XCTAssertEqual(shorthand.height, 64) + } + for value: Any in ["-1", "nan", "inf", true] { + let invalid = ScriptWidgetAttributeFrameModifier(.init(tagString: "ring", props: ["frame": value], children: nil)) + XCTAssertEqual(invalid.frameMode, .none) + } + } + + func testExtraLargePreviewMatchesWideDesignHint() { + XCTAssertEqual(AIWidgetSize.extraLarge.previewSize.width, 639) + XCTAssertEqual(AIWidgetSize.extraLarge.previewSize.height, 345) + } +} + final class ScriptWidgetBackgroundTests: XCTestCase { func testNamedColorWithOpacityIsParsed() { XCTAssertNotNil(ScriptWidgetAttributeColor("green,0.5").color) diff --git a/docs/README.md b/docs/README.md index b2ec7531..84d4026b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,6 +9,7 @@ Build native widgets for iPhone, iPad, and Mac with JavaScript and JSX. The quic - [ScriptWidget Studio](studio.md) — Mac editor, multi-size preview, Copilot, and Skills. - [Runtime API](runtime-api.md) — supported components, properties, globals, and limits. - [AI generation](ai-generate.md) — provider setup, prompting, iteration, privacy, and troubleshooting. +- [AI quality testing](ai-quality-testing.md) — bounded live generation, native snapshots, offline replay, and visual review. - [Apple PCC AI plan](apple-pcc-ai-plan.md) — feasibility, constraints, architecture, and zero-key rollout. - [Skills 1.0](skills.md) — reusable AI guidance, authoring, safe sharing, and package format. - [Widget & Skills Gallery](gallery.md) — discover, verify, install, update, and submit community packages. diff --git a/docs/ai-generate.md b/docs/ai-generate.md index 239d7cb6..51d4b1f4 100644 --- a/docs/ai-generate.md +++ b/docs/ai-generate.md @@ -1,5 +1,7 @@ # AI Generate — 设计文档 +生成效果回归:见 [AI quality testing](ai-quality-testing.md),包含真实模型生成、深浅色原生截图、OCR 提示和无 API 调用的重放对照。 + ScriptWidget 默认使用 Apple Private Cloud Compute (PCC) 生成 Widget,不要求用户提供 API key。用户输入自然语言 prompt 后,模型生成 JSX,App 在本机 runtime 中自动“跑—看错—修”,最后进入审阅和预览态,由用户确认落盘。OpenAI 及兼容端点继续作为可选后端。 本设计为 `feature/ai-generate` 分支的实施依据。实现阶段按第 9 节里程碑推进。 diff --git a/docs/ai-quality-testing.md b/docs/ai-quality-testing.md new file mode 100644 index 00000000..ad13b568 --- /dev/null +++ b/docs/ai-quality-testing.md @@ -0,0 +1,43 @@ +# AI widget quality regression + +`Scripts/ai-quality.sh` runs the real app AI client and generate → execute → repair loop against eight synthetic offline requests, twice each by default, with a four-iteration cap. Cases cover small, medium, large, extra-large, inline, circular and rectangular families, including Chinese text, rings, stats and a native chart. No user widgets are sent to the provider. + +## Run locally + +Use a macOS development environment with Xcode and an existing provider key. Pass credentials through environment variables; never commit a key or paste one into a command literal. For example, if your shell already exports `DEEPSEEK_API_KEY`: + +```sh +ROCKY_OPENAI_APIKEY="$DEEPSEEK_API_KEY" \ +ROCKY_OPENAI_BASEURL=https://api.deepseek.com \ +ROCKY_OPENAI_MODEL=deepseek-flash \ +./Scripts/ai-quality.sh +``` + +Discover the actual model ID from your server. The current DeepSeek presets were checked against `/v1/models` and [DeepSeek's official documentation](https://api-docs.deepseek.com/). Live runs use provider tokens. `AI_QUALITY_ATTEMPTS` defaults to 2 and is clamped to 1–3; requests are sequential and each attempt uses at most 4 model calls. + +Artifacts default to the git-ignored `__Release/ai-quality//`. Override with an absolute `AI_QUALITY_OUTPUT`. Each run writes generated JSX, `quality.json`, configuration, two native screenshots per successful attempt, `vision.json` and an offline `index.html` review page. Artifacts remain local; the script never uploads them. + +The default CI suite skips the opt-in live test. Deterministic frame and appearance regressions run in the normal suite without a key. + +## Compare without another model call + +Replay a prior run's JSX through the current runtime. This separates renderer fixes from randomness in generation and does not require credentials: + +```sh +AI_QUALITY_REPLAY=/absolute/path/to/baseline \ +AI_QUALITY_OUTPUT=/absolute/path/to/replay \ +./Scripts/ai-quality.sh +``` + +The attempt count must match the saved baseline. Missing input files fail explicitly. Each appearance re-executes the same generated source under the matching native appearance; merely recoloring the screenshot would not exercise `$device.isdarkmode()`. + +## Interpret results + +- Runtime checks: the agent returned a real element without an execution error. +- Semantic checks: requested labels/values are present in the element tree, and requested ring/progress/chart tags exist. These checks alone cannot prove visibility or correctness of every data field. +- Screenshot checks: native SwiftUI snapshots at the declared size in light and dark appearances. Vision OCR marks missing expected text for review; punctuation, small text and Chinese recognition can produce false positives. +- Visual review: inspect clipping, overlap, contrast, layout density, chart axes and the requested information. Do not label an image aesthetically correct simply because it rendered or OCR passed. + +Generated widgets are untrusted scripts and continue to run under the existing runtime limits. The suite uses fixed data to avoid confounding model quality with external service availability. It does not certify real WidgetKit lock-screen rendering, HealthKit/location access, PCC entitlements, live data accuracy or all possible prompts. + +If the run fails, inspect the saved report before retrying. The shell command preserves the XCTest failure exit status even when producing a review page. Do not loosen runtime limits or remove failing expectations to improve a reported pass rate. diff --git a/docs/runtime-api.md b/docs/runtime-api.md index e4eeb3e5..ee12e7d8 100644 --- a/docs/runtime-api.md +++ b/docs/runtime-api.md @@ -19,3 +19,9 @@ Removing or changing the meaning of a 1.0 global requires a new major API versio Limits are available under `$runtime.limits`. Exceeding one produces a visible resource-limit error instead of a blank widget. Widget extensions remain subject to stricter operating-system CPU and memory budgets. Bundled templates are contract-tested against the source limit. New examples must keep `main.jsx` UTF-8 encoded and runnable without undocumented globals. + +## Frame and appearance + +A finite, nonnegative numeric `frame` or a numeric string sets a square size: `frame={64}` and `frame="64"` both mean 64 × 64 points. Existing `frame="64,48"`, `frame="max"`, and alignment forms remain supported. Leave space around stroked shapes for their line width. + +`$device.isdarkmode()` uses the appearance captured when its runtime is created, so JavaScript worker threads preserve the rendering context's light/dark choice. On macOS this resolves the native drawing appearance instead of always reporting dark mode. diff --git a/docs/scriptwidget-runtime-api.md b/docs/scriptwidget-runtime-api.md index 5842e88a..441983db 100644 --- a/docs/scriptwidget-runtime-api.md +++ b/docs/scriptwidget-runtime-api.md @@ -15,7 +15,7 @@ Arrange children vertically. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -40,7 +40,7 @@ Arrange children horizontally. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -65,7 +65,7 @@ Overlay children. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -89,7 +89,7 @@ Vertical lazy grid. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -115,7 +115,7 @@ Horizontal lazy grid. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -141,7 +141,7 @@ Display text content. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -166,7 +166,7 @@ Display a formatted date. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -192,7 +192,7 @@ Display a bundled, remote, or SF Symbol image. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -224,7 +224,7 @@ Display a GIF from the package. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -249,7 +249,7 @@ Flexible layout space. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -274,7 +274,7 @@ Rectangle shape. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -300,7 +300,7 @@ Filled rounded rectangle. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -325,7 +325,7 @@ Capsule shape. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -351,7 +351,7 @@ Ellipse shape. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -377,7 +377,7 @@ Circle shape. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -403,7 +403,7 @@ Display a gauge or instrument. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -440,7 +440,7 @@ Render chart data. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -470,7 +470,7 @@ Open a URL when selected. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -495,7 +495,7 @@ Horizontal or vertical separator. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -521,7 +521,7 @@ Fixed-length line. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -548,7 +548,7 @@ SF Symbol icon. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -574,7 +574,7 @@ Text paired with an SF Symbol. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -600,7 +600,7 @@ Linear or circular progress. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -630,7 +630,7 @@ Circular progress ring. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -657,7 +657,7 @@ Compact status badge. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -683,7 +683,7 @@ Outlined metadata chip. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -710,7 +710,7 @@ Title, value, and subtitle statistic. | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -738,7 +738,7 @@ Interactive widget button. Use actionID to share a declared Package 2.0 action w | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | @@ -765,7 +765,7 @@ Interactive widget toggle. A declared actionID requires a package-relative stora | `font` | `enum` | No | Semantic text style. Values: `largeTitle`, `title`, `title2`, `title3`, `headline`, `subheadline`, `body`, `callout`, `footnote`, `caption`, `caption2` | | `fontWeight` | `enum` | No | Font weight. Values: `ultraLight`, `thin`, `light`, `regular`, `medium`, `semibold`, `bold`, `heavy`, `black` | | `fontDesign` | `enum` | No | Font design. Values: `default`, `rounded`, `serif`, `monospaced` | -| `frame` | `number|string` | No | Size or frame description. | +| `frame` | `number|string` | No | Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48"). | | `padding` | `number|string` | No | Padding amount or edge description. | | `corner` | `number` | No | Corner radius. | | `opacity` | `number` | No | Opacity from 0 through 1. | diff --git a/iOS/ScriptWidget/App/Settings/SettingAIView.swift b/iOS/ScriptWidget/App/Settings/SettingAIView.swift index 5b0d8760..ed92e6c1 100644 --- a/iOS/ScriptWidget/App/Settings/SettingAIView.swift +++ b/iOS/ScriptWidget/App/Settings/SettingAIView.swift @@ -187,7 +187,7 @@ struct AIProfileEditorView: View { private static let providerPresets: [(label: String, host: String, models: [String])] = [ ("OpenAI", "https://api.openai.com", ["gpt-4o-mini", "gpt-4o", "gpt-4.1-mini", "gpt-4.1", "o4-mini"]), - ("DeepSeek", "https://api.deepseek.com", ["deepseek-chat", "deepseek-reasoner"]), + ("DeepSeek", "https://api.deepseek.com", ["deepseek-flash", "deepseek-v4-pro"]), ("xAI", "https://api.x.ai", ["grok-2-latest", "grok-2-mini"]), ("Ollama", "http://localhost:11434", []), ] @@ -369,7 +369,7 @@ struct AIProfileEditorView: View { id: "", name: "", baseURL: baseURL, model: "", apiKey: "", authMethod: .apiKey ).normalizedBaseURL)?.host ?? "" if host.contains("deepseek") { - return ["deepseek-chat", "deepseek-reasoner"] + return ["deepseek-flash", "deepseek-v4-pro"] } else if host.contains("x.ai") { return ["grok-2-latest", "grok-2-mini"] } else if host.contains("localhost") || host.contains("127.0.0.1") { diff --git a/iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/assets/index-CaXXMCSr.js b/iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/assets/index-dCxXChRa.js similarity index 98% rename from iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/assets/index-CaXXMCSr.js rename to iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/assets/index-dCxXChRa.js index b9adb8de..ea1e0106 100644 --- a/iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/assets/index-CaXXMCSr.js +++ b/iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/assets/index-dCxXChRa.js @@ -21,7 +21,7 @@ \${} } }`,{label:"class",detail:"definition",type:"keyword"}),Te('import {${names}} from "${module}"\n${}',{label:"import",detail:"named",type:"keyword"}),Te('import ${name} from "${module}"\n${}',{label:"import",detail:"default",type:"keyword"})],C1=Tu.concat([Te("interface ${name} {\n ${}\n}",{label:"interface",detail:"definition",type:"keyword"}),Te("type ${name} = ${type}",{label:"type",detail:"definition",type:"keyword"}),Te("enum ${name} {\n ${}\n}",{label:"enum",detail:"definition",type:"keyword"})]),yh=new Am,Cu=new Set(["Script","Block","FunctionExpression","FunctionDeclaration","ArrowFunction","MethodDeclaration","ForStatement"]);function qi(n){return(e,t)=>{let i=e.node.getChild("VariableDefinition");return i&&t(i,n),!0}}const Z1=["FunctionDeclaration"],A1={FunctionDeclaration:qi("function"),ClassDeclaration:qi("class"),ClassExpression:()=>!0,EnumDeclaration:qi("constant"),TypeAliasDeclaration:qi("type"),NamespaceDeclaration:qi("namespace"),VariableDefinition(n,e){n.matchContext(Z1)||e(n,"variable")},TypeDefinition(n,e){e(n,"type")},__proto__:null};function Zu(n,e){let t=yh.get(e);if(t)return t;let i=[],s=!0;function r(o,l){let a=n.sliceString(o.from,o.to);i.push({label:a,type:l})}return e.cursor(te.IncludeAnonymous).iterate(o=>{if(s)s=!1;else if(o.name){let l=A1[o.name];if(l&&l(o,r)||Cu.has(o.name))return!1}else if(o.to-o.from>8192){for(let l of Zu(n,o.node))i.push(l);return!1}}),yh.set(e,i),i}const bh=/^[\w$\xa1-\uffff][\w$\d\xa1-\uffff]*$/,Au=["TemplateString","String","RegExp","LineComment","BlockComment","VariableDefinition","TypeDefinition","Label","PropertyDefinition","PropertyName","PrivatePropertyDefinition","PrivatePropertyName","JSXText","JSXAttributeValue","JSXOpenTag","JSXCloseTag","JSXSelfClosingTag",".","?."];function M1(n){let e=he(n.state).resolveInner(n.pos,-1);if(Au.indexOf(e.name)>-1)return null;let t=e.name=="VariableName"||e.to-e.from<20&&bh.test(n.state.sliceDoc(e.from,e.to));if(!t&&!n.explicit)return null;let i=[];for(let s=e;s;s=s.parent)Cu.has(s.name)&&(i=i.concat(Zu(n.state.doc,s)));return{options:i,from:t?e.from:n.pos,validFor:bh}}const Kt=ms.define({name:"javascript",parser:T1.configure({props:[wf.add({IfStatement:vr({except:/^\s*({|else\b)/}),TryStatement:vr({except:/^\s*({|catch\b|finally\b)/}),LabeledStatement:Km,SwitchBody:n=>{let e=n.textAfter,t=/^\s*\}/.test(e),i=/^\s*(case|default)\b/.test(e);return n.baseIndent+(t?0:i?1:2)*n.unit},Block:Hm({closing:"}"}),ArrowFunction:n=>n.baseIndent+n.unit,"TemplateString BlockComment":()=>null,"Statement Property":vr({except:/^\s*{/}),JSXElement(n){let e=/^\s*<\//.test(n.textAfter);return n.lineIndent(n.node.from)+(e?0:n.unit)},JSXEscape(n){let e=/\s*\}/.test(n.textAfter);return n.lineIndent(n.node.from)+(e?0:n.unit)},"JSXOpenTag JSXSelfClosingTag"(n){return n.column(n.node.from)+n.unit}}),vf.add({"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType":ig,BlockComment(n){return{from:n.from+2,to:n.to-2}},JSXElement(n){let e=n.firstChild;if(!e||e.name=="JSXSelfClosingTag")return null;let t=n.lastChild;return{from:e.to,to:t.type.isError?n.to:t.from}},"JSXSelfClosingTag JSXOpenTag"(n){var e;let t=(e=n.firstChild)===null||e===void 0?void 0:e.nextSibling,i=n.lastChild;return!t||t.type.isError?null:{from:t.to,to:i.type.isError?n.to:i.from}}})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"`"]},commentTokens:{line:"//",block:{open:"/*",close:"*/"}},indentOnInput:/^\s*(?:case |default:|\{|\}|<\/)$/,wordChars:"$"}}),Mu={test:n=>/^JSX/.test(n.name),facet:Sf({commentTokens:{block:{open:"{/*",close:"*/}"}}})},R1=Kt.configure({dialect:"ts"},"typescript"),X1=Kt.configure({dialect:"jsx",props:[sl.add(n=>n.isTop?[Mu]:void 0)]}),L1=Kt.configure({dialect:"jsx ts",props:[sl.add(n=>n.isTop?[Mu]:void 0)]},"typescript");let Ru=n=>({label:n,type:"keyword"});const Xu="break case const continue default delete export extends false finally in instanceof let new return static super switch this throw true typeof var yield".split(" ").map(Ru),D1=Xu.concat(["declare","implements","private","protected","public"].map(Ru));function E1(n={}){let e=n.jsx?n.typescript?L1:X1:n.typescript?R1:Kt,t=n.typescript?C1.concat(D1):Tu.concat(Xu);return new Ym(e,[Kt.data.of({autocomplete:G0(Au,mu(t))}),Kt.data.of({autocomplete:M1}),n.jsx?q1:[]])}function W1(n){for(;;){if(n.name=="JSXOpenTag"||n.name=="JSXSelfClosingTag"||n.name=="JSXFragmentTag")return n;if(n.name=="JSXEscape"||!n.parent)return null;n=n.parent}}function Sh(n,e,t=n.length){for(let i=e?.firstChild;i;i=i.nextSibling)if(i.name=="JSXIdentifier"||i.name=="JSXBuiltin"||i.name=="JSXNamespacedName"||i.name=="JSXMemberExpression")return n.sliceString(i.from,Math.min(i.to,t));return""}const z1=typeof navigator=="object"&&/Android\b/.test(navigator.userAgent),q1=T.inputHandler.of((n,e,t,i,s)=>{if((z1?n.composing:n.compositionStarted)||n.state.readOnly||e!=t||i!=">"&&i!="/"||!Kt.isActiveAt(n.state,e,-1))return!1;let r=s(),{state:o}=r,l=o.changeByRange(a=>{var h;let{head:c}=a,f=he(o).resolveInner(c-1,-1),u;if(f.name=="JSXStartTag"&&(f=f.parent),!(o.doc.sliceString(c-1,c)!=i||f.name=="JSXAttributeValue"&&f.to>c)){if(i==">"&&f.name=="JSXFragmentTag")return{range:a,changes:{from:c,insert:""}};if(i=="/"&&f.name=="JSXStartCloseTag"){let d=f.parent,p=d.parent;if(p&&d.from==c-2&&((u=Sh(o.doc,p.firstChild,c))||((h=p.firstChild)===null||h===void 0?void 0:h.name)=="JSXFragmentTag")){let O=`${u}>`;return{range:b.cursor(c+O.length,-1),changes:{from:c,insert:O}}}}else if(i==">"){let d=W1(f);if(d&&d.name=="JSXOpenTag"&&!/^\/?>|^<\//.test(o.doc.sliceString(c,c+2))&&(u=Sh(o.doc,d,c)))return{range:a,changes:{from:c,insert:``}}}}return{range:a}});return l.changes.empty?!1:(n.dispatch([r,o.update(l,{userEvent:"input.complete",scrollIntoView:!0})]),!0)}),xh=typeof String.prototype.normalize=="function"?n=>n.normalize("NFKD"):n=>n;class Pi{constructor(e,t,i=0,s=e.length,r,o){this.test=o,this.value={from:0,to:0,precise:!1},this.done=!1,this.matches=[],this.buffer="",this.bufferPos=0,this.iter=e.iterRange(i,s),this.bufferStart=i,this.normalize=r?l=>r(xh(l)):xh,this.query=this.normalize(t)}peek(){if(this.bufferPos==this.buffer.length){if(this.bufferStart+=this.buffer.length,this.iter.next(),this.iter.done)return-1;this.bufferPos=0,this.buffer=this.iter.value}return Ce(this.buffer,this.bufferPos)}next(){for(;this.matches.length;)this.matches.pop();return this.nextOverlapping()}nextOverlapping(){for(;;){let e=this.peek();if(e<0)return this.done=!0,this;let t=Eo(e),i=this.bufferStart+this.bufferPos;this.bufferPos+=ht(e);let s=this.normalize(t);if(s.length)for(let r=0,o=i,l=!0;;r++){let a=s.charCodeAt(r),h=this.match(a,o,l,this.bufferPos+this.bufferStart,r==s.length-1);if(h)return this.value=h,this;if(r==s.length-1)break;l&&rthis.to&&(this.curLine=this.curLine.slice(0,this.to-this.curLineStart)),this.iter.next())}nextLine(){this.curLineStart=this.curLineStart+this.curLine.length+1,this.curLineStart>this.to?this.curLine="":this.getLine(0)}next(){for(let e=this.matchPos-this.curLineStart;;){this.re.lastIndex=e;let t=this.matchPos<=this.to&&this.re.exec(this.curLine);if(t){let i=this.curLineStart+t.index,s=i+t[0].length;if(this.matchPos=Ps(this.text,s+(i==s?1:0)),i==this.curLineStart+this.curLine.length&&this.nextLine(),(ithis.value.to)&&(!this.test||this.test(i,s,t)))return this.value={from:i,to:s,precise:!0,match:t},this;e=this.matchPos-this.curLineStart}else if(this.curLineStart+this.curLine.length=i||s.to<=t){let l=new bi(t,e.sliceString(t,i));return Dr.set(e,l),l}if(s.from==t&&s.to==i)return s;let{text:r,from:o}=s;return o>t&&(r=e.sliceString(t,o)+r,o=t),s.to=this.to?this.to:this.text.lineAt(e).to}next(){for(;;){let e=this.re.lastIndex=this.matchPos-this.flat.from,t=this.re.exec(this.flat.text);if(t&&!t[0]&&t.index==e&&(this.re.lastIndex=e+1,t=this.re.exec(this.flat.text)),t){let i=this.flat.from+t.index,s=i+t[0].length;if((this.flat.to>=this.to||t.index+t[0].length<=this.flat.text.length-10)&&(!this.test||this.test(i,s,t)))return this.value={from:i,to:s,precise:!0,match:t},this.matchPos=Ps(this.text,s+(i==s?1:0)),this}if(this.flat.to==this.to)return this.done=!0,this;this.flat=bi.get(this.text,this.flat.from,this.chunkEnd(this.flat.from+this.flat.text.length*2))}}}typeof Symbol<"u"&&(Du.prototype[Symbol.iterator]=Eu.prototype[Symbol.iterator]=function(){return this});function B1(n){try{return new RegExp(n,yl),!0}catch{return!1}}function Ps(n,e){if(e>=n.length)return e;let t=n.lineAt(e),i;for(;e=56320&&i<57344;)e++;return e}const _1=n=>{let{state:e}=n,t=String(e.doc.lineAt(n.state.selection.main.head).number),{close:i,result:s}=fm(n,{label:e.phrase("Go to line"),input:{type:"text",name:"line",value:t},focus:!0,submitLabel:e.phrase("go")});return s.then(r=>{let o=r&&/^([+-])?(\d+)?(:\d+)?(%)?$/.exec(r.elements.line.value);if(!o){n.dispatch({effects:i});return}let l=e.doc.lineAt(e.selection.main.head),[,a,h,c,f]=o,u=c?+c.slice(1):0,d=h?+h:l.number;if(h&&f){let m=d/100;a&&(m=m*(a=="-"?-1:1)+l.number/e.doc.lines),d=Math.round(e.doc.lines*m)}else h&&a&&(d=d*(a=="-"?-1:1)+l.number);let p=e.doc.line(Math.max(1,Math.min(e.doc.lines,d))),O=b.cursor(p.from+Math.max(0,Math.min(u,p.length)));n.dispatch({effects:[i,T.scrollIntoView(O.from,{y:"center"})],selection:O})}),!0},Y1={highlightWordAroundCursor:!1,minSelectionLength:1,maxMatches:100,wholeWords:!1},I1=C.define({combine(n){return et(n,Y1,{highlightWordAroundCursor:(e,t)=>e||t,minSelectionLength:Math.min,maxMatches:Math.min})}});function V1(n){return[F1,U1]}const j1=X.mark({class:"cm-selectionMatch"}),N1=X.mark({class:"cm-selectionMatch cm-selectionMatch-main"});function wh(n,e,t,i){return(t==0||n(e.sliceDoc(t-1,t))!=ee.Word)&&(i==e.doc.length||n(e.sliceDoc(i,i+1))!=ee.Word)}function G1(n,e,t,i){return n(e.sliceDoc(t,t+1))==ee.Word&&n(e.sliceDoc(i-1,i))==ee.Word}const U1=ne.fromClass(class{constructor(n){this.decorations=this.getDeco(n)}update(n){(n.selectionSet||n.docChanged||n.viewportChanged)&&(this.decorations=this.getDeco(n.view))}getDeco(n){let e=n.state.facet(I1),{state:t}=n,i=t.selection;if(i.ranges.length>1)return X.none;let s=i.main,r,o=null;if(s.empty){if(!e.highlightWordAroundCursor)return X.none;let a=t.wordAt(s.head);if(!a)return X.none;o=t.charCategorizer(s.head),r=t.sliceDoc(a.from,a.to)}else{let a=s.to-s.from;if(a200)return X.none;if(e.wholeWords){if(r=t.sliceDoc(s.from,s.to),o=t.charCategorizer(s.head),!(wh(o,t,s.from,s.to)&&G1(o,t,s.from,s.to)))return X.none}else if(r=t.sliceDoc(s.from,s.to),!r)return X.none}let l=[];for(let a of n.visibleRanges){let h=new Pi(t.doc,r,a.from,a.to);for(;!h.next().done;){let{from:c,to:f}=h.value;if((!o||wh(o,t,c,f))&&(s.empty&&c<=s.from&&f>=s.to?l.push(N1.range(c,f)):(c>=s.to||f<=s.from)&&l.push(j1.range(c,f)),l.length>e.maxMatches))return X.none}}return X.set(l)}},{decorations:n=>n.decorations}),F1=T.baseTheme({".cm-selectionMatch":{backgroundColor:"#99ff7780"},".cm-searchMatch .cm-selectionMatch":{backgroundColor:"transparent"}}),H1=({state:n,dispatch:e})=>{let{selection:t}=n,i=b.create(t.ranges.map(s=>n.wordAt(s.head)||b.cursor(s.head)),t.mainIndex);return i.eq(t)?!1:(e(n.update({selection:i})),!0)};function K1(n,e){let{main:t,ranges:i}=n.selection,s=n.wordAt(t.head),r=s&&s.from==t.from&&s.to==t.to;for(let o=!1,l=new Pi(n.doc,e,i[i.length-1].to);;)if(l.next(),l.done){if(o)return null;l=new Pi(n.doc,e,0,Math.max(0,i[i.length-1].from-1)),o=!0}else{if(o&&i.some(a=>a.from==l.value.from))continue;if(r){let a=n.wordAt(l.value.from);if(!a||a.from!=l.value.from||a.to!=l.value.to)continue}return l.value}}const J1=({state:n,dispatch:e})=>{let{ranges:t}=n.selection;if(t.some(r=>r.from===r.to))return H1({state:n,dispatch:e});let i=n.sliceDoc(t[0].from,t[0].to);if(n.selection.ranges.some(r=>n.sliceDoc(r.from,r.to)!=i))return!1;let s=K1(n,i);return s?(e(n.update({selection:n.selection.addRange(b.range(s.from,s.to),!1),effects:T.scrollIntoView(s.to)})),!0):!1},Ri=C.define({combine(n){return et(n,{top:!1,caseSensitive:!1,literal:!1,regexp:!1,wholeWord:!1,createPanel:e=>new db(e),scrollToMatch:e=>T.scrollIntoView(e)})}});class Wu{constructor(e){this.search=e.search,this.caseSensitive=!!e.caseSensitive,this.literal=!!e.literal,this.regexp=!!e.regexp,this.replace=e.replace||"",this.valid=!!this.search&&(!this.regexp||B1(this.search)),this.unquoted=this.unquote(this.search),this.wholeWord=!!e.wholeWord,this.test=e.test}unquote(e){return this.literal?e:e.replace(/\\([nrt\\])/g,(t,i)=>i=="n"?` -`:i=="r"?"\r":i=="t"?" ":"\\")}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord&&this.test==e.test}create(){return this.regexp?new rb(this):new ib(this)}getCursor(e,t=0,i){let s=e.doc?e:I.create({doc:e});return i==null&&(i=s.doc.length),this.regexp?ai(this,s,t,i):li(this,s,t,i)}}class zu{constructor(e){this.spec=e}}function eb(n,e,t){return(i,s,r,o)=>{if(t&&!t(i,s,r,o))return!1;let l=i>=o&&s<=o+r.length?r.slice(i-o,s-o):e.doc.sliceString(i,s);return n(l,e,i,s)}}function li(n,e,t,i){let s;return n.wholeWord&&(s=tb(e.doc,e.charCategorizer(e.selection.main.head))),n.test&&(s=eb(n.test,e,s)),new Pi(e.doc,n.unquoted,t,i,n.caseSensitive?void 0:r=>r.toLowerCase(),s)}function tb(n,e){return(t,i,s,r)=>((r>t||r+s.length=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=li(this.spec,e,Math.max(0,t-this.spec.unquoted.length),Math.min(i+this.spec.unquoted.length,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}function nb(n,e,t){return(i,s,r)=>(!t||t(i,s,r))&&n(r[0],e,i,s)}function ai(n,e,t,i){let s;return n.wholeWord&&(s=sb(e.charCategorizer(e.selection.main.head))),n.test&&(s=nb(n.test,e,s)),new Du(e.doc,n.search,{ignoreCase:!n.caseSensitive,test:s},t,i)}function Ts(n,e){return n.slice(de(n,e,!1),e)}function Cs(n,e){return n.slice(e,de(n,e))}function sb(n){return(e,t,i)=>!i[0].length||(n(Ts(i.input,i.index))!=ee.Word||n(Cs(i.input,i.index))!=ee.Word)&&(n(Cs(i.input,i.index+i[0].length))!=ee.Word||n(Ts(i.input,i.index+i[0].length))!=ee.Word)}class rb extends zu{nextMatch(e,t,i){let s=ai(this.spec,e,i,e.doc.length).next();return s.done&&(s=ai(this.spec,e,0,t).next()),s.done?null:s.value}prevMatchInRange(e,t,i){for(let s=1;;s++){let r=Math.max(t,i-s*1e4),o=ai(this.spec,e,r,i),l=null;for(;!o.next().done;)l=o.value;if(l&&(r==t||l.from>r+10))return l;if(r==t)return null}}prevMatch(e,t,i){return this.prevMatchInRange(e,0,t)||this.prevMatchInRange(e,i,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g,(t,i)=>{if(i=="&")return e.match[0];if(i=="$")return"$";for(let s=i.length;s>0;s--){let r=+i.slice(0,s);if(r>0&&r=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=ai(this.spec,e,Math.max(0,t-250),Math.min(i+250,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}const un=z.define(),bl=z.define(),Rt=fe.define({create(n){return new Er(Xo(n).create(),null)},update(n,e){for(let t of e.effects)t.is(un)?n=new Er(t.value.create(),n.panel):t.is(bl)&&(n=new Er(n.query,t.value?Sl:null));return n},provide:n=>rn.from(n,e=>e.panel)});class Er{constructor(e,t){this.query=e,this.panel=t}}const ob=X.mark({class:"cm-searchMatch"}),lb=X.mark({class:"cm-searchMatch cm-searchMatch-selected"}),ab=ne.fromClass(class{constructor(n){this.view=n,this.decorations=this.highlight(n.state.field(Rt))}update(n){let e=n.state.field(Rt);(e!=n.startState.field(Rt)||n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=this.highlight(e))}highlight({query:n,panel:e}){if(!e||!n.spec.valid)return X.none;let{view:t}=this,i=new Qt;for(let s=0,r=t.visibleRanges,o=r.length;sr[s+1].from-500;)a=r[++s].to;n.highlight(t.state,l,a,(h,c)=>{let f=t.state.selection.ranges.some(u=>u.from==h&&u.to==c);i.add(h,c,f?lb:ob)})}return i.finish()}},{decorations:n=>n.decorations});function Sn(n){return e=>{let t=e.state.field(Rt,!1);return t&&t.query.spec.valid?n(e,t):_u(e)}}const Zs=Sn((n,{query:e})=>{let{to:t}=n.state.selection.main,i=e.nextMatch(n.state,t,t);if(!i)return!1;let s=b.single(i.from,i.to),r=n.state.facet(Ri);return n.dispatch({selection:s,effects:[xl(n,i),r.scrollToMatch(s.main,n)],userEvent:"select.search"}),Bu(n),!0}),As=Sn((n,{query:e})=>{let{state:t}=n,{from:i}=t.selection.main,s=e.prevMatch(t,i,i);if(!s)return!1;let r=b.single(s.from,s.to),o=n.state.facet(Ri);return n.dispatch({selection:r,effects:[xl(n,s),o.scrollToMatch(r.main,n)],userEvent:"select.search"}),Bu(n),!0}),hb=Sn((n,{query:e})=>{let t=e.matchAll(n.state,1e3);return!t||!t.length?!1:(n.dispatch({selection:b.create(t.map(i=>b.range(i.from,i.to))),userEvent:"select.search.matches"}),!0)}),cb=({state:n,dispatch:e})=>{let t=n.selection;if(t.ranges.length>1||t.main.empty)return!1;let{from:i,to:s}=t.main,r=[],o=0;for(let l=new Pi(n.doc,n.sliceDoc(i,s));!l.next().done;){if(r.length>1e3)return!1;l.value.from==i&&(o=r.length),r.push(b.range(l.value.from,l.value.to))}return e(n.update({selection:b.create(r,o),userEvent:"select.search.matches"})),!0},kh=Sn((n,{query:e})=>{let{state:t}=n,{from:i,to:s}=t.selection.main;if(t.readOnly)return!1;let r=e.nextMatch(t,i,i);if(!r)return!1;let o=r,l=[],a,h,c=[];o.precise?o.from==i&&o.to==s&&(h=t.toText(e.getReplacement(o)),l.push({from:o.from,to:o.to,insert:h}),o=e.nextMatch(t,o.from,o.to),c.push(T.announce.of(t.phrase("replaced match on line $",t.doc.lineAt(i).number)+"."))):o=e.nextMatch(t,o.from,o.to);let f=n.state.changes(l);return o&&(a=b.single(o.from,o.to).map(f),c.push(xl(n,o)),c.push(t.facet(Ri).scrollToMatch(a.main,n))),n.dispatch({changes:f,selection:a,effects:c,userEvent:"input.replace"}),!0}),fb=Sn((n,{query:e})=>{if(n.state.readOnly)return!1;let t=[];for(let s of e.matchAll(n.state,1e9)){let{from:r,to:o,precise:l}=s;l&&t.push({from:r,to:o,insert:e.getReplacement(s)})}if(!t.length)return!1;let i=n.state.phrase("replaced $ matches",t.length)+".";return n.dispatch({changes:t,effects:T.announce.of(i),userEvent:"input.replace.all"}),!0});function Sl(n){return n.state.facet(Ri).createPanel(n)}function Xo(n,e){var t,i,s,r,o;let l=n.selection.main,a=l.empty||l.to>l.from+100?"":n.sliceDoc(l.from,l.to);if(e&&!a)return e;let h=n.facet(Ri);return new Wu({search:((t=e?.literal)!==null&&t!==void 0?t:h.literal)?a:a.replace(/\n/g,"\\n"),caseSensitive:(i=e?.caseSensitive)!==null&&i!==void 0?i:h.caseSensitive,literal:(s=e?.literal)!==null&&s!==void 0?s:h.literal,regexp:(r=e?.regexp)!==null&&r!==void 0?r:h.regexp,wholeWord:(o=e?.wholeWord)!==null&&o!==void 0?o:h.wholeWord})}function qu(n){let e=rf(n,Sl);return e&&e.dom.querySelector("[main-field]")}function Bu(n){let e=qu(n);e&&e==n.root.activeElement&&e.select()}const _u=n=>{let e=n.state.field(Rt,!1);if(e&&e.panel){let t=qu(n);if(t&&t!=n.root.activeElement){let i=Xo(n.state,e.query.spec);i.valid&&n.dispatch({effects:un.of(i)}),t.focus(),t.select()}}else n.dispatch({effects:[bl.of(!0),e?un.of(Xo(n.state,e.query.spec)):z.appendConfig.of(Ob)]});return!0},Yu=n=>{let e=n.state.field(Rt,!1);if(!e||!e.panel)return!1;let t=rf(n,Sl);return t&&t.dom.contains(n.root.activeElement)&&n.focus(),n.dispatch({effects:bl.of(!1)}),!0},ub=[{key:"Mod-f",run:_u,scope:"editor search-panel"},{key:"F3",run:Zs,shift:As,scope:"editor search-panel",preventDefault:!0},{key:"Mod-g",run:Zs,shift:As,scope:"editor search-panel",preventDefault:!0},{key:"Escape",run:Yu,scope:"editor search-panel"},{key:"Mod-Shift-l",run:cb},{key:"Mod-Alt-g",run:_1},{key:"Mod-d",run:J1,preventDefault:!0}];class db{constructor(e){this.view=e;let t=this.query=e.state.field(Rt).query.spec;this.commit=this.commit.bind(this),this.searchField=U("input",{value:t.search,placeholder:We(e,"Find"),"aria-label":We(e,"Find"),class:"cm-textfield",name:"search",form:"","main-field":"true",onchange:this.commit,onkeyup:this.commit}),this.replaceField=U("input",{value:t.replace,placeholder:We(e,"Replace"),"aria-label":We(e,"Replace"),class:"cm-textfield",name:"replace",form:"",onchange:this.commit,onkeyup:this.commit}),this.caseField=U("input",{type:"checkbox",name:"case",form:"",checked:t.caseSensitive,onchange:this.commit}),this.reField=U("input",{type:"checkbox",name:"re",form:"",checked:t.regexp,onchange:this.commit}),this.wordField=U("input",{type:"checkbox",name:"word",form:"",checked:t.wholeWord,onchange:this.commit});function i(s,r,o){return U("button",{class:"cm-button",name:s,onclick:r,type:"button"},o)}this.dom=U("div",{onkeydown:s=>this.keydown(s),class:"cm-search"},[this.searchField,i("next",()=>Zs(e),[We(e,"next")]),i("prev",()=>As(e),[We(e,"previous")]),i("select",()=>hb(e),[We(e,"all")]),U("label",null,[this.caseField,We(e,"match case")]),U("label",null,[this.reField,We(e,"regexp")]),U("label",null,[this.wordField,We(e,"by word")]),...e.state.readOnly?[]:[U("br"),this.replaceField,i("replace",()=>kh(e),[We(e,"replace")]),i("replaceAll",()=>fb(e),[We(e,"replace all")])],U("button",{name:"close",onclick:()=>Yu(e),"aria-label":We(e,"close"),type:"button"},["×"])])}commit(){let e=new Wu({search:this.searchField.value,caseSensitive:this.caseField.checked,regexp:this.reField.checked,wholeWord:this.wordField.checked,replace:this.replaceField.value});e.eq(this.query)||(this.query=e,this.view.dispatch({effects:un.of(e)}))}keydown(e){wO(this.view,e,"search-panel")?e.preventDefault():e.keyCode==13&&e.target==this.searchField?(e.preventDefault(),(e.shiftKey?As:Zs)(this.view)):e.keyCode==13&&e.target==this.replaceField&&(e.preventDefault(),kh(this.view))}update(e){for(let t of e.transactions)for(let i of t.effects)i.is(un)&&!i.value.eq(this.query)&&this.setQuery(i.value)}setQuery(e){this.query=e,this.searchField.value=e.search,this.replaceField.value=e.replace,this.caseField.checked=e.caseSensitive,this.reField.checked=e.regexp,this.wordField.checked=e.wholeWord}mount(){this.searchField.select()}get pos(){return 80}get top(){return this.view.state.facet(Ri).top}}function We(n,e){return n.state.phrase(e)}const In=30,Vn=/[\s\.,:;?!]/;function xl(n,{from:e,to:t}){let i=n.state.doc.lineAt(e),s=n.state.doc.lineAt(t).to,r=Math.max(i.from,e-In),o=Math.min(s,t+In),l=n.state.sliceDoc(r,o);if(r!=i.from){for(let a=0;al.length-In;a--)if(!Vn.test(l[a-1])&&Vn.test(l[a])){l=l.slice(0,a);break}}return T.announce.of(`${n.state.phrase("current match")}. ${l} ${n.state.phrase("on line")} ${i.number}.`)}const pb=T.baseTheme({".cm-panel.cm-search":{padding:"2px 6px 4px",position:"relative","& [name=close]":{position:"absolute",top:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:0,margin:0},"& input, & button, & label":{margin:".2em .6em .2em 0"},"& input[type=checkbox]":{marginRight:".2em"},"& label":{fontSize:"80%",whiteSpace:"pre"}},"&light .cm-searchMatch":{backgroundColor:"#ffff0054"},"&dark .cm-searchMatch":{backgroundColor:"#00ffff8a"},"&light .cm-searchMatch-selected":{backgroundColor:"#ff6a0054"},"&dark .cm-searchMatch-selected":{backgroundColor:"#ff00ff8a"}}),Ob=[Rt,Bt.low(ab),pb];class Qh{constructor(e,t,i){this.from=e,this.to=t,this.diagnostic=i}}class jt{constructor(e,t,i){this.diagnostics=e,this.panel=t,this.selected=i}static init(e,t,i){let s=i.facet(Ot).markerFilter;s&&(e=s(e,i));let r=e.slice().sort((d,p)=>d.from-p.from||d.to-p.to),o=new Qt,l=[],a=0,h=i.doc.iter(),c=0,f=i.doc.length;for(let d=0;;){let p=d==r.length?null:r[d];if(!p&&!l.length)break;let O,m;if(l.length)O=a,m=l.reduce((x,Z)=>Math.min(x,Z.to),p&&p.from>O?p.from:1e8);else{if(O=p.from,O>f)break;m=p.to,l.push(p),d++}for(;dx.from||x.to==O))l.push(x),d++,m=Math.min(x.to,m);else{m=Math.min(x.from,m);break}}m=Math.min(m,f);let y=!1;if(l.some(x=>x.from==O&&(x.to==m||m==f))&&(y=O==m,!y&&m-O<10)){let x=O-(c+h.value.length);x>0&&(h.next(x),c=O);for(let Z=O;;){if(Z>=m){y=!0;break}if(!h.lineBreak&&c+h.value.length>Z)break;Z=c+h.value.length,c+=h.value.length,h.next()}}let w=Hu(l);if(y)o.add(O,O,X.widget({widget:new wb(w),diagnostics:l.slice()}));else{let x=l.reduce((Z,k)=>k.markClass?Z+" "+k.markClass:Z,"");o.add(O,m,X.mark({class:"cm-lintRange cm-lintRange-"+w+x,diagnostics:l.slice(),inclusiveEnd:l.some(Z=>Z.to>m)}))}if(a=m,a==f)break;for(let x=0;x{if(!(e&&o.diagnostics.indexOf(e)<0))if(!i)i=new Qh(s,r,e||o.diagnostics[0]);else{if(o.diagnostics.indexOf(i.diagnostic)<0)return!1;i=new Qh(i.from,r,i.diagnostic)}}),i}function Iu(n,e){let t=e.pos,i=e.end||t,s=n.state.facet(Ot).hideOn(n,t,i);if(s!=null)return s;let r=n.startState.doc.lineAt(e.pos);return!!(n.effects.some(o=>o.is(er))||n.changes.touchesRange(r.from,Math.max(r.to,i)))}function mb(n,e){return n.field(Ke,!1)?e:e.concat(z.appendConfig.of(ed))}function Vu(n,e){return{effects:mb(n,[er.of(e)])}}const er=z.define(),ju=z.define(),Nu=z.define(),Ke=fe.define({create(){return new jt(X.none,null,null)},update(n,e){if(e.docChanged&&n.diagnostics.size){let t=n.diagnostics.map(e.changes),i=null,s=n.panel;if(n.selected){let r=e.changes.mapPos(n.selected.from,1);i=Ti(t,n.selected.diagnostic,r)||Ti(t,null,r)}!t.size&&s&&e.state.facet(Ot).autoPanel&&(s=null),n=new jt(t,s,i)}for(let t of e.effects)if(t.is(er)){let i=e.state.facet(Ot).autoPanel?t.value.length?Ms.open:null:n.panel;n=jt.init(t.value,i,e.state)}else t.is(ju)?n=new jt(n.diagnostics,t.value?Ms.open:null,n.selected):t.is(Nu)&&(n=new jt(n.diagnostics,n.panel,t.value));return n},provide:n=>[rn.from(n,e=>e.panel),T.decorations.from(n,e=>e.diagnostics)]}),gb=X.mark({class:"cm-lintRange cm-lintRange-active"});function yb(n,e,t){let{diagnostics:i}=n.state.field(Ke),s,r=-1,o=-1;i.between(e-(t<0?1:0),e+(t>0?1:0),(a,h,{spec:c})=>{if(e>=a&&e<=h&&(a==h||(e>a||t>0)&&(eFu(n,t,!1)))}const vh=n=>{let e=n.state.field(Ke,!1);return!e||!e.panel?!1:(n.dispatch({effects:ju.of(!1)}),!0)},bb=ne.fromClass(class{constructor(n){this.view=n,this.timeout=-1,this.set=!0;let{delay:e}=n.state.facet(Ot);this.lintTime=Date.now()+e,this.run=this.run.bind(this),this.timeout=setTimeout(this.run,e)}run(){clearTimeout(this.timeout);let n=Date.now();if(nPromise.resolve(i(this.view))),i=>{this.view.state.doc==e.doc&&this.view.dispatch(Vu(this.view.state,i.reduce((s,r)=>s.concat(r))))},i=>{ve(this.view.state,i)})}}update(n){let e=n.state.facet(Ot);(n.docChanged||e!=n.startState.facet(Ot)||e.needsRefresh&&e.needsRefresh(n))&&(this.lintTime=Date.now()+e.delay,this.set||(this.set=!0,this.timeout=setTimeout(this.run,e.delay)))}force(){this.set&&(this.lintTime=Date.now(),this.run())}destroy(){clearTimeout(this.timeout)}});function Sb(n,e,t){let i=[],s=-1;for(let r of n)r.then(o=>{i.push(o),clearTimeout(s),i.length==n.length?e(i):s=setTimeout(()=>e(i),200)},t)}const Ot=C.define({combine(n){return{sources:n.map(e=>e.source).filter(e=>e!=null),...et(n.map(e=>e.config),{delay:750,markerFilter:null,tooltipFilter:null,needsRefresh:null,hideOn:()=>null},{delay:Math.max,markerFilter:$h,tooltipFilter:$h,needsRefresh:(e,t)=>e?t?i=>e(i)||t(i):e:t,hideOn:(e,t)=>e?t?(i,s,r)=>e(i,s,r)||t(i,s,r):e:t,autoPanel:(e,t)=>e||t})}}});function $h(n,e){return n?e?(t,i)=>e(n(t,i),i):n:e}function xb(n,e={}){return[Ot.of({source:n,config:e}),bb,ed]}function Uu(n){let e=[];if(n)e:for(let{name:t}of n){for(let i=0;ir.toLowerCase()==s.toLowerCase())){e.push(s);continue e}}e.push("")}return e}function Fu(n,e,t){var i;let s=t?Uu(e.actions):[];return U("li",{class:"cm-diagnostic cm-diagnostic-"+e.severity},U("span",{class:"cm-diagnosticText"},e.renderMessage?e.renderMessage(n):e.message),(i=e.actions)===null||i===void 0?void 0:i.map((r,o)=>{let l=!1,a=d=>{if(d.preventDefault(),l)return;l=!0;let p=Ti(n.state.field(Ke).diagnostics,e);p&&r.apply(n,p.from,p.to)},{name:h}=r,c=s[o]?h.indexOf(s[o]):-1,f=c<0?h:[h.slice(0,c),U("u",h.slice(c,c+1)),h.slice(c+1)],u=r.markClass?" "+r.markClass:"";return U("button",{type:"button",class:"cm-diagnosticAction"+u,onclick:a,onmousedown:a,"aria-label":` Action: ${h}${c<0?"":` (access key "${s[o]})"`}.`},f)}),e.source&&U("div",{class:"cm-diagnosticSource"},e.source))}class wb extends yt{constructor(e){super(),this.sev=e}eq(e){return e.sev==this.sev}toDOM(){return U("span",{class:"cm-lintPoint cm-lintPoint-"+this.sev})}}class Ph{constructor(e,t){this.diagnostic=t,this.id="item_"+Math.floor(Math.random()*4294967295).toString(16),this.dom=Fu(e,t,!0),this.dom.id=this.id,this.dom.setAttribute("role","option")}}class Ms{constructor(e){this.view=e,this.items=[];let t=s=>{if(!(s.ctrlKey||s.altKey||s.metaKey)){if(s.keyCode==27)vh(this.view),this.view.focus();else if(s.keyCode==38||s.keyCode==33)this.moveSelection((this.selectedIndex-1+this.items.length)%this.items.length);else if(s.keyCode==40||s.keyCode==34)this.moveSelection((this.selectedIndex+1)%this.items.length);else if(s.keyCode==36)this.moveSelection(0);else if(s.keyCode==35)this.moveSelection(this.items.length-1);else if(s.keyCode==13)this.view.focus();else if(s.keyCode>=65&&s.keyCode<=90&&this.selectedIndex>=0){let{diagnostic:r}=this.items[this.selectedIndex],o=Uu(r.actions);for(let l=0;l{for(let r=0;rvh(this.view)},"×")),this.update()}get selectedIndex(){let e=this.view.state.field(Ke).selected;if(!e)return-1;for(let t=0;t{for(let c of h.diagnostics){if(o.has(c))continue;o.add(c);let f=-1,u;for(let d=i;di&&(this.items.splice(i,f-i),s=!0)),t&&u.diagnostic==t.diagnostic?u.dom.hasAttribute("aria-selected")||(u.dom.setAttribute("aria-selected","true"),r=u):u.dom.hasAttribute("aria-selected")&&u.dom.removeAttribute("aria-selected"),i++}});i({sel:r.dom.getBoundingClientRect(),panel:this.list.getBoundingClientRect()}),write:({sel:l,panel:a})=>{let h=a.height/this.list.offsetHeight;l.topa.bottom&&(this.list.scrollTop+=(l.bottom-a.bottom)/h)}})):this.selectedIndex<0&&this.list.removeAttribute("aria-activedescendant"),s&&this.sync()}sync(){let e=this.list.firstChild;function t(){let i=e;e=i.nextSibling,i.remove()}for(let i of this.items)if(i.dom.parentNode==this.list){for(;e!=i.dom;)t();e=i.dom.nextSibling}else this.list.insertBefore(i.dom,e);for(;e;)t()}moveSelection(e){if(this.selectedIndex<0)return;let t=this.view.state.field(Ke),i=Ti(t.diagnostics,this.items[e].diagnostic);i&&this.view.dispatch({selection:{anchor:i.from,head:i.to},scrollIntoView:!0,effects:Nu.of(i)})}static open(e){return new Ms(e)}}function is(n,e='viewBox="0 0 40 40"'){return`url('data:image/svg+xml,${encodeURIComponent(n)}')`}function jn(n){return is(``,'width="6" height="3"')}const kb=T.baseTheme({".cm-diagnostic":{padding:"3px 6px 3px 8px",marginLeft:"-1px",display:"block",whiteSpace:"pre-wrap"},".cm-diagnostic-error":{borderLeft:"5px solid #d11"},".cm-diagnostic-warning":{borderLeft:"5px solid orange"},".cm-diagnostic-info":{borderLeft:"5px solid #999"},".cm-diagnostic-hint":{borderLeft:"5px solid #66d"},".cm-diagnosticAction":{font:"inherit",border:"none",padding:"2px 4px",backgroundColor:"#444",color:"white",borderRadius:"3px",marginLeft:"8px",cursor:"pointer"},".cm-diagnosticSource":{fontSize:"70%",opacity:.7},".cm-lintRange":{backgroundPosition:"left bottom",backgroundRepeat:"repeat-x",paddingBottom:"0.7px"},".cm-lintRange-error":{backgroundImage:jn("#f11")},".cm-lintRange-warning":{backgroundImage:jn("orange")},".cm-lintRange-info":{backgroundImage:jn("#999")},".cm-lintRange-hint":{backgroundImage:jn("#66d")},".cm-lintRange-active":{backgroundColor:"#ffdd9980"},".cm-tooltip-lint":{padding:0,margin:0},".cm-lintPoint":{position:"relative","&:after":{content:'""',position:"absolute",bottom:0,left:"-2px",borderLeft:"3px solid transparent",borderRight:"3px solid transparent",borderBottom:"4px solid #d11"}},".cm-lintPoint-warning":{"&:after":{borderBottomColor:"orange"}},".cm-lintPoint-info":{"&:after":{borderBottomColor:"#999"}},".cm-lintPoint-hint":{"&:after":{borderBottomColor:"#66d"}},".cm-panel.cm-panel-lint":{position:"relative","& ul":{maxHeight:"100px",overflowY:"auto","& [aria-selected]":{backgroundColor:"#ddd","& u":{textDecoration:"underline"}},"&:focus [aria-selected]":{background_fallback:"#bdf",backgroundColor:"Highlight",color_fallback:"white",color:"HighlightText"},"& u":{textDecoration:"none"},padding:0,margin:0},"& [name=close]":{position:"absolute",top:"0",right:"2px",background:"inherit",border:"none",font:"inherit",padding:0,margin:0}},"&dark .cm-lintRange-active":{backgroundColor:"#86714a80"},"&dark .cm-panel.cm-panel-lint ul":{"& [aria-selected]":{backgroundColor:"#2e343e"}}});function Qb(n){return n=="error"?4:n=="warning"?3:n=="info"?2:1}function Hu(n){let e="hint",t=1;for(let i of n){let s=Qb(i.severity);s>t&&(t=s,e=i.severity)}return e}class Ku extends gt{constructor(e){super(),this.diagnostics=e,this.severity=Hu(e)}toDOM(e){let t=document.createElement("div");t.className="cm-lint-marker cm-lint-marker-"+this.severity;let i=this.diagnostics,s=e.state.facet(tr).tooltipFilter;return s&&(i=s(i,e.state)),i.length&&(t.onmouseover=()=>$b(e,t,i)),t}}function vb(n,e){let t=i=>{let s=e.getBoundingClientRect();if(!(i.clientX>s.left-10&&i.clientXs.top-10&&i.clientYe.getBoundingClientRect()}}})}),e.onmouseout=e.onmousemove=null,vb(n,e)}let{hoverTime:s}=n.state.facet(tr),r=setTimeout(i,s);e.onmouseout=()=>{clearTimeout(r),e.onmouseout=e.onmousemove=null},e.onmousemove=()=>{clearTimeout(r),r=setTimeout(i,s)}}function Pb(n,e){let t=Object.create(null);for(let s of e){let r=n.lineAt(s.from);(t[r.from]||(t[r.from]=[])).push(s)}let i=[];for(let s in t)i.push(new Ku(t[s]).range(+s));return B.of(i,!0)}const Tb=hf({class:"cm-gutter-lint",markers:n=>n.state.field(Lo),widgetMarker:(n,e,t)=>{let i=[];return n.state.field(Lo).between(t.from,t.to,(s,r,o)=>{s>t.from&&si.is(wl)?i.value:t,n)},provide:n=>Ys.from(n)}),Cb=T.baseTheme({".cm-gutter-lint":{width:"1.4em","& .cm-gutterElement":{padding:".2em"}},".cm-lint-marker":{width:"1em",height:"1em"},".cm-lint-marker-info":{content:is('')},".cm-lint-marker-warning":{content:is('')},".cm-lint-marker-error":{content:is('')}}),Zb=nf(yb,{hideOn:Iu}),ed=[Ke,T.decorations.compute([Ke],n=>{let{selected:e,panel:t}=n.field(Ke);return!e||!t||e.from==e.to?X.none:X.set([gb.range(e.from,e.to)])}),Zb,kb],tr=C.define({combine(n){return et(n,{hoverTime:300,markerFilter:null,tooltipFilter:null})}});function Ab(n={}){return[tr.of(n),Lo,Tb,Cb,Ju]}const td=1,_e=Object.freeze({ready:"studio.ready",documentOpen:"document.open",documentReplace:"document.replace",documentChanged:"document.changed",documentSave:"document.save",documentSetReadOnly:"document.setReadOnly",editorInsert:"editor.insert",editorFormat:"editor.format",editorSetTheme:"editor.setTheme",editorGetState:"editor.getState",diagnosticsPublish:"diagnostics.publish"});function Mb(n,e={},t=null){return{protocolVersion:td,type:n,documentID:t,payload:e}}function Rb(n){if(window.WKWebViewJavascriptBridge){n(window.WKWebViewJavascriptBridge);return}if(window.WKWVJBCallbacks){window.WKWVJBCallbacks.push(n);return}window.webkit?.messageHandlers?.iOS_Native_InjectJavascript&&(window.WKWVJBCallbacks=[n],window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null))}function ir(n,e,t={},i=null,s=()=>{}){if(!n){s({result:"unavailable"});return}n.callHandler(e,Mb(e,t,i),s)}function Xb(n){const e={capabilities:["jsx","format","search","completion","diagnostics"]};ir(n,_e.ready,e)}const kt={globalProperties:{background:{type:"color",documentation:"Background color, hex value, or named color."},color:{type:"color",documentation:"Foreground color, hex value, or named color."},font:{type:"enum",values:["largeTitle","title","title2","title3","headline","subheadline","body","callout","footnote","caption","caption2"],documentation:"Semantic text style."},fontWeight:{type:"enum",values:["ultraLight","thin","light","regular","medium","semibold","bold","heavy","black"],documentation:"Font weight."},fontDesign:{type:"enum",values:["default","rounded","serif","monospaced"],documentation:"Font design."},frame:{type:"number|string",documentation:"Size or frame description."},padding:{type:"number|string",documentation:"Padding amount or edge description."},corner:{type:"number",documentation:"Corner radius."},opacity:{type:"number",documentation:"Opacity from 0 through 1."},alignment:{type:"enum",values:["center","leading","trailing","top","bottom","topLeading","topTrailing","bottomLeading","bottomTrailing","firstTextBaseline","lastTextBaseline"],documentation:"Layout alignment."},clip:{type:"enum",values:["circle","rect","capsule","ellipse"],documentation:"Clip the view to a shape."},rotation:{type:"number",documentation:"Rotation in degrees."},rotation3d:{type:"string",documentation:"3D rotation description."},shadow:{type:"string",documentation:"Shadow color, radius, and offset description."},animation:{type:"string",documentation:"Timeline-driven animation description."},widgetAccentable:{type:"boolean",documentation:"Group this view into the accent layer in tinted and vibrant widget appearances."},linkurl:{type:"url",documentation:"Widget deep link URL."}},components:{VStack:{documentation:"Arrange children vertically.",children:!0,properties:{spacing:{type:"number"}}},HStack:{documentation:"Arrange children horizontally.",children:!0,properties:{spacing:{type:"number"}}},ZStack:{documentation:"Overlay children.",children:!0,properties:{}},VGrid:{documentation:"Vertical lazy grid.",children:!0,properties:{columns:{type:"string",required:!0},spacing:{type:"number"},alignment:{type:"enum",values:["leading","center","trailing"]}}},HGrid:{documentation:"Horizontal lazy grid.",children:!0,properties:{columns:{type:"string",required:!0},spacing:{type:"number"},alignment:{type:"enum",values:["top","center","bottom","firstTextBaseline","lastTextBaseline"]}}},Text:{documentation:"Display text content.",children:!1,properties:{text:{type:"string"}}},Date:{documentation:"Display a formatted date.",children:!1,properties:{date:{type:"date|number",required:!0},style:{type:"enum",values:["time","date","relative","offset","timer"]}}},Image:{documentation:"Display a bundled, remote, or SF Symbol image.",children:!1,properties:{systemName:{type:"string"},name:{type:"string"},id:{type:"string",deprecated:"Use name."},url:{type:"url"},src:{type:"url",deprecated:"Use url."},ratio:{type:"number"},mode:{type:"enum",values:["fit","fill"]},accentedRenderingMode:{type:"enum",values:["accented","desaturated","accentedDesaturated","fullColor"],documentation:"Control how the image is rendered in tinted and clear widget appearances."}}},Gif:{documentation:"Display a GIF from the package.",children:!1,properties:{file:{type:"string",required:!0}}},Spacer:{documentation:"Flexible layout space.",children:!1,properties:{minLength:{type:"number"}}},Rect:{documentation:"Rectangle shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},RoundedRect:{documentation:"Filled rounded rectangle.",children:!1,properties:{radius:{type:"number"}}},Capsule:{documentation:"Capsule shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Ellipse:{documentation:"Ellipse shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Circle:{documentation:"Circle shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Gauge:{documentation:"Display a gauge or instrument.",children:!1,properties:{type:{type:"string"},value:{type:"number"},style:{type:"enum",values:["circular","linear"]},text:{type:"string"},current:{type:"string"},min:{type:"string"},max:{type:"string"},angle:{type:"number"},thickness:{type:"number"},needleColor:{type:"color"},label:{type:"string"},title:{type:"string"},sections:{type:"string"}}},Chart:{documentation:"Render chart data.",children:!1,availability:{ios:"16.0",macos:"26.0"},properties:{type:{type:"enum",values:["bar","bar-x","bar-y","bar-gantt","line","point","line-point","area","rect","rule-x"]},data:{type:"json",required:!0},category:{type:"boolean"},hideLegend:{type:"boolean"},hideXAxis:{type:"boolean"},hideYAxis:{type:"boolean"}}},Link:{documentation:"Open a URL when selected.",children:!0,properties:{url:{type:"url",required:!0}}},Divider:{documentation:"Horizontal or vertical separator.",children:!1,properties:{thickness:{type:"number"},axis:{type:"enum",values:["horizontal","vertical"]}}},Line:{documentation:"Fixed-length line.",children:!1,properties:{thickness:{type:"number"},length:{type:"number"},axis:{type:"enum",values:["horizontal","vertical"]}}},Icon:{documentation:"SF Symbol icon.",children:!1,properties:{systemName:{type:"string",required:!0},size:{type:"number"}}},Label:{documentation:"Text paired with an SF Symbol.",children:!1,properties:{title:{type:"string"},systemName:{type:"string",required:!0}}},Progress:{documentation:"Linear or circular progress.",children:!1,properties:{value:{type:"number",required:!0},total:{type:"number"},label:{type:"string"},style:{type:"enum",values:["linear","circular"]},trackColor:{type:"color"},thickness:{type:"number"}}},Ring:{documentation:"Circular progress ring.",children:!1,properties:{value:{type:"number",required:!0},thickness:{type:"number"},trackColor:{type:"color"}}},Badge:{documentation:"Compact status badge.",children:!1,properties:{text:{type:"string"},radius:{type:"number"}}},Chip:{documentation:"Outlined metadata chip.",children:!1,properties:{text:{type:"string"},radius:{type:"number"},borderColor:{type:"color"}}},Stat:{documentation:"Title, value, and subtitle statistic.",children:!1,properties:{title:{type:"string"},value:{type:"string",required:!0},subtitle:{type:"string"},mutedColor:{type:"color"}}},Button:{documentation:"Interactive widget button. Use actionID to share a declared Package 2.0 action with Siri, Shortcuts, and Control Widgets.",children:!0,availability:{interactiveIos:"17.0"},requiredAny:["action","onClick","actionID"],properties:{action:{type:"enum",values:["reload"],conflicts:["actionID"]},onClick:{type:"function",conflicts:["actionID"]},actionID:{type:"action-id",conflicts:["action","onClick"]}}},Toggle:{documentation:"Interactive widget toggle. A declared actionID requires a package-relative storage stateKey.",children:!0,availability:{interactiveIos:"17.0"},requiredAny:["onClick","actionID"],properties:{on:{type:"boolean",required:!0},onClick:{type:"function",conflicts:["actionID"]},actionID:{type:"action-id",requires:["stateKey"],conflicts:["onClick"]},stateKey:{type:"storage-key",requires:["actionID"]}}}}};function Lb(n,e){const t=Object.entries(e.properties??{}).filter(([,s])=>s.required).map(([s,r])=>`${s}=${r.type.includes("number")||r.type==="boolean"?"{${}}":'"${}"'}`).join(" "),i=t?` ${t}`:"";return e.children?`<${n}${i}> +`:i=="r"?"\r":i=="t"?" ":"\\")}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord&&this.test==e.test}create(){return this.regexp?new rb(this):new ib(this)}getCursor(e,t=0,i){let s=e.doc?e:I.create({doc:e});return i==null&&(i=s.doc.length),this.regexp?ai(this,s,t,i):li(this,s,t,i)}}class zu{constructor(e){this.spec=e}}function eb(n,e,t){return(i,s,r,o)=>{if(t&&!t(i,s,r,o))return!1;let l=i>=o&&s<=o+r.length?r.slice(i-o,s-o):e.doc.sliceString(i,s);return n(l,e,i,s)}}function li(n,e,t,i){let s;return n.wholeWord&&(s=tb(e.doc,e.charCategorizer(e.selection.main.head))),n.test&&(s=eb(n.test,e,s)),new Pi(e.doc,n.unquoted,t,i,n.caseSensitive?void 0:r=>r.toLowerCase(),s)}function tb(n,e){return(t,i,s,r)=>((r>t||r+s.length=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=li(this.spec,e,Math.max(0,t-this.spec.unquoted.length),Math.min(i+this.spec.unquoted.length,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}function nb(n,e,t){return(i,s,r)=>(!t||t(i,s,r))&&n(r[0],e,i,s)}function ai(n,e,t,i){let s;return n.wholeWord&&(s=sb(e.charCategorizer(e.selection.main.head))),n.test&&(s=nb(n.test,e,s)),new Du(e.doc,n.search,{ignoreCase:!n.caseSensitive,test:s},t,i)}function Ts(n,e){return n.slice(de(n,e,!1),e)}function Cs(n,e){return n.slice(e,de(n,e))}function sb(n){return(e,t,i)=>!i[0].length||(n(Ts(i.input,i.index))!=ee.Word||n(Cs(i.input,i.index))!=ee.Word)&&(n(Cs(i.input,i.index+i[0].length))!=ee.Word||n(Ts(i.input,i.index+i[0].length))!=ee.Word)}class rb extends zu{nextMatch(e,t,i){let s=ai(this.spec,e,i,e.doc.length).next();return s.done&&(s=ai(this.spec,e,0,t).next()),s.done?null:s.value}prevMatchInRange(e,t,i){for(let s=1;;s++){let r=Math.max(t,i-s*1e4),o=ai(this.spec,e,r,i),l=null;for(;!o.next().done;)l=o.value;if(l&&(r==t||l.from>r+10))return l;if(r==t)return null}}prevMatch(e,t,i){return this.prevMatchInRange(e,0,t)||this.prevMatchInRange(e,i,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g,(t,i)=>{if(i=="&")return e.match[0];if(i=="$")return"$";for(let s=i.length;s>0;s--){let r=+i.slice(0,s);if(r>0&&r=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=ai(this.spec,e,Math.max(0,t-250),Math.min(i+250,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}const un=z.define(),bl=z.define(),Rt=fe.define({create(n){return new Er(Xo(n).create(),null)},update(n,e){for(let t of e.effects)t.is(un)?n=new Er(t.value.create(),n.panel):t.is(bl)&&(n=new Er(n.query,t.value?Sl:null));return n},provide:n=>rn.from(n,e=>e.panel)});class Er{constructor(e,t){this.query=e,this.panel=t}}const ob=X.mark({class:"cm-searchMatch"}),lb=X.mark({class:"cm-searchMatch cm-searchMatch-selected"}),ab=ne.fromClass(class{constructor(n){this.view=n,this.decorations=this.highlight(n.state.field(Rt))}update(n){let e=n.state.field(Rt);(e!=n.startState.field(Rt)||n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=this.highlight(e))}highlight({query:n,panel:e}){if(!e||!n.spec.valid)return X.none;let{view:t}=this,i=new Qt;for(let s=0,r=t.visibleRanges,o=r.length;sr[s+1].from-500;)a=r[++s].to;n.highlight(t.state,l,a,(h,c)=>{let f=t.state.selection.ranges.some(u=>u.from==h&&u.to==c);i.add(h,c,f?lb:ob)})}return i.finish()}},{decorations:n=>n.decorations});function Sn(n){return e=>{let t=e.state.field(Rt,!1);return t&&t.query.spec.valid?n(e,t):_u(e)}}const Zs=Sn((n,{query:e})=>{let{to:t}=n.state.selection.main,i=e.nextMatch(n.state,t,t);if(!i)return!1;let s=b.single(i.from,i.to),r=n.state.facet(Ri);return n.dispatch({selection:s,effects:[xl(n,i),r.scrollToMatch(s.main,n)],userEvent:"select.search"}),Bu(n),!0}),As=Sn((n,{query:e})=>{let{state:t}=n,{from:i}=t.selection.main,s=e.prevMatch(t,i,i);if(!s)return!1;let r=b.single(s.from,s.to),o=n.state.facet(Ri);return n.dispatch({selection:r,effects:[xl(n,s),o.scrollToMatch(r.main,n)],userEvent:"select.search"}),Bu(n),!0}),hb=Sn((n,{query:e})=>{let t=e.matchAll(n.state,1e3);return!t||!t.length?!1:(n.dispatch({selection:b.create(t.map(i=>b.range(i.from,i.to))),userEvent:"select.search.matches"}),!0)}),cb=({state:n,dispatch:e})=>{let t=n.selection;if(t.ranges.length>1||t.main.empty)return!1;let{from:i,to:s}=t.main,r=[],o=0;for(let l=new Pi(n.doc,n.sliceDoc(i,s));!l.next().done;){if(r.length>1e3)return!1;l.value.from==i&&(o=r.length),r.push(b.range(l.value.from,l.value.to))}return e(n.update({selection:b.create(r,o),userEvent:"select.search.matches"})),!0},kh=Sn((n,{query:e})=>{let{state:t}=n,{from:i,to:s}=t.selection.main;if(t.readOnly)return!1;let r=e.nextMatch(t,i,i);if(!r)return!1;let o=r,l=[],a,h,c=[];o.precise?o.from==i&&o.to==s&&(h=t.toText(e.getReplacement(o)),l.push({from:o.from,to:o.to,insert:h}),o=e.nextMatch(t,o.from,o.to),c.push(T.announce.of(t.phrase("replaced match on line $",t.doc.lineAt(i).number)+"."))):o=e.nextMatch(t,o.from,o.to);let f=n.state.changes(l);return o&&(a=b.single(o.from,o.to).map(f),c.push(xl(n,o)),c.push(t.facet(Ri).scrollToMatch(a.main,n))),n.dispatch({changes:f,selection:a,effects:c,userEvent:"input.replace"}),!0}),fb=Sn((n,{query:e})=>{if(n.state.readOnly)return!1;let t=[];for(let s of e.matchAll(n.state,1e9)){let{from:r,to:o,precise:l}=s;l&&t.push({from:r,to:o,insert:e.getReplacement(s)})}if(!t.length)return!1;let i=n.state.phrase("replaced $ matches",t.length)+".";return n.dispatch({changes:t,effects:T.announce.of(i),userEvent:"input.replace.all"}),!0});function Sl(n){return n.state.facet(Ri).createPanel(n)}function Xo(n,e){var t,i,s,r,o;let l=n.selection.main,a=l.empty||l.to>l.from+100?"":n.sliceDoc(l.from,l.to);if(e&&!a)return e;let h=n.facet(Ri);return new Wu({search:((t=e?.literal)!==null&&t!==void 0?t:h.literal)?a:a.replace(/\n/g,"\\n"),caseSensitive:(i=e?.caseSensitive)!==null&&i!==void 0?i:h.caseSensitive,literal:(s=e?.literal)!==null&&s!==void 0?s:h.literal,regexp:(r=e?.regexp)!==null&&r!==void 0?r:h.regexp,wholeWord:(o=e?.wholeWord)!==null&&o!==void 0?o:h.wholeWord})}function qu(n){let e=rf(n,Sl);return e&&e.dom.querySelector("[main-field]")}function Bu(n){let e=qu(n);e&&e==n.root.activeElement&&e.select()}const _u=n=>{let e=n.state.field(Rt,!1);if(e&&e.panel){let t=qu(n);if(t&&t!=n.root.activeElement){let i=Xo(n.state,e.query.spec);i.valid&&n.dispatch({effects:un.of(i)}),t.focus(),t.select()}}else n.dispatch({effects:[bl.of(!0),e?un.of(Xo(n.state,e.query.spec)):z.appendConfig.of(Ob)]});return!0},Yu=n=>{let e=n.state.field(Rt,!1);if(!e||!e.panel)return!1;let t=rf(n,Sl);return t&&t.dom.contains(n.root.activeElement)&&n.focus(),n.dispatch({effects:bl.of(!1)}),!0},ub=[{key:"Mod-f",run:_u,scope:"editor search-panel"},{key:"F3",run:Zs,shift:As,scope:"editor search-panel",preventDefault:!0},{key:"Mod-g",run:Zs,shift:As,scope:"editor search-panel",preventDefault:!0},{key:"Escape",run:Yu,scope:"editor search-panel"},{key:"Mod-Shift-l",run:cb},{key:"Mod-Alt-g",run:_1},{key:"Mod-d",run:J1,preventDefault:!0}];class db{constructor(e){this.view=e;let t=this.query=e.state.field(Rt).query.spec;this.commit=this.commit.bind(this),this.searchField=U("input",{value:t.search,placeholder:We(e,"Find"),"aria-label":We(e,"Find"),class:"cm-textfield",name:"search",form:"","main-field":"true",onchange:this.commit,onkeyup:this.commit}),this.replaceField=U("input",{value:t.replace,placeholder:We(e,"Replace"),"aria-label":We(e,"Replace"),class:"cm-textfield",name:"replace",form:"",onchange:this.commit,onkeyup:this.commit}),this.caseField=U("input",{type:"checkbox",name:"case",form:"",checked:t.caseSensitive,onchange:this.commit}),this.reField=U("input",{type:"checkbox",name:"re",form:"",checked:t.regexp,onchange:this.commit}),this.wordField=U("input",{type:"checkbox",name:"word",form:"",checked:t.wholeWord,onchange:this.commit});function i(s,r,o){return U("button",{class:"cm-button",name:s,onclick:r,type:"button"},o)}this.dom=U("div",{onkeydown:s=>this.keydown(s),class:"cm-search"},[this.searchField,i("next",()=>Zs(e),[We(e,"next")]),i("prev",()=>As(e),[We(e,"previous")]),i("select",()=>hb(e),[We(e,"all")]),U("label",null,[this.caseField,We(e,"match case")]),U("label",null,[this.reField,We(e,"regexp")]),U("label",null,[this.wordField,We(e,"by word")]),...e.state.readOnly?[]:[U("br"),this.replaceField,i("replace",()=>kh(e),[We(e,"replace")]),i("replaceAll",()=>fb(e),[We(e,"replace all")])],U("button",{name:"close",onclick:()=>Yu(e),"aria-label":We(e,"close"),type:"button"},["×"])])}commit(){let e=new Wu({search:this.searchField.value,caseSensitive:this.caseField.checked,regexp:this.reField.checked,wholeWord:this.wordField.checked,replace:this.replaceField.value});e.eq(this.query)||(this.query=e,this.view.dispatch({effects:un.of(e)}))}keydown(e){wO(this.view,e,"search-panel")?e.preventDefault():e.keyCode==13&&e.target==this.searchField?(e.preventDefault(),(e.shiftKey?As:Zs)(this.view)):e.keyCode==13&&e.target==this.replaceField&&(e.preventDefault(),kh(this.view))}update(e){for(let t of e.transactions)for(let i of t.effects)i.is(un)&&!i.value.eq(this.query)&&this.setQuery(i.value)}setQuery(e){this.query=e,this.searchField.value=e.search,this.replaceField.value=e.replace,this.caseField.checked=e.caseSensitive,this.reField.checked=e.regexp,this.wordField.checked=e.wholeWord}mount(){this.searchField.select()}get pos(){return 80}get top(){return this.view.state.facet(Ri).top}}function We(n,e){return n.state.phrase(e)}const In=30,Vn=/[\s\.,:;?!]/;function xl(n,{from:e,to:t}){let i=n.state.doc.lineAt(e),s=n.state.doc.lineAt(t).to,r=Math.max(i.from,e-In),o=Math.min(s,t+In),l=n.state.sliceDoc(r,o);if(r!=i.from){for(let a=0;al.length-In;a--)if(!Vn.test(l[a-1])&&Vn.test(l[a])){l=l.slice(0,a);break}}return T.announce.of(`${n.state.phrase("current match")}. ${l} ${n.state.phrase("on line")} ${i.number}.`)}const pb=T.baseTheme({".cm-panel.cm-search":{padding:"2px 6px 4px",position:"relative","& [name=close]":{position:"absolute",top:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:0,margin:0},"& input, & button, & label":{margin:".2em .6em .2em 0"},"& input[type=checkbox]":{marginRight:".2em"},"& label":{fontSize:"80%",whiteSpace:"pre"}},"&light .cm-searchMatch":{backgroundColor:"#ffff0054"},"&dark .cm-searchMatch":{backgroundColor:"#00ffff8a"},"&light .cm-searchMatch-selected":{backgroundColor:"#ff6a0054"},"&dark .cm-searchMatch-selected":{backgroundColor:"#ff00ff8a"}}),Ob=[Rt,Bt.low(ab),pb];class Qh{constructor(e,t,i){this.from=e,this.to=t,this.diagnostic=i}}class jt{constructor(e,t,i){this.diagnostics=e,this.panel=t,this.selected=i}static init(e,t,i){let s=i.facet(Ot).markerFilter;s&&(e=s(e,i));let r=e.slice().sort((d,p)=>d.from-p.from||d.to-p.to),o=new Qt,l=[],a=0,h=i.doc.iter(),c=0,f=i.doc.length;for(let d=0;;){let p=d==r.length?null:r[d];if(!p&&!l.length)break;let O,m;if(l.length)O=a,m=l.reduce((x,Z)=>Math.min(x,Z.to),p&&p.from>O?p.from:1e8);else{if(O=p.from,O>f)break;m=p.to,l.push(p),d++}for(;dx.from||x.to==O))l.push(x),d++,m=Math.min(x.to,m);else{m=Math.min(x.from,m);break}}m=Math.min(m,f);let y=!1;if(l.some(x=>x.from==O&&(x.to==m||m==f))&&(y=O==m,!y&&m-O<10)){let x=O-(c+h.value.length);x>0&&(h.next(x),c=O);for(let Z=O;;){if(Z>=m){y=!0;break}if(!h.lineBreak&&c+h.value.length>Z)break;Z=c+h.value.length,c+=h.value.length,h.next()}}let w=Hu(l);if(y)o.add(O,O,X.widget({widget:new wb(w),diagnostics:l.slice()}));else{let x=l.reduce((Z,k)=>k.markClass?Z+" "+k.markClass:Z,"");o.add(O,m,X.mark({class:"cm-lintRange cm-lintRange-"+w+x,diagnostics:l.slice(),inclusiveEnd:l.some(Z=>Z.to>m)}))}if(a=m,a==f)break;for(let x=0;x{if(!(e&&o.diagnostics.indexOf(e)<0))if(!i)i=new Qh(s,r,e||o.diagnostics[0]);else{if(o.diagnostics.indexOf(i.diagnostic)<0)return!1;i=new Qh(i.from,r,i.diagnostic)}}),i}function Iu(n,e){let t=e.pos,i=e.end||t,s=n.state.facet(Ot).hideOn(n,t,i);if(s!=null)return s;let r=n.startState.doc.lineAt(e.pos);return!!(n.effects.some(o=>o.is(er))||n.changes.touchesRange(r.from,Math.max(r.to,i)))}function mb(n,e){return n.field(Ke,!1)?e:e.concat(z.appendConfig.of(ed))}function Vu(n,e){return{effects:mb(n,[er.of(e)])}}const er=z.define(),ju=z.define(),Nu=z.define(),Ke=fe.define({create(){return new jt(X.none,null,null)},update(n,e){if(e.docChanged&&n.diagnostics.size){let t=n.diagnostics.map(e.changes),i=null,s=n.panel;if(n.selected){let r=e.changes.mapPos(n.selected.from,1);i=Ti(t,n.selected.diagnostic,r)||Ti(t,null,r)}!t.size&&s&&e.state.facet(Ot).autoPanel&&(s=null),n=new jt(t,s,i)}for(let t of e.effects)if(t.is(er)){let i=e.state.facet(Ot).autoPanel?t.value.length?Ms.open:null:n.panel;n=jt.init(t.value,i,e.state)}else t.is(ju)?n=new jt(n.diagnostics,t.value?Ms.open:null,n.selected):t.is(Nu)&&(n=new jt(n.diagnostics,n.panel,t.value));return n},provide:n=>[rn.from(n,e=>e.panel),T.decorations.from(n,e=>e.diagnostics)]}),gb=X.mark({class:"cm-lintRange cm-lintRange-active"});function yb(n,e,t){let{diagnostics:i}=n.state.field(Ke),s,r=-1,o=-1;i.between(e-(t<0?1:0),e+(t>0?1:0),(a,h,{spec:c})=>{if(e>=a&&e<=h&&(a==h||(e>a||t>0)&&(eFu(n,t,!1)))}const vh=n=>{let e=n.state.field(Ke,!1);return!e||!e.panel?!1:(n.dispatch({effects:ju.of(!1)}),!0)},bb=ne.fromClass(class{constructor(n){this.view=n,this.timeout=-1,this.set=!0;let{delay:e}=n.state.facet(Ot);this.lintTime=Date.now()+e,this.run=this.run.bind(this),this.timeout=setTimeout(this.run,e)}run(){clearTimeout(this.timeout);let n=Date.now();if(nPromise.resolve(i(this.view))),i=>{this.view.state.doc==e.doc&&this.view.dispatch(Vu(this.view.state,i.reduce((s,r)=>s.concat(r))))},i=>{ve(this.view.state,i)})}}update(n){let e=n.state.facet(Ot);(n.docChanged||e!=n.startState.facet(Ot)||e.needsRefresh&&e.needsRefresh(n))&&(this.lintTime=Date.now()+e.delay,this.set||(this.set=!0,this.timeout=setTimeout(this.run,e.delay)))}force(){this.set&&(this.lintTime=Date.now(),this.run())}destroy(){clearTimeout(this.timeout)}});function Sb(n,e,t){let i=[],s=-1;for(let r of n)r.then(o=>{i.push(o),clearTimeout(s),i.length==n.length?e(i):s=setTimeout(()=>e(i),200)},t)}const Ot=C.define({combine(n){return{sources:n.map(e=>e.source).filter(e=>e!=null),...et(n.map(e=>e.config),{delay:750,markerFilter:null,tooltipFilter:null,needsRefresh:null,hideOn:()=>null},{delay:Math.max,markerFilter:$h,tooltipFilter:$h,needsRefresh:(e,t)=>e?t?i=>e(i)||t(i):e:t,hideOn:(e,t)=>e?t?(i,s,r)=>e(i,s,r)||t(i,s,r):e:t,autoPanel:(e,t)=>e||t})}}});function $h(n,e){return n?e?(t,i)=>e(n(t,i),i):n:e}function xb(n,e={}){return[Ot.of({source:n,config:e}),bb,ed]}function Uu(n){let e=[];if(n)e:for(let{name:t}of n){for(let i=0;ir.toLowerCase()==s.toLowerCase())){e.push(s);continue e}}e.push("")}return e}function Fu(n,e,t){var i;let s=t?Uu(e.actions):[];return U("li",{class:"cm-diagnostic cm-diagnostic-"+e.severity},U("span",{class:"cm-diagnosticText"},e.renderMessage?e.renderMessage(n):e.message),(i=e.actions)===null||i===void 0?void 0:i.map((r,o)=>{let l=!1,a=d=>{if(d.preventDefault(),l)return;l=!0;let p=Ti(n.state.field(Ke).diagnostics,e);p&&r.apply(n,p.from,p.to)},{name:h}=r,c=s[o]?h.indexOf(s[o]):-1,f=c<0?h:[h.slice(0,c),U("u",h.slice(c,c+1)),h.slice(c+1)],u=r.markClass?" "+r.markClass:"";return U("button",{type:"button",class:"cm-diagnosticAction"+u,onclick:a,onmousedown:a,"aria-label":` Action: ${h}${c<0?"":` (access key "${s[o]})"`}.`},f)}),e.source&&U("div",{class:"cm-diagnosticSource"},e.source))}class wb extends yt{constructor(e){super(),this.sev=e}eq(e){return e.sev==this.sev}toDOM(){return U("span",{class:"cm-lintPoint cm-lintPoint-"+this.sev})}}class Ph{constructor(e,t){this.diagnostic=t,this.id="item_"+Math.floor(Math.random()*4294967295).toString(16),this.dom=Fu(e,t,!0),this.dom.id=this.id,this.dom.setAttribute("role","option")}}class Ms{constructor(e){this.view=e,this.items=[];let t=s=>{if(!(s.ctrlKey||s.altKey||s.metaKey)){if(s.keyCode==27)vh(this.view),this.view.focus();else if(s.keyCode==38||s.keyCode==33)this.moveSelection((this.selectedIndex-1+this.items.length)%this.items.length);else if(s.keyCode==40||s.keyCode==34)this.moveSelection((this.selectedIndex+1)%this.items.length);else if(s.keyCode==36)this.moveSelection(0);else if(s.keyCode==35)this.moveSelection(this.items.length-1);else if(s.keyCode==13)this.view.focus();else if(s.keyCode>=65&&s.keyCode<=90&&this.selectedIndex>=0){let{diagnostic:r}=this.items[this.selectedIndex],o=Uu(r.actions);for(let l=0;l{for(let r=0;rvh(this.view)},"×")),this.update()}get selectedIndex(){let e=this.view.state.field(Ke).selected;if(!e)return-1;for(let t=0;t{for(let c of h.diagnostics){if(o.has(c))continue;o.add(c);let f=-1,u;for(let d=i;di&&(this.items.splice(i,f-i),s=!0)),t&&u.diagnostic==t.diagnostic?u.dom.hasAttribute("aria-selected")||(u.dom.setAttribute("aria-selected","true"),r=u):u.dom.hasAttribute("aria-selected")&&u.dom.removeAttribute("aria-selected"),i++}});i({sel:r.dom.getBoundingClientRect(),panel:this.list.getBoundingClientRect()}),write:({sel:l,panel:a})=>{let h=a.height/this.list.offsetHeight;l.topa.bottom&&(this.list.scrollTop+=(l.bottom-a.bottom)/h)}})):this.selectedIndex<0&&this.list.removeAttribute("aria-activedescendant"),s&&this.sync()}sync(){let e=this.list.firstChild;function t(){let i=e;e=i.nextSibling,i.remove()}for(let i of this.items)if(i.dom.parentNode==this.list){for(;e!=i.dom;)t();e=i.dom.nextSibling}else this.list.insertBefore(i.dom,e);for(;e;)t()}moveSelection(e){if(this.selectedIndex<0)return;let t=this.view.state.field(Ke),i=Ti(t.diagnostics,this.items[e].diagnostic);i&&this.view.dispatch({selection:{anchor:i.from,head:i.to},scrollIntoView:!0,effects:Nu.of(i)})}static open(e){return new Ms(e)}}function is(n,e='viewBox="0 0 40 40"'){return`url('data:image/svg+xml,${encodeURIComponent(n)}')`}function jn(n){return is(``,'width="6" height="3"')}const kb=T.baseTheme({".cm-diagnostic":{padding:"3px 6px 3px 8px",marginLeft:"-1px",display:"block",whiteSpace:"pre-wrap"},".cm-diagnostic-error":{borderLeft:"5px solid #d11"},".cm-diagnostic-warning":{borderLeft:"5px solid orange"},".cm-diagnostic-info":{borderLeft:"5px solid #999"},".cm-diagnostic-hint":{borderLeft:"5px solid #66d"},".cm-diagnosticAction":{font:"inherit",border:"none",padding:"2px 4px",backgroundColor:"#444",color:"white",borderRadius:"3px",marginLeft:"8px",cursor:"pointer"},".cm-diagnosticSource":{fontSize:"70%",opacity:.7},".cm-lintRange":{backgroundPosition:"left bottom",backgroundRepeat:"repeat-x",paddingBottom:"0.7px"},".cm-lintRange-error":{backgroundImage:jn("#f11")},".cm-lintRange-warning":{backgroundImage:jn("orange")},".cm-lintRange-info":{backgroundImage:jn("#999")},".cm-lintRange-hint":{backgroundImage:jn("#66d")},".cm-lintRange-active":{backgroundColor:"#ffdd9980"},".cm-tooltip-lint":{padding:0,margin:0},".cm-lintPoint":{position:"relative","&:after":{content:'""',position:"absolute",bottom:0,left:"-2px",borderLeft:"3px solid transparent",borderRight:"3px solid transparent",borderBottom:"4px solid #d11"}},".cm-lintPoint-warning":{"&:after":{borderBottomColor:"orange"}},".cm-lintPoint-info":{"&:after":{borderBottomColor:"#999"}},".cm-lintPoint-hint":{"&:after":{borderBottomColor:"#66d"}},".cm-panel.cm-panel-lint":{position:"relative","& ul":{maxHeight:"100px",overflowY:"auto","& [aria-selected]":{backgroundColor:"#ddd","& u":{textDecoration:"underline"}},"&:focus [aria-selected]":{background_fallback:"#bdf",backgroundColor:"Highlight",color_fallback:"white",color:"HighlightText"},"& u":{textDecoration:"none"},padding:0,margin:0},"& [name=close]":{position:"absolute",top:"0",right:"2px",background:"inherit",border:"none",font:"inherit",padding:0,margin:0}},"&dark .cm-lintRange-active":{backgroundColor:"#86714a80"},"&dark .cm-panel.cm-panel-lint ul":{"& [aria-selected]":{backgroundColor:"#2e343e"}}});function Qb(n){return n=="error"?4:n=="warning"?3:n=="info"?2:1}function Hu(n){let e="hint",t=1;for(let i of n){let s=Qb(i.severity);s>t&&(t=s,e=i.severity)}return e}class Ku extends gt{constructor(e){super(),this.diagnostics=e,this.severity=Hu(e)}toDOM(e){let t=document.createElement("div");t.className="cm-lint-marker cm-lint-marker-"+this.severity;let i=this.diagnostics,s=e.state.facet(tr).tooltipFilter;return s&&(i=s(i,e.state)),i.length&&(t.onmouseover=()=>$b(e,t,i)),t}}function vb(n,e){let t=i=>{let s=e.getBoundingClientRect();if(!(i.clientX>s.left-10&&i.clientXs.top-10&&i.clientYe.getBoundingClientRect()}}})}),e.onmouseout=e.onmousemove=null,vb(n,e)}let{hoverTime:s}=n.state.facet(tr),r=setTimeout(i,s);e.onmouseout=()=>{clearTimeout(r),e.onmouseout=e.onmousemove=null},e.onmousemove=()=>{clearTimeout(r),r=setTimeout(i,s)}}function Pb(n,e){let t=Object.create(null);for(let s of e){let r=n.lineAt(s.from);(t[r.from]||(t[r.from]=[])).push(s)}let i=[];for(let s in t)i.push(new Ku(t[s]).range(+s));return B.of(i,!0)}const Tb=hf({class:"cm-gutter-lint",markers:n=>n.state.field(Lo),widgetMarker:(n,e,t)=>{let i=[];return n.state.field(Lo).between(t.from,t.to,(s,r,o)=>{s>t.from&&si.is(wl)?i.value:t,n)},provide:n=>Ys.from(n)}),Cb=T.baseTheme({".cm-gutter-lint":{width:"1.4em","& .cm-gutterElement":{padding:".2em"}},".cm-lint-marker":{width:"1em",height:"1em"},".cm-lint-marker-info":{content:is('')},".cm-lint-marker-warning":{content:is('')},".cm-lint-marker-error":{content:is('')}}),Zb=nf(yb,{hideOn:Iu}),ed=[Ke,T.decorations.compute([Ke],n=>{let{selected:e,panel:t}=n.field(Ke);return!e||!t||e.from==e.to?X.none:X.set([gb.range(e.from,e.to)])}),Zb,kb],tr=C.define({combine(n){return et(n,{hoverTime:300,markerFilter:null,tooltipFilter:null})}});function Ab(n={}){return[tr.of(n),Lo,Tb,Cb,Ju]}const td=1,_e=Object.freeze({ready:"studio.ready",documentOpen:"document.open",documentReplace:"document.replace",documentChanged:"document.changed",documentSave:"document.save",documentSetReadOnly:"document.setReadOnly",editorInsert:"editor.insert",editorFormat:"editor.format",editorSetTheme:"editor.setTheme",editorGetState:"editor.getState",diagnosticsPublish:"diagnostics.publish"});function Mb(n,e={},t=null){return{protocolVersion:td,type:n,documentID:t,payload:e}}function Rb(n){if(window.WKWebViewJavascriptBridge){n(window.WKWebViewJavascriptBridge);return}if(window.WKWVJBCallbacks){window.WKWVJBCallbacks.push(n);return}window.webkit?.messageHandlers?.iOS_Native_InjectJavascript&&(window.WKWVJBCallbacks=[n],window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null))}function ir(n,e,t={},i=null,s=()=>{}){if(!n){s({result:"unavailable"});return}n.callHandler(e,Mb(e,t,i),s)}function Xb(n){const e={capabilities:["jsx","format","search","completion","diagnostics"]};ir(n,_e.ready,e)}const kt={globalProperties:{background:{type:"color",documentation:"Background color, hex value, or named color."},color:{type:"color",documentation:"Foreground color, hex value, or named color."},font:{type:"enum",values:["largeTitle","title","title2","title3","headline","subheadline","body","callout","footnote","caption","caption2"],documentation:"Semantic text style."},fontWeight:{type:"enum",values:["ultraLight","thin","light","regular","medium","semibold","bold","heavy","black"],documentation:"Font weight."},fontDesign:{type:"enum",values:["default","rounded","serif","monospaced"],documentation:"Font design."},frame:{type:"number|string",documentation:'Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48").'},padding:{type:"number|string",documentation:"Padding amount or edge description."},corner:{type:"number",documentation:"Corner radius."},opacity:{type:"number",documentation:"Opacity from 0 through 1."},alignment:{type:"enum",values:["center","leading","trailing","top","bottom","topLeading","topTrailing","bottomLeading","bottomTrailing","firstTextBaseline","lastTextBaseline"],documentation:"Layout alignment."},clip:{type:"enum",values:["circle","rect","capsule","ellipse"],documentation:"Clip the view to a shape."},rotation:{type:"number",documentation:"Rotation in degrees."},rotation3d:{type:"string",documentation:"3D rotation description."},shadow:{type:"string",documentation:"Shadow color, radius, and offset description."},animation:{type:"string",documentation:"Timeline-driven animation description."},widgetAccentable:{type:"boolean",documentation:"Group this view into the accent layer in tinted and vibrant widget appearances."},linkurl:{type:"url",documentation:"Widget deep link URL."}},components:{VStack:{documentation:"Arrange children vertically.",children:!0,properties:{spacing:{type:"number"}}},HStack:{documentation:"Arrange children horizontally.",children:!0,properties:{spacing:{type:"number"}}},ZStack:{documentation:"Overlay children.",children:!0,properties:{}},VGrid:{documentation:"Vertical lazy grid.",children:!0,properties:{columns:{type:"string",required:!0},spacing:{type:"number"},alignment:{type:"enum",values:["leading","center","trailing"]}}},HGrid:{documentation:"Horizontal lazy grid.",children:!0,properties:{columns:{type:"string",required:!0},spacing:{type:"number"},alignment:{type:"enum",values:["top","center","bottom","firstTextBaseline","lastTextBaseline"]}}},Text:{documentation:"Display text content.",children:!1,properties:{text:{type:"string"}}},Date:{documentation:"Display a formatted date.",children:!1,properties:{date:{type:"date|number",required:!0},style:{type:"enum",values:["time","date","relative","offset","timer"]}}},Image:{documentation:"Display a bundled, remote, or SF Symbol image.",children:!1,properties:{systemName:{type:"string"},name:{type:"string"},id:{type:"string",deprecated:"Use name."},url:{type:"url"},src:{type:"url",deprecated:"Use url."},ratio:{type:"number"},mode:{type:"enum",values:["fit","fill"]},accentedRenderingMode:{type:"enum",values:["accented","desaturated","accentedDesaturated","fullColor"],documentation:"Control how the image is rendered in tinted and clear widget appearances."}}},Gif:{documentation:"Display a GIF from the package.",children:!1,properties:{file:{type:"string",required:!0}}},Spacer:{documentation:"Flexible layout space.",children:!1,properties:{minLength:{type:"number"}}},Rect:{documentation:"Rectangle shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},RoundedRect:{documentation:"Filled rounded rectangle.",children:!1,properties:{radius:{type:"number"}}},Capsule:{documentation:"Capsule shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Ellipse:{documentation:"Ellipse shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Circle:{documentation:"Circle shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Gauge:{documentation:"Display a gauge or instrument.",children:!1,properties:{type:{type:"string"},value:{type:"number"},style:{type:"enum",values:["circular","linear"]},text:{type:"string"},current:{type:"string"},min:{type:"string"},max:{type:"string"},angle:{type:"number"},thickness:{type:"number"},needleColor:{type:"color"},label:{type:"string"},title:{type:"string"},sections:{type:"string"}}},Chart:{documentation:"Render chart data.",children:!1,availability:{ios:"16.0",macos:"26.0"},properties:{type:{type:"enum",values:["bar","bar-x","bar-y","bar-gantt","line","point","line-point","area","rect","rule-x"]},data:{type:"json",required:!0},category:{type:"boolean"},hideLegend:{type:"boolean"},hideXAxis:{type:"boolean"},hideYAxis:{type:"boolean"}}},Link:{documentation:"Open a URL when selected.",children:!0,properties:{url:{type:"url",required:!0}}},Divider:{documentation:"Horizontal or vertical separator.",children:!1,properties:{thickness:{type:"number"},axis:{type:"enum",values:["horizontal","vertical"]}}},Line:{documentation:"Fixed-length line.",children:!1,properties:{thickness:{type:"number"},length:{type:"number"},axis:{type:"enum",values:["horizontal","vertical"]}}},Icon:{documentation:"SF Symbol icon.",children:!1,properties:{systemName:{type:"string",required:!0},size:{type:"number"}}},Label:{documentation:"Text paired with an SF Symbol.",children:!1,properties:{title:{type:"string"},systemName:{type:"string",required:!0}}},Progress:{documentation:"Linear or circular progress.",children:!1,properties:{value:{type:"number",required:!0},total:{type:"number"},label:{type:"string"},style:{type:"enum",values:["linear","circular"]},trackColor:{type:"color"},thickness:{type:"number"}}},Ring:{documentation:"Circular progress ring.",children:!1,properties:{value:{type:"number",required:!0},thickness:{type:"number"},trackColor:{type:"color"}}},Badge:{documentation:"Compact status badge.",children:!1,properties:{text:{type:"string"},radius:{type:"number"}}},Chip:{documentation:"Outlined metadata chip.",children:!1,properties:{text:{type:"string"},radius:{type:"number"},borderColor:{type:"color"}}},Stat:{documentation:"Title, value, and subtitle statistic.",children:!1,properties:{title:{type:"string"},value:{type:"string",required:!0},subtitle:{type:"string"},mutedColor:{type:"color"}}},Button:{documentation:"Interactive widget button. Use actionID to share a declared Package 2.0 action with Siri, Shortcuts, and Control Widgets.",children:!0,availability:{interactiveIos:"17.0"},requiredAny:["action","onClick","actionID"],properties:{action:{type:"enum",values:["reload"],conflicts:["actionID"]},onClick:{type:"function",conflicts:["actionID"]},actionID:{type:"action-id",conflicts:["action","onClick"]}}},Toggle:{documentation:"Interactive widget toggle. A declared actionID requires a package-relative storage stateKey.",children:!0,availability:{interactiveIos:"17.0"},requiredAny:["onClick","actionID"],properties:{on:{type:"boolean",required:!0},onClick:{type:"function",conflicts:["actionID"]},actionID:{type:"action-id",requires:["stateKey"],conflicts:["onClick"]},stateKey:{type:"storage-key",requires:["actionID"]}}}}};function Lb(n,e){const t=Object.entries(e.properties??{}).filter(([,s])=>s.required).map(([s,r])=>`${s}=${r.type.includes("number")||r.type==="boolean"?"{${}}":'"${}"'}`).join(" "),i=t?` ${t}`:"";return e.children?`<${n}${i}> \${} `:`<${n}${i} />`}const Th=Object.entries(kt.components).map(([n,e])=>({label:n,type:"class",detail:`ScriptWidget · ${Object.keys(e.properties??{}).length} properties`,info:e.documentation,apply:Lb(n,e)}));function Db(n){const e=n.match(/<([A-Za-z][\w]*)\b([^<>]*)$/);return!e||e[2].includes(">")?null:{name:e[1],attributes:e[2]}}function Eb(n,e){const t=kt.components[n];return t?Object.entries({...kt.globalProperties,...t.properties??{}}).filter(([i])=>!e.has(i)).map(([i,s])=>({label:i,type:"property",detail:s.required?`${s.type} · required`:s.type,info:s.deprecated?`Deprecated: ${s.deprecated}`:s.documentation,apply:`${i}=${s.type.includes("number")||s.type==="boolean"?"{${}}":'"${}"'}`})):[]}function Wb(n){const e=n.match(/<([A-Za-z][\w]*)\b[^<>]*\b([A-Za-z][\w]*)\s*=\s*["']([^"']*)$/);if(!e)return null;const t=kt.components[e[1]]?.properties?.[e[2]]??kt.globalProperties[e[2]];return t?.values?{typed:e[3],values:t.values}:null}function zb(n){const e=n.state.doc.sliceString(Math.max(0,n.pos-1200),n.pos),t=Wb(e);if(t)return{from:n.pos-t.typed.length,options:t.values.map(r=>({label:r,type:"enum"})),validFor:/^[\w-]*$/};const i=n.matchBefore(/<[A-Za-z]*$/);if(i)return{from:i.from+1,options:Th,validFor:/^[A-Za-z]*$/};const s=Db(e);if(s&&/(?:\s|^)\w*$/.test(s.attributes)){const r=n.matchBefore(/[A-Za-z][\w]*$/),o=new Set([...s.attributes.matchAll(/\b([A-Za-z][\w]*)\s*=/g)].map(l=>l[1]));return{from:r?.from??n.pos,options:Eb(s.name,o),validFor:/^[A-Za-z][\w]*$/}}return n.explicit?{from:n.pos,options:Th,validFor:/^[A-Za-z]*$/}:null}function Ch(n,e){const t=[];for(let i=n.node.firstChild;i;i=i.nextSibling)i.name===e&&t.push(i);return t}function id(n){const e=[];return he(n).iterate({enter(t){if(t.name!=="JSXOpenTag"&&t.name!=="JSXSelfClosingTag")return;const s=Ch(t,"JSXIdentifier")[0];s&&e.push({name:n.doc.sliceString(s.from,s.to),from:s.from,to:s.to,attributes:Ch(t,"JSXAttribute").map(r=>{const o=r.firstChild;return o?{name:n.doc.sliceString(o.from,o.to),from:o.from,to:o.to}:null}).filter(Boolean)})}}),e}function nd(n){const e=[];for(const t of id(n.state)){const i=kt.components[t.name];if(!i)continue;const s=new Set([...Object.keys(kt.globalProperties),...Object.keys(i.properties??{})]),r=new Set(t.attributes.map(o=>o.name));for(const o of t.attributes){s.has(o.name)||e.push({from:o.from,to:o.to,severity:"warning",message:`“${o.name}” is not supported by <${t.name}>.`});const l=i.properties?.[o.name]??kt.globalProperties[o.name];l?.deprecated&&e.push({from:o.from,to:o.to,severity:"warning",message:`${o.name} is deprecated. ${l.deprecated}`})}for(const[o,l]of Object.entries(i.properties??{}))if(l.required&&!r.has(o)&&e.push({from:t.from,to:t.to,severity:"error",message:`<${t.name}> requires the “${o}” property.`}),r.has(o)){for(const a of l.requires??[])r.has(a)||e.push({from:t.from,to:t.to,severity:"error",message:`<${t.name}> “${o}” requires the “${a}” property.`});for(const a of l.conflicts??[])r.has(a)&&o cannot combine “${o}” with “${a}”.`})}i.requiredAny?.length&&!i.requiredAny.some(o=>r.has(o))&&e.push({from:t.from,to:t.to,severity:"error",message:`<${t.name}> requires one of: ${i.requiredAny.map(o=>`“${o}”`).join(", ")}.`})}return e}function qb(n,e){const t=id(n.state).find(s=>e>=s.from&&e<=s.to);if(!t)return null;const i=kt.components[t.name];return i?{pos:t.from,end:t.to,above:!0,create(){const s=document.createElement("div");s.className="studio-hover";const r=document.createElement("strong");r.textContent=`<${t.name}>`;const o=document.createElement("p");return o.textContent=i.documentation,s.append(r,o),{dom:s}}}:null}const Zh={light:{background:"#FAFAFC",foreground:"#202124",gutter:"#F3F3F6",gutterText:"#8A8A93",activeLine:"#EDEEF3",selection:"#B9D7FF",caret:"#0067C0"},dark:{background:"#1E1F22",foreground:"#E8E8ED",gutter:"#191A1D",gutterText:"#777982",activeLine:"#292A2F",selection:"#315A85",caret:"#65B7FF"}};function Bb(n,e){return T.theme({"&":{height:"100%",color:n.foreground,backgroundColor:n.background,fontSize:"13px"},".cm-scroller":{fontFamily:'ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, monospace',lineHeight:"1.58",overscrollBehavior:"contain"},".cm-content":{caretColor:n.caret,padding:"12px 0 32px"},".cm-line":{padding:"0 8px"},".cm-cursor, .cm-dropCursor":{borderLeftColor:n.caret},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:n.selection},".cm-activeLine":{backgroundColor:n.activeLine},".cm-gutters":{backgroundColor:n.gutter,color:n.gutterText,border:"none",paddingLeft:"env(safe-area-inset-left)"},".cm-activeLineGutter":{backgroundColor:n.activeLine,color:n.foreground},".cm-foldPlaceholder":{backgroundColor:"transparent",border:`1px solid ${n.gutterText}`,color:n.gutterText},".cm-tooltip":{border:e?"1px solid #41434A":"1px solid #D2D3D8",backgroundColor:e?"#292A2F":"#FFFFFF",borderRadius:"8px",overflow:"hidden",boxShadow:"0 8px 28px rgba(0, 0, 0, 0.2)"},".cm-tooltip-autocomplete ul li[aria-selected]":{backgroundColor:e?"#315A85":"#DCEBFA",color:n.foreground},".cm-panels":{backgroundColor:n.gutter,color:n.foreground},".cm-searchMatch":{backgroundColor:e?"#725C1D":"#FFE69A"},".cm-searchMatch.cm-searchMatch-selected":{backgroundColor:e?"#8D6D20":"#FFD45C"}},{dark:e})}function sd(n){const e=n==="dark";return[Bb(e?Zh.dark:Zh.light,e),gg(Sg)]}const rd="scriptwidget.studio.document-state.v1.";function od(n,e,t){if(!n||!e)return!1;try{return n.setItem(`${rd}${e}`,JSON.stringify({anchor:Number(t.anchor)||0,head:Number(t.head)||0,scrollTop:Number(t.scrollTop)||0})),!0}catch{return!1}}function _b(n,e,t){if(!n||!e)return null;try{const i=JSON.parse(n.getItem(`${rd}${e}`));if(!i||typeof i!="object")return null;const s=r=>Math.max(0,Math.min(Number(r)||0,t));return{anchor:s(i.anchor),head:s(i.head),scrollTop:Math.max(0,Number(i.scrollTop)||0)}}catch{return null}}const Yb="scriptwidget.web-studio.draft.v1:";function kl(n){return`${Yb}${n}`}function Ib(n,e){if(!e)return null;try{const t=JSON.parse(n.getItem(kl(e))||"null");return t&&typeof t.content=="string"&&typeof t.baseRevision=="string"?t:null}catch{return null}}function Ah(n,e,t,i,s=Date.now()){if(!e||typeof i!="string")return null;const r={documentID:e,content:t,baseRevision:i,updatedAt:s};return n.setItem(kl(e),JSON.stringify(r)),r}function Wr(n,e){e&&n.removeItem(kl(e))}function Vb(n,e,t,i){const s=Ib(n,e);return!s||s.content===t?null:{...s,serverContent:t,serverRevision:i,isStale:s.baseRevision!==i}}function jb(){return{connection:"connecting",save:"idle",preview:"idle",conflict:null}}function Nb(n,e){switch(e.type){case"CONNECTED":return{...n,connection:"connected"};case"OFFLINE":return{...n,connection:"offline",save:n.save==="saving"?"draft":n.save};case"DISCONNECTED":return{...n,connection:"disconnected"};case"EDITED":return{...n,save:"draft",conflict:null};case"SAVING":return{...n,save:"saving"};case"SAVED":return{...n,save:"saved",preview:e.preview||"requested",conflict:null};case"SAVE_FAILED":return{...n,save:"error"};case"CONFLICT":return{...n,save:"conflict",conflict:e.conflict};default:return n}}class Gb{constructor(e){this.send=e,this.epoch=0,this.context=null,this.inFlight=null,this.needsFlush=!1}open({documentID:e,packageID:t,path:i,revision:s,content:r}){return this.epoch+=1,this.context={documentID:e,packageID:t,path:i,revision:s,content:r,generation:0,savedGeneration:0},this.needsFlush=!1,this.snapshot()}edit(e){return this.context?(this.context.content=e,this.context.generation+=1,this.snapshot()):null}rebase(e){return this.context&&(this.context.revision=e),this.snapshot()}get isDirty(){return!!(this.context&&this.context.generation!==this.context.savedGeneration)}snapshot(){return this.context?{...this.context,dirty:this.isDirty}:null}async flush(){if(!this.context||!this.isDirty)return{skipped:!0,snapshot:this.snapshot()};if(this.inFlight)return this.needsFlush=!0,this.inFlight.then(()=>this.isDirty?this.flush():{skipped:!0,snapshot:this.snapshot()});const e=this.epoch,t={...this.context};this.needsFlush=!1,this.inFlight=this.send({documentID:t.documentID,packageID:t.packageID,path:t.path,content:t.content,baseRevision:t.revision}).then(s=>this.epoch!==e||this.context?.documentID!==t.documentID?{ignored:!0,result:s,snapshot:this.snapshot()}:(this.context.revision=s.revision,this.context.savedGeneration=t.generation,{result:s,snapshot:this.snapshot()})).finally(()=>{this.inFlight=null});const i=await this.inFlight;return this.needsFlush&&this.isDirty?this.flush():i}}function Mh(n){return["draft","saving","error","conflict"].includes(n)}class Ub extends Error{constructor(e,t,i={}){super(e),this.name="StudioAPIError",this.status=t,this.body=i}}class Fb{constructor({fetchImpl:e=globalThis.fetch,token:t=()=>"",onUnauthorized:i=()=>{}}={}){if(typeof e!="function")throw new TypeError("A fetch implementation is required");this.fetchImpl=e,this.token=t,this.onUnauthorized=i}async request(e,t={}){const i=await this.fetchImpl(e,this.authorizedOptions(t)),s=await i.json().catch(()=>({}));return this.validate(i,e,s),s}async requestBlob(e,t={}){const i=await this.fetchImpl(e,this.authorizedOptions(t));if(!i.ok){const s=await i.json().catch(()=>({}));this.validate(i,e,s)}return i.blob()}authorizedOptions(e){return{...e,headers:{"Content-Type":"application/json","X-Studio-Token":this.token(),...e.headers||{}}}}validate(e,t,i){if(!e.ok){const s=new Ub(i.message||`Request failed (${e.status})`,e.status,i);throw e.status===401&&t!=="/api/v1/pair"&&this.onUnauthorized(s),s}}}const Ql=/^https?:$/.test(window.location.protocol),Hb=document.querySelector(Ql?"#editor":"#native-editor"),ld=new Ci,ad=new Ci;let ni=null,me=null,$t=0,Do=!1,Rs=null,Rh=null;const Xh=document.querySelector("#save-status");let hd=null;function Xs(n,e="idle"){Xh.textContent=n,Xh.dataset.state=e}function Kb(){window.clearTimeout(Rh),Rh=window.setTimeout(()=>{const n=Y.state.selection.main;od(window.localStorage,me,{anchor:n.anchor,head:n.head,scrollTop:Y.scrollDOM.scrollTop})},180)}function cd(){return window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light"}function fd(){window.clearTimeout(Rs),Xs("Saving…","saving"),Rs=window.setTimeout(()=>{const n=Y.state.doc.toString();ir(ni,_e.documentSave,{content:n,version:$t},me,(e={})=>{Ql||Xs(e.result==="ok"||e.result==="unavailable"?"Saved":"Save failed",e.result==="failed"?"error":"saved")})},700)}function Jb(n){if((n.selectionSet||n.viewportChanged||n.docChanged)&&Kb(),!n.docChanged||Do)return;$t+=1,hd?.documentChanged();const e=[];n.changes.iterChanges((t,i,s,r,o)=>{e.push({from:t,to:i,insert:o.toString(),newFrom:s,newTo:r})}),ir(ni,_e.documentChanged,{changes:e,version:$t},me),fd()}const eS=[xm(),Qm(),qO(),Yg(),pg(),TO(),XO(),I.allowMultipleSelections.of(!0),eg(),Pg(),Zy(),By({override:[zb],activateOnTyping:!0}),KO(),tm(),jO(),V1(),Ab(),xb(nd,{delay:350}),nf(qb),E1({jsx:!0}),_s.of([j0,...Xy,...V0,...ub,...Kg,...cg,...vu]),ld.of(I.readOnly.of(!1)),ad.of(sd(cd())),T.updateListener.of(Jb),T.contentAttributes.of({autocapitalize:"off",autocomplete:"off",spellcheck:"false"})],Y=new T({state:I.create({doc:"",extensions:eS}),parent:Hb});function Xt(n,e=me,t=0){const i=Y.state.selection.main;od(window.localStorage,me,{anchor:i.anchor,head:i.head,scrollTop:Y.scrollDOM.scrollTop}),Do=!0,me=e,$t=t;const s=_b(window.localStorage,me,(n??"").length);Y.dispatch({changes:{from:0,to:Y.state.doc.length,insert:n??""},selection:s?{anchor:s.anchor,head:s.head}:{anchor:0},scrollIntoView:!0}),s&&window.requestAnimationFrame(()=>{Y.scrollDOM.scrollTop=s.scrollTop}),Do=!1,Xs("Saved","saved")}function Lh(n){if(Y.state.readOnly)return!1;const e=Y.state.selection.main;return Y.dispatch({changes:{from:e.from,to:e.to,insert:n},selection:{anchor:e.from+n.length},userEvent:"input"}),Y.focus(),!0}async function Ls(){if(Y.state.readOnly)return!1;try{const[{format:n},{default:e},{default:t}]=await Promise.all([sr(()=>import("./standalone-Cayz_KD-.js"),[],import.meta.url),sr(()=>import("./babel-BktJt1uC.js"),[],import.meta.url),sr(()=>import("./estree-DFfjoHvx.js"),[],import.meta.url)]),i=await n(Y.state.doc.toString(),{parser:"babel",plugins:[e,t],semi:!0,singleQuote:!0,trailingComma:"es5"});return Xt(i,me,$t+1),fd(),!0}catch(n){return ir(ni,"diagnostics.publish",{message:String(n),severity:"error"},me),!1}}function Si(n){Y.dispatch({effects:ld.reconfigure(I.readOnly.of(!!n))})}function Ds(n){const e=n==="dark"||n==="light"?n:cd();document.documentElement.dataset.theme=e,Y.dispatch({effects:ad.reconfigure(sd(e))})}function tS(n=[]){const e=n.map(t=>({from:Math.max(0,Math.min(t.from??0,Y.state.doc.length)),to:Math.max(0,Math.min(t.to??t.from??0,Y.state.doc.length)),severity:t.severity??"error",message:t.message??"Unknown error"}));Y.dispatch(Vu(Y.state,e))}function ze(n,e){ni.registerHandler(n,async(t={},i=()=>{})=>{try{i({result:"ok",...await e(t)})}catch(s){i({result:"failed",message:String(s)})}})}Rb(n=>{ni=n,ze(_e.documentOpen,({payload:e={},documentID:t})=>(Xt(e.content,t,e.version??0),Si(e.readOnly),{protocolVersion:td})),ze(_e.documentReplace,({payload:e={},documentID:t})=>(Xt(e.content,t,e.version??$t),{})),ze(_e.documentSetReadOnly,({payload:e={}})=>(Si(e.readOnly),{readOnly:!!e.readOnly})),ze(_e.editorInsert,({payload:e={}})=>({inserted:Lh(e.content??"")})),ze(_e.editorFormat,async()=>({formatted:await Ls()})),ze(_e.editorSetTheme,({payload:e={}})=>(Ds(e.theme),{})),ze(_e.editorGetState,()=>({content:Y.state.doc.toString(),version:$t,documentID:me,selection:{from:Y.state.selection.main.from,to:Y.state.selection.main.to}})),ze(_e.diagnosticsPublish,({payload:e={}})=>(tS(e.items),{})),ze("editor_setValue",({value:e})=>(Xt(e),{})),ze("editor_insertValue",({value:e})=>({inserted:Lh(e??"")})),ze("editor_getValue",()=>({value:Y.state.doc.toString()})),ze("editor_setReadonly",({readonly:e})=>(Si(e),{readonly:!!e})),ze("editor_formatCode",async()=>({formatted:await Ls()})),Xb(ni)});Ql&&(document.querySelector("#native-editor").hidden=!0,document.querySelector("#web-studio").hidden=!1,iS());async function iS(){const n=document.querySelector("#pair-dialog"),e=document.querySelector("#pair-form"),t=document.querySelector("#pair-error"),i=document.querySelector("#package-select"),s=document.querySelector("#file-select"),r=document.querySelector("#connection-status"),o=document.querySelector("#disconnect-button"),l=document.querySelector("#studio-grid"),a=document.querySelector(".editor-column"),h=document.querySelector("#recovery-banner"),c=document.querySelector("#conflict-banner"),f=document.querySelector("#command-dialog"),u=document.querySelector("#command-search"),d=document.querySelector("#command-list"),p=document.querySelector("#compare-dialog");let O=window.sessionStorage.getItem("scriptwidget.web-studio.token")||"",m=[],y=null,w=null,x=null,Z=0,k=null,Q="",v="",R=null,E=jb(),q="",L="",M=null;function j(S="Session ended. Enter the new code shown on your device."){O="",window.sessionStorage.removeItem("scriptwidget.web-studio.token"),o.hidden=!0,W({type:"DISCONNECTED"}),r.textContent=S,Si(!0),n.open||n.showModal()}function W(S){E=Nb(E,S);const A={connecting:"Connecting",connected:"Connected",offline:"Offline",disconnected:"Disconnected"},D={idle:"Ready",draft:"Draft saved locally",saving:"Saving…",saved:"Saved",error:"Save failed",conflict:"Conflict"};r.dataset.state=E.connection,document.querySelector("#status-connection").textContent=A[E.connection]||E.connection,Xs(D[E.save]||E.save,E.save),document.querySelector("#dirty-indicator").hidden=!["draft","saving","error","conflict"].includes(E.save),document.querySelector("#status-preview").textContent=E.preview==="requested"?"Preview requested":"Preview idle",document.querySelector("#preview-detail").textContent=E.preview==="requested"?"Requested on device":"Not requested"}const G=new Fb({token:()=>O,onUnauthorized:()=>j()}),F=(S,A)=>G.request(S,A);M=new Gb(({packageID:S,path:A,content:D,baseRevision:N})=>F("/api/v1/document",{method:"PUT",body:JSON.stringify({package:S,path:A,content:D,baseRevision:N})}));async function we(S){O=(await F("/api/v1/pair",{method:"POST",body:JSON.stringify({code:S})})).token,window.sessionStorage.setItem("scriptwidget.web-studio.token",O),o.hidden=!1,W({type:"CONNECTED"}),Le()}function Le(){window.clearInterval(y),y=window.setInterval(async()=>{if(O)try{const S=await F("/api/v1/session");if(!navigator.onLine)return;nt(S),W({type:"CONNECTED"})}catch(S){S.status!==401&&(r.textContent=`Interrupted · ${S.message}`,W({type:"OFFLINE"}))}},5e3)}async function se(){if(m=(await F("/api/v1/packages")).packages||[],i.replaceChildren(...m.map(A=>new Option(A.name,A.id))),!m.length){r.textContent="No editable widgets",Si(!0);return}await ke()}async function ke(){const S=m.find(N=>N.id===i.value),A=S?.files||[];s.replaceChildren(...A.map(N=>new Option(N,N)));const D=A.includes(S?.entry)?S.entry:A[0];D&&(s.value=D),await pe()}async function De(S=""){m=(await F("/api/v1/packages")).packages||[],i.replaceChildren(...m.map(le=>new Option(le.name,le.id))),q&&(i.value=q);const D=m.find(le=>le.id===i.value),N=D?.files||[];s.replaceChildren(...N.map(le=>new Option(le,le))),s.value=N.includes(S)?S:N.includes(L)?L:D?.entry||N[0]}async function pe(){if(!i.value||!s.value)return;const S=new URLSearchParams({package:i.value,path:s.value}),A=await F(`/api/v1/document?${S}`),D=`${i.value}/${s.value}`;q=i.value,L=s.value,Q=A.revision,v=A.content,R=null,c.hidden=!0,Xt(A.content,D,0),M.open({documentID:D,packageID:q,path:L,revision:A.revision,content:A.content}),Si(!!A.readOnly),Be(A);const N=Vb(window.localStorage,D,A.content,A.revision);h.hidden=!N,h._draft=N,document.querySelector("#recovery-message").textContent=N?.isStale?"The device version also changed. Review before saving.":"Restore it or keep the device version.",r.textContent="Connected",W({type:"CONNECTED"}),o.hidden=!1,wn(),Le(),xn()}function Be(S){document.querySelector("#breadcrumb-package").textContent=S.packageName||i.value,document.querySelector("#breadcrumb-file").textContent=s.value,document.querySelector("#editor-tab-name").textContent=s.value,document.querySelector("#revision-detail").textContent=Q?Q.slice(0,8):"—",document.querySelector("#access-detail").textContent=S.readOnly?"Read only":"Editable"}function nt(S){S.device&&(document.querySelector("#device-name").textContent=S.device.name||S.device.model,document.querySelector("#device-system").textContent=`${S.device.model} · ${S.device.system}`),S.preview?.package&&(document.querySelector("#preview-target").textContent=S.preview.package),S.preview?.snapshotSequence&&bt()}async function bt(){try{const S=await G.requestBlob("/api/v1/preview"),A=URL.createObjectURL(S),D=document.querySelector("#device-preview"),N=k;k=A,D.onload=()=>{N&&URL.revokeObjectURL(N)},D.src=A,D.hidden=!1,document.querySelector("#preview-detail").textContent="Rendered on device"}catch{}}function si(S){const A=document.querySelector("#console-list"),D=document.createElement("li");for(D.className=S.level||"info",D.textContent=S.message||"",A.append(D);A.children.length>200;)A.firstChild.remove();A.scrollTop=A.scrollHeight}function xn(){window.clearTimeout(x);const S=async()=>{if(O)try{const A=await F(`/api/v1/events?after=${Z}`);Z=A.nextSequence??Z;for(const D of A.events||[])D.type==="console"&&si(D.payload||{}),D.type==="preview.snapshot"&&bt(),D.type==="preview.requested"&&(document.querySelector("#status-preview").textContent="Preview requested",document.querySelector("#preview-detail").textContent="Requested on device"),D.type==="files.changed"&&D.payload?.package===q&&De(L).catch(ri);W({type:"CONNECTED"})}catch(A){A.status!==401&&W({type:"OFFLINE"})}finally{O&&(x=window.setTimeout(S,1e3))}};S()}function wn(){const S=nd(Y);document.querySelector("#problems-list").replaceChildren(...S.map(D=>{const N=Y.state.doc.lineAt(D.from),le=document.createElement("li");le.className=`problem-item ${D.severity}`;const Ge=document.createElement("button");return Ge.type="button",Ge.innerHTML=`${D.severity==="error"?"●":"▲"}Ln ${N.number}`,Ge.children[1].textContent=D.message,Ge.addEventListener("click",()=>{Y.dispatch({selection:{anchor:D.from},scrollIntoView:!0}),Y.focus()}),le.append(Ge),le})),document.querySelector("#problems-count").textContent=String(S.length),document.querySelector("#status-problem-count").textContent=String(S.length),document.querySelector("#problems-summary").textContent=S.length?`${S.filter(D=>D.severity==="error").length} errors, ${S.filter(D=>D.severity!=="error").length} warnings`:"No problems detected"}async function kn(S,A,D=null){M.snapshot()?.content!==S&&M.edit(S),D&&M.rebase(D),W({type:"SAVING"});try{const N=await M.flush();if(N.ignored){A({result:"ok",ignored:!0});return}if(N.skipped){W({type:"SAVED"}),A({result:"ok",skipped:!0});return}const le=N.result||{},Ge=M.snapshot();Q=Ge?.revision||Q,v=Ge?.content||S,Wr(window.localStorage,me),R=null,c.hidden=!0,document.querySelector("#revision-detail").textContent=Q?.slice(0,8)||"—",W({type:"SAVED",preview:le.preview?.state}),A({result:"ok",...le})}catch(N){N.status===409?(R=N.body,c.hidden=!1,W({type:"CONFLICT",conflict:R})):W({type:"SAVE_FAILED"}),A({result:"failed",message:N.message})}}ni={registerHandler(){},callHandler(S,A,D=()=>{}){S===_e.documentSave?kn(A.payload.content,D):D({result:"ok"})}},hd={documentChanged(){const S=Y.state.doc.toString();M.edit(S),Ah(window.localStorage,me,S,M.snapshot()?.revision||Q),W({type:"EDITED"}),window.clearTimeout(w),w=window.setTimeout(wn,380)}};async function vl(S,A){if(!Mh(E.save)){await S();return}try{if(window.clearTimeout(Rs),await kn(Y.state.doc.toString(),()=>{}),!M.isDirty&&E.save!=="conflict"){await S();return}}catch{}window.confirm("This document has changes that are not saved on the device. A browser draft is available. Switch anyway?")?await S():A()}i.addEventListener("change",()=>{const S=i.value;i.value=q,vl(async()=>{i.value=S,await ke()},()=>{i.value=q}).catch(ri)}),s.addEventListener("change",()=>{const S=s.value;s.value=L,vl(async()=>{s.value=S,await pe()},()=>{s.value=L}).catch(ri)});function ri(S){r.textContent=S.message||String(S),W({type:"SAVE_FAILED"})}e.addEventListener("submit",async S=>{S.preventDefault(),t.textContent="";try{await we(document.querySelector("#pair-code").value),n.close(),await se()}catch(A){t.textContent=A.message}}),o.addEventListener("click",async()=>{try{await F("/api/v1/session",{method:"DELETE"})}catch{}j("Disconnected. Start a new session with the code on your device.")}),document.querySelector("#new-file").addEventListener("click",async()=>{const S=window.prompt("New package-relative text file","source/helper.js")?.trim();if(S)try{await F("/api/v1/document",{method:"POST",body:JSON.stringify({package:q,path:S})}),await De(S),await pe()}catch(A){ri(A)}}),document.querySelector("#delete-file").addEventListener("click",async()=>{const S=m.find(A=>A.id===q);if(!L||L===S?.entry){window.alert("The widget entry file cannot be deleted.");return}if(window.confirm(`Delete ${L}? This cannot be undone.`))try{const A=new URLSearchParams({package:q,path:L});await F(`/api/v1/document?${A}`,{method:"DELETE"}),L="",await De(),await pe()}catch(A){ri(A)}}),document.querySelector("#clear-console").addEventListener("click",()=>document.querySelector("#console-list").replaceChildren()),document.querySelector("#restore-draft").addEventListener("click",()=>{const S=h._draft;S&&(Xt(S.content,S.documentID,$t+1),h.hidden=!0,Ah(window.localStorage,me,S.content,Q),W({type:"EDITED"}),wn())}),document.querySelector("#discard-draft").addEventListener("click",()=>{Wr(window.localStorage,me),h.hidden=!0}),document.querySelector("#reload-server").addEventListener("click",()=>{R&&(Wr(window.localStorage,me),Q=R.currentRevision,v=R.currentContent,Xt(v,me,$t+1),M.open({documentID:me,packageID:q,path:L,revision:Q,content:v}),R=null,c.hidden=!0,W({type:"SAVED"}),wn())}),document.querySelector("#keep-local").addEventListener("click",()=>{R&&kn(Y.state.doc.toString(),()=>{},R.currentRevision)}),document.querySelector("#compare-conflict").addEventListener("click",()=>{document.querySelector("#compare-local").textContent=Y.state.doc.toString(),document.querySelector("#compare-server").textContent=R?.currentContent||v,p.showModal()}),p.querySelector("button").addEventListener("click",()=>p.close());function nr(){const S=a.classList.toggle("problems-collapsed");document.querySelector("#problems-toggle").setAttribute("aria-expanded",String(!S))}function Xi(S){l.classList.toggle(`show-${S}`)}document.querySelector("#problems-toggle").addEventListener("click",nr),document.querySelector("#status-problems").addEventListener("click",()=>{a.classList.remove("problems-collapsed")}),document.querySelector("#explorer-button").addEventListener("click",()=>Xi("explorer")),document.querySelector("#inspector-button").addEventListener("click",()=>Xi("inspector")),document.querySelectorAll("[data-close-panel]").forEach(S=>S.addEventListener("click",()=>l.classList.remove(`show-${S.dataset.closePanel}`)));const $l=[{name:"Save Document",keys:"⌘S",run:()=>{window.clearTimeout(Rs),kn(Y.state.doc.toString(),()=>{})}},{name:"Format Document",keys:"⇧⌥F",run:Ls},{name:"Toggle Problems",keys:"⌘J",run:nr},{name:"Toggle Explorer",keys:"⌘⇧E",run:()=>Xi("explorer")},{name:"Toggle Inspector",keys:"",run:()=>Xi("inspector")},{name:"Use Light Theme",keys:"",run:()=>Ds("light")},{name:"Use Dark Theme",keys:"",run:()=>Ds("dark")}];function Pl(S=""){const A=$l.filter(D=>D.name.toLowerCase().includes(S.toLowerCase()));d.replaceChildren(...A.map(D=>{const N=document.createElement("li"),le=document.createElement("button");le.type="button",le.className="command";const Ge=document.createElement("span");Ge.textContent=D.name;const Zl=document.createElement("kbd");return Zl.textContent=D.keys,le.append(Ge,Zl),le.addEventListener("click",()=>{f.close(),D.run()}),N.append(le),N}))}function Tl(){Pl(),f.showModal(),u.value="",u.focus()}document.querySelector("#command-button").addEventListener("click",Tl),u.addEventListener("input",()=>Pl(u.value)),document.addEventListener("keydown",S=>{const A=S.metaKey||S.ctrlKey;A&&S.shiftKey&&S.key.toLowerCase()==="p"?(S.preventDefault(),Tl()):A&&S.key.toLowerCase()==="s"?(S.preventDefault(),$l[0].run()):A&&S.key.toLowerCase()==="j"?(S.preventDefault(),nr()):A&&S.shiftKey&&S.key.toLowerCase()==="e"?(S.preventDefault(),Xi("explorer")):S.shiftKey&&S.altKey&&S.key.toLowerCase()==="f"&&(S.preventDefault(),Ls())}),Y.dom.addEventListener("keyup",Cl),Y.dom.addEventListener("mouseup",Cl);function Cl(){const S=Y.state.selection.main.head,A=Y.state.doc.lineAt(S);document.querySelector("#cursor-position").textContent=`Ln ${A.number}, Col ${S-A.from+1}`}window.addEventListener("offline",()=>{r.textContent="Computer is offline",W({type:"OFFLINE"})}),window.addEventListener("online",()=>{O&&F("/api/v1/session").then(S=>(nt(S),W({type:"CONNECTED"}),se())).catch(ri)}),window.addEventListener("beforeunload",S=>{Mh(E.save)&&(S.preventDefault(),S.returnValue="")});try{await se()}catch{j("Pair with the code shown on your device.")}}window.matchMedia?.("(prefers-color-scheme: dark)").addEventListener("change",()=>Ds("system"));window.webkit||Xt(`// ScriptWidget Studio const widget = ( diff --git a/iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/index.html b/iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/index.html index 50c4c278..f1919a4e 100644 --- a/iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/index.html +++ b/iOS/ScriptWidget/View/CodeEditor/MirrorEditor/StudioEditor.bundle/index.html @@ -5,7 +5,7 @@ ScriptWidget Web Studio - + diff --git a/macOS/ScriptWidgetMac/Settings/SettingAIView.swift b/macOS/ScriptWidgetMac/Settings/SettingAIView.swift index b970281d..3d319624 100644 --- a/macOS/ScriptWidgetMac/Settings/SettingAIView.swift +++ b/macOS/ScriptWidgetMac/Settings/SettingAIView.swift @@ -319,7 +319,7 @@ private struct AIProfileEditorPane: View { private static let providerPresets: [(label: String, host: String, models: [String])] = [ ("OpenAI", "https://api.openai.com", ["gpt-4o-mini", "gpt-4o", "gpt-4.1-mini", "gpt-4.1", "o4-mini"]), - ("DeepSeek", "https://api.deepseek.com", ["deepseek-chat", "deepseek-reasoner"]), + ("DeepSeek", "https://api.deepseek.com", ["deepseek-flash", "deepseek-v4-pro"]), ("xAI", "https://api.x.ai", ["grok-2-latest", "grok-2-mini"]), ("Ollama", "http://localhost:11434", []), ] @@ -476,7 +476,7 @@ private struct AIProfileEditorPane: View { id: "", name: "", baseURL: baseURL, model: "", apiKey: "", authMethod: .apiKey ).normalizedBaseURL)?.host ?? "" if host.contains("deepseek") { - return ["deepseek-chat", "deepseek-reasoner"] + return ["deepseek-flash", "deepseek-v4-pro"] } else if host.contains("x.ai") { return ["grok-2-latest", "grok-2-mini"] } else if host.contains("localhost") || host.contains("127.0.0.1") { diff --git a/macOS/ScriptWidgetMac/StudioEditor.bundle/assets/index-CaXXMCSr.js b/macOS/ScriptWidgetMac/StudioEditor.bundle/assets/index-dCxXChRa.js similarity index 98% rename from macOS/ScriptWidgetMac/StudioEditor.bundle/assets/index-CaXXMCSr.js rename to macOS/ScriptWidgetMac/StudioEditor.bundle/assets/index-dCxXChRa.js index b9adb8de..ea1e0106 100644 --- a/macOS/ScriptWidgetMac/StudioEditor.bundle/assets/index-CaXXMCSr.js +++ b/macOS/ScriptWidgetMac/StudioEditor.bundle/assets/index-dCxXChRa.js @@ -21,7 +21,7 @@ \${} } }`,{label:"class",detail:"definition",type:"keyword"}),Te('import {${names}} from "${module}"\n${}',{label:"import",detail:"named",type:"keyword"}),Te('import ${name} from "${module}"\n${}',{label:"import",detail:"default",type:"keyword"})],C1=Tu.concat([Te("interface ${name} {\n ${}\n}",{label:"interface",detail:"definition",type:"keyword"}),Te("type ${name} = ${type}",{label:"type",detail:"definition",type:"keyword"}),Te("enum ${name} {\n ${}\n}",{label:"enum",detail:"definition",type:"keyword"})]),yh=new Am,Cu=new Set(["Script","Block","FunctionExpression","FunctionDeclaration","ArrowFunction","MethodDeclaration","ForStatement"]);function qi(n){return(e,t)=>{let i=e.node.getChild("VariableDefinition");return i&&t(i,n),!0}}const Z1=["FunctionDeclaration"],A1={FunctionDeclaration:qi("function"),ClassDeclaration:qi("class"),ClassExpression:()=>!0,EnumDeclaration:qi("constant"),TypeAliasDeclaration:qi("type"),NamespaceDeclaration:qi("namespace"),VariableDefinition(n,e){n.matchContext(Z1)||e(n,"variable")},TypeDefinition(n,e){e(n,"type")},__proto__:null};function Zu(n,e){let t=yh.get(e);if(t)return t;let i=[],s=!0;function r(o,l){let a=n.sliceString(o.from,o.to);i.push({label:a,type:l})}return e.cursor(te.IncludeAnonymous).iterate(o=>{if(s)s=!1;else if(o.name){let l=A1[o.name];if(l&&l(o,r)||Cu.has(o.name))return!1}else if(o.to-o.from>8192){for(let l of Zu(n,o.node))i.push(l);return!1}}),yh.set(e,i),i}const bh=/^[\w$\xa1-\uffff][\w$\d\xa1-\uffff]*$/,Au=["TemplateString","String","RegExp","LineComment","BlockComment","VariableDefinition","TypeDefinition","Label","PropertyDefinition","PropertyName","PrivatePropertyDefinition","PrivatePropertyName","JSXText","JSXAttributeValue","JSXOpenTag","JSXCloseTag","JSXSelfClosingTag",".","?."];function M1(n){let e=he(n.state).resolveInner(n.pos,-1);if(Au.indexOf(e.name)>-1)return null;let t=e.name=="VariableName"||e.to-e.from<20&&bh.test(n.state.sliceDoc(e.from,e.to));if(!t&&!n.explicit)return null;let i=[];for(let s=e;s;s=s.parent)Cu.has(s.name)&&(i=i.concat(Zu(n.state.doc,s)));return{options:i,from:t?e.from:n.pos,validFor:bh}}const Kt=ms.define({name:"javascript",parser:T1.configure({props:[wf.add({IfStatement:vr({except:/^\s*({|else\b)/}),TryStatement:vr({except:/^\s*({|catch\b|finally\b)/}),LabeledStatement:Km,SwitchBody:n=>{let e=n.textAfter,t=/^\s*\}/.test(e),i=/^\s*(case|default)\b/.test(e);return n.baseIndent+(t?0:i?1:2)*n.unit},Block:Hm({closing:"}"}),ArrowFunction:n=>n.baseIndent+n.unit,"TemplateString BlockComment":()=>null,"Statement Property":vr({except:/^\s*{/}),JSXElement(n){let e=/^\s*<\//.test(n.textAfter);return n.lineIndent(n.node.from)+(e?0:n.unit)},JSXEscape(n){let e=/\s*\}/.test(n.textAfter);return n.lineIndent(n.node.from)+(e?0:n.unit)},"JSXOpenTag JSXSelfClosingTag"(n){return n.column(n.node.from)+n.unit}}),vf.add({"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType":ig,BlockComment(n){return{from:n.from+2,to:n.to-2}},JSXElement(n){let e=n.firstChild;if(!e||e.name=="JSXSelfClosingTag")return null;let t=n.lastChild;return{from:e.to,to:t.type.isError?n.to:t.from}},"JSXSelfClosingTag JSXOpenTag"(n){var e;let t=(e=n.firstChild)===null||e===void 0?void 0:e.nextSibling,i=n.lastChild;return!t||t.type.isError?null:{from:t.to,to:i.type.isError?n.to:i.from}}})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"`"]},commentTokens:{line:"//",block:{open:"/*",close:"*/"}},indentOnInput:/^\s*(?:case |default:|\{|\}|<\/)$/,wordChars:"$"}}),Mu={test:n=>/^JSX/.test(n.name),facet:Sf({commentTokens:{block:{open:"{/*",close:"*/}"}}})},R1=Kt.configure({dialect:"ts"},"typescript"),X1=Kt.configure({dialect:"jsx",props:[sl.add(n=>n.isTop?[Mu]:void 0)]}),L1=Kt.configure({dialect:"jsx ts",props:[sl.add(n=>n.isTop?[Mu]:void 0)]},"typescript");let Ru=n=>({label:n,type:"keyword"});const Xu="break case const continue default delete export extends false finally in instanceof let new return static super switch this throw true typeof var yield".split(" ").map(Ru),D1=Xu.concat(["declare","implements","private","protected","public"].map(Ru));function E1(n={}){let e=n.jsx?n.typescript?L1:X1:n.typescript?R1:Kt,t=n.typescript?C1.concat(D1):Tu.concat(Xu);return new Ym(e,[Kt.data.of({autocomplete:G0(Au,mu(t))}),Kt.data.of({autocomplete:M1}),n.jsx?q1:[]])}function W1(n){for(;;){if(n.name=="JSXOpenTag"||n.name=="JSXSelfClosingTag"||n.name=="JSXFragmentTag")return n;if(n.name=="JSXEscape"||!n.parent)return null;n=n.parent}}function Sh(n,e,t=n.length){for(let i=e?.firstChild;i;i=i.nextSibling)if(i.name=="JSXIdentifier"||i.name=="JSXBuiltin"||i.name=="JSXNamespacedName"||i.name=="JSXMemberExpression")return n.sliceString(i.from,Math.min(i.to,t));return""}const z1=typeof navigator=="object"&&/Android\b/.test(navigator.userAgent),q1=T.inputHandler.of((n,e,t,i,s)=>{if((z1?n.composing:n.compositionStarted)||n.state.readOnly||e!=t||i!=">"&&i!="/"||!Kt.isActiveAt(n.state,e,-1))return!1;let r=s(),{state:o}=r,l=o.changeByRange(a=>{var h;let{head:c}=a,f=he(o).resolveInner(c-1,-1),u;if(f.name=="JSXStartTag"&&(f=f.parent),!(o.doc.sliceString(c-1,c)!=i||f.name=="JSXAttributeValue"&&f.to>c)){if(i==">"&&f.name=="JSXFragmentTag")return{range:a,changes:{from:c,insert:""}};if(i=="/"&&f.name=="JSXStartCloseTag"){let d=f.parent,p=d.parent;if(p&&d.from==c-2&&((u=Sh(o.doc,p.firstChild,c))||((h=p.firstChild)===null||h===void 0?void 0:h.name)=="JSXFragmentTag")){let O=`${u}>`;return{range:b.cursor(c+O.length,-1),changes:{from:c,insert:O}}}}else if(i==">"){let d=W1(f);if(d&&d.name=="JSXOpenTag"&&!/^\/?>|^<\//.test(o.doc.sliceString(c,c+2))&&(u=Sh(o.doc,d,c)))return{range:a,changes:{from:c,insert:``}}}}return{range:a}});return l.changes.empty?!1:(n.dispatch([r,o.update(l,{userEvent:"input.complete",scrollIntoView:!0})]),!0)}),xh=typeof String.prototype.normalize=="function"?n=>n.normalize("NFKD"):n=>n;class Pi{constructor(e,t,i=0,s=e.length,r,o){this.test=o,this.value={from:0,to:0,precise:!1},this.done=!1,this.matches=[],this.buffer="",this.bufferPos=0,this.iter=e.iterRange(i,s),this.bufferStart=i,this.normalize=r?l=>r(xh(l)):xh,this.query=this.normalize(t)}peek(){if(this.bufferPos==this.buffer.length){if(this.bufferStart+=this.buffer.length,this.iter.next(),this.iter.done)return-1;this.bufferPos=0,this.buffer=this.iter.value}return Ce(this.buffer,this.bufferPos)}next(){for(;this.matches.length;)this.matches.pop();return this.nextOverlapping()}nextOverlapping(){for(;;){let e=this.peek();if(e<0)return this.done=!0,this;let t=Eo(e),i=this.bufferStart+this.bufferPos;this.bufferPos+=ht(e);let s=this.normalize(t);if(s.length)for(let r=0,o=i,l=!0;;r++){let a=s.charCodeAt(r),h=this.match(a,o,l,this.bufferPos+this.bufferStart,r==s.length-1);if(h)return this.value=h,this;if(r==s.length-1)break;l&&rthis.to&&(this.curLine=this.curLine.slice(0,this.to-this.curLineStart)),this.iter.next())}nextLine(){this.curLineStart=this.curLineStart+this.curLine.length+1,this.curLineStart>this.to?this.curLine="":this.getLine(0)}next(){for(let e=this.matchPos-this.curLineStart;;){this.re.lastIndex=e;let t=this.matchPos<=this.to&&this.re.exec(this.curLine);if(t){let i=this.curLineStart+t.index,s=i+t[0].length;if(this.matchPos=Ps(this.text,s+(i==s?1:0)),i==this.curLineStart+this.curLine.length&&this.nextLine(),(ithis.value.to)&&(!this.test||this.test(i,s,t)))return this.value={from:i,to:s,precise:!0,match:t},this;e=this.matchPos-this.curLineStart}else if(this.curLineStart+this.curLine.length=i||s.to<=t){let l=new bi(t,e.sliceString(t,i));return Dr.set(e,l),l}if(s.from==t&&s.to==i)return s;let{text:r,from:o}=s;return o>t&&(r=e.sliceString(t,o)+r,o=t),s.to=this.to?this.to:this.text.lineAt(e).to}next(){for(;;){let e=this.re.lastIndex=this.matchPos-this.flat.from,t=this.re.exec(this.flat.text);if(t&&!t[0]&&t.index==e&&(this.re.lastIndex=e+1,t=this.re.exec(this.flat.text)),t){let i=this.flat.from+t.index,s=i+t[0].length;if((this.flat.to>=this.to||t.index+t[0].length<=this.flat.text.length-10)&&(!this.test||this.test(i,s,t)))return this.value={from:i,to:s,precise:!0,match:t},this.matchPos=Ps(this.text,s+(i==s?1:0)),this}if(this.flat.to==this.to)return this.done=!0,this;this.flat=bi.get(this.text,this.flat.from,this.chunkEnd(this.flat.from+this.flat.text.length*2))}}}typeof Symbol<"u"&&(Du.prototype[Symbol.iterator]=Eu.prototype[Symbol.iterator]=function(){return this});function B1(n){try{return new RegExp(n,yl),!0}catch{return!1}}function Ps(n,e){if(e>=n.length)return e;let t=n.lineAt(e),i;for(;e=56320&&i<57344;)e++;return e}const _1=n=>{let{state:e}=n,t=String(e.doc.lineAt(n.state.selection.main.head).number),{close:i,result:s}=fm(n,{label:e.phrase("Go to line"),input:{type:"text",name:"line",value:t},focus:!0,submitLabel:e.phrase("go")});return s.then(r=>{let o=r&&/^([+-])?(\d+)?(:\d+)?(%)?$/.exec(r.elements.line.value);if(!o){n.dispatch({effects:i});return}let l=e.doc.lineAt(e.selection.main.head),[,a,h,c,f]=o,u=c?+c.slice(1):0,d=h?+h:l.number;if(h&&f){let m=d/100;a&&(m=m*(a=="-"?-1:1)+l.number/e.doc.lines),d=Math.round(e.doc.lines*m)}else h&&a&&(d=d*(a=="-"?-1:1)+l.number);let p=e.doc.line(Math.max(1,Math.min(e.doc.lines,d))),O=b.cursor(p.from+Math.max(0,Math.min(u,p.length)));n.dispatch({effects:[i,T.scrollIntoView(O.from,{y:"center"})],selection:O})}),!0},Y1={highlightWordAroundCursor:!1,minSelectionLength:1,maxMatches:100,wholeWords:!1},I1=C.define({combine(n){return et(n,Y1,{highlightWordAroundCursor:(e,t)=>e||t,minSelectionLength:Math.min,maxMatches:Math.min})}});function V1(n){return[F1,U1]}const j1=X.mark({class:"cm-selectionMatch"}),N1=X.mark({class:"cm-selectionMatch cm-selectionMatch-main"});function wh(n,e,t,i){return(t==0||n(e.sliceDoc(t-1,t))!=ee.Word)&&(i==e.doc.length||n(e.sliceDoc(i,i+1))!=ee.Word)}function G1(n,e,t,i){return n(e.sliceDoc(t,t+1))==ee.Word&&n(e.sliceDoc(i-1,i))==ee.Word}const U1=ne.fromClass(class{constructor(n){this.decorations=this.getDeco(n)}update(n){(n.selectionSet||n.docChanged||n.viewportChanged)&&(this.decorations=this.getDeco(n.view))}getDeco(n){let e=n.state.facet(I1),{state:t}=n,i=t.selection;if(i.ranges.length>1)return X.none;let s=i.main,r,o=null;if(s.empty){if(!e.highlightWordAroundCursor)return X.none;let a=t.wordAt(s.head);if(!a)return X.none;o=t.charCategorizer(s.head),r=t.sliceDoc(a.from,a.to)}else{let a=s.to-s.from;if(a200)return X.none;if(e.wholeWords){if(r=t.sliceDoc(s.from,s.to),o=t.charCategorizer(s.head),!(wh(o,t,s.from,s.to)&&G1(o,t,s.from,s.to)))return X.none}else if(r=t.sliceDoc(s.from,s.to),!r)return X.none}let l=[];for(let a of n.visibleRanges){let h=new Pi(t.doc,r,a.from,a.to);for(;!h.next().done;){let{from:c,to:f}=h.value;if((!o||wh(o,t,c,f))&&(s.empty&&c<=s.from&&f>=s.to?l.push(N1.range(c,f)):(c>=s.to||f<=s.from)&&l.push(j1.range(c,f)),l.length>e.maxMatches))return X.none}}return X.set(l)}},{decorations:n=>n.decorations}),F1=T.baseTheme({".cm-selectionMatch":{backgroundColor:"#99ff7780"},".cm-searchMatch .cm-selectionMatch":{backgroundColor:"transparent"}}),H1=({state:n,dispatch:e})=>{let{selection:t}=n,i=b.create(t.ranges.map(s=>n.wordAt(s.head)||b.cursor(s.head)),t.mainIndex);return i.eq(t)?!1:(e(n.update({selection:i})),!0)};function K1(n,e){let{main:t,ranges:i}=n.selection,s=n.wordAt(t.head),r=s&&s.from==t.from&&s.to==t.to;for(let o=!1,l=new Pi(n.doc,e,i[i.length-1].to);;)if(l.next(),l.done){if(o)return null;l=new Pi(n.doc,e,0,Math.max(0,i[i.length-1].from-1)),o=!0}else{if(o&&i.some(a=>a.from==l.value.from))continue;if(r){let a=n.wordAt(l.value.from);if(!a||a.from!=l.value.from||a.to!=l.value.to)continue}return l.value}}const J1=({state:n,dispatch:e})=>{let{ranges:t}=n.selection;if(t.some(r=>r.from===r.to))return H1({state:n,dispatch:e});let i=n.sliceDoc(t[0].from,t[0].to);if(n.selection.ranges.some(r=>n.sliceDoc(r.from,r.to)!=i))return!1;let s=K1(n,i);return s?(e(n.update({selection:n.selection.addRange(b.range(s.from,s.to),!1),effects:T.scrollIntoView(s.to)})),!0):!1},Ri=C.define({combine(n){return et(n,{top:!1,caseSensitive:!1,literal:!1,regexp:!1,wholeWord:!1,createPanel:e=>new db(e),scrollToMatch:e=>T.scrollIntoView(e)})}});class Wu{constructor(e){this.search=e.search,this.caseSensitive=!!e.caseSensitive,this.literal=!!e.literal,this.regexp=!!e.regexp,this.replace=e.replace||"",this.valid=!!this.search&&(!this.regexp||B1(this.search)),this.unquoted=this.unquote(this.search),this.wholeWord=!!e.wholeWord,this.test=e.test}unquote(e){return this.literal?e:e.replace(/\\([nrt\\])/g,(t,i)=>i=="n"?` -`:i=="r"?"\r":i=="t"?" ":"\\")}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord&&this.test==e.test}create(){return this.regexp?new rb(this):new ib(this)}getCursor(e,t=0,i){let s=e.doc?e:I.create({doc:e});return i==null&&(i=s.doc.length),this.regexp?ai(this,s,t,i):li(this,s,t,i)}}class zu{constructor(e){this.spec=e}}function eb(n,e,t){return(i,s,r,o)=>{if(t&&!t(i,s,r,o))return!1;let l=i>=o&&s<=o+r.length?r.slice(i-o,s-o):e.doc.sliceString(i,s);return n(l,e,i,s)}}function li(n,e,t,i){let s;return n.wholeWord&&(s=tb(e.doc,e.charCategorizer(e.selection.main.head))),n.test&&(s=eb(n.test,e,s)),new Pi(e.doc,n.unquoted,t,i,n.caseSensitive?void 0:r=>r.toLowerCase(),s)}function tb(n,e){return(t,i,s,r)=>((r>t||r+s.length=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=li(this.spec,e,Math.max(0,t-this.spec.unquoted.length),Math.min(i+this.spec.unquoted.length,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}function nb(n,e,t){return(i,s,r)=>(!t||t(i,s,r))&&n(r[0],e,i,s)}function ai(n,e,t,i){let s;return n.wholeWord&&(s=sb(e.charCategorizer(e.selection.main.head))),n.test&&(s=nb(n.test,e,s)),new Du(e.doc,n.search,{ignoreCase:!n.caseSensitive,test:s},t,i)}function Ts(n,e){return n.slice(de(n,e,!1),e)}function Cs(n,e){return n.slice(e,de(n,e))}function sb(n){return(e,t,i)=>!i[0].length||(n(Ts(i.input,i.index))!=ee.Word||n(Cs(i.input,i.index))!=ee.Word)&&(n(Cs(i.input,i.index+i[0].length))!=ee.Word||n(Ts(i.input,i.index+i[0].length))!=ee.Word)}class rb extends zu{nextMatch(e,t,i){let s=ai(this.spec,e,i,e.doc.length).next();return s.done&&(s=ai(this.spec,e,0,t).next()),s.done?null:s.value}prevMatchInRange(e,t,i){for(let s=1;;s++){let r=Math.max(t,i-s*1e4),o=ai(this.spec,e,r,i),l=null;for(;!o.next().done;)l=o.value;if(l&&(r==t||l.from>r+10))return l;if(r==t)return null}}prevMatch(e,t,i){return this.prevMatchInRange(e,0,t)||this.prevMatchInRange(e,i,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g,(t,i)=>{if(i=="&")return e.match[0];if(i=="$")return"$";for(let s=i.length;s>0;s--){let r=+i.slice(0,s);if(r>0&&r=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=ai(this.spec,e,Math.max(0,t-250),Math.min(i+250,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}const un=z.define(),bl=z.define(),Rt=fe.define({create(n){return new Er(Xo(n).create(),null)},update(n,e){for(let t of e.effects)t.is(un)?n=new Er(t.value.create(),n.panel):t.is(bl)&&(n=new Er(n.query,t.value?Sl:null));return n},provide:n=>rn.from(n,e=>e.panel)});class Er{constructor(e,t){this.query=e,this.panel=t}}const ob=X.mark({class:"cm-searchMatch"}),lb=X.mark({class:"cm-searchMatch cm-searchMatch-selected"}),ab=ne.fromClass(class{constructor(n){this.view=n,this.decorations=this.highlight(n.state.field(Rt))}update(n){let e=n.state.field(Rt);(e!=n.startState.field(Rt)||n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=this.highlight(e))}highlight({query:n,panel:e}){if(!e||!n.spec.valid)return X.none;let{view:t}=this,i=new Qt;for(let s=0,r=t.visibleRanges,o=r.length;sr[s+1].from-500;)a=r[++s].to;n.highlight(t.state,l,a,(h,c)=>{let f=t.state.selection.ranges.some(u=>u.from==h&&u.to==c);i.add(h,c,f?lb:ob)})}return i.finish()}},{decorations:n=>n.decorations});function Sn(n){return e=>{let t=e.state.field(Rt,!1);return t&&t.query.spec.valid?n(e,t):_u(e)}}const Zs=Sn((n,{query:e})=>{let{to:t}=n.state.selection.main,i=e.nextMatch(n.state,t,t);if(!i)return!1;let s=b.single(i.from,i.to),r=n.state.facet(Ri);return n.dispatch({selection:s,effects:[xl(n,i),r.scrollToMatch(s.main,n)],userEvent:"select.search"}),Bu(n),!0}),As=Sn((n,{query:e})=>{let{state:t}=n,{from:i}=t.selection.main,s=e.prevMatch(t,i,i);if(!s)return!1;let r=b.single(s.from,s.to),o=n.state.facet(Ri);return n.dispatch({selection:r,effects:[xl(n,s),o.scrollToMatch(r.main,n)],userEvent:"select.search"}),Bu(n),!0}),hb=Sn((n,{query:e})=>{let t=e.matchAll(n.state,1e3);return!t||!t.length?!1:(n.dispatch({selection:b.create(t.map(i=>b.range(i.from,i.to))),userEvent:"select.search.matches"}),!0)}),cb=({state:n,dispatch:e})=>{let t=n.selection;if(t.ranges.length>1||t.main.empty)return!1;let{from:i,to:s}=t.main,r=[],o=0;for(let l=new Pi(n.doc,n.sliceDoc(i,s));!l.next().done;){if(r.length>1e3)return!1;l.value.from==i&&(o=r.length),r.push(b.range(l.value.from,l.value.to))}return e(n.update({selection:b.create(r,o),userEvent:"select.search.matches"})),!0},kh=Sn((n,{query:e})=>{let{state:t}=n,{from:i,to:s}=t.selection.main;if(t.readOnly)return!1;let r=e.nextMatch(t,i,i);if(!r)return!1;let o=r,l=[],a,h,c=[];o.precise?o.from==i&&o.to==s&&(h=t.toText(e.getReplacement(o)),l.push({from:o.from,to:o.to,insert:h}),o=e.nextMatch(t,o.from,o.to),c.push(T.announce.of(t.phrase("replaced match on line $",t.doc.lineAt(i).number)+"."))):o=e.nextMatch(t,o.from,o.to);let f=n.state.changes(l);return o&&(a=b.single(o.from,o.to).map(f),c.push(xl(n,o)),c.push(t.facet(Ri).scrollToMatch(a.main,n))),n.dispatch({changes:f,selection:a,effects:c,userEvent:"input.replace"}),!0}),fb=Sn((n,{query:e})=>{if(n.state.readOnly)return!1;let t=[];for(let s of e.matchAll(n.state,1e9)){let{from:r,to:o,precise:l}=s;l&&t.push({from:r,to:o,insert:e.getReplacement(s)})}if(!t.length)return!1;let i=n.state.phrase("replaced $ matches",t.length)+".";return n.dispatch({changes:t,effects:T.announce.of(i),userEvent:"input.replace.all"}),!0});function Sl(n){return n.state.facet(Ri).createPanel(n)}function Xo(n,e){var t,i,s,r,o;let l=n.selection.main,a=l.empty||l.to>l.from+100?"":n.sliceDoc(l.from,l.to);if(e&&!a)return e;let h=n.facet(Ri);return new Wu({search:((t=e?.literal)!==null&&t!==void 0?t:h.literal)?a:a.replace(/\n/g,"\\n"),caseSensitive:(i=e?.caseSensitive)!==null&&i!==void 0?i:h.caseSensitive,literal:(s=e?.literal)!==null&&s!==void 0?s:h.literal,regexp:(r=e?.regexp)!==null&&r!==void 0?r:h.regexp,wholeWord:(o=e?.wholeWord)!==null&&o!==void 0?o:h.wholeWord})}function qu(n){let e=rf(n,Sl);return e&&e.dom.querySelector("[main-field]")}function Bu(n){let e=qu(n);e&&e==n.root.activeElement&&e.select()}const _u=n=>{let e=n.state.field(Rt,!1);if(e&&e.panel){let t=qu(n);if(t&&t!=n.root.activeElement){let i=Xo(n.state,e.query.spec);i.valid&&n.dispatch({effects:un.of(i)}),t.focus(),t.select()}}else n.dispatch({effects:[bl.of(!0),e?un.of(Xo(n.state,e.query.spec)):z.appendConfig.of(Ob)]});return!0},Yu=n=>{let e=n.state.field(Rt,!1);if(!e||!e.panel)return!1;let t=rf(n,Sl);return t&&t.dom.contains(n.root.activeElement)&&n.focus(),n.dispatch({effects:bl.of(!1)}),!0},ub=[{key:"Mod-f",run:_u,scope:"editor search-panel"},{key:"F3",run:Zs,shift:As,scope:"editor search-panel",preventDefault:!0},{key:"Mod-g",run:Zs,shift:As,scope:"editor search-panel",preventDefault:!0},{key:"Escape",run:Yu,scope:"editor search-panel"},{key:"Mod-Shift-l",run:cb},{key:"Mod-Alt-g",run:_1},{key:"Mod-d",run:J1,preventDefault:!0}];class db{constructor(e){this.view=e;let t=this.query=e.state.field(Rt).query.spec;this.commit=this.commit.bind(this),this.searchField=U("input",{value:t.search,placeholder:We(e,"Find"),"aria-label":We(e,"Find"),class:"cm-textfield",name:"search",form:"","main-field":"true",onchange:this.commit,onkeyup:this.commit}),this.replaceField=U("input",{value:t.replace,placeholder:We(e,"Replace"),"aria-label":We(e,"Replace"),class:"cm-textfield",name:"replace",form:"",onchange:this.commit,onkeyup:this.commit}),this.caseField=U("input",{type:"checkbox",name:"case",form:"",checked:t.caseSensitive,onchange:this.commit}),this.reField=U("input",{type:"checkbox",name:"re",form:"",checked:t.regexp,onchange:this.commit}),this.wordField=U("input",{type:"checkbox",name:"word",form:"",checked:t.wholeWord,onchange:this.commit});function i(s,r,o){return U("button",{class:"cm-button",name:s,onclick:r,type:"button"},o)}this.dom=U("div",{onkeydown:s=>this.keydown(s),class:"cm-search"},[this.searchField,i("next",()=>Zs(e),[We(e,"next")]),i("prev",()=>As(e),[We(e,"previous")]),i("select",()=>hb(e),[We(e,"all")]),U("label",null,[this.caseField,We(e,"match case")]),U("label",null,[this.reField,We(e,"regexp")]),U("label",null,[this.wordField,We(e,"by word")]),...e.state.readOnly?[]:[U("br"),this.replaceField,i("replace",()=>kh(e),[We(e,"replace")]),i("replaceAll",()=>fb(e),[We(e,"replace all")])],U("button",{name:"close",onclick:()=>Yu(e),"aria-label":We(e,"close"),type:"button"},["×"])])}commit(){let e=new Wu({search:this.searchField.value,caseSensitive:this.caseField.checked,regexp:this.reField.checked,wholeWord:this.wordField.checked,replace:this.replaceField.value});e.eq(this.query)||(this.query=e,this.view.dispatch({effects:un.of(e)}))}keydown(e){wO(this.view,e,"search-panel")?e.preventDefault():e.keyCode==13&&e.target==this.searchField?(e.preventDefault(),(e.shiftKey?As:Zs)(this.view)):e.keyCode==13&&e.target==this.replaceField&&(e.preventDefault(),kh(this.view))}update(e){for(let t of e.transactions)for(let i of t.effects)i.is(un)&&!i.value.eq(this.query)&&this.setQuery(i.value)}setQuery(e){this.query=e,this.searchField.value=e.search,this.replaceField.value=e.replace,this.caseField.checked=e.caseSensitive,this.reField.checked=e.regexp,this.wordField.checked=e.wholeWord}mount(){this.searchField.select()}get pos(){return 80}get top(){return this.view.state.facet(Ri).top}}function We(n,e){return n.state.phrase(e)}const In=30,Vn=/[\s\.,:;?!]/;function xl(n,{from:e,to:t}){let i=n.state.doc.lineAt(e),s=n.state.doc.lineAt(t).to,r=Math.max(i.from,e-In),o=Math.min(s,t+In),l=n.state.sliceDoc(r,o);if(r!=i.from){for(let a=0;al.length-In;a--)if(!Vn.test(l[a-1])&&Vn.test(l[a])){l=l.slice(0,a);break}}return T.announce.of(`${n.state.phrase("current match")}. ${l} ${n.state.phrase("on line")} ${i.number}.`)}const pb=T.baseTheme({".cm-panel.cm-search":{padding:"2px 6px 4px",position:"relative","& [name=close]":{position:"absolute",top:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:0,margin:0},"& input, & button, & label":{margin:".2em .6em .2em 0"},"& input[type=checkbox]":{marginRight:".2em"},"& label":{fontSize:"80%",whiteSpace:"pre"}},"&light .cm-searchMatch":{backgroundColor:"#ffff0054"},"&dark .cm-searchMatch":{backgroundColor:"#00ffff8a"},"&light .cm-searchMatch-selected":{backgroundColor:"#ff6a0054"},"&dark .cm-searchMatch-selected":{backgroundColor:"#ff00ff8a"}}),Ob=[Rt,Bt.low(ab),pb];class Qh{constructor(e,t,i){this.from=e,this.to=t,this.diagnostic=i}}class jt{constructor(e,t,i){this.diagnostics=e,this.panel=t,this.selected=i}static init(e,t,i){let s=i.facet(Ot).markerFilter;s&&(e=s(e,i));let r=e.slice().sort((d,p)=>d.from-p.from||d.to-p.to),o=new Qt,l=[],a=0,h=i.doc.iter(),c=0,f=i.doc.length;for(let d=0;;){let p=d==r.length?null:r[d];if(!p&&!l.length)break;let O,m;if(l.length)O=a,m=l.reduce((x,Z)=>Math.min(x,Z.to),p&&p.from>O?p.from:1e8);else{if(O=p.from,O>f)break;m=p.to,l.push(p),d++}for(;dx.from||x.to==O))l.push(x),d++,m=Math.min(x.to,m);else{m=Math.min(x.from,m);break}}m=Math.min(m,f);let y=!1;if(l.some(x=>x.from==O&&(x.to==m||m==f))&&(y=O==m,!y&&m-O<10)){let x=O-(c+h.value.length);x>0&&(h.next(x),c=O);for(let Z=O;;){if(Z>=m){y=!0;break}if(!h.lineBreak&&c+h.value.length>Z)break;Z=c+h.value.length,c+=h.value.length,h.next()}}let w=Hu(l);if(y)o.add(O,O,X.widget({widget:new wb(w),diagnostics:l.slice()}));else{let x=l.reduce((Z,k)=>k.markClass?Z+" "+k.markClass:Z,"");o.add(O,m,X.mark({class:"cm-lintRange cm-lintRange-"+w+x,diagnostics:l.slice(),inclusiveEnd:l.some(Z=>Z.to>m)}))}if(a=m,a==f)break;for(let x=0;x{if(!(e&&o.diagnostics.indexOf(e)<0))if(!i)i=new Qh(s,r,e||o.diagnostics[0]);else{if(o.diagnostics.indexOf(i.diagnostic)<0)return!1;i=new Qh(i.from,r,i.diagnostic)}}),i}function Iu(n,e){let t=e.pos,i=e.end||t,s=n.state.facet(Ot).hideOn(n,t,i);if(s!=null)return s;let r=n.startState.doc.lineAt(e.pos);return!!(n.effects.some(o=>o.is(er))||n.changes.touchesRange(r.from,Math.max(r.to,i)))}function mb(n,e){return n.field(Ke,!1)?e:e.concat(z.appendConfig.of(ed))}function Vu(n,e){return{effects:mb(n,[er.of(e)])}}const er=z.define(),ju=z.define(),Nu=z.define(),Ke=fe.define({create(){return new jt(X.none,null,null)},update(n,e){if(e.docChanged&&n.diagnostics.size){let t=n.diagnostics.map(e.changes),i=null,s=n.panel;if(n.selected){let r=e.changes.mapPos(n.selected.from,1);i=Ti(t,n.selected.diagnostic,r)||Ti(t,null,r)}!t.size&&s&&e.state.facet(Ot).autoPanel&&(s=null),n=new jt(t,s,i)}for(let t of e.effects)if(t.is(er)){let i=e.state.facet(Ot).autoPanel?t.value.length?Ms.open:null:n.panel;n=jt.init(t.value,i,e.state)}else t.is(ju)?n=new jt(n.diagnostics,t.value?Ms.open:null,n.selected):t.is(Nu)&&(n=new jt(n.diagnostics,n.panel,t.value));return n},provide:n=>[rn.from(n,e=>e.panel),T.decorations.from(n,e=>e.diagnostics)]}),gb=X.mark({class:"cm-lintRange cm-lintRange-active"});function yb(n,e,t){let{diagnostics:i}=n.state.field(Ke),s,r=-1,o=-1;i.between(e-(t<0?1:0),e+(t>0?1:0),(a,h,{spec:c})=>{if(e>=a&&e<=h&&(a==h||(e>a||t>0)&&(eFu(n,t,!1)))}const vh=n=>{let e=n.state.field(Ke,!1);return!e||!e.panel?!1:(n.dispatch({effects:ju.of(!1)}),!0)},bb=ne.fromClass(class{constructor(n){this.view=n,this.timeout=-1,this.set=!0;let{delay:e}=n.state.facet(Ot);this.lintTime=Date.now()+e,this.run=this.run.bind(this),this.timeout=setTimeout(this.run,e)}run(){clearTimeout(this.timeout);let n=Date.now();if(nPromise.resolve(i(this.view))),i=>{this.view.state.doc==e.doc&&this.view.dispatch(Vu(this.view.state,i.reduce((s,r)=>s.concat(r))))},i=>{ve(this.view.state,i)})}}update(n){let e=n.state.facet(Ot);(n.docChanged||e!=n.startState.facet(Ot)||e.needsRefresh&&e.needsRefresh(n))&&(this.lintTime=Date.now()+e.delay,this.set||(this.set=!0,this.timeout=setTimeout(this.run,e.delay)))}force(){this.set&&(this.lintTime=Date.now(),this.run())}destroy(){clearTimeout(this.timeout)}});function Sb(n,e,t){let i=[],s=-1;for(let r of n)r.then(o=>{i.push(o),clearTimeout(s),i.length==n.length?e(i):s=setTimeout(()=>e(i),200)},t)}const Ot=C.define({combine(n){return{sources:n.map(e=>e.source).filter(e=>e!=null),...et(n.map(e=>e.config),{delay:750,markerFilter:null,tooltipFilter:null,needsRefresh:null,hideOn:()=>null},{delay:Math.max,markerFilter:$h,tooltipFilter:$h,needsRefresh:(e,t)=>e?t?i=>e(i)||t(i):e:t,hideOn:(e,t)=>e?t?(i,s,r)=>e(i,s,r)||t(i,s,r):e:t,autoPanel:(e,t)=>e||t})}}});function $h(n,e){return n?e?(t,i)=>e(n(t,i),i):n:e}function xb(n,e={}){return[Ot.of({source:n,config:e}),bb,ed]}function Uu(n){let e=[];if(n)e:for(let{name:t}of n){for(let i=0;ir.toLowerCase()==s.toLowerCase())){e.push(s);continue e}}e.push("")}return e}function Fu(n,e,t){var i;let s=t?Uu(e.actions):[];return U("li",{class:"cm-diagnostic cm-diagnostic-"+e.severity},U("span",{class:"cm-diagnosticText"},e.renderMessage?e.renderMessage(n):e.message),(i=e.actions)===null||i===void 0?void 0:i.map((r,o)=>{let l=!1,a=d=>{if(d.preventDefault(),l)return;l=!0;let p=Ti(n.state.field(Ke).diagnostics,e);p&&r.apply(n,p.from,p.to)},{name:h}=r,c=s[o]?h.indexOf(s[o]):-1,f=c<0?h:[h.slice(0,c),U("u",h.slice(c,c+1)),h.slice(c+1)],u=r.markClass?" "+r.markClass:"";return U("button",{type:"button",class:"cm-diagnosticAction"+u,onclick:a,onmousedown:a,"aria-label":` Action: ${h}${c<0?"":` (access key "${s[o]})"`}.`},f)}),e.source&&U("div",{class:"cm-diagnosticSource"},e.source))}class wb extends yt{constructor(e){super(),this.sev=e}eq(e){return e.sev==this.sev}toDOM(){return U("span",{class:"cm-lintPoint cm-lintPoint-"+this.sev})}}class Ph{constructor(e,t){this.diagnostic=t,this.id="item_"+Math.floor(Math.random()*4294967295).toString(16),this.dom=Fu(e,t,!0),this.dom.id=this.id,this.dom.setAttribute("role","option")}}class Ms{constructor(e){this.view=e,this.items=[];let t=s=>{if(!(s.ctrlKey||s.altKey||s.metaKey)){if(s.keyCode==27)vh(this.view),this.view.focus();else if(s.keyCode==38||s.keyCode==33)this.moveSelection((this.selectedIndex-1+this.items.length)%this.items.length);else if(s.keyCode==40||s.keyCode==34)this.moveSelection((this.selectedIndex+1)%this.items.length);else if(s.keyCode==36)this.moveSelection(0);else if(s.keyCode==35)this.moveSelection(this.items.length-1);else if(s.keyCode==13)this.view.focus();else if(s.keyCode>=65&&s.keyCode<=90&&this.selectedIndex>=0){let{diagnostic:r}=this.items[this.selectedIndex],o=Uu(r.actions);for(let l=0;l{for(let r=0;rvh(this.view)},"×")),this.update()}get selectedIndex(){let e=this.view.state.field(Ke).selected;if(!e)return-1;for(let t=0;t{for(let c of h.diagnostics){if(o.has(c))continue;o.add(c);let f=-1,u;for(let d=i;di&&(this.items.splice(i,f-i),s=!0)),t&&u.diagnostic==t.diagnostic?u.dom.hasAttribute("aria-selected")||(u.dom.setAttribute("aria-selected","true"),r=u):u.dom.hasAttribute("aria-selected")&&u.dom.removeAttribute("aria-selected"),i++}});i({sel:r.dom.getBoundingClientRect(),panel:this.list.getBoundingClientRect()}),write:({sel:l,panel:a})=>{let h=a.height/this.list.offsetHeight;l.topa.bottom&&(this.list.scrollTop+=(l.bottom-a.bottom)/h)}})):this.selectedIndex<0&&this.list.removeAttribute("aria-activedescendant"),s&&this.sync()}sync(){let e=this.list.firstChild;function t(){let i=e;e=i.nextSibling,i.remove()}for(let i of this.items)if(i.dom.parentNode==this.list){for(;e!=i.dom;)t();e=i.dom.nextSibling}else this.list.insertBefore(i.dom,e);for(;e;)t()}moveSelection(e){if(this.selectedIndex<0)return;let t=this.view.state.field(Ke),i=Ti(t.diagnostics,this.items[e].diagnostic);i&&this.view.dispatch({selection:{anchor:i.from,head:i.to},scrollIntoView:!0,effects:Nu.of(i)})}static open(e){return new Ms(e)}}function is(n,e='viewBox="0 0 40 40"'){return`url('data:image/svg+xml,${encodeURIComponent(n)}')`}function jn(n){return is(``,'width="6" height="3"')}const kb=T.baseTheme({".cm-diagnostic":{padding:"3px 6px 3px 8px",marginLeft:"-1px",display:"block",whiteSpace:"pre-wrap"},".cm-diagnostic-error":{borderLeft:"5px solid #d11"},".cm-diagnostic-warning":{borderLeft:"5px solid orange"},".cm-diagnostic-info":{borderLeft:"5px solid #999"},".cm-diagnostic-hint":{borderLeft:"5px solid #66d"},".cm-diagnosticAction":{font:"inherit",border:"none",padding:"2px 4px",backgroundColor:"#444",color:"white",borderRadius:"3px",marginLeft:"8px",cursor:"pointer"},".cm-diagnosticSource":{fontSize:"70%",opacity:.7},".cm-lintRange":{backgroundPosition:"left bottom",backgroundRepeat:"repeat-x",paddingBottom:"0.7px"},".cm-lintRange-error":{backgroundImage:jn("#f11")},".cm-lintRange-warning":{backgroundImage:jn("orange")},".cm-lintRange-info":{backgroundImage:jn("#999")},".cm-lintRange-hint":{backgroundImage:jn("#66d")},".cm-lintRange-active":{backgroundColor:"#ffdd9980"},".cm-tooltip-lint":{padding:0,margin:0},".cm-lintPoint":{position:"relative","&:after":{content:'""',position:"absolute",bottom:0,left:"-2px",borderLeft:"3px solid transparent",borderRight:"3px solid transparent",borderBottom:"4px solid #d11"}},".cm-lintPoint-warning":{"&:after":{borderBottomColor:"orange"}},".cm-lintPoint-info":{"&:after":{borderBottomColor:"#999"}},".cm-lintPoint-hint":{"&:after":{borderBottomColor:"#66d"}},".cm-panel.cm-panel-lint":{position:"relative","& ul":{maxHeight:"100px",overflowY:"auto","& [aria-selected]":{backgroundColor:"#ddd","& u":{textDecoration:"underline"}},"&:focus [aria-selected]":{background_fallback:"#bdf",backgroundColor:"Highlight",color_fallback:"white",color:"HighlightText"},"& u":{textDecoration:"none"},padding:0,margin:0},"& [name=close]":{position:"absolute",top:"0",right:"2px",background:"inherit",border:"none",font:"inherit",padding:0,margin:0}},"&dark .cm-lintRange-active":{backgroundColor:"#86714a80"},"&dark .cm-panel.cm-panel-lint ul":{"& [aria-selected]":{backgroundColor:"#2e343e"}}});function Qb(n){return n=="error"?4:n=="warning"?3:n=="info"?2:1}function Hu(n){let e="hint",t=1;for(let i of n){let s=Qb(i.severity);s>t&&(t=s,e=i.severity)}return e}class Ku extends gt{constructor(e){super(),this.diagnostics=e,this.severity=Hu(e)}toDOM(e){let t=document.createElement("div");t.className="cm-lint-marker cm-lint-marker-"+this.severity;let i=this.diagnostics,s=e.state.facet(tr).tooltipFilter;return s&&(i=s(i,e.state)),i.length&&(t.onmouseover=()=>$b(e,t,i)),t}}function vb(n,e){let t=i=>{let s=e.getBoundingClientRect();if(!(i.clientX>s.left-10&&i.clientXs.top-10&&i.clientYe.getBoundingClientRect()}}})}),e.onmouseout=e.onmousemove=null,vb(n,e)}let{hoverTime:s}=n.state.facet(tr),r=setTimeout(i,s);e.onmouseout=()=>{clearTimeout(r),e.onmouseout=e.onmousemove=null},e.onmousemove=()=>{clearTimeout(r),r=setTimeout(i,s)}}function Pb(n,e){let t=Object.create(null);for(let s of e){let r=n.lineAt(s.from);(t[r.from]||(t[r.from]=[])).push(s)}let i=[];for(let s in t)i.push(new Ku(t[s]).range(+s));return B.of(i,!0)}const Tb=hf({class:"cm-gutter-lint",markers:n=>n.state.field(Lo),widgetMarker:(n,e,t)=>{let i=[];return n.state.field(Lo).between(t.from,t.to,(s,r,o)=>{s>t.from&&si.is(wl)?i.value:t,n)},provide:n=>Ys.from(n)}),Cb=T.baseTheme({".cm-gutter-lint":{width:"1.4em","& .cm-gutterElement":{padding:".2em"}},".cm-lint-marker":{width:"1em",height:"1em"},".cm-lint-marker-info":{content:is('')},".cm-lint-marker-warning":{content:is('')},".cm-lint-marker-error":{content:is('')}}),Zb=nf(yb,{hideOn:Iu}),ed=[Ke,T.decorations.compute([Ke],n=>{let{selected:e,panel:t}=n.field(Ke);return!e||!t||e.from==e.to?X.none:X.set([gb.range(e.from,e.to)])}),Zb,kb],tr=C.define({combine(n){return et(n,{hoverTime:300,markerFilter:null,tooltipFilter:null})}});function Ab(n={}){return[tr.of(n),Lo,Tb,Cb,Ju]}const td=1,_e=Object.freeze({ready:"studio.ready",documentOpen:"document.open",documentReplace:"document.replace",documentChanged:"document.changed",documentSave:"document.save",documentSetReadOnly:"document.setReadOnly",editorInsert:"editor.insert",editorFormat:"editor.format",editorSetTheme:"editor.setTheme",editorGetState:"editor.getState",diagnosticsPublish:"diagnostics.publish"});function Mb(n,e={},t=null){return{protocolVersion:td,type:n,documentID:t,payload:e}}function Rb(n){if(window.WKWebViewJavascriptBridge){n(window.WKWebViewJavascriptBridge);return}if(window.WKWVJBCallbacks){window.WKWVJBCallbacks.push(n);return}window.webkit?.messageHandlers?.iOS_Native_InjectJavascript&&(window.WKWVJBCallbacks=[n],window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null))}function ir(n,e,t={},i=null,s=()=>{}){if(!n){s({result:"unavailable"});return}n.callHandler(e,Mb(e,t,i),s)}function Xb(n){const e={capabilities:["jsx","format","search","completion","diagnostics"]};ir(n,_e.ready,e)}const kt={globalProperties:{background:{type:"color",documentation:"Background color, hex value, or named color."},color:{type:"color",documentation:"Foreground color, hex value, or named color."},font:{type:"enum",values:["largeTitle","title","title2","title3","headline","subheadline","body","callout","footnote","caption","caption2"],documentation:"Semantic text style."},fontWeight:{type:"enum",values:["ultraLight","thin","light","regular","medium","semibold","bold","heavy","black"],documentation:"Font weight."},fontDesign:{type:"enum",values:["default","rounded","serif","monospaced"],documentation:"Font design."},frame:{type:"number|string",documentation:"Size or frame description."},padding:{type:"number|string",documentation:"Padding amount or edge description."},corner:{type:"number",documentation:"Corner radius."},opacity:{type:"number",documentation:"Opacity from 0 through 1."},alignment:{type:"enum",values:["center","leading","trailing","top","bottom","topLeading","topTrailing","bottomLeading","bottomTrailing","firstTextBaseline","lastTextBaseline"],documentation:"Layout alignment."},clip:{type:"enum",values:["circle","rect","capsule","ellipse"],documentation:"Clip the view to a shape."},rotation:{type:"number",documentation:"Rotation in degrees."},rotation3d:{type:"string",documentation:"3D rotation description."},shadow:{type:"string",documentation:"Shadow color, radius, and offset description."},animation:{type:"string",documentation:"Timeline-driven animation description."},widgetAccentable:{type:"boolean",documentation:"Group this view into the accent layer in tinted and vibrant widget appearances."},linkurl:{type:"url",documentation:"Widget deep link URL."}},components:{VStack:{documentation:"Arrange children vertically.",children:!0,properties:{spacing:{type:"number"}}},HStack:{documentation:"Arrange children horizontally.",children:!0,properties:{spacing:{type:"number"}}},ZStack:{documentation:"Overlay children.",children:!0,properties:{}},VGrid:{documentation:"Vertical lazy grid.",children:!0,properties:{columns:{type:"string",required:!0},spacing:{type:"number"},alignment:{type:"enum",values:["leading","center","trailing"]}}},HGrid:{documentation:"Horizontal lazy grid.",children:!0,properties:{columns:{type:"string",required:!0},spacing:{type:"number"},alignment:{type:"enum",values:["top","center","bottom","firstTextBaseline","lastTextBaseline"]}}},Text:{documentation:"Display text content.",children:!1,properties:{text:{type:"string"}}},Date:{documentation:"Display a formatted date.",children:!1,properties:{date:{type:"date|number",required:!0},style:{type:"enum",values:["time","date","relative","offset","timer"]}}},Image:{documentation:"Display a bundled, remote, or SF Symbol image.",children:!1,properties:{systemName:{type:"string"},name:{type:"string"},id:{type:"string",deprecated:"Use name."},url:{type:"url"},src:{type:"url",deprecated:"Use url."},ratio:{type:"number"},mode:{type:"enum",values:["fit","fill"]},accentedRenderingMode:{type:"enum",values:["accented","desaturated","accentedDesaturated","fullColor"],documentation:"Control how the image is rendered in tinted and clear widget appearances."}}},Gif:{documentation:"Display a GIF from the package.",children:!1,properties:{file:{type:"string",required:!0}}},Spacer:{documentation:"Flexible layout space.",children:!1,properties:{minLength:{type:"number"}}},Rect:{documentation:"Rectangle shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},RoundedRect:{documentation:"Filled rounded rectangle.",children:!1,properties:{radius:{type:"number"}}},Capsule:{documentation:"Capsule shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Ellipse:{documentation:"Ellipse shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Circle:{documentation:"Circle shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Gauge:{documentation:"Display a gauge or instrument.",children:!1,properties:{type:{type:"string"},value:{type:"number"},style:{type:"enum",values:["circular","linear"]},text:{type:"string"},current:{type:"string"},min:{type:"string"},max:{type:"string"},angle:{type:"number"},thickness:{type:"number"},needleColor:{type:"color"},label:{type:"string"},title:{type:"string"},sections:{type:"string"}}},Chart:{documentation:"Render chart data.",children:!1,availability:{ios:"16.0",macos:"26.0"},properties:{type:{type:"enum",values:["bar","bar-x","bar-y","bar-gantt","line","point","line-point","area","rect","rule-x"]},data:{type:"json",required:!0},category:{type:"boolean"},hideLegend:{type:"boolean"},hideXAxis:{type:"boolean"},hideYAxis:{type:"boolean"}}},Link:{documentation:"Open a URL when selected.",children:!0,properties:{url:{type:"url",required:!0}}},Divider:{documentation:"Horizontal or vertical separator.",children:!1,properties:{thickness:{type:"number"},axis:{type:"enum",values:["horizontal","vertical"]}}},Line:{documentation:"Fixed-length line.",children:!1,properties:{thickness:{type:"number"},length:{type:"number"},axis:{type:"enum",values:["horizontal","vertical"]}}},Icon:{documentation:"SF Symbol icon.",children:!1,properties:{systemName:{type:"string",required:!0},size:{type:"number"}}},Label:{documentation:"Text paired with an SF Symbol.",children:!1,properties:{title:{type:"string"},systemName:{type:"string",required:!0}}},Progress:{documentation:"Linear or circular progress.",children:!1,properties:{value:{type:"number",required:!0},total:{type:"number"},label:{type:"string"},style:{type:"enum",values:["linear","circular"]},trackColor:{type:"color"},thickness:{type:"number"}}},Ring:{documentation:"Circular progress ring.",children:!1,properties:{value:{type:"number",required:!0},thickness:{type:"number"},trackColor:{type:"color"}}},Badge:{documentation:"Compact status badge.",children:!1,properties:{text:{type:"string"},radius:{type:"number"}}},Chip:{documentation:"Outlined metadata chip.",children:!1,properties:{text:{type:"string"},radius:{type:"number"},borderColor:{type:"color"}}},Stat:{documentation:"Title, value, and subtitle statistic.",children:!1,properties:{title:{type:"string"},value:{type:"string",required:!0},subtitle:{type:"string"},mutedColor:{type:"color"}}},Button:{documentation:"Interactive widget button. Use actionID to share a declared Package 2.0 action with Siri, Shortcuts, and Control Widgets.",children:!0,availability:{interactiveIos:"17.0"},requiredAny:["action","onClick","actionID"],properties:{action:{type:"enum",values:["reload"],conflicts:["actionID"]},onClick:{type:"function",conflicts:["actionID"]},actionID:{type:"action-id",conflicts:["action","onClick"]}}},Toggle:{documentation:"Interactive widget toggle. A declared actionID requires a package-relative storage stateKey.",children:!0,availability:{interactiveIos:"17.0"},requiredAny:["onClick","actionID"],properties:{on:{type:"boolean",required:!0},onClick:{type:"function",conflicts:["actionID"]},actionID:{type:"action-id",requires:["stateKey"],conflicts:["onClick"]},stateKey:{type:"storage-key",requires:["actionID"]}}}}};function Lb(n,e){const t=Object.entries(e.properties??{}).filter(([,s])=>s.required).map(([s,r])=>`${s}=${r.type.includes("number")||r.type==="boolean"?"{${}}":'"${}"'}`).join(" "),i=t?` ${t}`:"";return e.children?`<${n}${i}> +`:i=="r"?"\r":i=="t"?" ":"\\")}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord&&this.test==e.test}create(){return this.regexp?new rb(this):new ib(this)}getCursor(e,t=0,i){let s=e.doc?e:I.create({doc:e});return i==null&&(i=s.doc.length),this.regexp?ai(this,s,t,i):li(this,s,t,i)}}class zu{constructor(e){this.spec=e}}function eb(n,e,t){return(i,s,r,o)=>{if(t&&!t(i,s,r,o))return!1;let l=i>=o&&s<=o+r.length?r.slice(i-o,s-o):e.doc.sliceString(i,s);return n(l,e,i,s)}}function li(n,e,t,i){let s;return n.wholeWord&&(s=tb(e.doc,e.charCategorizer(e.selection.main.head))),n.test&&(s=eb(n.test,e,s)),new Pi(e.doc,n.unquoted,t,i,n.caseSensitive?void 0:r=>r.toLowerCase(),s)}function tb(n,e){return(t,i,s,r)=>((r>t||r+s.length=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=li(this.spec,e,Math.max(0,t-this.spec.unquoted.length),Math.min(i+this.spec.unquoted.length,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}function nb(n,e,t){return(i,s,r)=>(!t||t(i,s,r))&&n(r[0],e,i,s)}function ai(n,e,t,i){let s;return n.wholeWord&&(s=sb(e.charCategorizer(e.selection.main.head))),n.test&&(s=nb(n.test,e,s)),new Du(e.doc,n.search,{ignoreCase:!n.caseSensitive,test:s},t,i)}function Ts(n,e){return n.slice(de(n,e,!1),e)}function Cs(n,e){return n.slice(e,de(n,e))}function sb(n){return(e,t,i)=>!i[0].length||(n(Ts(i.input,i.index))!=ee.Word||n(Cs(i.input,i.index))!=ee.Word)&&(n(Cs(i.input,i.index+i[0].length))!=ee.Word||n(Ts(i.input,i.index+i[0].length))!=ee.Word)}class rb extends zu{nextMatch(e,t,i){let s=ai(this.spec,e,i,e.doc.length).next();return s.done&&(s=ai(this.spec,e,0,t).next()),s.done?null:s.value}prevMatchInRange(e,t,i){for(let s=1;;s++){let r=Math.max(t,i-s*1e4),o=ai(this.spec,e,r,i),l=null;for(;!o.next().done;)l=o.value;if(l&&(r==t||l.from>r+10))return l;if(r==t)return null}}prevMatch(e,t,i){return this.prevMatchInRange(e,0,t)||this.prevMatchInRange(e,i,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g,(t,i)=>{if(i=="&")return e.match[0];if(i=="$")return"$";for(let s=i.length;s>0;s--){let r=+i.slice(0,s);if(r>0&&r=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=ai(this.spec,e,Math.max(0,t-250),Math.min(i+250,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}const un=z.define(),bl=z.define(),Rt=fe.define({create(n){return new Er(Xo(n).create(),null)},update(n,e){for(let t of e.effects)t.is(un)?n=new Er(t.value.create(),n.panel):t.is(bl)&&(n=new Er(n.query,t.value?Sl:null));return n},provide:n=>rn.from(n,e=>e.panel)});class Er{constructor(e,t){this.query=e,this.panel=t}}const ob=X.mark({class:"cm-searchMatch"}),lb=X.mark({class:"cm-searchMatch cm-searchMatch-selected"}),ab=ne.fromClass(class{constructor(n){this.view=n,this.decorations=this.highlight(n.state.field(Rt))}update(n){let e=n.state.field(Rt);(e!=n.startState.field(Rt)||n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=this.highlight(e))}highlight({query:n,panel:e}){if(!e||!n.spec.valid)return X.none;let{view:t}=this,i=new Qt;for(let s=0,r=t.visibleRanges,o=r.length;sr[s+1].from-500;)a=r[++s].to;n.highlight(t.state,l,a,(h,c)=>{let f=t.state.selection.ranges.some(u=>u.from==h&&u.to==c);i.add(h,c,f?lb:ob)})}return i.finish()}},{decorations:n=>n.decorations});function Sn(n){return e=>{let t=e.state.field(Rt,!1);return t&&t.query.spec.valid?n(e,t):_u(e)}}const Zs=Sn((n,{query:e})=>{let{to:t}=n.state.selection.main,i=e.nextMatch(n.state,t,t);if(!i)return!1;let s=b.single(i.from,i.to),r=n.state.facet(Ri);return n.dispatch({selection:s,effects:[xl(n,i),r.scrollToMatch(s.main,n)],userEvent:"select.search"}),Bu(n),!0}),As=Sn((n,{query:e})=>{let{state:t}=n,{from:i}=t.selection.main,s=e.prevMatch(t,i,i);if(!s)return!1;let r=b.single(s.from,s.to),o=n.state.facet(Ri);return n.dispatch({selection:r,effects:[xl(n,s),o.scrollToMatch(r.main,n)],userEvent:"select.search"}),Bu(n),!0}),hb=Sn((n,{query:e})=>{let t=e.matchAll(n.state,1e3);return!t||!t.length?!1:(n.dispatch({selection:b.create(t.map(i=>b.range(i.from,i.to))),userEvent:"select.search.matches"}),!0)}),cb=({state:n,dispatch:e})=>{let t=n.selection;if(t.ranges.length>1||t.main.empty)return!1;let{from:i,to:s}=t.main,r=[],o=0;for(let l=new Pi(n.doc,n.sliceDoc(i,s));!l.next().done;){if(r.length>1e3)return!1;l.value.from==i&&(o=r.length),r.push(b.range(l.value.from,l.value.to))}return e(n.update({selection:b.create(r,o),userEvent:"select.search.matches"})),!0},kh=Sn((n,{query:e})=>{let{state:t}=n,{from:i,to:s}=t.selection.main;if(t.readOnly)return!1;let r=e.nextMatch(t,i,i);if(!r)return!1;let o=r,l=[],a,h,c=[];o.precise?o.from==i&&o.to==s&&(h=t.toText(e.getReplacement(o)),l.push({from:o.from,to:o.to,insert:h}),o=e.nextMatch(t,o.from,o.to),c.push(T.announce.of(t.phrase("replaced match on line $",t.doc.lineAt(i).number)+"."))):o=e.nextMatch(t,o.from,o.to);let f=n.state.changes(l);return o&&(a=b.single(o.from,o.to).map(f),c.push(xl(n,o)),c.push(t.facet(Ri).scrollToMatch(a.main,n))),n.dispatch({changes:f,selection:a,effects:c,userEvent:"input.replace"}),!0}),fb=Sn((n,{query:e})=>{if(n.state.readOnly)return!1;let t=[];for(let s of e.matchAll(n.state,1e9)){let{from:r,to:o,precise:l}=s;l&&t.push({from:r,to:o,insert:e.getReplacement(s)})}if(!t.length)return!1;let i=n.state.phrase("replaced $ matches",t.length)+".";return n.dispatch({changes:t,effects:T.announce.of(i),userEvent:"input.replace.all"}),!0});function Sl(n){return n.state.facet(Ri).createPanel(n)}function Xo(n,e){var t,i,s,r,o;let l=n.selection.main,a=l.empty||l.to>l.from+100?"":n.sliceDoc(l.from,l.to);if(e&&!a)return e;let h=n.facet(Ri);return new Wu({search:((t=e?.literal)!==null&&t!==void 0?t:h.literal)?a:a.replace(/\n/g,"\\n"),caseSensitive:(i=e?.caseSensitive)!==null&&i!==void 0?i:h.caseSensitive,literal:(s=e?.literal)!==null&&s!==void 0?s:h.literal,regexp:(r=e?.regexp)!==null&&r!==void 0?r:h.regexp,wholeWord:(o=e?.wholeWord)!==null&&o!==void 0?o:h.wholeWord})}function qu(n){let e=rf(n,Sl);return e&&e.dom.querySelector("[main-field]")}function Bu(n){let e=qu(n);e&&e==n.root.activeElement&&e.select()}const _u=n=>{let e=n.state.field(Rt,!1);if(e&&e.panel){let t=qu(n);if(t&&t!=n.root.activeElement){let i=Xo(n.state,e.query.spec);i.valid&&n.dispatch({effects:un.of(i)}),t.focus(),t.select()}}else n.dispatch({effects:[bl.of(!0),e?un.of(Xo(n.state,e.query.spec)):z.appendConfig.of(Ob)]});return!0},Yu=n=>{let e=n.state.field(Rt,!1);if(!e||!e.panel)return!1;let t=rf(n,Sl);return t&&t.dom.contains(n.root.activeElement)&&n.focus(),n.dispatch({effects:bl.of(!1)}),!0},ub=[{key:"Mod-f",run:_u,scope:"editor search-panel"},{key:"F3",run:Zs,shift:As,scope:"editor search-panel",preventDefault:!0},{key:"Mod-g",run:Zs,shift:As,scope:"editor search-panel",preventDefault:!0},{key:"Escape",run:Yu,scope:"editor search-panel"},{key:"Mod-Shift-l",run:cb},{key:"Mod-Alt-g",run:_1},{key:"Mod-d",run:J1,preventDefault:!0}];class db{constructor(e){this.view=e;let t=this.query=e.state.field(Rt).query.spec;this.commit=this.commit.bind(this),this.searchField=U("input",{value:t.search,placeholder:We(e,"Find"),"aria-label":We(e,"Find"),class:"cm-textfield",name:"search",form:"","main-field":"true",onchange:this.commit,onkeyup:this.commit}),this.replaceField=U("input",{value:t.replace,placeholder:We(e,"Replace"),"aria-label":We(e,"Replace"),class:"cm-textfield",name:"replace",form:"",onchange:this.commit,onkeyup:this.commit}),this.caseField=U("input",{type:"checkbox",name:"case",form:"",checked:t.caseSensitive,onchange:this.commit}),this.reField=U("input",{type:"checkbox",name:"re",form:"",checked:t.regexp,onchange:this.commit}),this.wordField=U("input",{type:"checkbox",name:"word",form:"",checked:t.wholeWord,onchange:this.commit});function i(s,r,o){return U("button",{class:"cm-button",name:s,onclick:r,type:"button"},o)}this.dom=U("div",{onkeydown:s=>this.keydown(s),class:"cm-search"},[this.searchField,i("next",()=>Zs(e),[We(e,"next")]),i("prev",()=>As(e),[We(e,"previous")]),i("select",()=>hb(e),[We(e,"all")]),U("label",null,[this.caseField,We(e,"match case")]),U("label",null,[this.reField,We(e,"regexp")]),U("label",null,[this.wordField,We(e,"by word")]),...e.state.readOnly?[]:[U("br"),this.replaceField,i("replace",()=>kh(e),[We(e,"replace")]),i("replaceAll",()=>fb(e),[We(e,"replace all")])],U("button",{name:"close",onclick:()=>Yu(e),"aria-label":We(e,"close"),type:"button"},["×"])])}commit(){let e=new Wu({search:this.searchField.value,caseSensitive:this.caseField.checked,regexp:this.reField.checked,wholeWord:this.wordField.checked,replace:this.replaceField.value});e.eq(this.query)||(this.query=e,this.view.dispatch({effects:un.of(e)}))}keydown(e){wO(this.view,e,"search-panel")?e.preventDefault():e.keyCode==13&&e.target==this.searchField?(e.preventDefault(),(e.shiftKey?As:Zs)(this.view)):e.keyCode==13&&e.target==this.replaceField&&(e.preventDefault(),kh(this.view))}update(e){for(let t of e.transactions)for(let i of t.effects)i.is(un)&&!i.value.eq(this.query)&&this.setQuery(i.value)}setQuery(e){this.query=e,this.searchField.value=e.search,this.replaceField.value=e.replace,this.caseField.checked=e.caseSensitive,this.reField.checked=e.regexp,this.wordField.checked=e.wholeWord}mount(){this.searchField.select()}get pos(){return 80}get top(){return this.view.state.facet(Ri).top}}function We(n,e){return n.state.phrase(e)}const In=30,Vn=/[\s\.,:;?!]/;function xl(n,{from:e,to:t}){let i=n.state.doc.lineAt(e),s=n.state.doc.lineAt(t).to,r=Math.max(i.from,e-In),o=Math.min(s,t+In),l=n.state.sliceDoc(r,o);if(r!=i.from){for(let a=0;al.length-In;a--)if(!Vn.test(l[a-1])&&Vn.test(l[a])){l=l.slice(0,a);break}}return T.announce.of(`${n.state.phrase("current match")}. ${l} ${n.state.phrase("on line")} ${i.number}.`)}const pb=T.baseTheme({".cm-panel.cm-search":{padding:"2px 6px 4px",position:"relative","& [name=close]":{position:"absolute",top:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:0,margin:0},"& input, & button, & label":{margin:".2em .6em .2em 0"},"& input[type=checkbox]":{marginRight:".2em"},"& label":{fontSize:"80%",whiteSpace:"pre"}},"&light .cm-searchMatch":{backgroundColor:"#ffff0054"},"&dark .cm-searchMatch":{backgroundColor:"#00ffff8a"},"&light .cm-searchMatch-selected":{backgroundColor:"#ff6a0054"},"&dark .cm-searchMatch-selected":{backgroundColor:"#ff00ff8a"}}),Ob=[Rt,Bt.low(ab),pb];class Qh{constructor(e,t,i){this.from=e,this.to=t,this.diagnostic=i}}class jt{constructor(e,t,i){this.diagnostics=e,this.panel=t,this.selected=i}static init(e,t,i){let s=i.facet(Ot).markerFilter;s&&(e=s(e,i));let r=e.slice().sort((d,p)=>d.from-p.from||d.to-p.to),o=new Qt,l=[],a=0,h=i.doc.iter(),c=0,f=i.doc.length;for(let d=0;;){let p=d==r.length?null:r[d];if(!p&&!l.length)break;let O,m;if(l.length)O=a,m=l.reduce((x,Z)=>Math.min(x,Z.to),p&&p.from>O?p.from:1e8);else{if(O=p.from,O>f)break;m=p.to,l.push(p),d++}for(;dx.from||x.to==O))l.push(x),d++,m=Math.min(x.to,m);else{m=Math.min(x.from,m);break}}m=Math.min(m,f);let y=!1;if(l.some(x=>x.from==O&&(x.to==m||m==f))&&(y=O==m,!y&&m-O<10)){let x=O-(c+h.value.length);x>0&&(h.next(x),c=O);for(let Z=O;;){if(Z>=m){y=!0;break}if(!h.lineBreak&&c+h.value.length>Z)break;Z=c+h.value.length,c+=h.value.length,h.next()}}let w=Hu(l);if(y)o.add(O,O,X.widget({widget:new wb(w),diagnostics:l.slice()}));else{let x=l.reduce((Z,k)=>k.markClass?Z+" "+k.markClass:Z,"");o.add(O,m,X.mark({class:"cm-lintRange cm-lintRange-"+w+x,diagnostics:l.slice(),inclusiveEnd:l.some(Z=>Z.to>m)}))}if(a=m,a==f)break;for(let x=0;x{if(!(e&&o.diagnostics.indexOf(e)<0))if(!i)i=new Qh(s,r,e||o.diagnostics[0]);else{if(o.diagnostics.indexOf(i.diagnostic)<0)return!1;i=new Qh(i.from,r,i.diagnostic)}}),i}function Iu(n,e){let t=e.pos,i=e.end||t,s=n.state.facet(Ot).hideOn(n,t,i);if(s!=null)return s;let r=n.startState.doc.lineAt(e.pos);return!!(n.effects.some(o=>o.is(er))||n.changes.touchesRange(r.from,Math.max(r.to,i)))}function mb(n,e){return n.field(Ke,!1)?e:e.concat(z.appendConfig.of(ed))}function Vu(n,e){return{effects:mb(n,[er.of(e)])}}const er=z.define(),ju=z.define(),Nu=z.define(),Ke=fe.define({create(){return new jt(X.none,null,null)},update(n,e){if(e.docChanged&&n.diagnostics.size){let t=n.diagnostics.map(e.changes),i=null,s=n.panel;if(n.selected){let r=e.changes.mapPos(n.selected.from,1);i=Ti(t,n.selected.diagnostic,r)||Ti(t,null,r)}!t.size&&s&&e.state.facet(Ot).autoPanel&&(s=null),n=new jt(t,s,i)}for(let t of e.effects)if(t.is(er)){let i=e.state.facet(Ot).autoPanel?t.value.length?Ms.open:null:n.panel;n=jt.init(t.value,i,e.state)}else t.is(ju)?n=new jt(n.diagnostics,t.value?Ms.open:null,n.selected):t.is(Nu)&&(n=new jt(n.diagnostics,n.panel,t.value));return n},provide:n=>[rn.from(n,e=>e.panel),T.decorations.from(n,e=>e.diagnostics)]}),gb=X.mark({class:"cm-lintRange cm-lintRange-active"});function yb(n,e,t){let{diagnostics:i}=n.state.field(Ke),s,r=-1,o=-1;i.between(e-(t<0?1:0),e+(t>0?1:0),(a,h,{spec:c})=>{if(e>=a&&e<=h&&(a==h||(e>a||t>0)&&(eFu(n,t,!1)))}const vh=n=>{let e=n.state.field(Ke,!1);return!e||!e.panel?!1:(n.dispatch({effects:ju.of(!1)}),!0)},bb=ne.fromClass(class{constructor(n){this.view=n,this.timeout=-1,this.set=!0;let{delay:e}=n.state.facet(Ot);this.lintTime=Date.now()+e,this.run=this.run.bind(this),this.timeout=setTimeout(this.run,e)}run(){clearTimeout(this.timeout);let n=Date.now();if(nPromise.resolve(i(this.view))),i=>{this.view.state.doc==e.doc&&this.view.dispatch(Vu(this.view.state,i.reduce((s,r)=>s.concat(r))))},i=>{ve(this.view.state,i)})}}update(n){let e=n.state.facet(Ot);(n.docChanged||e!=n.startState.facet(Ot)||e.needsRefresh&&e.needsRefresh(n))&&(this.lintTime=Date.now()+e.delay,this.set||(this.set=!0,this.timeout=setTimeout(this.run,e.delay)))}force(){this.set&&(this.lintTime=Date.now(),this.run())}destroy(){clearTimeout(this.timeout)}});function Sb(n,e,t){let i=[],s=-1;for(let r of n)r.then(o=>{i.push(o),clearTimeout(s),i.length==n.length?e(i):s=setTimeout(()=>e(i),200)},t)}const Ot=C.define({combine(n){return{sources:n.map(e=>e.source).filter(e=>e!=null),...et(n.map(e=>e.config),{delay:750,markerFilter:null,tooltipFilter:null,needsRefresh:null,hideOn:()=>null},{delay:Math.max,markerFilter:$h,tooltipFilter:$h,needsRefresh:(e,t)=>e?t?i=>e(i)||t(i):e:t,hideOn:(e,t)=>e?t?(i,s,r)=>e(i,s,r)||t(i,s,r):e:t,autoPanel:(e,t)=>e||t})}}});function $h(n,e){return n?e?(t,i)=>e(n(t,i),i):n:e}function xb(n,e={}){return[Ot.of({source:n,config:e}),bb,ed]}function Uu(n){let e=[];if(n)e:for(let{name:t}of n){for(let i=0;ir.toLowerCase()==s.toLowerCase())){e.push(s);continue e}}e.push("")}return e}function Fu(n,e,t){var i;let s=t?Uu(e.actions):[];return U("li",{class:"cm-diagnostic cm-diagnostic-"+e.severity},U("span",{class:"cm-diagnosticText"},e.renderMessage?e.renderMessage(n):e.message),(i=e.actions)===null||i===void 0?void 0:i.map((r,o)=>{let l=!1,a=d=>{if(d.preventDefault(),l)return;l=!0;let p=Ti(n.state.field(Ke).diagnostics,e);p&&r.apply(n,p.from,p.to)},{name:h}=r,c=s[o]?h.indexOf(s[o]):-1,f=c<0?h:[h.slice(0,c),U("u",h.slice(c,c+1)),h.slice(c+1)],u=r.markClass?" "+r.markClass:"";return U("button",{type:"button",class:"cm-diagnosticAction"+u,onclick:a,onmousedown:a,"aria-label":` Action: ${h}${c<0?"":` (access key "${s[o]})"`}.`},f)}),e.source&&U("div",{class:"cm-diagnosticSource"},e.source))}class wb extends yt{constructor(e){super(),this.sev=e}eq(e){return e.sev==this.sev}toDOM(){return U("span",{class:"cm-lintPoint cm-lintPoint-"+this.sev})}}class Ph{constructor(e,t){this.diagnostic=t,this.id="item_"+Math.floor(Math.random()*4294967295).toString(16),this.dom=Fu(e,t,!0),this.dom.id=this.id,this.dom.setAttribute("role","option")}}class Ms{constructor(e){this.view=e,this.items=[];let t=s=>{if(!(s.ctrlKey||s.altKey||s.metaKey)){if(s.keyCode==27)vh(this.view),this.view.focus();else if(s.keyCode==38||s.keyCode==33)this.moveSelection((this.selectedIndex-1+this.items.length)%this.items.length);else if(s.keyCode==40||s.keyCode==34)this.moveSelection((this.selectedIndex+1)%this.items.length);else if(s.keyCode==36)this.moveSelection(0);else if(s.keyCode==35)this.moveSelection(this.items.length-1);else if(s.keyCode==13)this.view.focus();else if(s.keyCode>=65&&s.keyCode<=90&&this.selectedIndex>=0){let{diagnostic:r}=this.items[this.selectedIndex],o=Uu(r.actions);for(let l=0;l{for(let r=0;rvh(this.view)},"×")),this.update()}get selectedIndex(){let e=this.view.state.field(Ke).selected;if(!e)return-1;for(let t=0;t{for(let c of h.diagnostics){if(o.has(c))continue;o.add(c);let f=-1,u;for(let d=i;di&&(this.items.splice(i,f-i),s=!0)),t&&u.diagnostic==t.diagnostic?u.dom.hasAttribute("aria-selected")||(u.dom.setAttribute("aria-selected","true"),r=u):u.dom.hasAttribute("aria-selected")&&u.dom.removeAttribute("aria-selected"),i++}});i({sel:r.dom.getBoundingClientRect(),panel:this.list.getBoundingClientRect()}),write:({sel:l,panel:a})=>{let h=a.height/this.list.offsetHeight;l.topa.bottom&&(this.list.scrollTop+=(l.bottom-a.bottom)/h)}})):this.selectedIndex<0&&this.list.removeAttribute("aria-activedescendant"),s&&this.sync()}sync(){let e=this.list.firstChild;function t(){let i=e;e=i.nextSibling,i.remove()}for(let i of this.items)if(i.dom.parentNode==this.list){for(;e!=i.dom;)t();e=i.dom.nextSibling}else this.list.insertBefore(i.dom,e);for(;e;)t()}moveSelection(e){if(this.selectedIndex<0)return;let t=this.view.state.field(Ke),i=Ti(t.diagnostics,this.items[e].diagnostic);i&&this.view.dispatch({selection:{anchor:i.from,head:i.to},scrollIntoView:!0,effects:Nu.of(i)})}static open(e){return new Ms(e)}}function is(n,e='viewBox="0 0 40 40"'){return`url('data:image/svg+xml,${encodeURIComponent(n)}')`}function jn(n){return is(``,'width="6" height="3"')}const kb=T.baseTheme({".cm-diagnostic":{padding:"3px 6px 3px 8px",marginLeft:"-1px",display:"block",whiteSpace:"pre-wrap"},".cm-diagnostic-error":{borderLeft:"5px solid #d11"},".cm-diagnostic-warning":{borderLeft:"5px solid orange"},".cm-diagnostic-info":{borderLeft:"5px solid #999"},".cm-diagnostic-hint":{borderLeft:"5px solid #66d"},".cm-diagnosticAction":{font:"inherit",border:"none",padding:"2px 4px",backgroundColor:"#444",color:"white",borderRadius:"3px",marginLeft:"8px",cursor:"pointer"},".cm-diagnosticSource":{fontSize:"70%",opacity:.7},".cm-lintRange":{backgroundPosition:"left bottom",backgroundRepeat:"repeat-x",paddingBottom:"0.7px"},".cm-lintRange-error":{backgroundImage:jn("#f11")},".cm-lintRange-warning":{backgroundImage:jn("orange")},".cm-lintRange-info":{backgroundImage:jn("#999")},".cm-lintRange-hint":{backgroundImage:jn("#66d")},".cm-lintRange-active":{backgroundColor:"#ffdd9980"},".cm-tooltip-lint":{padding:0,margin:0},".cm-lintPoint":{position:"relative","&:after":{content:'""',position:"absolute",bottom:0,left:"-2px",borderLeft:"3px solid transparent",borderRight:"3px solid transparent",borderBottom:"4px solid #d11"}},".cm-lintPoint-warning":{"&:after":{borderBottomColor:"orange"}},".cm-lintPoint-info":{"&:after":{borderBottomColor:"#999"}},".cm-lintPoint-hint":{"&:after":{borderBottomColor:"#66d"}},".cm-panel.cm-panel-lint":{position:"relative","& ul":{maxHeight:"100px",overflowY:"auto","& [aria-selected]":{backgroundColor:"#ddd","& u":{textDecoration:"underline"}},"&:focus [aria-selected]":{background_fallback:"#bdf",backgroundColor:"Highlight",color_fallback:"white",color:"HighlightText"},"& u":{textDecoration:"none"},padding:0,margin:0},"& [name=close]":{position:"absolute",top:"0",right:"2px",background:"inherit",border:"none",font:"inherit",padding:0,margin:0}},"&dark .cm-lintRange-active":{backgroundColor:"#86714a80"},"&dark .cm-panel.cm-panel-lint ul":{"& [aria-selected]":{backgroundColor:"#2e343e"}}});function Qb(n){return n=="error"?4:n=="warning"?3:n=="info"?2:1}function Hu(n){let e="hint",t=1;for(let i of n){let s=Qb(i.severity);s>t&&(t=s,e=i.severity)}return e}class Ku extends gt{constructor(e){super(),this.diagnostics=e,this.severity=Hu(e)}toDOM(e){let t=document.createElement("div");t.className="cm-lint-marker cm-lint-marker-"+this.severity;let i=this.diagnostics,s=e.state.facet(tr).tooltipFilter;return s&&(i=s(i,e.state)),i.length&&(t.onmouseover=()=>$b(e,t,i)),t}}function vb(n,e){let t=i=>{let s=e.getBoundingClientRect();if(!(i.clientX>s.left-10&&i.clientXs.top-10&&i.clientYe.getBoundingClientRect()}}})}),e.onmouseout=e.onmousemove=null,vb(n,e)}let{hoverTime:s}=n.state.facet(tr),r=setTimeout(i,s);e.onmouseout=()=>{clearTimeout(r),e.onmouseout=e.onmousemove=null},e.onmousemove=()=>{clearTimeout(r),r=setTimeout(i,s)}}function Pb(n,e){let t=Object.create(null);for(let s of e){let r=n.lineAt(s.from);(t[r.from]||(t[r.from]=[])).push(s)}let i=[];for(let s in t)i.push(new Ku(t[s]).range(+s));return B.of(i,!0)}const Tb=hf({class:"cm-gutter-lint",markers:n=>n.state.field(Lo),widgetMarker:(n,e,t)=>{let i=[];return n.state.field(Lo).between(t.from,t.to,(s,r,o)=>{s>t.from&&si.is(wl)?i.value:t,n)},provide:n=>Ys.from(n)}),Cb=T.baseTheme({".cm-gutter-lint":{width:"1.4em","& .cm-gutterElement":{padding:".2em"}},".cm-lint-marker":{width:"1em",height:"1em"},".cm-lint-marker-info":{content:is('')},".cm-lint-marker-warning":{content:is('')},".cm-lint-marker-error":{content:is('')}}),Zb=nf(yb,{hideOn:Iu}),ed=[Ke,T.decorations.compute([Ke],n=>{let{selected:e,panel:t}=n.field(Ke);return!e||!t||e.from==e.to?X.none:X.set([gb.range(e.from,e.to)])}),Zb,kb],tr=C.define({combine(n){return et(n,{hoverTime:300,markerFilter:null,tooltipFilter:null})}});function Ab(n={}){return[tr.of(n),Lo,Tb,Cb,Ju]}const td=1,_e=Object.freeze({ready:"studio.ready",documentOpen:"document.open",documentReplace:"document.replace",documentChanged:"document.changed",documentSave:"document.save",documentSetReadOnly:"document.setReadOnly",editorInsert:"editor.insert",editorFormat:"editor.format",editorSetTheme:"editor.setTheme",editorGetState:"editor.getState",diagnosticsPublish:"diagnostics.publish"});function Mb(n,e={},t=null){return{protocolVersion:td,type:n,documentID:t,payload:e}}function Rb(n){if(window.WKWebViewJavascriptBridge){n(window.WKWebViewJavascriptBridge);return}if(window.WKWVJBCallbacks){window.WKWVJBCallbacks.push(n);return}window.webkit?.messageHandlers?.iOS_Native_InjectJavascript&&(window.WKWVJBCallbacks=[n],window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null))}function ir(n,e,t={},i=null,s=()=>{}){if(!n){s({result:"unavailable"});return}n.callHandler(e,Mb(e,t,i),s)}function Xb(n){const e={capabilities:["jsx","format","search","completion","diagnostics"]};ir(n,_e.ready,e)}const kt={globalProperties:{background:{type:"color",documentation:"Background color, hex value, or named color."},color:{type:"color",documentation:"Foreground color, hex value, or named color."},font:{type:"enum",values:["largeTitle","title","title2","title3","headline","subheadline","body","callout","footnote","caption","caption2"],documentation:"Semantic text style."},fontWeight:{type:"enum",values:["ultraLight","thin","light","regular","medium","semibold","bold","heavy","black"],documentation:"Font weight."},fontDesign:{type:"enum",values:["default","rounded","serif","monospaced"],documentation:"Font design."},frame:{type:"number|string",documentation:'Square size (64 or "64"), width,height ("64,48"), or flexible frame ("max", "max,48").'},padding:{type:"number|string",documentation:"Padding amount or edge description."},corner:{type:"number",documentation:"Corner radius."},opacity:{type:"number",documentation:"Opacity from 0 through 1."},alignment:{type:"enum",values:["center","leading","trailing","top","bottom","topLeading","topTrailing","bottomLeading","bottomTrailing","firstTextBaseline","lastTextBaseline"],documentation:"Layout alignment."},clip:{type:"enum",values:["circle","rect","capsule","ellipse"],documentation:"Clip the view to a shape."},rotation:{type:"number",documentation:"Rotation in degrees."},rotation3d:{type:"string",documentation:"3D rotation description."},shadow:{type:"string",documentation:"Shadow color, radius, and offset description."},animation:{type:"string",documentation:"Timeline-driven animation description."},widgetAccentable:{type:"boolean",documentation:"Group this view into the accent layer in tinted and vibrant widget appearances."},linkurl:{type:"url",documentation:"Widget deep link URL."}},components:{VStack:{documentation:"Arrange children vertically.",children:!0,properties:{spacing:{type:"number"}}},HStack:{documentation:"Arrange children horizontally.",children:!0,properties:{spacing:{type:"number"}}},ZStack:{documentation:"Overlay children.",children:!0,properties:{}},VGrid:{documentation:"Vertical lazy grid.",children:!0,properties:{columns:{type:"string",required:!0},spacing:{type:"number"},alignment:{type:"enum",values:["leading","center","trailing"]}}},HGrid:{documentation:"Horizontal lazy grid.",children:!0,properties:{columns:{type:"string",required:!0},spacing:{type:"number"},alignment:{type:"enum",values:["top","center","bottom","firstTextBaseline","lastTextBaseline"]}}},Text:{documentation:"Display text content.",children:!1,properties:{text:{type:"string"}}},Date:{documentation:"Display a formatted date.",children:!1,properties:{date:{type:"date|number",required:!0},style:{type:"enum",values:["time","date","relative","offset","timer"]}}},Image:{documentation:"Display a bundled, remote, or SF Symbol image.",children:!1,properties:{systemName:{type:"string"},name:{type:"string"},id:{type:"string",deprecated:"Use name."},url:{type:"url"},src:{type:"url",deprecated:"Use url."},ratio:{type:"number"},mode:{type:"enum",values:["fit","fill"]},accentedRenderingMode:{type:"enum",values:["accented","desaturated","accentedDesaturated","fullColor"],documentation:"Control how the image is rendered in tinted and clear widget appearances."}}},Gif:{documentation:"Display a GIF from the package.",children:!1,properties:{file:{type:"string",required:!0}}},Spacer:{documentation:"Flexible layout space.",children:!1,properties:{minLength:{type:"number"}}},Rect:{documentation:"Rectangle shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},RoundedRect:{documentation:"Filled rounded rectangle.",children:!1,properties:{radius:{type:"number"}}},Capsule:{documentation:"Capsule shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Ellipse:{documentation:"Ellipse shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Circle:{documentation:"Circle shape.",children:!1,properties:{trim:{type:"number|string"},stroke:{type:"string"}}},Gauge:{documentation:"Display a gauge or instrument.",children:!1,properties:{type:{type:"string"},value:{type:"number"},style:{type:"enum",values:["circular","linear"]},text:{type:"string"},current:{type:"string"},min:{type:"string"},max:{type:"string"},angle:{type:"number"},thickness:{type:"number"},needleColor:{type:"color"},label:{type:"string"},title:{type:"string"},sections:{type:"string"}}},Chart:{documentation:"Render chart data.",children:!1,availability:{ios:"16.0",macos:"26.0"},properties:{type:{type:"enum",values:["bar","bar-x","bar-y","bar-gantt","line","point","line-point","area","rect","rule-x"]},data:{type:"json",required:!0},category:{type:"boolean"},hideLegend:{type:"boolean"},hideXAxis:{type:"boolean"},hideYAxis:{type:"boolean"}}},Link:{documentation:"Open a URL when selected.",children:!0,properties:{url:{type:"url",required:!0}}},Divider:{documentation:"Horizontal or vertical separator.",children:!1,properties:{thickness:{type:"number"},axis:{type:"enum",values:["horizontal","vertical"]}}},Line:{documentation:"Fixed-length line.",children:!1,properties:{thickness:{type:"number"},length:{type:"number"},axis:{type:"enum",values:["horizontal","vertical"]}}},Icon:{documentation:"SF Symbol icon.",children:!1,properties:{systemName:{type:"string",required:!0},size:{type:"number"}}},Label:{documentation:"Text paired with an SF Symbol.",children:!1,properties:{title:{type:"string"},systemName:{type:"string",required:!0}}},Progress:{documentation:"Linear or circular progress.",children:!1,properties:{value:{type:"number",required:!0},total:{type:"number"},label:{type:"string"},style:{type:"enum",values:["linear","circular"]},trackColor:{type:"color"},thickness:{type:"number"}}},Ring:{documentation:"Circular progress ring.",children:!1,properties:{value:{type:"number",required:!0},thickness:{type:"number"},trackColor:{type:"color"}}},Badge:{documentation:"Compact status badge.",children:!1,properties:{text:{type:"string"},radius:{type:"number"}}},Chip:{documentation:"Outlined metadata chip.",children:!1,properties:{text:{type:"string"},radius:{type:"number"},borderColor:{type:"color"}}},Stat:{documentation:"Title, value, and subtitle statistic.",children:!1,properties:{title:{type:"string"},value:{type:"string",required:!0},subtitle:{type:"string"},mutedColor:{type:"color"}}},Button:{documentation:"Interactive widget button. Use actionID to share a declared Package 2.0 action with Siri, Shortcuts, and Control Widgets.",children:!0,availability:{interactiveIos:"17.0"},requiredAny:["action","onClick","actionID"],properties:{action:{type:"enum",values:["reload"],conflicts:["actionID"]},onClick:{type:"function",conflicts:["actionID"]},actionID:{type:"action-id",conflicts:["action","onClick"]}}},Toggle:{documentation:"Interactive widget toggle. A declared actionID requires a package-relative storage stateKey.",children:!0,availability:{interactiveIos:"17.0"},requiredAny:["onClick","actionID"],properties:{on:{type:"boolean",required:!0},onClick:{type:"function",conflicts:["actionID"]},actionID:{type:"action-id",requires:["stateKey"],conflicts:["onClick"]},stateKey:{type:"storage-key",requires:["actionID"]}}}}};function Lb(n,e){const t=Object.entries(e.properties??{}).filter(([,s])=>s.required).map(([s,r])=>`${s}=${r.type.includes("number")||r.type==="boolean"?"{${}}":'"${}"'}`).join(" "),i=t?` ${t}`:"";return e.children?`<${n}${i}> \${} `:`<${n}${i} />`}const Th=Object.entries(kt.components).map(([n,e])=>({label:n,type:"class",detail:`ScriptWidget · ${Object.keys(e.properties??{}).length} properties`,info:e.documentation,apply:Lb(n,e)}));function Db(n){const e=n.match(/<([A-Za-z][\w]*)\b([^<>]*)$/);return!e||e[2].includes(">")?null:{name:e[1],attributes:e[2]}}function Eb(n,e){const t=kt.components[n];return t?Object.entries({...kt.globalProperties,...t.properties??{}}).filter(([i])=>!e.has(i)).map(([i,s])=>({label:i,type:"property",detail:s.required?`${s.type} · required`:s.type,info:s.deprecated?`Deprecated: ${s.deprecated}`:s.documentation,apply:`${i}=${s.type.includes("number")||s.type==="boolean"?"{${}}":'"${}"'}`})):[]}function Wb(n){const e=n.match(/<([A-Za-z][\w]*)\b[^<>]*\b([A-Za-z][\w]*)\s*=\s*["']([^"']*)$/);if(!e)return null;const t=kt.components[e[1]]?.properties?.[e[2]]??kt.globalProperties[e[2]];return t?.values?{typed:e[3],values:t.values}:null}function zb(n){const e=n.state.doc.sliceString(Math.max(0,n.pos-1200),n.pos),t=Wb(e);if(t)return{from:n.pos-t.typed.length,options:t.values.map(r=>({label:r,type:"enum"})),validFor:/^[\w-]*$/};const i=n.matchBefore(/<[A-Za-z]*$/);if(i)return{from:i.from+1,options:Th,validFor:/^[A-Za-z]*$/};const s=Db(e);if(s&&/(?:\s|^)\w*$/.test(s.attributes)){const r=n.matchBefore(/[A-Za-z][\w]*$/),o=new Set([...s.attributes.matchAll(/\b([A-Za-z][\w]*)\s*=/g)].map(l=>l[1]));return{from:r?.from??n.pos,options:Eb(s.name,o),validFor:/^[A-Za-z][\w]*$/}}return n.explicit?{from:n.pos,options:Th,validFor:/^[A-Za-z]*$/}:null}function Ch(n,e){const t=[];for(let i=n.node.firstChild;i;i=i.nextSibling)i.name===e&&t.push(i);return t}function id(n){const e=[];return he(n).iterate({enter(t){if(t.name!=="JSXOpenTag"&&t.name!=="JSXSelfClosingTag")return;const s=Ch(t,"JSXIdentifier")[0];s&&e.push({name:n.doc.sliceString(s.from,s.to),from:s.from,to:s.to,attributes:Ch(t,"JSXAttribute").map(r=>{const o=r.firstChild;return o?{name:n.doc.sliceString(o.from,o.to),from:o.from,to:o.to}:null}).filter(Boolean)})}}),e}function nd(n){const e=[];for(const t of id(n.state)){const i=kt.components[t.name];if(!i)continue;const s=new Set([...Object.keys(kt.globalProperties),...Object.keys(i.properties??{})]),r=new Set(t.attributes.map(o=>o.name));for(const o of t.attributes){s.has(o.name)||e.push({from:o.from,to:o.to,severity:"warning",message:`“${o.name}” is not supported by <${t.name}>.`});const l=i.properties?.[o.name]??kt.globalProperties[o.name];l?.deprecated&&e.push({from:o.from,to:o.to,severity:"warning",message:`${o.name} is deprecated. ${l.deprecated}`})}for(const[o,l]of Object.entries(i.properties??{}))if(l.required&&!r.has(o)&&e.push({from:t.from,to:t.to,severity:"error",message:`<${t.name}> requires the “${o}” property.`}),r.has(o)){for(const a of l.requires??[])r.has(a)||e.push({from:t.from,to:t.to,severity:"error",message:`<${t.name}> “${o}” requires the “${a}” property.`});for(const a of l.conflicts??[])r.has(a)&&o cannot combine “${o}” with “${a}”.`})}i.requiredAny?.length&&!i.requiredAny.some(o=>r.has(o))&&e.push({from:t.from,to:t.to,severity:"error",message:`<${t.name}> requires one of: ${i.requiredAny.map(o=>`“${o}”`).join(", ")}.`})}return e}function qb(n,e){const t=id(n.state).find(s=>e>=s.from&&e<=s.to);if(!t)return null;const i=kt.components[t.name];return i?{pos:t.from,end:t.to,above:!0,create(){const s=document.createElement("div");s.className="studio-hover";const r=document.createElement("strong");r.textContent=`<${t.name}>`;const o=document.createElement("p");return o.textContent=i.documentation,s.append(r,o),{dom:s}}}:null}const Zh={light:{background:"#FAFAFC",foreground:"#202124",gutter:"#F3F3F6",gutterText:"#8A8A93",activeLine:"#EDEEF3",selection:"#B9D7FF",caret:"#0067C0"},dark:{background:"#1E1F22",foreground:"#E8E8ED",gutter:"#191A1D",gutterText:"#777982",activeLine:"#292A2F",selection:"#315A85",caret:"#65B7FF"}};function Bb(n,e){return T.theme({"&":{height:"100%",color:n.foreground,backgroundColor:n.background,fontSize:"13px"},".cm-scroller":{fontFamily:'ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, monospace',lineHeight:"1.58",overscrollBehavior:"contain"},".cm-content":{caretColor:n.caret,padding:"12px 0 32px"},".cm-line":{padding:"0 8px"},".cm-cursor, .cm-dropCursor":{borderLeftColor:n.caret},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:n.selection},".cm-activeLine":{backgroundColor:n.activeLine},".cm-gutters":{backgroundColor:n.gutter,color:n.gutterText,border:"none",paddingLeft:"env(safe-area-inset-left)"},".cm-activeLineGutter":{backgroundColor:n.activeLine,color:n.foreground},".cm-foldPlaceholder":{backgroundColor:"transparent",border:`1px solid ${n.gutterText}`,color:n.gutterText},".cm-tooltip":{border:e?"1px solid #41434A":"1px solid #D2D3D8",backgroundColor:e?"#292A2F":"#FFFFFF",borderRadius:"8px",overflow:"hidden",boxShadow:"0 8px 28px rgba(0, 0, 0, 0.2)"},".cm-tooltip-autocomplete ul li[aria-selected]":{backgroundColor:e?"#315A85":"#DCEBFA",color:n.foreground},".cm-panels":{backgroundColor:n.gutter,color:n.foreground},".cm-searchMatch":{backgroundColor:e?"#725C1D":"#FFE69A"},".cm-searchMatch.cm-searchMatch-selected":{backgroundColor:e?"#8D6D20":"#FFD45C"}},{dark:e})}function sd(n){const e=n==="dark";return[Bb(e?Zh.dark:Zh.light,e),gg(Sg)]}const rd="scriptwidget.studio.document-state.v1.";function od(n,e,t){if(!n||!e)return!1;try{return n.setItem(`${rd}${e}`,JSON.stringify({anchor:Number(t.anchor)||0,head:Number(t.head)||0,scrollTop:Number(t.scrollTop)||0})),!0}catch{return!1}}function _b(n,e,t){if(!n||!e)return null;try{const i=JSON.parse(n.getItem(`${rd}${e}`));if(!i||typeof i!="object")return null;const s=r=>Math.max(0,Math.min(Number(r)||0,t));return{anchor:s(i.anchor),head:s(i.head),scrollTop:Math.max(0,Number(i.scrollTop)||0)}}catch{return null}}const Yb="scriptwidget.web-studio.draft.v1:";function kl(n){return`${Yb}${n}`}function Ib(n,e){if(!e)return null;try{const t=JSON.parse(n.getItem(kl(e))||"null");return t&&typeof t.content=="string"&&typeof t.baseRevision=="string"?t:null}catch{return null}}function Ah(n,e,t,i,s=Date.now()){if(!e||typeof i!="string")return null;const r={documentID:e,content:t,baseRevision:i,updatedAt:s};return n.setItem(kl(e),JSON.stringify(r)),r}function Wr(n,e){e&&n.removeItem(kl(e))}function Vb(n,e,t,i){const s=Ib(n,e);return!s||s.content===t?null:{...s,serverContent:t,serverRevision:i,isStale:s.baseRevision!==i}}function jb(){return{connection:"connecting",save:"idle",preview:"idle",conflict:null}}function Nb(n,e){switch(e.type){case"CONNECTED":return{...n,connection:"connected"};case"OFFLINE":return{...n,connection:"offline",save:n.save==="saving"?"draft":n.save};case"DISCONNECTED":return{...n,connection:"disconnected"};case"EDITED":return{...n,save:"draft",conflict:null};case"SAVING":return{...n,save:"saving"};case"SAVED":return{...n,save:"saved",preview:e.preview||"requested",conflict:null};case"SAVE_FAILED":return{...n,save:"error"};case"CONFLICT":return{...n,save:"conflict",conflict:e.conflict};default:return n}}class Gb{constructor(e){this.send=e,this.epoch=0,this.context=null,this.inFlight=null,this.needsFlush=!1}open({documentID:e,packageID:t,path:i,revision:s,content:r}){return this.epoch+=1,this.context={documentID:e,packageID:t,path:i,revision:s,content:r,generation:0,savedGeneration:0},this.needsFlush=!1,this.snapshot()}edit(e){return this.context?(this.context.content=e,this.context.generation+=1,this.snapshot()):null}rebase(e){return this.context&&(this.context.revision=e),this.snapshot()}get isDirty(){return!!(this.context&&this.context.generation!==this.context.savedGeneration)}snapshot(){return this.context?{...this.context,dirty:this.isDirty}:null}async flush(){if(!this.context||!this.isDirty)return{skipped:!0,snapshot:this.snapshot()};if(this.inFlight)return this.needsFlush=!0,this.inFlight.then(()=>this.isDirty?this.flush():{skipped:!0,snapshot:this.snapshot()});const e=this.epoch,t={...this.context};this.needsFlush=!1,this.inFlight=this.send({documentID:t.documentID,packageID:t.packageID,path:t.path,content:t.content,baseRevision:t.revision}).then(s=>this.epoch!==e||this.context?.documentID!==t.documentID?{ignored:!0,result:s,snapshot:this.snapshot()}:(this.context.revision=s.revision,this.context.savedGeneration=t.generation,{result:s,snapshot:this.snapshot()})).finally(()=>{this.inFlight=null});const i=await this.inFlight;return this.needsFlush&&this.isDirty?this.flush():i}}function Mh(n){return["draft","saving","error","conflict"].includes(n)}class Ub extends Error{constructor(e,t,i={}){super(e),this.name="StudioAPIError",this.status=t,this.body=i}}class Fb{constructor({fetchImpl:e=globalThis.fetch,token:t=()=>"",onUnauthorized:i=()=>{}}={}){if(typeof e!="function")throw new TypeError("A fetch implementation is required");this.fetchImpl=e,this.token=t,this.onUnauthorized=i}async request(e,t={}){const i=await this.fetchImpl(e,this.authorizedOptions(t)),s=await i.json().catch(()=>({}));return this.validate(i,e,s),s}async requestBlob(e,t={}){const i=await this.fetchImpl(e,this.authorizedOptions(t));if(!i.ok){const s=await i.json().catch(()=>({}));this.validate(i,e,s)}return i.blob()}authorizedOptions(e){return{...e,headers:{"Content-Type":"application/json","X-Studio-Token":this.token(),...e.headers||{}}}}validate(e,t,i){if(!e.ok){const s=new Ub(i.message||`Request failed (${e.status})`,e.status,i);throw e.status===401&&t!=="/api/v1/pair"&&this.onUnauthorized(s),s}}}const Ql=/^https?:$/.test(window.location.protocol),Hb=document.querySelector(Ql?"#editor":"#native-editor"),ld=new Ci,ad=new Ci;let ni=null,me=null,$t=0,Do=!1,Rs=null,Rh=null;const Xh=document.querySelector("#save-status");let hd=null;function Xs(n,e="idle"){Xh.textContent=n,Xh.dataset.state=e}function Kb(){window.clearTimeout(Rh),Rh=window.setTimeout(()=>{const n=Y.state.selection.main;od(window.localStorage,me,{anchor:n.anchor,head:n.head,scrollTop:Y.scrollDOM.scrollTop})},180)}function cd(){return window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light"}function fd(){window.clearTimeout(Rs),Xs("Saving…","saving"),Rs=window.setTimeout(()=>{const n=Y.state.doc.toString();ir(ni,_e.documentSave,{content:n,version:$t},me,(e={})=>{Ql||Xs(e.result==="ok"||e.result==="unavailable"?"Saved":"Save failed",e.result==="failed"?"error":"saved")})},700)}function Jb(n){if((n.selectionSet||n.viewportChanged||n.docChanged)&&Kb(),!n.docChanged||Do)return;$t+=1,hd?.documentChanged();const e=[];n.changes.iterChanges((t,i,s,r,o)=>{e.push({from:t,to:i,insert:o.toString(),newFrom:s,newTo:r})}),ir(ni,_e.documentChanged,{changes:e,version:$t},me),fd()}const eS=[xm(),Qm(),qO(),Yg(),pg(),TO(),XO(),I.allowMultipleSelections.of(!0),eg(),Pg(),Zy(),By({override:[zb],activateOnTyping:!0}),KO(),tm(),jO(),V1(),Ab(),xb(nd,{delay:350}),nf(qb),E1({jsx:!0}),_s.of([j0,...Xy,...V0,...ub,...Kg,...cg,...vu]),ld.of(I.readOnly.of(!1)),ad.of(sd(cd())),T.updateListener.of(Jb),T.contentAttributes.of({autocapitalize:"off",autocomplete:"off",spellcheck:"false"})],Y=new T({state:I.create({doc:"",extensions:eS}),parent:Hb});function Xt(n,e=me,t=0){const i=Y.state.selection.main;od(window.localStorage,me,{anchor:i.anchor,head:i.head,scrollTop:Y.scrollDOM.scrollTop}),Do=!0,me=e,$t=t;const s=_b(window.localStorage,me,(n??"").length);Y.dispatch({changes:{from:0,to:Y.state.doc.length,insert:n??""},selection:s?{anchor:s.anchor,head:s.head}:{anchor:0},scrollIntoView:!0}),s&&window.requestAnimationFrame(()=>{Y.scrollDOM.scrollTop=s.scrollTop}),Do=!1,Xs("Saved","saved")}function Lh(n){if(Y.state.readOnly)return!1;const e=Y.state.selection.main;return Y.dispatch({changes:{from:e.from,to:e.to,insert:n},selection:{anchor:e.from+n.length},userEvent:"input"}),Y.focus(),!0}async function Ls(){if(Y.state.readOnly)return!1;try{const[{format:n},{default:e},{default:t}]=await Promise.all([sr(()=>import("./standalone-Cayz_KD-.js"),[],import.meta.url),sr(()=>import("./babel-BktJt1uC.js"),[],import.meta.url),sr(()=>import("./estree-DFfjoHvx.js"),[],import.meta.url)]),i=await n(Y.state.doc.toString(),{parser:"babel",plugins:[e,t],semi:!0,singleQuote:!0,trailingComma:"es5"});return Xt(i,me,$t+1),fd(),!0}catch(n){return ir(ni,"diagnostics.publish",{message:String(n),severity:"error"},me),!1}}function Si(n){Y.dispatch({effects:ld.reconfigure(I.readOnly.of(!!n))})}function Ds(n){const e=n==="dark"||n==="light"?n:cd();document.documentElement.dataset.theme=e,Y.dispatch({effects:ad.reconfigure(sd(e))})}function tS(n=[]){const e=n.map(t=>({from:Math.max(0,Math.min(t.from??0,Y.state.doc.length)),to:Math.max(0,Math.min(t.to??t.from??0,Y.state.doc.length)),severity:t.severity??"error",message:t.message??"Unknown error"}));Y.dispatch(Vu(Y.state,e))}function ze(n,e){ni.registerHandler(n,async(t={},i=()=>{})=>{try{i({result:"ok",...await e(t)})}catch(s){i({result:"failed",message:String(s)})}})}Rb(n=>{ni=n,ze(_e.documentOpen,({payload:e={},documentID:t})=>(Xt(e.content,t,e.version??0),Si(e.readOnly),{protocolVersion:td})),ze(_e.documentReplace,({payload:e={},documentID:t})=>(Xt(e.content,t,e.version??$t),{})),ze(_e.documentSetReadOnly,({payload:e={}})=>(Si(e.readOnly),{readOnly:!!e.readOnly})),ze(_e.editorInsert,({payload:e={}})=>({inserted:Lh(e.content??"")})),ze(_e.editorFormat,async()=>({formatted:await Ls()})),ze(_e.editorSetTheme,({payload:e={}})=>(Ds(e.theme),{})),ze(_e.editorGetState,()=>({content:Y.state.doc.toString(),version:$t,documentID:me,selection:{from:Y.state.selection.main.from,to:Y.state.selection.main.to}})),ze(_e.diagnosticsPublish,({payload:e={}})=>(tS(e.items),{})),ze("editor_setValue",({value:e})=>(Xt(e),{})),ze("editor_insertValue",({value:e})=>({inserted:Lh(e??"")})),ze("editor_getValue",()=>({value:Y.state.doc.toString()})),ze("editor_setReadonly",({readonly:e})=>(Si(e),{readonly:!!e})),ze("editor_formatCode",async()=>({formatted:await Ls()})),Xb(ni)});Ql&&(document.querySelector("#native-editor").hidden=!0,document.querySelector("#web-studio").hidden=!1,iS());async function iS(){const n=document.querySelector("#pair-dialog"),e=document.querySelector("#pair-form"),t=document.querySelector("#pair-error"),i=document.querySelector("#package-select"),s=document.querySelector("#file-select"),r=document.querySelector("#connection-status"),o=document.querySelector("#disconnect-button"),l=document.querySelector("#studio-grid"),a=document.querySelector(".editor-column"),h=document.querySelector("#recovery-banner"),c=document.querySelector("#conflict-banner"),f=document.querySelector("#command-dialog"),u=document.querySelector("#command-search"),d=document.querySelector("#command-list"),p=document.querySelector("#compare-dialog");let O=window.sessionStorage.getItem("scriptwidget.web-studio.token")||"",m=[],y=null,w=null,x=null,Z=0,k=null,Q="",v="",R=null,E=jb(),q="",L="",M=null;function j(S="Session ended. Enter the new code shown on your device."){O="",window.sessionStorage.removeItem("scriptwidget.web-studio.token"),o.hidden=!0,W({type:"DISCONNECTED"}),r.textContent=S,Si(!0),n.open||n.showModal()}function W(S){E=Nb(E,S);const A={connecting:"Connecting",connected:"Connected",offline:"Offline",disconnected:"Disconnected"},D={idle:"Ready",draft:"Draft saved locally",saving:"Saving…",saved:"Saved",error:"Save failed",conflict:"Conflict"};r.dataset.state=E.connection,document.querySelector("#status-connection").textContent=A[E.connection]||E.connection,Xs(D[E.save]||E.save,E.save),document.querySelector("#dirty-indicator").hidden=!["draft","saving","error","conflict"].includes(E.save),document.querySelector("#status-preview").textContent=E.preview==="requested"?"Preview requested":"Preview idle",document.querySelector("#preview-detail").textContent=E.preview==="requested"?"Requested on device":"Not requested"}const G=new Fb({token:()=>O,onUnauthorized:()=>j()}),F=(S,A)=>G.request(S,A);M=new Gb(({packageID:S,path:A,content:D,baseRevision:N})=>F("/api/v1/document",{method:"PUT",body:JSON.stringify({package:S,path:A,content:D,baseRevision:N})}));async function we(S){O=(await F("/api/v1/pair",{method:"POST",body:JSON.stringify({code:S})})).token,window.sessionStorage.setItem("scriptwidget.web-studio.token",O),o.hidden=!1,W({type:"CONNECTED"}),Le()}function Le(){window.clearInterval(y),y=window.setInterval(async()=>{if(O)try{const S=await F("/api/v1/session");if(!navigator.onLine)return;nt(S),W({type:"CONNECTED"})}catch(S){S.status!==401&&(r.textContent=`Interrupted · ${S.message}`,W({type:"OFFLINE"}))}},5e3)}async function se(){if(m=(await F("/api/v1/packages")).packages||[],i.replaceChildren(...m.map(A=>new Option(A.name,A.id))),!m.length){r.textContent="No editable widgets",Si(!0);return}await ke()}async function ke(){const S=m.find(N=>N.id===i.value),A=S?.files||[];s.replaceChildren(...A.map(N=>new Option(N,N)));const D=A.includes(S?.entry)?S.entry:A[0];D&&(s.value=D),await pe()}async function De(S=""){m=(await F("/api/v1/packages")).packages||[],i.replaceChildren(...m.map(le=>new Option(le.name,le.id))),q&&(i.value=q);const D=m.find(le=>le.id===i.value),N=D?.files||[];s.replaceChildren(...N.map(le=>new Option(le,le))),s.value=N.includes(S)?S:N.includes(L)?L:D?.entry||N[0]}async function pe(){if(!i.value||!s.value)return;const S=new URLSearchParams({package:i.value,path:s.value}),A=await F(`/api/v1/document?${S}`),D=`${i.value}/${s.value}`;q=i.value,L=s.value,Q=A.revision,v=A.content,R=null,c.hidden=!0,Xt(A.content,D,0),M.open({documentID:D,packageID:q,path:L,revision:A.revision,content:A.content}),Si(!!A.readOnly),Be(A);const N=Vb(window.localStorage,D,A.content,A.revision);h.hidden=!N,h._draft=N,document.querySelector("#recovery-message").textContent=N?.isStale?"The device version also changed. Review before saving.":"Restore it or keep the device version.",r.textContent="Connected",W({type:"CONNECTED"}),o.hidden=!1,wn(),Le(),xn()}function Be(S){document.querySelector("#breadcrumb-package").textContent=S.packageName||i.value,document.querySelector("#breadcrumb-file").textContent=s.value,document.querySelector("#editor-tab-name").textContent=s.value,document.querySelector("#revision-detail").textContent=Q?Q.slice(0,8):"—",document.querySelector("#access-detail").textContent=S.readOnly?"Read only":"Editable"}function nt(S){S.device&&(document.querySelector("#device-name").textContent=S.device.name||S.device.model,document.querySelector("#device-system").textContent=`${S.device.model} · ${S.device.system}`),S.preview?.package&&(document.querySelector("#preview-target").textContent=S.preview.package),S.preview?.snapshotSequence&&bt()}async function bt(){try{const S=await G.requestBlob("/api/v1/preview"),A=URL.createObjectURL(S),D=document.querySelector("#device-preview"),N=k;k=A,D.onload=()=>{N&&URL.revokeObjectURL(N)},D.src=A,D.hidden=!1,document.querySelector("#preview-detail").textContent="Rendered on device"}catch{}}function si(S){const A=document.querySelector("#console-list"),D=document.createElement("li");for(D.className=S.level||"info",D.textContent=S.message||"",A.append(D);A.children.length>200;)A.firstChild.remove();A.scrollTop=A.scrollHeight}function xn(){window.clearTimeout(x);const S=async()=>{if(O)try{const A=await F(`/api/v1/events?after=${Z}`);Z=A.nextSequence??Z;for(const D of A.events||[])D.type==="console"&&si(D.payload||{}),D.type==="preview.snapshot"&&bt(),D.type==="preview.requested"&&(document.querySelector("#status-preview").textContent="Preview requested",document.querySelector("#preview-detail").textContent="Requested on device"),D.type==="files.changed"&&D.payload?.package===q&&De(L).catch(ri);W({type:"CONNECTED"})}catch(A){A.status!==401&&W({type:"OFFLINE"})}finally{O&&(x=window.setTimeout(S,1e3))}};S()}function wn(){const S=nd(Y);document.querySelector("#problems-list").replaceChildren(...S.map(D=>{const N=Y.state.doc.lineAt(D.from),le=document.createElement("li");le.className=`problem-item ${D.severity}`;const Ge=document.createElement("button");return Ge.type="button",Ge.innerHTML=`${D.severity==="error"?"●":"▲"}Ln ${N.number}`,Ge.children[1].textContent=D.message,Ge.addEventListener("click",()=>{Y.dispatch({selection:{anchor:D.from},scrollIntoView:!0}),Y.focus()}),le.append(Ge),le})),document.querySelector("#problems-count").textContent=String(S.length),document.querySelector("#status-problem-count").textContent=String(S.length),document.querySelector("#problems-summary").textContent=S.length?`${S.filter(D=>D.severity==="error").length} errors, ${S.filter(D=>D.severity!=="error").length} warnings`:"No problems detected"}async function kn(S,A,D=null){M.snapshot()?.content!==S&&M.edit(S),D&&M.rebase(D),W({type:"SAVING"});try{const N=await M.flush();if(N.ignored){A({result:"ok",ignored:!0});return}if(N.skipped){W({type:"SAVED"}),A({result:"ok",skipped:!0});return}const le=N.result||{},Ge=M.snapshot();Q=Ge?.revision||Q,v=Ge?.content||S,Wr(window.localStorage,me),R=null,c.hidden=!0,document.querySelector("#revision-detail").textContent=Q?.slice(0,8)||"—",W({type:"SAVED",preview:le.preview?.state}),A({result:"ok",...le})}catch(N){N.status===409?(R=N.body,c.hidden=!1,W({type:"CONFLICT",conflict:R})):W({type:"SAVE_FAILED"}),A({result:"failed",message:N.message})}}ni={registerHandler(){},callHandler(S,A,D=()=>{}){S===_e.documentSave?kn(A.payload.content,D):D({result:"ok"})}},hd={documentChanged(){const S=Y.state.doc.toString();M.edit(S),Ah(window.localStorage,me,S,M.snapshot()?.revision||Q),W({type:"EDITED"}),window.clearTimeout(w),w=window.setTimeout(wn,380)}};async function vl(S,A){if(!Mh(E.save)){await S();return}try{if(window.clearTimeout(Rs),await kn(Y.state.doc.toString(),()=>{}),!M.isDirty&&E.save!=="conflict"){await S();return}}catch{}window.confirm("This document has changes that are not saved on the device. A browser draft is available. Switch anyway?")?await S():A()}i.addEventListener("change",()=>{const S=i.value;i.value=q,vl(async()=>{i.value=S,await ke()},()=>{i.value=q}).catch(ri)}),s.addEventListener("change",()=>{const S=s.value;s.value=L,vl(async()=>{s.value=S,await pe()},()=>{s.value=L}).catch(ri)});function ri(S){r.textContent=S.message||String(S),W({type:"SAVE_FAILED"})}e.addEventListener("submit",async S=>{S.preventDefault(),t.textContent="";try{await we(document.querySelector("#pair-code").value),n.close(),await se()}catch(A){t.textContent=A.message}}),o.addEventListener("click",async()=>{try{await F("/api/v1/session",{method:"DELETE"})}catch{}j("Disconnected. Start a new session with the code on your device.")}),document.querySelector("#new-file").addEventListener("click",async()=>{const S=window.prompt("New package-relative text file","source/helper.js")?.trim();if(S)try{await F("/api/v1/document",{method:"POST",body:JSON.stringify({package:q,path:S})}),await De(S),await pe()}catch(A){ri(A)}}),document.querySelector("#delete-file").addEventListener("click",async()=>{const S=m.find(A=>A.id===q);if(!L||L===S?.entry){window.alert("The widget entry file cannot be deleted.");return}if(window.confirm(`Delete ${L}? This cannot be undone.`))try{const A=new URLSearchParams({package:q,path:L});await F(`/api/v1/document?${A}`,{method:"DELETE"}),L="",await De(),await pe()}catch(A){ri(A)}}),document.querySelector("#clear-console").addEventListener("click",()=>document.querySelector("#console-list").replaceChildren()),document.querySelector("#restore-draft").addEventListener("click",()=>{const S=h._draft;S&&(Xt(S.content,S.documentID,$t+1),h.hidden=!0,Ah(window.localStorage,me,S.content,Q),W({type:"EDITED"}),wn())}),document.querySelector("#discard-draft").addEventListener("click",()=>{Wr(window.localStorage,me),h.hidden=!0}),document.querySelector("#reload-server").addEventListener("click",()=>{R&&(Wr(window.localStorage,me),Q=R.currentRevision,v=R.currentContent,Xt(v,me,$t+1),M.open({documentID:me,packageID:q,path:L,revision:Q,content:v}),R=null,c.hidden=!0,W({type:"SAVED"}),wn())}),document.querySelector("#keep-local").addEventListener("click",()=>{R&&kn(Y.state.doc.toString(),()=>{},R.currentRevision)}),document.querySelector("#compare-conflict").addEventListener("click",()=>{document.querySelector("#compare-local").textContent=Y.state.doc.toString(),document.querySelector("#compare-server").textContent=R?.currentContent||v,p.showModal()}),p.querySelector("button").addEventListener("click",()=>p.close());function nr(){const S=a.classList.toggle("problems-collapsed");document.querySelector("#problems-toggle").setAttribute("aria-expanded",String(!S))}function Xi(S){l.classList.toggle(`show-${S}`)}document.querySelector("#problems-toggle").addEventListener("click",nr),document.querySelector("#status-problems").addEventListener("click",()=>{a.classList.remove("problems-collapsed")}),document.querySelector("#explorer-button").addEventListener("click",()=>Xi("explorer")),document.querySelector("#inspector-button").addEventListener("click",()=>Xi("inspector")),document.querySelectorAll("[data-close-panel]").forEach(S=>S.addEventListener("click",()=>l.classList.remove(`show-${S.dataset.closePanel}`)));const $l=[{name:"Save Document",keys:"⌘S",run:()=>{window.clearTimeout(Rs),kn(Y.state.doc.toString(),()=>{})}},{name:"Format Document",keys:"⇧⌥F",run:Ls},{name:"Toggle Problems",keys:"⌘J",run:nr},{name:"Toggle Explorer",keys:"⌘⇧E",run:()=>Xi("explorer")},{name:"Toggle Inspector",keys:"",run:()=>Xi("inspector")},{name:"Use Light Theme",keys:"",run:()=>Ds("light")},{name:"Use Dark Theme",keys:"",run:()=>Ds("dark")}];function Pl(S=""){const A=$l.filter(D=>D.name.toLowerCase().includes(S.toLowerCase()));d.replaceChildren(...A.map(D=>{const N=document.createElement("li"),le=document.createElement("button");le.type="button",le.className="command";const Ge=document.createElement("span");Ge.textContent=D.name;const Zl=document.createElement("kbd");return Zl.textContent=D.keys,le.append(Ge,Zl),le.addEventListener("click",()=>{f.close(),D.run()}),N.append(le),N}))}function Tl(){Pl(),f.showModal(),u.value="",u.focus()}document.querySelector("#command-button").addEventListener("click",Tl),u.addEventListener("input",()=>Pl(u.value)),document.addEventListener("keydown",S=>{const A=S.metaKey||S.ctrlKey;A&&S.shiftKey&&S.key.toLowerCase()==="p"?(S.preventDefault(),Tl()):A&&S.key.toLowerCase()==="s"?(S.preventDefault(),$l[0].run()):A&&S.key.toLowerCase()==="j"?(S.preventDefault(),nr()):A&&S.shiftKey&&S.key.toLowerCase()==="e"?(S.preventDefault(),Xi("explorer")):S.shiftKey&&S.altKey&&S.key.toLowerCase()==="f"&&(S.preventDefault(),Ls())}),Y.dom.addEventListener("keyup",Cl),Y.dom.addEventListener("mouseup",Cl);function Cl(){const S=Y.state.selection.main.head,A=Y.state.doc.lineAt(S);document.querySelector("#cursor-position").textContent=`Ln ${A.number}, Col ${S-A.from+1}`}window.addEventListener("offline",()=>{r.textContent="Computer is offline",W({type:"OFFLINE"})}),window.addEventListener("online",()=>{O&&F("/api/v1/session").then(S=>(nt(S),W({type:"CONNECTED"}),se())).catch(ri)}),window.addEventListener("beforeunload",S=>{Mh(E.save)&&(S.preventDefault(),S.returnValue="")});try{await se()}catch{j("Pair with the code shown on your device.")}}window.matchMedia?.("(prefers-color-scheme: dark)").addEventListener("change",()=>Ds("system"));window.webkit||Xt(`// ScriptWidget Studio const widget = ( diff --git a/macOS/ScriptWidgetMac/StudioEditor.bundle/index.html b/macOS/ScriptWidgetMac/StudioEditor.bundle/index.html index 50c4c278..f1919a4e 100644 --- a/macOS/ScriptWidgetMac/StudioEditor.bundle/index.html +++ b/macOS/ScriptWidgetMac/StudioEditor.bundle/index.html @@ -5,7 +5,7 @@ ScriptWidget Web Studio - +