{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://messenger.scrile.com/docs/mini-apps/bridge.schema.json",
  "title": "SMeet Mini Apps bridge, version 1",
  "description": "Every message between a Mini App page and the SMeet window, both ways. The page side is the SDK (smeet-mini-apps-1.x.js); the SMeet side is the window of the web app, of iOS and of macOS. In web the page and the window first meet on the window with hello and connect, then talk over the MessagePort that connect hands over: pong and leaving from the page, ping from SMeet, requests from the page, replies and events from SMeet. On iOS and macOS the page sends requests, hello included, to the smeet message handler and gets each reply as the handler's answer; events arrive through window.__smeetMiniAppEvent. A message is at most 64 KiB of JSON. A reply carries the id of its request; its result has the shape of result.<method> of that request's method. This version describes the bridge of SDK 1.0.0 exactly. Within bridge version 1 a later version of this schema, at the same address, only adds optional fields, methods, events, status values and error codes, so a message valid under this version stays valid. Check what a page sends, and test doubles of SMeet, against the current schema; a page at run time skips what a message of SMeet carries beyond what it knows instead of rejecting the message.",
  "anyOf": [
    { "$ref": "#/$defs/pageMessage" },
    { "$ref": "#/$defs/containerMessage" }
  ],
  "$defs": {
    "pageMessage": {
      "description": "What the page sends: hello on the window (web), pong and leaving over the port (web), and requests (web over the port, iOS and macOS through the handler).",
      "oneOf": [
        { "$ref": "#/$defs/hello" },
        { "$ref": "#/$defs/pong" },
        { "$ref": "#/$defs/leaving" },
        { "$ref": "#/$defs/request" }
      ]
    },
    "containerMessage": {
      "description": "What SMeet sends: connect on the window with one port (web), ping over the port (web), replies and events.",
      "oneOf": [
        { "$ref": "#/$defs/connect" },
        { "$ref": "#/$defs/ping" },
        { "$ref": "#/$defs/response" },
        { "$ref": "#/$defs/event" }
      ]
    },

    "uuid": {
      "type": "string",
      "pattern": "^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$"
    },
    "timestamp": {
      "description": "RFC 3339 in UTC.",
      "type": "string",
      "format": "date-time",
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?Z$"
    },
    "empty": {
      "type": "object",
      "additionalProperties": false
    },

    "hello": {
      "description": "Web: the page posts it to window.parent, to each allowed SMeet origin in turn, every 250 ms until a port arrives and for 10 s at most.",
      "type": "object",
      "required": ["smeet", "type", "v", "sdk", "instance"],
      "properties": {
        "smeet": { "const": "mini-app-bridge" },
        "type": { "const": "hello" },
        "v": { "const": 1 },
        "sdk": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
        "instance": { "$ref": "#/$defs/uuid", "description": "A random id of this document." }
      },
      "additionalProperties": false,
      "examples": [
        { "smeet": "mini-app-bridge", "type": "hello", "v": 1, "sdk": "1.0.0", "instance": "3f6c1a52-9d1e-4c1b-8a8b-0f3d2e5a7c41" }
      ]
    },
    "connect": {
      "description": "Web: SMeet posts it to the frame with exactly one MessagePort. Without instance it was sent on the frame's load event; an instance, when present, is never null and must be the page's own.",
      "type": "object",
      "required": ["smeet", "type", "v", "channel"],
      "properties": {
        "smeet": { "const": "mini-app-bridge" },
        "type": { "const": "connect" },
        "v": { "const": 1 },
        "channel": { "$ref": "#/$defs/uuid" },
        "instance": { "$ref": "#/$defs/uuid" }
      },
      "additionalProperties": false,
      "examples": [
        { "smeet": "mini-app-bridge", "type": "connect", "v": 1, "channel": "b2d7e1f0-5c3a-4e8b-9f1d-6a2c4e8b0d13", "instance": "3f6c1a52-9d1e-4c1b-8a8b-0f3d2e5a7c41" },
        { "smeet": "mini-app-bridge", "type": "connect", "v": 1, "channel": "c4a9e2d1-7b6f-4a3c-8e5d-1f0b2c3d4e5f" }
      ]
    },
    "ping": {
      "description": "Web: SMeet over the port, once a second while the page is connected. Not a request.",
      "type": "object",
      "required": ["type"],
      "properties": { "type": { "const": "ping" } },
      "additionalProperties": false,
      "examples": [{ "type": "ping" }]
    },
    "pong": {
      "description": "Web: the page over the port, first on every port it takes and then to every ping. Not a request.",
      "type": "object",
      "required": ["type", "instance"],
      "properties": {
        "type": { "const": "pong" },
        "instance": { "$ref": "#/$defs/uuid" }
      },
      "additionalProperties": false,
      "examples": [{ "type": "pong", "instance": "3f6c1a52-9d1e-4c1b-8a8b-0f3d2e5a7c41" }]
    },
    "leaving": {
      "description": "Web: the page over the port on pagehide. Not a request.",
      "type": "object",
      "required": ["type", "instance"],
      "properties": {
        "type": { "const": "leaving" },
        "instance": { "$ref": "#/$defs/uuid" }
      },
      "additionalProperties": false,
      "examples": [{ "type": "leaving", "instance": "3f6c1a52-9d1e-4c1b-8a8b-0f3d2e5a7c41" }]
    },

    "request": {
      "description": "A call of the page. id is a new UUID for every request; after a port replacement the page sends unfinished requests again with the same id. At most 20 requests a second per channel.",
      "oneOf": [
        { "$ref": "#/$defs/request.hello" },
        { "$ref": "#/$defs/request.getEnvironment" },
        { "$ref": "#/$defs/request.ready" },
        { "$ref": "#/$defs/request.authorize" },
        { "$ref": "#/$defs/request.submitToBot" },
        { "$ref": "#/$defs/request.getSubmissionStatus" },
        { "$ref": "#/$defs/request.setBackHandler" },
        { "$ref": "#/$defs/request.setClosingConfirmation" },
        { "$ref": "#/$defs/request.openExternalLink" },
        { "$ref": "#/$defs/request.close" }
      ]
    },
    "request.hello": {
      "description": "iOS and macOS only: the first request; the reply is the environment. In web the handshake is the hello message instead.",
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "hello" },
        "params": {
          "type": "object",
          "required": ["v", "sdk"],
          "properties": {
            "v": { "const": 1 },
            "sdk": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "id": "5e0a1c2b-3d4e-4f5a-8b6c-7d8e9f0a1b2c", "method": "hello", "params": { "v": 1, "sdk": "1.0.0" } }]
    },
    "request.getEnvironment": {
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "getEnvironment" },
        "params": { "$ref": "#/$defs/empty" }
      },
      "additionalProperties": false,
      "examples": [{ "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "method": "getEnvironment", "params": {} }]
    },
    "request.ready": {
      "description": "The page has drawn its first screen; SMeet removes its loading screen.",
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "ready" },
        "params": { "$ref": "#/$defs/empty" }
      },
      "additionalProperties": false,
      "examples": [{ "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e", "method": "ready", "params": {} }]
    },
    "request.authorize": {
      "description": "A new login code. Only the PKCE challenge crosses the bridge: base64url(SHA-256(verifier)) without padding.",
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "authorize" },
        "params": {
          "type": "object",
          "required": ["codeChallenge"],
          "properties": {
            "codeChallenge": { "type": "string", "pattern": "^[A-Za-z0-9_-]{43}$" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "id": "3c4d5e6f-7a8b-4c9d-8e1f-2a3b4c5d6e7f", "method": "authorize", "params": { "codeChallenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM" } }]
    },
    "request.submitToBot": {
      "description": "A result for the bot, sent after the person confirms it in SMeet. data is a JSON object of up to 16 KiB in UTF-8 (a size this schema cannot state); requestId is made by the page with its draft, and a repeat with the same requestId and the same data gives the same submission.",
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "submitToBot" },
        "params": {
          "type": "object",
          "required": ["requestId", "data"],
          "properties": {
            "requestId": { "type": "string", "pattern": "^[A-Za-z0-9._:-]{1,64}$" },
            "data": { "type": "object" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "id": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f7a", "method": "submitToBot", "params": { "requestId": "f3b0c9e2-form-1", "data": { "subject": "VPN", "priority": "high" } } }]
    },
    "request.getSubmissionStatus": {
      "description": "Where a submission stands; submissionId is the one submitToBot returned, also in an earlier launch. An unknown or foreign one gets INVALID_PARAMS.",
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "getSubmissionStatus" },
        "params": {
          "type": "object",
          "required": ["submissionId"],
          "properties": {
            "submissionId": { "type": "string", "minLength": 1 }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b", "method": "getSubmissionStatus", "params": { "submissionId": "6f1c9a2e-8a8f-4d6b-9a4e-6d2f0a3b7c11" } }]
    },
    "request.setBackHandler": {
      "description": "enabled: true makes SMeet's Back button send backPressed to the page instead of acting itself.",
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "setBackHandler" },
        "params": {
          "type": "object",
          "required": ["enabled"],
          "properties": { "enabled": { "type": "boolean" } },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "id": "6f7a8b9c-0d1e-4f2a-9b3c-4d5e6f7a8b9c", "method": "setBackHandler", "params": { "enabled": true } }]
    },
    "request.setClosingConfirmation": {
      "description": "enabled: true makes SMeet ask once before it closes the window: the page has unsaved changes.",
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "setClosingConfirmation" },
        "params": {
          "type": "object",
          "required": ["enabled"],
          "properties": { "enabled": { "type": "boolean" } },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d", "method": "setClosingConfirmation", "params": { "enabled": true } }]
    },
    "request.openExternalLink": {
      "description": "SMeet shows the address and opens it in the browser after the person agrees. SMeet takes only an absolute https address with a host, without user name and password, up to 2048 characters and not on SMeet's own host; anything else gets INVALID_PARAMS without a dialog.",
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "openExternalLink" },
        "params": {
          "type": "object",
          "required": ["url"],
          "properties": { "url": { "type": "string" } },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "id": "8b9c0d1e-2f3a-4b4c-9d5e-6f7a8b9c0d1e", "method": "openExternalLink", "params": { "url": "https://example.com/help" } }]
    },
    "request.close": {
      "type": "object",
      "required": ["id", "method", "params"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "method": { "const": "close" },
        "params": { "$ref": "#/$defs/empty" }
      },
      "additionalProperties": false,
      "examples": [{ "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f", "method": "close", "params": {} }]
    },

    "response": {
      "description": "The reply to a request, with its id: a result or an error, never both.",
      "oneOf": [
        { "$ref": "#/$defs/success" },
        { "$ref": "#/$defs/failure" }
      ]
    },
    "success": {
      "type": "object",
      "required": ["id", "result"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "result": { "type": "object", "description": "Of the shape result.<method> of the request's method." }
      },
      "additionalProperties": false
    },
    "failure": {
      "type": "object",
      "required": ["id", "error"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "error": { "$ref": "#/$defs/error" }
      },
      "additionalProperties": false,
      "examples": [
        { "id": "3c4d5e6f-7a8b-4c9d-8e1f-2a3b4c5d6e7f", "error": { "code": "CODE_EXPIRED", "message": "The code expired; call authorize() again" } },
        { "id": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f7a", "error": { "code": "USER_DECLINED", "message": "The person did not send it" } }
      ]
    },
    "error": {
      "type": "object",
      "required": ["code", "message"],
      "properties": {
        "code": { "$ref": "#/$defs/errorCode" },
        "message": { "type": "string", "description": "For people reading logs; do not parse it." }
      },
      "additionalProperties": false
    },
    "errorCode": {
      "description": "The codes of the bridge. CODE_EXPIRED and NETWORK can be retried: call the method again (a new request with a new id). On LAUNCH_CLOSED SMeet itself tells the person why the window closed. INTERNAL on authorize is a fault of SMeet; a new authorize() is a new request.",
      "enum": [
        "UNSUPPORTED_METHOD",
        "INVALID_PARAMS",
        "NOT_READY",
        "USER_DECLINED",
        "BUSY",
        "LAUNCH_CLOSED",
        "CODE_EXPIRED",
        "RATE_LIMITED",
        "PAYLOAD_TOO_LARGE",
        "SUBMISSION_CONFLICT",
        "QUEUE_FULL",
        "NOT_ALLOWED",
        "MAINTENANCE",
        "NETWORK",
        "INTERNAL"
      ]
    },

    "result.hello": {
      "$ref": "#/$defs/environment"
    },
    "result.getEnvironment": {
      "$ref": "#/$defs/environment"
    },
    "result.ready": { "$ref": "#/$defs/empty" },
    "result.authorize": {
      "type": "object",
      "required": ["code", "expiresAt"],
      "properties": {
        "code": { "type": "string", "pattern": "^smlc_[A-Za-z0-9_-]{43}$", "description": "The login code for the author's server; it lives 60 s." },
        "expiresAt": { "$ref": "#/$defs/timestamp" }
      },
      "additionalProperties": false,
      "examples": [{ "code": "smlc_EXAMPLE000000000000000000000000000000000000", "expiresAt": "2026-10-10T12:01:00Z" }]
    },
    "result.submitToBot": {
      "type": "object",
      "required": ["submissionId", "status"],
      "properties": {
        "submissionId": { "$ref": "#/$defs/uuid" },
        "status": { "const": "accepted" }
      },
      "additionalProperties": false,
      "examples": [{ "submissionId": "6f1c9a2e-8a8f-4d6b-9a4e-6d2f0a3b7c11", "status": "accepted" }]
    },
    "result.getSubmissionStatus": {
      "type": "object",
      "required": ["status"],
      "properties": {
        "status": { "$ref": "#/$defs/submissionStatus" }
      },
      "additionalProperties": false,
      "examples": [{ "status": "delivered" }]
    },
    "result.setBackHandler": { "$ref": "#/$defs/empty" },
    "result.setClosingConfirmation": { "$ref": "#/$defs/empty" },
    "result.openExternalLink": {
      "type": "object",
      "required": ["opened"],
      "properties": {
        "opened": { "type": "boolean", "description": "false when the person chose Cancel." }
      },
      "additionalProperties": false,
      "examples": [{ "opened": true }, { "opened": false }]
    },
    "result.close": { "$ref": "#/$defs/empty" },
    "submissionStatus": {
      "description": "pending: in the bot's queue; delivered: the bot confirmed it; failed: in the owner's list of failed updates; cancelled: cancelled before delivery or skipped; expired: not confirmed within 7 days.",
      "enum": ["pending", "delivered", "failed", "cancelled", "expired"]
    },

    "environment": {
      "description": "What SMeet says about this launch. viewport is the visible area of the app under the SMeet bar and above the on-screen keyboard; safeArea gives the device cut-outs that cross it.",
      "type": "object",
      "required": ["bridgeVersion", "platform", "appId", "deployment", "startParam", "language", "colorScheme", "theme", "viewport", "safeArea", "methods"],
      "properties": {
        "bridgeVersion": { "const": 1 },
        "platform": { "enum": ["web", "ios", "macos"] },
        "appId": { "type": "string", "pattern": "^[0-9]{1,20}$" },
        "deployment": { "enum": ["test", "production"] },
        "startParam": { "type": ["string", "null"], "pattern": "^[A-Za-z0-9_-]{0,64}$" },
        "language": { "$ref": "#/$defs/language" },
        "colorScheme": { "$ref": "#/$defs/colorScheme" },
        "theme": { "$ref": "#/$defs/theme" },
        "viewport": { "$ref": "#/$defs/viewport" },
        "safeArea": { "$ref": "#/$defs/safeArea" },
        "methods": {
          "description": "The methods this SMeet client serves. A method that is not listed fails in the SDK with UNSUPPORTED_METHOD.",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "enum": ["getEnvironment", "ready", "authorize", "submitToBot", "getSubmissionStatus", "setBackHandler", "setClosingConfirmation", "openExternalLink", "close"]
          }
        }
      },
      "additionalProperties": false,
      "examples": [
        {
          "bridgeVersion": 1, "platform": "web", "appId": "1000", "deployment": "production", "startParam": "vpn-access",
          "language": "en", "colorScheme": "dark",
          "theme": { "bg": "#1c1c1e", "text": "#f5f5f7", "hint": "rgba(235, 235, 245, 0.62)", "link": "#0a84ff", "button": "#0a84ff", "buttonText": "#ffffff", "secondaryBg": "#000000" },
          "viewport": { "width": 420, "height": 702, "isExpanded": false },
          "safeArea": { "top": 0, "bottom": 0, "left": 0, "right": 0 },
          "methods": ["getEnvironment", "ready", "authorize", "submitToBot", "getSubmissionStatus", "setBackHandler", "setClosingConfirmation", "openExternalLink", "close"]
        }
      ]
    },
    "language": { "enum": ["ru", "en"] },
    "colorScheme": { "enum": ["light", "dark"] },
    "theme": {
      "description": "CSS colors of SMeet's look.",
      "type": "object",
      "required": ["bg", "text", "hint", "link", "button", "buttonText", "secondaryBg"],
      "properties": {
        "bg": { "type": "string", "minLength": 1 },
        "text": { "type": "string", "minLength": 1 },
        "hint": { "type": "string", "minLength": 1 },
        "link": { "type": "string", "minLength": 1 },
        "button": { "type": "string", "minLength": 1 },
        "buttonText": { "type": "string", "minLength": 1 },
        "secondaryBg": { "type": "string", "minLength": 1 }
      },
      "additionalProperties": false
    },
    "viewport": {
      "type": "object",
      "required": ["width", "height", "isExpanded"],
      "properties": {
        "width": { "type": "number", "minimum": 0 },
        "height": { "type": "number", "minimum": 0 },
        "isExpanded": { "type": "boolean" }
      },
      "additionalProperties": false
    },
    "safeArea": {
      "type": "object",
      "required": ["top", "bottom", "left", "right"],
      "properties": {
        "top": { "type": "number", "minimum": 0 },
        "bottom": { "type": "number", "minimum": 0 },
        "left": { "type": "number", "minimum": 0 },
        "right": { "type": "number", "minimum": 0 }
      },
      "additionalProperties": false
    },

    "event": {
      "description": "An event of SMeet. The page ignores an event it does not know.",
      "oneOf": [
        { "$ref": "#/$defs/event.themeChanged" },
        { "$ref": "#/$defs/event.viewportChanged" },
        { "$ref": "#/$defs/event.visibilityChanged" },
        { "$ref": "#/$defs/event.languageChanged" },
        { "$ref": "#/$defs/event.backPressed" }
      ]
    },
    "event.themeChanged": {
      "type": "object",
      "required": ["event", "data"],
      "properties": {
        "event": { "const": "themeChanged" },
        "data": {
          "type": "object",
          "required": ["colorScheme", "theme"],
          "properties": {
            "colorScheme": { "$ref": "#/$defs/colorScheme" },
            "theme": { "$ref": "#/$defs/theme" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "event": "themeChanged", "data": { "colorScheme": "light", "theme": { "bg": "#ffffff", "text": "#1c1c1e", "hint": "rgba(60, 60, 67, 0.62)", "link": "#007aff", "button": "#007aff", "buttonText": "#ffffff", "secondaryBg": "#f2f2f7" } } }]
    },
    "event.viewportChanged": {
      "description": "The keyboard, a rotation, the size of the window on a Mac, expanding and collapsing.",
      "type": "object",
      "required": ["event", "data"],
      "properties": {
        "event": { "const": "viewportChanged" },
        "data": {
          "type": "object",
          "required": ["viewport", "safeArea"],
          "properties": {
            "viewport": { "$ref": "#/$defs/viewport" },
            "safeArea": { "$ref": "#/$defs/safeArea" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "event": "viewportChanged", "data": { "viewport": { "width": 390, "height": 412, "isExpanded": true }, "safeArea": { "top": 0, "bottom": 0, "left": 0, "right": 0 } } }]
    },
    "event.visibilityChanged": {
      "description": "visible is false while SMeet hides the window, for example during a call.",
      "type": "object",
      "required": ["event", "data"],
      "properties": {
        "event": { "const": "visibilityChanged" },
        "data": {
          "type": "object",
          "required": ["visible"],
          "properties": { "visible": { "type": "boolean" } },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "event": "visibilityChanged", "data": { "visible": false } }]
    },
    "event.languageChanged": {
      "description": "Web only: on iOS and macOS a change of language closes the window.",
      "type": "object",
      "required": ["event", "data"],
      "properties": {
        "event": { "const": "languageChanged" },
        "data": {
          "type": "object",
          "required": ["language"],
          "properties": { "language": { "$ref": "#/$defs/language" } },
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "examples": [{ "event": "languageChanged", "data": { "language": "ru" } }]
    },
    "event.backPressed": {
      "description": "The person pressed SMeet's Back while the page holds a back handler.",
      "type": "object",
      "required": ["event", "data"],
      "properties": {
        "event": { "const": "backPressed" },
        "data": { "$ref": "#/$defs/empty" }
      },
      "additionalProperties": false,
      "examples": [{ "event": "backPressed", "data": {} }]
    }
  }
}
